From 1a659880ee755d96eeabe64bded059abed6d5ef5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 8 Dec 2008 17:42:35 +0100 Subject: Revert "ide: respect current DMA setting during resume" This reverts commit e9eb8388306364295308132265c00bea685f409f since it could break resume (thanks to Paul Collins for the report). I'll look into sorting this out properly for 2.6.29 but for 2.6.28 it is the best to just revert my patch. Reported-by: Paul Collins Cc: rjw@sisk.pl Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 7d275b2af3eb..cc35d6dbd410 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -208,8 +208,10 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request * */ if (drive->hwif->dma_ops == NULL) break; - if (drive->dev_flags & IDE_DFLAG_USING_DMA) - ide_set_dma(drive); + /* + * TODO: respect IDE_DFLAG_USING_DMA + */ + ide_set_dma(drive); break; } -- cgit v1.2.3 From 3e0e29f7373ec96a1bd972790649524af7353f42 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:29 +0100 Subject: ide: unify ide_intr()'s exit points Just a preparation for future changes. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index cc35d6dbd410..35b625882803 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1363,14 +1363,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) ide_drive_t *drive; ide_handler_t *handler; ide_startstop_t startstop; + irqreturn_t irq_ret = IRQ_NONE; spin_lock_irqsave(&ide_lock, flags); hwif = hwgroup->hwif; - if (!ide_ack_intr(hwif)) { - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; - } + if (!ide_ack_intr(hwif)) + goto out; if ((handler = hwgroup->handler) == NULL || hwgroup->polling) { /* @@ -1406,9 +1405,9 @@ irqreturn_t ide_intr (int irq, void *dev_id) (void)hwif->tp_ops->read_status(hwif); #endif /* CONFIG_BLK_DEV_IDEPCI */ } - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; + goto out; } + drive = hwgroup->drive; if (!drive) { /* @@ -1417,10 +1416,10 @@ irqreturn_t ide_intr (int irq, void *dev_id) * * [Note - this can occur if the drive is hot unplugged] */ - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + goto out_handled; } - if (!drive_is_ready(drive)) { + + if (!drive_is_ready(drive)) /* * This happens regularly when we share a PCI IRQ with * another device. Unfortunately, it can also happen @@ -1428,9 +1427,8 @@ irqreturn_t ide_intr (int irq, void *dev_id) * their status register is up to date. Hopefully we have * enough advance overhead that the latter isn't a problem. */ - spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_NONE; - } + goto out; + if (!hwgroup->busy) { hwgroup->busy = 1; /* paranoia */ printk(KERN_ERR "%s: ide_intr: hwgroup->busy was 0 ??\n", drive->name); @@ -1467,8 +1465,11 @@ irqreturn_t ide_intr (int irq, void *dev_id) "on exit\n", drive->name); } } +out_handled: + irq_ret = IRQ_HANDLED; +out: spin_unlock_irqrestore(&ide_lock, flags); - return IRQ_HANDLED; + return irq_ret; } /** -- cgit v1.2.3 From 1d0bf587df5b17bb93b32d760171417883ca907f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:30 +0100 Subject: ide: ide_hwgroup_t.rq doesn't need an ide_lock held While at it: - no need to check for hwgroup presence in ide_dump_opcode() Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 35b625882803..8afe7b15decf 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -107,17 +107,10 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) { unsigned int nr_bytes = nr_sectors << 9; - struct request *rq; + struct request *rq = drive->hwif->hwgroup->rq; unsigned long flags; int ret = 1; - /* - * room for locking improvements here, the calls below don't - * need the queue lock held at all - */ - spin_lock_irqsave(&ide_lock, flags); - rq = HWGROUP(drive)->rq; - if (!nr_bytes) { if (blk_pc_request(rq)) nr_bytes = rq->data_len; @@ -125,9 +118,10 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) nr_bytes = rq->hard_cur_sectors << 9; } + spin_lock_irqsave(&ide_lock, flags); ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1); - spin_unlock_irqrestore(&ide_lock, flags); + return ret; } EXPORT_SYMBOL(ide_end_request); @@ -245,8 +239,9 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, unsigned long flags; int ret; - spin_lock_irqsave(&ide_lock, flags); BUG_ON(!blk_rq_started(rq)); + + spin_lock_irqsave(&ide_lock, flags); ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); spin_unlock_irqrestore(&ide_lock, flags); @@ -278,7 +273,11 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) drive->dev_flags &= ~IDE_DFLAG_BLOCKED; blk_start_queue(drive->queue); } - HWGROUP(drive)->rq = NULL; + spin_unlock_irqrestore(&ide_lock, flags); + + drive->hwif->hwgroup->rq = NULL; + + spin_lock_irqsave(&ide_lock, flags); if (__blk_end_request(rq, 0, 0)) BUG(); spin_unlock_irqrestore(&ide_lock, flags); @@ -300,12 +299,9 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + struct request *rq = hwgroup->rq; unsigned long flags; - struct request *rq; - - spin_lock_irqsave(&ide_lock, flags); - rq = HWGROUP(drive)->rq; - spin_unlock_irqrestore(&ide_lock, flags); if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; @@ -333,15 +329,16 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) return; } - spin_lock_irqsave(&ide_lock, flags); - HWGROUP(drive)->rq = NULL; + hwgroup->rq = NULL; + rq->errors = err; + + spin_lock_irqsave(&ide_lock, flags); if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0), blk_rq_bytes(rq)))) BUG(); spin_unlock_irqrestore(&ide_lock, flags); } - EXPORT_SYMBOL(ide_end_drive_cmd); static void ide_kill_rq(ide_drive_t *drive, struct request *rq) @@ -1489,11 +1486,12 @@ out: void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) { + ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; unsigned long flags; - ide_hwgroup_t *hwgroup = HWGROUP(drive); - spin_lock_irqsave(&ide_lock, flags); hwgroup->rq = NULL; + + spin_lock_irqsave(&ide_lock, flags); __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); blk_start_queueing(drive->queue); spin_unlock_irqrestore(&ide_lock, flags); -- cgit v1.2.3 From a72b2147ec9e77be68308ba06190603550d1cb61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:30 +0100 Subject: ide: push ide_lock to __ide_end_request() __ide_end_request() needs ide_lock only for __blk_end_request() call so push ide_lock taking inside __ide_end_requests(). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 8afe7b15decf..709163536015 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -58,6 +58,7 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, unsigned int nr_bytes, int dequeue) { + unsigned long flags; int ret = 1; int error = 0; @@ -84,11 +85,13 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ide_dma_on(drive); } - if (!__blk_end_request(rq, error, nr_bytes)) { - if (dequeue) - HWGROUP(drive)->rq = NULL; + spin_lock_irqsave(&ide_lock, flags); + if (!__blk_end_request(rq, error, nr_bytes)) ret = 0; - } + spin_unlock_irqrestore(&ide_lock, flags); + + if (ret == 0 && dequeue) + drive->hwif->hwgroup->rq = NULL; return ret; } @@ -108,8 +111,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) { unsigned int nr_bytes = nr_sectors << 9; struct request *rq = drive->hwif->hwgroup->rq; - unsigned long flags; - int ret = 1; if (!nr_bytes) { if (blk_pc_request(rq)) @@ -118,11 +119,7 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) nr_bytes = rq->hard_cur_sectors << 9; } - spin_lock_irqsave(&ide_lock, flags); - ret = __ide_end_request(drive, rq, uptodate, nr_bytes, 1); - spin_unlock_irqrestore(&ide_lock, flags); - - return ret; + return __ide_end_request(drive, rq, uptodate, nr_bytes, 1); } EXPORT_SYMBOL(ide_end_request); @@ -236,16 +233,9 @@ out_do_tf: int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors) { - unsigned long flags; - int ret; - BUG_ON(!blk_rq_started(rq)); - spin_lock_irqsave(&ide_lock, flags); - ret = __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); - spin_unlock_irqrestore(&ide_lock, flags); - - return ret; + return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0); } EXPORT_SYMBOL_GPL(ide_end_dequeued_request); -- cgit v1.2.3 From 3c8a2cce47c6813383c9e38134e31f7e5f72e9d8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: ide_lock + __blk_end_request() -> blk_end_request() Use blk_end_request() instead of ide_lock + __blk_end_request() in cdrom_end_request(), cdrom_newpc_intr(), __ide_end_request(), ide_complete_pm_request() and ide_end_drive_cmd(). [ ide_lock is currently also used as queue lock ] Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 709163536015..4a6576f6146b 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -58,7 +58,6 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, unsigned int nr_bytes, int dequeue) { - unsigned long flags; int ret = 1; int error = 0; @@ -85,10 +84,8 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq, ide_dma_on(drive); } - spin_lock_irqsave(&ide_lock, flags); - if (!__blk_end_request(rq, error, nr_bytes)) + if (!blk_end_request(rq, error, nr_bytes)) ret = 0; - spin_unlock_irqrestore(&ide_lock, flags); if (ret == 0 && dequeue) drive->hwif->hwgroup->rq = NULL; @@ -267,10 +264,8 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) drive->hwif->hwgroup->rq = NULL; - spin_lock_irqsave(&ide_lock, flags); - if (__blk_end_request(rq, 0, 0)) + if (blk_end_request(rq, 0, 0)) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); } /** @@ -291,7 +286,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) { ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; struct request *rq = hwgroup->rq; - unsigned long flags; if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; @@ -323,11 +317,9 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) rq->errors = err; - spin_lock_irqsave(&ide_lock, flags); - if (unlikely(__blk_end_request(rq, (rq->errors ? -EIO : 0), - blk_rq_bytes(rq)))) + if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0), + blk_rq_bytes(rq)))) BUG(); - spin_unlock_irqrestore(&ide_lock, flags); } EXPORT_SYMBOL(ide_end_drive_cmd); -- cgit v1.2.3 From 6ea52226ca131a99bb619bd56fbeee566ea5a966 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: use queue lock instead of ide_lock when possible This is just a preparation for future changes and there should be no functional changes caused by this patch since ide_lock is currently also used as queue lock. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 4a6576f6146b..02059e96e6cd 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -247,20 +247,21 @@ EXPORT_SYMBOL_GPL(ide_end_dequeued_request); */ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) { + struct request_queue *q = drive->queue; unsigned long flags; #ifdef DEBUG_PM printk("%s: completing PM request, %s\n", drive->name, blk_pm_suspend_request(rq) ? "suspend" : "resume"); #endif - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); if (blk_pm_suspend_request(rq)) { - blk_stop_queue(drive->queue); + blk_stop_queue(q); } else { drive->dev_flags &= ~IDE_DFLAG_BLOCKED; - blk_start_queue(drive->queue); + blk_start_queue(q); } - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(q->queue_lock, flags); drive->hwif->hwgroup->rq = NULL; @@ -1469,16 +1470,16 @@ out: void ide_do_drive_cmd(ide_drive_t *drive, struct request *rq) { ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; + struct request_queue *q = drive->queue; unsigned long flags; hwgroup->rq = NULL; - spin_lock_irqsave(&ide_lock, flags); - __elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0); - blk_start_queueing(drive->queue); - spin_unlock_irqrestore(&ide_lock, flags); + spin_lock_irqsave(q->queue_lock, flags); + __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); + blk_start_queueing(q); + spin_unlock_irqrestore(q->queue_lock, flags); } - EXPORT_SYMBOL(ide_do_drive_cmd); void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount, u8 dma) -- cgit v1.2.3 From 2a2ca6a96194c4744a2adeefbc09ce881f3c5abe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: replace the global ide_lock spinlock by per-hwgroup spinlocks (v2) Now that (almost) all host drivers have been fixed not to abuse ide_lock and core code usage of ide_lock has been sanitized we may safely replace ide_lock by per-hwgroup locks. This patch is partially based on earlier patch from Ravikiran G Thirumalai. While at it: - don't use deprecated HWIF() and HWGROUP() macros - update locking documentation in ide.h v2: Add missing spin_lock_init(&hwgroup->lock). (Noticed by Elias Oltmanns) Cc: Vaibhav V. Nivargi Cc: Alok N. Kataria Cc: Shai Fultheim Signed-off-by: Ravikiran Thirumalai Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 02059e96e6cd..72d0d702d5da 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -907,7 +907,7 @@ repeat: /* * Issue a new request to a drive from hwgroup - * Caller must have already done spin_lock_irqsave(&ide_lock, ..); + * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..); * * A hwgroup is a serialized group of IDE interfaces. Usually there is * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) @@ -919,7 +919,7 @@ repeat: * possibly along with many other devices. This is especially common in * PCI-based systems with off-board IDE controller cards. * - * The IDE driver uses the single global ide_lock spinlock to protect + * The IDE driver uses a per-hwgroup spinlock to protect * access to the request queues, and to protect the hwgroup->busy flag. * * The first thread into the driver for a particular hwgroup sets the @@ -935,7 +935,7 @@ repeat: * will start the next request from the queue. If no more work remains, * the driver will clear the hwgroup->busy flag and exit. * - * The ide_lock (spinlock) is used to protect all access to the + * The per-hwgroup spinlock is used to protect all access to the * hwgroup->busy flag, but is otherwise not needed for most processing in * the driver. This makes the driver much more friendlier to shared IRQs * than previous designs, while remaining 100% (?) SMP safe and capable. @@ -948,7 +948,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) ide_startstop_t startstop; int loops = 0; - /* caller must own ide_lock */ + /* caller must own hwgroup->lock */ BUG_ON(!irqs_disabled()); while (!hwgroup->busy) { @@ -1070,11 +1070,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) */ if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) disable_irq_nosync(hwif->irq); - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); local_irq_enable_in_hardirq(); /* allow other IRQs while we start this request */ startstop = start_request(drive, rq); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) enable_irq(hwif->irq); if (startstop == ide_stopped) @@ -1172,7 +1172,7 @@ void ide_timer_expiry (unsigned long data) unsigned long flags; unsigned long wait = -1; - spin_lock_irqsave(&ide_lock, flags); + spin_lock_irqsave(&hwgroup->lock, flags); if (((handler = hwgroup->handler) == NULL) || (hwgroup->req_gen != hwgroup->req_gen_timer)) { @@ -1205,7 +1205,7 @@ void ide_timer_expiry (unsigned long data) hwgroup->timer.expires = jiffies + wait; hwgroup->req_gen_timer = hwgroup->req_gen; add_timer(&hwgroup->timer); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return; } } @@ -1215,7 +1215,7 @@ void ide_timer_expiry (unsigned long data) * the handler() function, which means we need to * globally mask the specific IRQ: */ - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); hwif = HWIF(drive); /* disable_irq_nosync ?? */ disable_irq(hwif->irq); @@ -1239,14 +1239,14 @@ void ide_timer_expiry (unsigned long data) hwif->tp_ops->read_status(hwif)); } drive->service_time = jiffies - drive->service_start; - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); enable_irq(hwif->irq); if (startstop == ide_stopped) hwgroup->busy = 0; } } ide_do_request(hwgroup, IDE_NO_IRQ); - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); } /** @@ -1339,14 +1339,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) { unsigned long flags; ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; - ide_hwif_t *hwif; + ide_hwif_t *hwif = hwgroup->hwif; ide_drive_t *drive; ide_handler_t *handler; ide_startstop_t startstop; irqreturn_t irq_ret = IRQ_NONE; - spin_lock_irqsave(&ide_lock, flags); - hwif = hwgroup->hwif; + spin_lock_irqsave(&hwgroup->lock, flags); if (!ide_ack_intr(hwif)) goto out; @@ -1416,7 +1415,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) hwgroup->handler = NULL; hwgroup->req_gen++; del_timer(&hwgroup->timer); - spin_unlock(&ide_lock); + spin_unlock(&hwgroup->lock); if (hwif->port_ops && hwif->port_ops->clear_irq) hwif->port_ops->clear_irq(drive); @@ -1427,7 +1426,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) /* service this interrupt, may set handler for next interrupt */ startstop = handler(drive); - spin_lock_irq(&ide_lock); + spin_lock_irq(&hwgroup->lock); /* * Note that handler() may have set things up for another * interrupt to occur soon, but it cannot happen until @@ -1448,7 +1447,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) out_handled: irq_ret = IRQ_HANDLED; out: - spin_unlock_irqrestore(&ide_lock, flags); + spin_unlock_irqrestore(&hwgroup->lock, flags); return irq_ret; } -- cgit v1.2.3 From 08cd1dca00f7c84c8b30c2726e078529d4ebc93f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: ide: cleanup ide_do_request() Both choose_drive() and PM handling code make sure that the queue is unplugged so no need to check it again. Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 72d0d702d5da..e41488e1ed4e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1016,11 +1016,6 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); drive->service_start = jiffies; - if (blk_queue_plugged(drive->queue)) { - printk(KERN_ERR "ide: huh? queue was plugged!\n"); - break; - } - /* * we know that the queue isn't empty, but this can happen * if the q->prep_rq_fn() decides to kill a request -- cgit v1.2.3 From 46aa7af1d6bf46d0973dc9e8f13275f2c001d3dd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: ide: fix ->quirk_list checking in ide_do_request() Fix nIEN quirk check to also omit quirky devices using pdc202xx_{new,old} host drivers for which ->quirk_list == 2. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index e41488e1ed4e..ca51460af756 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1008,7 +1008,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) * set nIEN for previous hwif, drives in the * quirk_list may not like intr setups/cleanups */ - if (drive->quirk_list != 1) + if (drive->quirk_list == 0) hwif->tp_ops->set_irq(hwif, 0); } hwgroup->hwif = hwif; -- cgit v1.2.3 From f58c1ab8deebc2360cef998f169a6727c288210f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: ide: always set nIEN on idle devices * Set nIEN for previous port/device in ide_do_request() also if port uses a non-shared IRQ. * Remove no longer needed ide_hwif_t.sharing_irq. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index ca51460af756..f776bd475010 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -1003,7 +1003,7 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) } again: hwif = HWIF(drive); - if (hwgroup->hwif->sharing_irq && hwif != hwgroup->hwif) { + if (hwif != hwgroup->hwif) { /* * set nIEN for previous hwif, drives in the * quirk_list may not like intr setups/cleanups -- cgit v1.2.3 From b002415012f518e6940fabb77e35f0fb21b3640d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: remove redundant code from ide_end_drive_cmd() rq->errors is overwritten later in this function. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index f776bd475010..26d3f3cacc8a 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -291,9 +291,6 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err) if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *task = (ide_task_t *)rq->special; - if (rq->errors == 0) - rq->errors = !OK_STAT(stat, ATA_DRDY, BAD_STAT); - if (task) { struct ide_taskfile *tf = &task->tf; -- cgit v1.2.3 From e2984c628c924442132304ae662da433f41c05c9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: move Power Management support to ide-pm.c There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-io.c | 159 --------------------------------------------------- 1 file changed, 159 deletions(-) (limited to 'drivers/ide/ide-io.c') diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 26d3f3cacc8a..ecacc008fdaf 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c @@ -120,98 +120,6 @@ int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors) } EXPORT_SYMBOL(ide_end_request); -static void ide_complete_power_step(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - -#ifdef DEBUG_PM - printk(KERN_INFO "%s: complete_power_step(step: %d)\n", - drive->name, pm->pm_step); -#endif - if (drive->media != ide_disk) - return; - - switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ - if (pm->pm_state == PM_EVENT_FREEZE) - pm->pm_step = IDE_PM_COMPLETED; - else - pm->pm_step = IDE_PM_STANDBY; - break; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - pm->pm_step = IDE_PM_COMPLETED; - break; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ - pm->pm_step = IDE_PM_IDLE; - break; - case IDE_PM_IDLE: /* Resume step 2 (idle)*/ - pm->pm_step = IDE_PM_RESTORE_DMA; - break; - } -} - -static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - ide_task_t *args = rq->special; - - memset(args, 0, sizeof(*args)); - - switch (pm->pm_step) { - case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */ - if (drive->media != ide_disk) - break; - /* Not supported? Switch to next step now. */ - if (ata_id_flush_enabled(drive->id) == 0 || - (drive->dev_flags & IDE_DFLAG_WCACHE) == 0) { - ide_complete_power_step(drive, rq); - return ide_stopped; - } - if (ata_id_flush_ext_enabled(drive->id)) - args->tf.command = ATA_CMD_FLUSH_EXT; - else - args->tf.command = ATA_CMD_FLUSH; - goto out_do_tf; - case IDE_PM_STANDBY: /* Suspend step 2 (standby) */ - args->tf.command = ATA_CMD_STANDBYNOW1; - goto out_do_tf; - case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */ - ide_set_max_pio(drive); - /* - * skip IDE_PM_IDLE for ATAPI devices - */ - if (drive->media != ide_disk) - pm->pm_step = IDE_PM_RESTORE_DMA; - else - ide_complete_power_step(drive, rq); - return ide_stopped; - case IDE_PM_IDLE: /* Resume step 2 (idle) */ - args->tf.command = ATA_CMD_IDLEIMMEDIATE; - goto out_do_tf; - case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */ - /* - * Right now, all we do is call ide_set_dma(drive), - * we could be smarter and check for current xfer_speed - * in struct drive etc... - */ - if (drive->hwif->dma_ops == NULL) - break; - /* - * TODO: respect IDE_DFLAG_USING_DMA - */ - ide_set_dma(drive); - break; - } - - pm->pm_step = IDE_PM_COMPLETED; - return ide_stopped; - -out_do_tf: - args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; - args->data_phase = TASKFILE_NO_DATA; - return do_rw_taskfile(drive, args); -} - /** * ide_end_dequeued_request - complete an IDE I/O * @drive: IDE device for the I/O @@ -236,39 +144,6 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, } EXPORT_SYMBOL_GPL(ide_end_dequeued_request); - -/** - * ide_complete_pm_request - end the current Power Management request - * @drive: target drive - * @rq: request - * - * This function cleans up the current PM request and stops the queue - * if necessary. - */ -static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq) -{ - struct request_queue *q = drive->queue; - unsigned long flags; - -#ifdef DEBUG_PM - printk("%s: completing PM request, %s\n", drive->name, - blk_pm_suspend_request(rq) ? "suspend" : "resume"); -#endif - spin_lock_irqsave(q->queue_lock, flags); - if (blk_pm_suspend_request(rq)) { - blk_stop_queue(q); - } else { - drive->dev_flags &= ~IDE_DFLAG_BLOCKED; - blk_start_queue(q); - } - spin_unlock_irqrestore(q->queue_lock, flags); - - drive->hwif->hwgroup->rq = NULL; - - if (blk_end_request(rq, 0, 0)) - BUG(); -} - /** * ide_end_drive_cmd - end an explicit drive command * @drive: command @@ -697,40 +572,6 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) } } -static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) -{ - struct request_pm_state *pm = rq->data; - - if (blk_pm_suspend_request(rq) && - pm->pm_step == IDE_PM_START_SUSPEND) - /* Mark drive blocked when starting the suspend sequence. */ - drive->dev_flags |= IDE_DFLAG_BLOCKED; - else if (blk_pm_resume_request(rq) && - pm->pm_step == IDE_PM_START_RESUME) { - /* - * The first thing we do on wakeup is to wait for BSY bit to - * go away (with a looong timeout) as a drive on this hwif may - * just be POSTing itself. - * We do that before even selecting as the "other" device on - * the bus may be broken enough to walk on our toes at this - * point. - */ - ide_hwif_t *hwif = drive->hwif; - int rc; -#ifdef DEBUG_PM - printk("%s: Wakeup request inited, waiting for !BSY...\n", drive->name); -#endif - rc = ide_wait_not_busy(hwif, 35000); - if (rc) - printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name); - SELECT_DRIVE(drive); - hwif->tp_ops->set_irq(hwif, 1); - rc = ide_wait_not_busy(hwif, 100000); - if (rc) - printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name); - } -} - /** * start_request - start of I/O and command issuing for IDE * -- cgit v1.2.3