diff -X dontdiff -ur linux-2.5.24/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c --- linux-2.5.24/drivers/block/ll_rw_blk.c Mon Jun 24 22:20:53 2002 +++ linux/drivers/block/ll_rw_blk.c Wed Jun 26 19:56:53 2002 @@ -1203,6 +1203,26 @@ return rq; } +/* + * Non-locking blk_get_request variant, for special requests from drivers. + */ +struct request *__blk_get_request(request_queue_t *q, int rw) +{ + struct request *rq; + + BUG_ON(rw != READ && rw != WRITE); + + rq = get_request(q, rw); + + if (rq) { + rq->flags = 0; + rq->buffer = NULL; + rq->bio = rq->biotail = NULL; + rq->waiting = NULL; + } + return rq; +} + void blk_put_request(struct request *rq) { blkdev_release_request(rq); @@ -1384,6 +1404,14 @@ spin_unlock_irqrestore(q->queue_lock, flags); } +/* + * Non-locking blk_attempt_remerge variant. + */ +void __blk_attempt_remerge(request_queue_t *q, struct request *rq) +{ + attempt_back_merge(q, rq); +} + static int __make_request(request_queue_t *q, struct bio *bio) { struct request *req, *freereq = NULL; @@ -2042,6 +2070,7 @@ EXPORT_SYMBOL(blk_plug_device); EXPORT_SYMBOL(blk_remove_plug); EXPORT_SYMBOL(blk_attempt_remerge); +EXPORT_SYMBOL(__blk_attempt_remerge); EXPORT_SYMBOL(blk_max_low_pfn); EXPORT_SYMBOL(blk_max_pfn); EXPORT_SYMBOL(blk_queue_max_sectors); @@ -2058,6 +2087,7 @@ EXPORT_SYMBOL(blk_phys_contig_segment); EXPORT_SYMBOL(blk_hw_contig_segment); EXPORT_SYMBOL(blk_get_request); +EXPORT_SYMBOL(__blk_get_request); EXPORT_SYMBOL(blk_put_request); EXPORT_SYMBOL(blk_queue_prep_rq); diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide-cd.c linux/drivers/ide/ide-cd.c --- linux-2.5.24/drivers/ide/ide-cd.c Tue Jun 18 00:29:02 2002 +++ linux/drivers/ide/ide-cd.c Thu Jun 27 01:36:08 2002 @@ -556,7 +556,7 @@ if ((rq->flags & REQ_CMD) && !rq->current_nr_sectors) uptodate = 1; - ata_end_request(drive, rq, uptodate); + __ata_end_request(drive, rq, uptodate, 0); } @@ -692,10 +692,8 @@ return 1; } -static int cdrom_timer_expiry(struct ata_device *drive, struct request *rq) +static ide_startstop_t cdrom_timer_expiry(struct ata_device *drive, struct request *rq, unsigned long *wait) { - unsigned long wait = 0; - /* * Some commands are *slow* and normally take a long time to * complete. Usually we can use the ATAPI "disconnect" to bypass @@ -706,14 +704,14 @@ case GPCMD_BLANK: case GPCMD_FORMAT_UNIT: case GPCMD_RESERVE_RZONE_TRACK: - wait = WAIT_CMD; - break; + *wait = WAIT_CMD; + return ide_started; default: - wait = 0; + *wait = 0; break; } - return wait; + return ide_stopped; } /* Set up the device registers for transferring a packet command on DEV, @@ -728,13 +726,10 @@ int xferlen, ata_handler_t handler) { - unsigned long flags; - struct ata_channel *ch = drive->channel; ide_startstop_t startstop; struct cdrom_info *info = drive->driver_data; int ret; - spin_lock_irqsave(ch->lock, flags); /* Wait for the controller to be idle. */ if (ata_status_poll(drive, 0, BUSY_STAT, WAIT_READY, rq, &startstop)) ret = startstop; @@ -764,15 +759,9 @@ } else { OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */ - /* FIXME: Oj kurwa! We have to ungrab the lock before - * the IRQ handler gets called. - */ - spin_unlock_irqrestore(ch->lock, flags); ret = handler(drive, rq); - spin_lock_irqsave(ch->lock, flags); } } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -787,8 +776,6 @@ unsigned char *cmd, unsigned long timeout, ata_handler_t handler) { - unsigned long flags; - struct ata_channel *ch = drive->channel; ide_startstop_t startstop; if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { @@ -800,24 +787,15 @@ if (cdrom_decode_status(&startstop, drive, rq, DRQ_STAT, &stat_dum)) return startstop; } else { - /* FIXME: make this locking go away */ - spin_lock_irqsave(ch->lock, flags); /* Otherwise, we must wait for DRQ to get set. */ if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT, - WAIT_READY, rq, &startstop)) { - spin_unlock_irqrestore(ch->lock, flags); - + WAIT_READY, rq, &startstop)) return startstop; - } - spin_unlock_irqrestore(ch->lock, flags); } /* Arm the interrupt handler and send the command to the device. */ - /* FIXME: make this locking go away */ - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, handler, timeout, cdrom_timer_expiry); atapi_write(drive, cmd, CDROM_PACKET_SIZE); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -917,8 +895,6 @@ */ static ide_startstop_t cdrom_read_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int stat; int ireason, len, sectors_to_transfer, nskip; struct cdrom_info *info = drive->driver_data; @@ -937,13 +913,7 @@ if (dma) { if (!dma_error) { - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); __ata_end_request(drive, rq, 1, rq->nr_sectors); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } else @@ -1040,9 +1010,7 @@ } /* Done moving data! Wait for another interrupt. */ - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, cdrom_read_intr, WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -1245,7 +1213,7 @@ if (cdrom_read_from_buffer(drive, rq)) return ide_stopped; - blk_attempt_remerge(&drive->queue, rq); + __blk_attempt_remerge(&drive->queue, rq); /* Clear the local sector buffer. */ info->nsectors_buffered = 0; @@ -1269,8 +1237,6 @@ /* Interrupt routine for packet command completion. */ static ide_startstop_t cdrom_pc_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int ireason, len, stat, thislen; /* FIXME --mdcki */ @@ -1363,9 +1329,7 @@ } /* Now we wait for another interrupt. */ - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -1508,8 +1472,6 @@ static ide_startstop_t cdrom_write_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int stat, ireason, len, sectors_to_transfer, uptodate; struct cdrom_info *info = drive->driver_data; int dma_error = 0, dma = info->dma; @@ -1536,13 +1498,7 @@ if (dma_error) return ata_error(drive, rq, "dma error"); - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); __ata_end_request(drive, rq, 1, rq->nr_sectors); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } @@ -1607,9 +1563,7 @@ } /* re-arm handler */ - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, cdrom_write_intr, 5 * WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -1637,7 +1591,7 @@ * remerge requests, often the plugging will not have had time * to do this properly */ - blk_attempt_remerge(&drive->queue, rq); + __blk_attempt_remerge(&drive->queue, rq); info->nsectors_buffered = 0; @@ -1658,7 +1612,6 @@ static ide_startstop_t ide_cdrom_do_request(struct ata_device *drive, struct request *rq, sector_t block) { - struct ata_channel *ch = drive->channel; int ret; struct cdrom_info *info = drive->driver_data; @@ -1675,8 +1628,6 @@ } CDROM_CONFIG_FLAGS(drive)->seeking = 0; } - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); if (IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) { ret = cdrom_start_seek(drive, rq, block); } else { @@ -1686,13 +1637,9 @@ ret = cdrom_start_write(drive, rq); } info->last_block = block; - spin_lock_irq(ch->lock); return ret; } else if (rq->flags & (REQ_PC | REQ_SENSE)) { - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); ret = cdrom_do_packet_command(drive, rq); - spin_lock_irq(ch->lock); return ret; } else if (rq->flags & REQ_SPECIAL) { @@ -1703,10 +1650,7 @@ * right now this can only be a reset... */ - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); cdrom_end_request(drive, rq, 1); - spin_lock_irq(ch->lock); return ide_stopped; } else if (rq->flags & REQ_BLOCK_PC) { @@ -1720,10 +1664,7 @@ /* FIXME --mdcki */ rq->special = (char *) &pc; - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); startstop = cdrom_do_packet_command(drive, rq); - spin_lock_irq(ch->lock); if (pc.stat) ++rq->errors; @@ -1732,10 +1673,8 @@ } blk_dump_rq_flags(rq, "ide-cd bad flags"); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + cdrom_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); return ide_stopped; } diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c --- linux-2.5.24/drivers/ide/ide-disk.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/ide-disk.c Wed Jun 26 22:17:11 2002 @@ -107,22 +107,20 @@ } /* + * The following IRQ handlers (*_intr) should be called + * with the channel lock held and interrupts disabled. + */ + +/* * Handler for command with PIO data-in phase. */ static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int ret; - spin_lock_irqsave(ch->lock, flags); - if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { - if (drive->status & (ERR_STAT | DRQ_STAT)) { - spin_unlock_irqrestore(ch->lock, flags); - + if (drive->status & (ERR_STAT | DRQ_STAT)) return ata_error(drive, rq, __FUNCTION__); - } /* no data yet, so wait for another interrupt */ ata_set_handler(drive, task_in_intr, WAIT_CMD, NULL); @@ -149,7 +147,6 @@ if (rq->current_nr_sectors <= 0) { if (!__ata_end_request(drive, rq, 1, 0)) { // printk("Request Ended stat: %02x\n", drive->status); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } @@ -160,7 +157,6 @@ ret = ide_started; } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -170,16 +166,10 @@ */ static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int ret; - spin_lock_irqsave(ch->lock, flags); - if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) { - spin_unlock_irqrestore(ch->lock, flags); - + if (!ata_status(drive, DRIVE_READY, drive->bad_wstat)) return ata_error(drive, rq, __FUNCTION__); - } if (!rq->current_nr_sectors && !__ata_end_request(drive, rq, 1, 0)) { ret = ide_stopped; @@ -200,7 +190,6 @@ ret = ide_started; } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -210,17 +199,11 @@ */ static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; int ret; - spin_lock_irqsave(ch->lock, flags); if (!ata_status(drive, DATA_READY, BAD_R_STAT)) { - if (drive->status & (ERR_STAT | DRQ_STAT)) { - spin_unlock_irqrestore(ch->lock, flags); - + if (drive->status & (ERR_STAT | DRQ_STAT)) return ata_error(drive, rq, __FUNCTION__); - } /* no data yet, so wait for another interrupt */ ata_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL); @@ -257,11 +240,8 @@ /* FIXME: this seems buggy */ if (rq->current_nr_sectors <= 0) { - if (!__ata_end_request(drive, rq, 1, 0)) { - spin_unlock_irqrestore(ch->lock, flags); - + if (!__ata_end_request(drive, rq, 1, 0)) return ide_stopped; - } } msect -= nsect; } while (msect); @@ -271,20 +251,16 @@ ret = ide_started; } - spin_unlock_irqrestore(ch->lock, flags); return ret; } static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; struct ata_channel *ch = drive->channel; int ok; int ret; - spin_lock_irqsave(ch->lock, flags); - /* * FIXME: the drive->status checks here seem to be messy. * @@ -295,11 +271,8 @@ ok = ata_status(drive, DATA_READY, BAD_R_STAT); if (!ok || !rq->nr_sectors) { - if (drive->status & (ERR_STAT | DRQ_STAT)) { - spin_unlock_irqrestore(ch->lock, flags); - + if (drive->status & (ERR_STAT | DRQ_STAT)) return ata_error(drive, rq, __FUNCTION__); - } } if (!rq->nr_sectors) { __ata_end_request(drive, rq, 1, rq->hard_nr_sectors); @@ -307,6 +280,7 @@ ret = ide_stopped; } else if (!ok) { /* no data yet, so wait for another interrupt */ + /* FIXME: --bzolnier */ if (!ch->handler) ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); ret = ide_started; @@ -351,14 +325,14 @@ rq->errors = 0; + /* FIXME: --bzolnier */ if (!ch->handler) ata_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL); ret = ide_started; } - spin_unlock_irqrestore(ch->lock, flags); - return ide_started; + return ret; } /* @@ -508,8 +482,7 @@ } else if (drive->using_dma) { cmd = WIN_READDMA; } else if (drive->mult_count) { - /* FIXME : Shouldn't this be task_mulin_intr?! */ - args.XXX_handler = task_in_intr; + args.XXX_handler = task_mulin_intr; cmd = WIN_MULTREAD; } else { args.XXX_handler = task_in_intr; @@ -579,7 +552,6 @@ /* FIXME: this is actually distingushing between PIO and DMA requests. */ if (ar->XXX_handler) { - struct ata_channel *ch = drive->channel; ata_set_handler(drive, ar->XXX_handler, WAIT_CMD, NULL); OUT_BYTE(cmd, IDE_COMMAND_REG); @@ -628,7 +600,6 @@ return ide_started; } else { int i; - int ret; /* Polling wait until the drive is ready. * @@ -649,12 +620,8 @@ */ printk(KERN_ERR "DISASTER WAITING TO HAPPEN!\n"); } - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); - ret = ar->XXX_handler(drive, rq); - spin_lock_irq(ch->lock); - return ret; + return ar->XXX_handler(drive, rq); } } } else { diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide-floppy.c linux/drivers/ide/ide-floppy.c --- linux-2.5.24/drivers/ide/ide-floppy.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/ide-floppy.c Thu Jun 27 12:37:53 2002 @@ -365,7 +365,7 @@ return 0; if (!(rq->flags & REQ_SPECIAL)) { - ata_end_request(drive, rq, uptodate); + __ata_end_request(drive, rq, uptodate, 0); return 0; } @@ -554,8 +554,6 @@ */ static ide_startstop_t idefloppy_pc_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; idefloppy_floppy_t *floppy = drive->driver_data; atapi_status_reg_t status; atapi_bcount_reg_t bcount; @@ -618,26 +616,20 @@ return ide_stopped; } #endif - /* FIXME: this locking should encompass the above register - * file access too. - */ - spin_lock_irqsave(ch->lock, flags); bcount.b.high=IN_BYTE (IDE_BCOUNTH_REG); /* Get the number of bytes to transfer */ bcount.b.low=IN_BYTE (IDE_BCOUNTL_REG); /* on this interrupt */ ireason.all=IN_BYTE (IDE_IREASON_REG); if (ireason.b.cod) { - spin_unlock_irqrestore(ch->lock, flags); - printk (KERN_ERR "ide-floppy: CoD != 0 in idefloppy_pc_intr\n"); + return ide_stopped; } if (ireason.b.io == test_bit(PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ - spin_unlock_irqrestore(ch->lock, flags); - printk (KERN_ERR "ide-floppy: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk (KERN_ERR "but the floppy wants us to %s !\n",ireason.b.io ? "Read":"Write"); + return ide_stopped; } if (!test_bit(PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */ @@ -648,7 +640,6 @@ atapi_discard_data (drive,bcount.all); ata_set_handler(drive, idefloppy_pc_intr,IDEFLOPPY_WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -672,7 +663,6 @@ pc->current_position+=bcount.all; ata_set_handler(drive, idefloppy_pc_intr, IDEFLOPPY_WAIT_CMD, NULL); /* And set the interrupt handler again */ - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -684,16 +674,11 @@ */ static ide_startstop_t idefloppy_transfer_pc(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; ide_startstop_t startstop; idefloppy_floppy_t *floppy = drive->driver_data; atapi_ireason_reg_t ireason; int ret; - /* FIXME: Move this lock upwards. - */ - spin_lock_irqsave(ch->lock, flags); if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq, &startstop)) { printk (KERN_ERR "ide-floppy: Strange, packet command initiated yet DRQ isn't asserted\n"); @@ -711,7 +696,6 @@ ret = ide_started; } } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -729,18 +713,18 @@ * packet, we schedule the packet transfer to occur about 2-3 ticks * later in transfer_pc2. */ -static int idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq) +static ide_startstop_t idefloppy_transfer_pc2(struct ata_device *drive, struct request *__rq, unsigned long *wait) { idefloppy_floppy_t *floppy = drive->driver_data; atapi_write(drive, floppy->pc->c, 12); /* Send the actual packet */ - return IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */ + *wait = IDEFLOPPY_WAIT_CMD; /* Timeout for the packet command */ + + return ide_started; } static ide_startstop_t idefloppy_transfer_pc1(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; idefloppy_floppy_t *floppy = drive->driver_data; ide_startstop_t startstop; atapi_ireason_reg_t ireason; @@ -753,11 +737,6 @@ return startstop; } - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ireason.all=IN_BYTE(IDE_IREASON_REG); if (!ireason.b.cod || ireason.b.io) { printk (KERN_ERR "ide-floppy: (IO,CoD) != (0,1) while issuing a packet command\n"); @@ -778,7 +757,6 @@ idefloppy_transfer_pc2); /* fail == transfer_pc2 */ ret = ide_started; } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -859,17 +837,8 @@ } if (test_bit(IDEFLOPPY_DRQ_INTERRUPT, &floppy->flags)) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, pkt_xfer_routine, IDEFLOPPY_WAIT_CMD, NULL); OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } else { @@ -1010,10 +979,8 @@ */ static ide_startstop_t idefloppy_do_request(struct ata_device *drive, struct request *rq, sector_t block) { - struct ata_channel *ch = drive->channel; idefloppy_floppy_t *floppy = drive->driver_data; struct atapi_packet_command *pc; - int ret; #if IDEFLOPPY_DEBUG_LOG printk (KERN_INFO "rq_status: %d, rq_dev: %u, flags: %lx, errors: %d\n",rq->rq_status,(unsigned int) rq->rq_dev,rq->flags,rq->errors); @@ -1027,20 +994,15 @@ else printk (KERN_ERR "ide-floppy: %s: I/O error\n", drive->name); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); idefloppy_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); return ide_stopped; } if (rq->flags & REQ_CMD) { if (rq->sector % floppy->bs_factor || rq->nr_sectors % floppy->bs_factor) { printk ("%s: unsupported r/w request size\n", drive->name); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + idefloppy_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); return ide_stopped; } @@ -1051,20 +1013,13 @@ pc = (struct atapi_packet_command *) rq->buffer; } else { blk_dump_rq_flags(rq, "ide-floppy: unsupported command in queue"); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + idefloppy_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); return ide_stopped; } - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); - ret = idefloppy_issue_pc(drive, rq, pc); - spin_lock_irq(ch->lock); - - return ret; + return idefloppy_issue_pc(drive, rq, pc); } /* diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide-tape.c linux/drivers/ide/ide-tape.c --- linux-2.5.24/drivers/ide/ide-tape.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/ide-tape.c Wed Jun 26 17:54:11 2002 @@ -10,6 +10,10 @@ */ /* + * BIG FAT FIXME: clean tape->spinlock locking --bzolnier + */ + +/* * IDE ATAPI streaming tape driver. * * This driver is a part of the Linux ide driver and works in co-operation @@ -1818,8 +1822,6 @@ */ static ide_startstop_t idetape_pc_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; idetape_tape_t *tape = drive->driver_data; atapi_status_reg_t status; atapi_bcount_reg_t bcount; @@ -1915,17 +1917,11 @@ pc->callback(drive, rq); /* Command finished - Call the callback function */ return ide_stopped; } - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); #ifdef CONFIG_BLK_DEV_IDEDMA if (test_and_clear_bit (PC_DMA_IN_PROGRESS, &pc->flags)) { printk (KERN_ERR "ide-tape: The tape wants to issue more interrupts in DMA mode\n"); printk (KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); udma_enable(drive, 0, 1); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } @@ -1936,16 +1932,14 @@ ireason.all = IN_BYTE (IDE_IREASON_REG); if (ireason.b.cod) { - spin_unlock_irqrestore(ch->lock, flags); - printk (KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); + return ide_stopped; } if (ireason.b.io == test_bit (PC_WRITING, &pc->flags)) { /* Hopefully, we will never get here */ - spin_unlock_irqrestore(ch->lock, flags); - printk (KERN_ERR "ide-tape: We wanted to %s, ", ireason.b.io ? "Write":"Read"); printk (KERN_ERR "ide-tape: but the tape wants us to %s !\n",ireason.b.io ? "Read":"Write"); + return ide_stopped; } if (!test_bit (PC_WRITING, &pc->flags)) { /* Reading - Check that we have enough space */ @@ -1955,7 +1949,6 @@ printk (KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); atapi_discard_data (drive, bcount.all); ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -1983,7 +1976,6 @@ printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes on that interrupt\n", pc->c[0], bcount.all); #endif ata_set_handler(drive, idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); /* And set the interrupt handler again */ - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -2032,8 +2024,6 @@ */ static ide_startstop_t idetape_transfer_pc(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; idetape_tape_t *tape = drive->driver_data; struct atapi_packet_command *pc = tape->pc; atapi_ireason_reg_t ireason; @@ -2041,9 +2031,6 @@ ide_startstop_t startstop; int ret; - /* FIXME: Move this lock upwards. - */ - spin_lock_irqsave(ch->lock, flags); if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq, &startstop)) { printk (KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); @@ -2071,7 +2058,6 @@ ret = ide_started; } } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -2145,17 +2131,8 @@ } #endif if (test_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags)) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, idetape_transfer_pc, IDETAPE_WAIT_CMD, NULL); OUT_BYTE(WIN_PACKETCMD, IDE_COMMAND_REG); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } else { @@ -2445,12 +2422,10 @@ */ static ide_startstop_t idetape_do_request(struct ata_device *drive, struct request *rq, sector_t block) { - struct ata_channel *ch = drive->channel; idetape_tape_t *tape = drive->driver_data; struct atapi_packet_command *pc; struct request *postponed_rq = tape->postponed_rq; atapi_status_reg_t status; - int ret; #if IDETAPE_DEBUG_LOG /* if (tape->debug_level >= 5) @@ -2472,23 +2447,15 @@ * Retry a failed packet command */ if (tape->failed_pc != NULL && tape->pc->c[0] == IDETAPE_REQUEST_SENSE_CMD) { - int ret; - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); - ret = idetape_issue_packet_command(drive, rq, tape->failed_pc); - spin_lock_irq(ch->lock); - - return ret; + return idetape_issue_packet_command(drive, rq, tape->failed_pc); } #if IDETAPE_DEBUG_BUGS if (postponed_rq != NULL) if (rq != postponed_rq) { printk (KERN_ERR "ide-tape: ide-tape.c bug - Two DSC requests were queued\n"); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + idetape_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); return ide_stopped; } @@ -2566,15 +2533,11 @@ tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; } else if ((signed long) (jiffies - tape->dsc_timeout) > 0) { printk (KERN_ERR "ide-tape: %s: DSC timeout\n", tape->name); - if (rq->flags == IDETAPE_PC_RQ2) { - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + + if (rq->flags == IDETAPE_PC_RQ2) idetape_media_access_finished(drive, rq); - spin_lock_irq(ch->lock); - return ide_stopped; - } else { - return ide_stopped; - } + + return ide_stopped; } else if (jiffies - tape->dsc_polling_start > IDETAPE_DSC_MA_THRESHOLD) tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW; idetape_postpone_request(drive, rq); @@ -2638,25 +2601,18 @@ rq->flags = IDETAPE_PC_RQ2; break; case IDETAPE_PC_RQ2: - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); idetape_media_access_finished(drive, rq); - spin_lock_irq(ch->lock); + return ide_stopped; default: printk (KERN_ERR "ide-tape: bug in IDETAPE_RQ_CMD macro\n"); - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); + idetape_end_request(drive, rq, 0); - spin_lock_irq(ch->lock); + return ide_stopped; } - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); - ret = idetape_issue_packet_command(drive, rq, pc); - spin_lock_irq(ch->lock); - return ret; + return idetape_issue_packet_command(drive, rq, pc); } /* diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide-taskfile.c linux/drivers/ide/ide-taskfile.c --- linux-2.5.24/drivers/ide/ide-taskfile.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/ide-taskfile.c Thu Jun 27 01:34:44 2002 @@ -242,16 +242,18 @@ /* * Invoked on completion of a special REQ_SPECIAL command. */ +/* + * Channel lock should be held. + */ static ide_startstop_t special_intr(struct ata_device *drive, struct request *rq) { struct ata_taskfile *ar = rq->special; ide_startstop_t ret = ide_stopped; - unsigned long flags; - ide__sti(); /* local CPU only */ - - spin_lock_irqsave(drive->channel->lock, flags); + /* FIXME: --bzolnier + ide__sti(); + */ if (rq->buffer && ar->taskfile.sector_number) { if (!ata_status(drive, 0, DRQ_STAT) && ar->taskfile.sector_number) { @@ -287,8 +289,6 @@ drive->rq = NULL; end_that_request_last(rq); - spin_unlock_irqrestore(drive->channel->lock, flags); - return ret; } diff -X dontdiff -ur linux-2.5.24/drivers/ide/ide.c linux/drivers/ide/ide.c --- linux-2.5.24/drivers/ide/ide.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/ide.c Thu Jun 27 02:03:30 2002 @@ -148,22 +148,6 @@ } /* - * This is the default end request function as well - */ -int ata_end_request(struct ata_device *drive, struct request *rq, int uptodate) -{ - unsigned long flags; - struct ata_channel *ch = drive->channel; - int ret; - - spin_lock_irqsave(ch->lock, flags); - ret = __ata_end_request(drive, rq, uptodate, 0); - spin_unlock_irqrestore(drive->channel->lock, flags); - - return ret; -} - -/* * This should get invoked any time we exit the driver to * wait for an interrupt response from a drive. handler() points * at the appropriate code to handle the next interrupt, and a @@ -347,7 +331,7 @@ } ch->poll_timeout = 0; /* done polling */ - return ide_stopped; + return ret; } /* @@ -374,6 +358,7 @@ unsigned long flags; struct ata_channel *ch = drive->channel; + /* FIXME: --bzolnier */ __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only */ @@ -467,6 +452,7 @@ unsigned long flags; u8 err = 0; + /* FIXME: --bzolnier */ __save_flags (flags); /* local CPU only */ ide__sti(); /* local CPU only */ @@ -573,7 +559,7 @@ /* * Take action based on the error returned by the drive. * - * FIXME: Channel lock should be held. + * Channel lock should be held. */ ide_startstop_t ata_error(struct ata_device *drive, struct request *rq, const char *msg) { @@ -617,7 +603,6 @@ if (rq->errors >= ERROR_MAX) { printk(KERN_ERR "%s: max number of retries exceeded!\n", drive->name); - /* FIXME: make sure all end_request implementations are lock free */ if (ata_ops(drive) && ata_ops(drive)->end_request) ata_ops(drive)->end_request(drive, rq, 0); else @@ -627,6 +612,7 @@ if ((rq->errors & ERROR_RESET) == ERROR_RESET) return do_reset1(drive, 1); if ((rq->errors & ERROR_RECAL) == ERROR_RECAL) + /* FIXME: tries to acquire the channel lock -Zwane */ return do_recalibrate(drive); } @@ -700,35 +686,14 @@ return ret; kill_rq: - if (ata_ops(drive)) { - if (ata_ops(drive)->end_request) { - spin_unlock_irq(ch->lock); - ata_ops(drive)->end_request(drive, rq, 0); - spin_lock_irq(ch->lock); - } else - __ata_end_request(drive, rq, 0, 0); - } else + if (ata_ops(drive) && ata_ops(drive)->end_request) + ata_ops(drive)->end_request(drive, rq, 0); + else __ata_end_request(drive, rq, 0, 0); return ide_stopped; } -ide_startstop_t restart_request(struct ata_device *drive) -{ - struct ata_channel *ch = drive->channel; - unsigned long flags; - int ret; - - spin_lock_irqsave(ch->lock, flags); - - ch->handler = NULL; - del_timer(&ch->timer); - ret = start_request(drive, drive->rq); - spin_unlock_irqrestore(ch->lock, flags); - - return ret; -} - /* * This is used by a drive to give excess bandwidth back by sleeping for * timeout jiffies. @@ -993,10 +958,13 @@ unsigned long wait; /* continue */ - if ((wait = ch->expiry(drive, drive->rq)) != 0) { + ret = ch->expiry(drive, drive->rq, &wait); + if (ret == ide_started) { /* reengage timer */ - ch->timer.expires = jiffies + wait; - add_timer(&ch->timer); + if (wait) { + ch->timer.expires = jiffies + wait; + add_timer(&ch->timer); + } spin_unlock_irqrestore(ch->lock, flags); @@ -1012,7 +980,6 @@ handler = ch->handler; ch->handler = NULL; - spin_unlock(ch->lock); ch = drive->channel; #if DISABLE_IRQ_NOSYNC @@ -1069,12 +1036,9 @@ enable_irq(ch->irq); - spin_lock_irq(ch->lock); - if (ret == ide_stopped) clear_bit(IDE_BUSY, ch->active); - /* Reenter the request handling engine */ do_request(ch); } @@ -1202,14 +1166,14 @@ ch->handler = NULL; del_timer(&ch->timer); - spin_unlock(ch->lock); - - if (ch->unmask) - ide__sti(); /* local CPU only */ + if (ch->unmask) { + /* FIXME: perhaps disable_irq(irq); __sti(); ? -Zwane + ide__sti(); + */ + } /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive, drive->rq); - spin_lock_irq(ch->lock); /* * Note that handler() may have set things up for another @@ -1376,9 +1340,6 @@ EXPORT_SYMBOL(ata_dump); EXPORT_SYMBOL(ata_error); -/* FIXME: this is a trully bad name */ -EXPORT_SYMBOL(restart_request); -EXPORT_SYMBOL(ata_end_request); EXPORT_SYMBOL(__ata_end_request); EXPORT_SYMBOL(ide_stall_queue); diff -X dontdiff -ur linux-2.5.24/drivers/ide/pcidma.c linux/drivers/ide/pcidma.c --- linux-2.5.24/drivers/ide/pcidma.c Tue Jun 25 22:46:36 2002 +++ linux/drivers/ide/pcidma.c Wed Jun 26 17:46:50 2002 @@ -36,6 +36,8 @@ /* * This is the handler for disk read/write DMA interrupts. + * + * Channel lock should be held. */ ide_startstop_t ide_dma_intr(struct ata_device *drive, struct request *rq) { @@ -44,16 +46,7 @@ if (ata_status(drive, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) { if (!dma_stat) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); __ata_end_request(drive, rq, 1, rq->nr_sectors); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } @@ -128,7 +121,7 @@ /* * 1 dma-ing, 2 error, 4 intr */ -static int dma_timer_expiry(struct ata_device *drive, struct request *rq) +static ide_startstop_t dma_timer_expiry(struct ata_device *drive, struct request *rq, unsigned long *wait) { /* FIXME: What's that? */ u8 dma_stat = inb(drive->channel->dma_base + 2); @@ -140,15 +133,17 @@ #if 0 drive->expiry = NULL; /* one free ride for now */ #endif - + *wait = 0; if (dma_stat & 2) { /* ERROR */ ata_status(drive, 0, 0); return ata_error(drive, rq, __FUNCTION__); } - if (dma_stat & 1) /* DMAing */ - return WAIT_CMD; + if (dma_stat & 1) { /* DMAing */ + *wait = WAIT_CMD; + return ide_started; + } - return 0; + return ide_stopped; } int ata_start_dma(struct ata_device *drive, struct request *rq) diff -X dontdiff -ur linux-2.5.24/drivers/ide/pdc4030.c linux/drivers/ide/pdc4030.c --- linux-2.5.24/drivers/ide/pdc4030.c Tue Jun 18 00:29:02 2002 +++ linux/drivers/ide/pdc4030.c Wed Jun 26 16:34:52 2002 @@ -414,10 +414,8 @@ rq->errors = 0; rq->nr_sectors -= nsect; total_remaining = rq->nr_sectors; - if ((rq->current_nr_sectors -= nsect) <= 0) { - /* FIXME: no queue locking above! */ - ata_end_request(drive, rq, 1); - } + if ((rq->current_nr_sectors -= nsect) <= 0) + __ata_end_request(drive, rq, 1, 0); /* * Now the data has been read in, do the following: @@ -437,16 +435,7 @@ if (drive->status & DRQ_STAT) goto read_again; if (drive->status & BUSY_STAT) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); #ifdef DEBUG_READ printk(KERN_DEBUG "%s: promise_read: waiting for" "interrupt\n", drive->name); @@ -470,18 +459,11 @@ */ static ide_startstop_t promise_complete_pollfunc(struct ata_device *drive, struct request *rq) { - unsigned long flags; struct ata_channel *ch = drive->channel; if (!ata_status(drive, 0, BUSY_STAT)) { if (time_before(jiffies, ch->poll_timeout)) { - /* FIXME: this locking should encompass the above - * register file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; /* continue polling... */ } @@ -495,13 +477,7 @@ #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: Write complete - end_request\n", drive->name); #endif - /* FIXME: this locking should encompass the above - * register file access too. - */ - - spin_lock_irqsave(ch->lock, flags); __ata_end_request(drive, rq, 1, rq->nr_sectors); - spin_unlock_irqrestore(ch->lock, flags); return ide_stopped; } @@ -563,21 +539,17 @@ */ static ide_startstop_t promise_write_pollfunc(struct ata_device *drive, struct request *rq) { - unsigned long flags; struct ata_channel *ch = drive->channel; - spin_lock_irqsave(ch->lock, flags); if (inb(IDE_NSECTOR_REG) != 0) { if (time_before(jiffies, ch->poll_timeout)) { ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; /* continue polling... */ } ch->poll_timeout = 0; printk(KERN_ERR "%s: write timed out!\n", drive->name); ata_status(drive, 0, 0); - spin_unlock_irqrestore(ch->lock, flags); return ata_error(drive, rq, "write timeout"); } @@ -592,7 +564,7 @@ printk(KERN_DEBUG "%s: Done last 4 sectors - status = %02x\n", drive->name, drive->status); #endif - spin_unlock_irqrestore(ch->lock, flags); + return ide_started; } @@ -605,7 +577,6 @@ */ static ide_startstop_t promise_do_write(struct ata_device *drive, struct request *rq) { - unsigned long flags; struct ata_channel *ch = drive->channel; #ifdef DEBUG_WRITE @@ -613,23 +584,17 @@ "buffer=%p\n", drive->name, rq->sector, rq->sector + rq->nr_sectors - 1, rq->buffer); #endif - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); /* * If there are more than 4 sectors to transfer, do n-4 then go into * the polling strategy as defined above. */ if (rq->nr_sectors > 4) { if (promise_multwrite(drive, rq, rq->nr_sectors - 4)) { - spin_unlock_irqrestore(ch->lock, flags); + return ide_stopped; } ch->poll_timeout = jiffies + WAIT_WORSTCASE; ata_set_handler(drive, promise_write_pollfunc, HZ/100, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } else { @@ -637,13 +602,11 @@ * There are 4 or fewer sectors to transfer, do them all in one go * and wait for NOT BUSY. */ - if (promise_multwrite(drive, rq, rq->nr_sectors)) { - spin_unlock_irqrestore(ch->lock, flags); + if (promise_multwrite(drive, rq, rq->nr_sectors)) return ide_stopped; - } + ch->poll_timeout = jiffies + WAIT_WORSTCASE; ata_set_handler(drive, promise_complete_pollfunc, HZ/100, NULL); - spin_unlock_irqrestore(ch->lock, flags); #ifdef DEBUG_WRITE printk(KERN_DEBUG "%s: promise_write: <= 4 sectors, " @@ -666,7 +629,7 @@ /* Check that it's a regular command. If not, bomb out early. */ if (!(rq->flags & REQ_CMD)) { blk_dump_rq_flags(rq, "pdc4030 bad flags"); - ata_end_request(drive, rq, 0); + __ata_end_request(drive, rq, 0, 0); return ide_stopped; } @@ -701,20 +664,11 @@ return promise_read_intr(drive, rq); } if (inb(IDE_SELECT_REG) & 0x01) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); #ifdef DEBUG_READ printk(KERN_DEBUG "%s: read: waiting for " "interrupt\n", drive->name); #endif ata_set_handler(drive, promise_read_intr, WAIT_CMD, NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -727,8 +681,6 @@ case WRITE: { ide_startstop_t startstop; - unsigned long flags; - struct ata_channel *ch = drive->channel; /* * Strategy on write is: look for the DRQ that should have been @@ -740,28 +692,23 @@ * completion must be polled */ - /* FIXME: Move this lock upwards. - */ - spin_lock_irqsave(ch->lock, flags); if (ata_status_poll(drive, DATA_READY, drive->bad_wstat, WAIT_DRQ, rq, &startstop )) { printk(KERN_ERR "%s: no DRQ after issuing " "PROMISE_WRITE\n", drive->name); - spin_unlock_irqrestore(ch->lock, flags); return startstop; } if (!drive->channel->unmask) __cli(); /* local CPU only */ - spin_unlock_irqrestore(ch->lock, flags); return promise_do_write(drive, rq); } default: printk(KERN_ERR "pdc4030: command not READ or WRITE! Huh?\n"); - /* FIXME: This should already run under the lock. */ - ata_end_request(drive, rq, 0); + + __ata_end_request(drive, rq, 0, 0); return ide_stopped; } } diff -X dontdiff -ur linux-2.5.24/drivers/ide/tcq.c linux/drivers/ide/tcq.c --- linux-2.5.24/drivers/ide/tcq.c Wed Jun 26 00:02:53 2002 +++ linux/drivers/ide/tcq.c Wed Jun 26 19:53:14 2002 @@ -58,18 +58,15 @@ static ide_startstop_t tcq_nop_handler(struct ata_device *drive, struct request *rq) { struct ata_taskfile *args = rq->special; - unsigned long flags; + /* FIXME: --bzolnier ide__sti(); - - spin_lock_irqsave(drive->channel->lock, flags); + */ blkdev_dequeue_request(rq); drive->rq = NULL; end_that_request_last(rq); - spin_unlock_irqrestore(drive->channel->lock, flags); - kfree(args); return ide_stopped; @@ -86,12 +83,9 @@ request_queue_t *q = &drive->queue; struct ata_taskfile *ar; struct request *rq; - unsigned long flags; printk(KERN_INFO "ATA: %s: invalidating pending queue (%d)\n", drive->name, ata_pending_commands(drive)); - spin_lock_irqsave(ch->lock, flags); - del_timer(&ch->timer); if (test_bit(IDE_DMA, ch->active)) @@ -116,9 +110,9 @@ goto out; } - rq = blk_get_request(&drive->queue, READ, GFP_ATOMIC); + rq = __blk_get_request(&drive->queue, READ); if (!rq) - rq = blk_get_request(&drive->queue, WRITE, GFP_ATOMIC); + rq = __blk_get_request(&drive->queue, WRITE); /* * blk_queue_invalidate_tags() just added back at least one command @@ -143,7 +137,7 @@ * start doing stuff again */ q->request_fn(q); - spin_unlock_irqrestore(ch->lock, flags); + printk(KERN_DEBUG "ATA: tcq_invalidate_queue: done\n"); } @@ -162,17 +156,20 @@ if (!ch->handler) printk(KERN_ERR "ATA: %s: missing ISR!\n", __FUNCTION__); - spin_unlock_irqrestore(ch->lock, flags); - /* * if pending commands, try service before giving up */ if (ata_pending_commands(drive) && !ata_status(drive, 0, SERVICE_STAT)) - if (service(drive, drive->rq) == ide_started) + if (service(drive, drive->rq) == ide_started) { + spin_unlock_irqrestore(ch->lock, flags); + return; + } if (drive) tcq_invalidate_queue(drive); + + spin_unlock_irqrestore(ch->lock, flags); } static void __set_irq(struct ata_channel *ch, ata_handler_t *handler) @@ -191,16 +188,6 @@ ch->handler = handler; } -static void set_irq(struct ata_device *drive, ata_handler_t *handler) -{ - struct ata_channel *ch = drive->channel; - unsigned long flags; - - spin_lock_irqsave(ch->lock, flags); - __set_irq(ch, handler); - spin_unlock_irqrestore(ch->lock, flags); -} - /* * wait 400ns, then poll for busy_mask to clear from alt status */ @@ -233,9 +220,6 @@ */ static ide_startstop_t service(struct ata_device *drive, struct request *rq) { - struct ata_channel *ch = drive->channel; - ide_startstop_t ret; - unsigned long flags; u8 feat, stat; int tag; @@ -296,12 +280,10 @@ TCQ_PRINTK("%s: stat %x, feat %x\n", __FUNCTION__, stat, feat); - spin_lock_irqsave(ch->lock, flags); - rq = blk_queue_find_tag(&drive->queue, tag); if (!rq) { printk(KERN_ERR"%s: missing request for tag %d\n", __FUNCTION__, tag); - spin_unlock_irqrestore(ch->lock, flags); + return ide_stopped; } @@ -313,9 +295,7 @@ */ TCQ_PRINTK("%s: starting command %x\n", __FUNCTION__, stat); - ret = udma_tcq_start(drive, rq); - spin_unlock_irqrestore(ch->lock, flags); - return ret; + return udma_tcq_start(drive, rq); } static ide_startstop_t check_service(struct ata_device *drive, struct request *rq) @@ -331,15 +311,13 @@ /* * we have pending commands, wait for interrupt */ - set_irq(drive, ide_dmaq_intr); + __set_irq(drive, ide_dmaq_intr); return ide_started; } static ide_startstop_t dmaq_complete(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; u8 dma_stat; /* @@ -362,13 +340,7 @@ TCQ_PRINTK("%s: ending %p, tag %d\n", __FUNCTION__, rq, rq->tag); - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); __ata_end_request(drive, rq, !dma_stat, rq->nr_sectors); - spin_unlock_irqrestore(ch->lock, flags); /* * we completed this command, check if we can service a new command diff -X dontdiff -ur linux-2.5.24/drivers/scsi/ide-scsi.c linux/drivers/scsi/ide-scsi.c --- linux-2.5.24/drivers/scsi/ide-scsi.c Tue Jun 18 00:29:03 2002 +++ linux/drivers/scsi/ide-scsi.c Thu Jun 27 02:18:19 2002 @@ -241,10 +241,9 @@ struct atapi_packet_command *pc = (struct atapi_packet_command *) rq->special; int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); u8 *scsi_buf; - unsigned long flags; if (!(rq->flags & REQ_PC)) { - ata_end_request(drive, rq, uptodate); + __ata_end_request(drive, rq, uptodate, 0); return 0; } @@ -273,9 +272,7 @@ } } host = pc->s.scsi_cmd->host; - spin_lock_irqsave(host->host_lock, flags); pc->s.done(pc->s.scsi_cmd); - spin_unlock_irqrestore(host->host_lock, flags); idescsi_free_bio(rq->bio); kfree(pc); kfree(rq); scsi->pc = NULL; @@ -293,8 +290,6 @@ */ static ide_startstop_t idescsi_pc_intr(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; struct Scsi_Host *host = drive->driver_data; idescsi_scsi_t *scsi = idescsi_private(host); u8 ireason; @@ -335,8 +330,6 @@ temp = pc->actually_transferred + bcount; if ( temp > pc->request_transfer) { if (temp > pc->buffer_size) { - unsigned long flags; - struct ata_channel *ch = drive->channel; printk (KERN_ERR "ide-scsi: The scsi wants to send us more data than expected - discarding data\n"); temp = pc->buffer_size - pc->actually_transferred; if (temp) { @@ -350,13 +343,8 @@ pc->actually_transferred += temp; pc->current_position += temp; atapi_discard_data(drive,bcount - temp); - /* FIXME: this locking should encompass the above register - * file access too. - */ - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); - spin_unlock_irqrestore(ch->lock, flags); return ide_started; } @@ -381,21 +369,14 @@ pc->actually_transferred+=bcount; /* Update the current position */ pc->current_position+=bcount; - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); - ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); /* And set the interrupt handler again */ - spin_unlock_irqrestore(ch->lock, flags); + /* And set the interrupt handler again */ + ata_set_handler(drive, idescsi_pc_intr, get_timeout(pc), NULL); return ide_started; } static ide_startstop_t idescsi_transfer_pc(struct ata_device *drive, struct request *rq) { - unsigned long flags; - struct ata_channel *ch = drive->channel; struct Scsi_Host *host = drive->driver_data; idescsi_scsi_t *scsi = idescsi_private(host); struct atapi_packet_command *pc = scsi->pc; @@ -403,9 +384,6 @@ ide_startstop_t startstop; int ret; - /* FIXME: Move this lock upwards. - */ - spin_lock_irqsave(ch->lock, flags); if (ata_status_poll(drive, DRQ_STAT, BUSY_STAT, WAIT_READY, rq, &startstop)) { printk (KERN_ERR "ide-scsi: Strange, packet command initiated yet DRQ isn't asserted\n"); @@ -422,7 +400,6 @@ ret = ide_started; } } - spin_unlock_irqrestore(ch->lock, flags); return ret; } @@ -457,18 +434,9 @@ udma_start(drive, rq); } if (test_bit(IDESCSI_DRQ_INTERRUPT, &scsi->flags)) { - unsigned long flags; - struct ata_channel *ch = drive->channel; - - /* FIXME: this locking should encompass the above register - * file access too. - */ - - spin_lock_irqsave(ch->lock, flags); ata_set_handler(drive, idescsi_transfer_pc, get_timeout(pc), NULL); - spin_unlock_irqrestore(ch->lock, flags); - OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* Issue the packet command */ + OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); return ide_started; } else { OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); @@ -481,7 +449,6 @@ */ static ide_startstop_t idescsi_do_request(struct ata_device *drive, struct request *rq, sector_t block) { - struct ata_channel *ch = drive->channel; int ret; #ifdef DEBUG @@ -496,8 +463,6 @@ rq->current_nr_sectors); #endif - /* FIXME: make this unlocking go away*/ - spin_unlock_irq(ch->lock); if (rq->flags & REQ_PC) { ret = idescsi_issue_pc(drive, rq, (struct atapi_packet_command *) rq->special); } else { @@ -505,7 +470,6 @@ idescsi_end_request(drive, rq, 0); ret = ide_stopped; } - spin_lock_irq(ch->lock); return ret; } @@ -720,9 +684,7 @@ rq->flags = REQ_PC; rq->special = (char *) pc; rq->bio = idescsi_dma_bio (drive, pc); - spin_unlock_irq(cmd->host->host_lock); - ide_do_drive_cmd (drive, rq, ide_end); - spin_lock_irq(cmd->host->host_lock); + ide_do_drive_cmd(drive, rq, ide_end); return 0; abort: diff -X dontdiff -ur linux-2.5.24/include/linux/blkdev.h linux/include/linux/blkdev.h --- linux-2.5.24/include/linux/blkdev.h Mon Jun 24 22:20:54 2002 +++ linux/include/linux/blkdev.h Wed Jun 26 17:21:41 2002 @@ -283,7 +283,9 @@ extern inline request_queue_t *bdev_get_queue(struct block_device *bdev); extern void blkdev_release_request(struct request *); extern void blk_attempt_remerge(request_queue_t *, struct request *); +extern void __blk_attempt_remerge(request_queue_t *, struct request *); extern struct request *blk_get_request(request_queue_t *, int, int); +extern struct request *__blk_get_request(request_queue_t *, int); extern void blk_put_request(struct request *); extern void blk_plug_device(request_queue_t *); extern int blk_remove_plug(request_queue_t *); diff -X dontdiff -ur linux-2.5.24/include/linux/ide.h linux/include/linux/ide.h --- linux-2.5.24/include/linux/ide.h Wed Jun 26 00:02:53 2002 +++ linux/include/linux/ide.h Thu Jun 27 01:39:37 2002 @@ -381,7 +381,7 @@ * Interrupt and timeout handler type. */ typedef ide_startstop_t (ata_handler_t)(struct ata_device *, struct request *); -typedef int (ata_expiry_t)(struct ata_device *, struct request *); +typedef ide_startstop_t (ata_expiry_t)(struct ata_device *, struct request *, unsigned long *); enum { ATA_PRIMARY = 0, @@ -406,7 +406,7 @@ ide_startstop_t (*handler)(struct ata_device *, struct request *); /* irq handler, if active */ struct timer_list timer; /* failsafe timer */ - int (*expiry)(struct ata_device *, struct request *); /* irq handler, if active */ + ide_startstop_t (*expiry)(struct ata_device *, struct request *, unsigned long *); /* irq handler, if active */ unsigned long poll_timeout; /* timeout value during polled operations */ struct ata_device *drive; /* last serviced drive */ @@ -602,9 +602,7 @@ #define DEVICE_NR(device) (minor(device) >> PARTN_BITS) #include -/* Not locking and locking variant: */ extern int __ata_end_request(struct ata_device *, struct request *, int, unsigned int); -extern int ata_end_request(struct ata_device *drive, struct request *, int); extern void ata_set_handler(struct ata_device *drive, ata_handler_t handler, unsigned long timeout, ata_expiry_t expiry); @@ -626,12 +624,6 @@ struct ata_device *get_info_ptr(kdev_t i_rdev); /* - * Re-Start an operation for an IDE interface. - * The caller should return immediately after invoking this. - */ -ide_startstop_t restart_request(struct ata_device *); - -/* * "action" parameter type for ide_do_drive_cmd() below. */ typedef enum {