I have Martin's permission to push some ide-clean patches, so here we go.
I'm running fine SMP kernel with spinlocks debugging enabled on UP.
Note that this patch brokes ide-cd/tape/floppy/scsi locking...
This patch is mainly for developers to have something to sync with... ;-)
still TODO:
- remove ide_wait commands from interrupt paths
- move locking/completion upwards from ide_do_drive_cmd()
- fix ide device setup/tear down locking
- locking of ioctls
- tape->spinlock is probably obsolete now
Thu Jun 27 13:32:35 CEST 2002 ide-clean-95
It is a merge of patches by Alexander Atanasov and Zwane Mwaikambo
(big thanks guys!) plus some corrections by me...
- Remove locking from IRQ handlers (*_intr etc.) and ata_ops->do_reqeuest(),
ata_ops->end_request().
- Add non-locking __blk_get_request() and __blk_attempt_remege() helpers
to block layer (ll_rw_blk.c).
- Move locking up to the entry points.
- Move ata_expiry_t functions to the ide_startstop_t interface
(need to call ata_error, and its return is idestartstop_t, not wait time).
- Kill ata_end_request() and restart_request() (they were locking variants).
- Disable some ide__sti() for now.
- Misc fixes.
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 <linux/blk.h>
-/* 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 {