ide: add ide_[un]lock_hwgroup() helpers

Add ide_[un]lock_hwgroup() inline helpers for obtaining exclusive
access to the given hwgroup and update the core code accordingly.

[ This change besides making code saner results in more efficient
  use of ide_{get,release}_lock(). ]

Cc: Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Elias Oltmanns <eo@nebensachen.de>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent b2cfb05a
...@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q) ...@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q)
/* caller must own hwgroup->lock */ /* caller must own hwgroup->lock */
BUG_ON(!irqs_disabled()); BUG_ON(!irqs_disabled());
while (!hwgroup->busy) { while (!ide_lock_hwgroup(hwgroup)) {
hwgroup->busy = 1;
/* for atari only */
ide_get_lock(ide_intr, hwgroup);
drive = choose_drive(hwgroup); drive = choose_drive(hwgroup);
if (drive == NULL) { if (drive == NULL) {
int sleeping = 0; int sleeping = 0;
...@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q) ...@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q)
hwgroup->sleeping = 1; hwgroup->sleeping = 1;
hwgroup->req_gen_timer = hwgroup->req_gen; hwgroup->req_gen_timer = hwgroup->req_gen;
mod_timer(&hwgroup->timer, sleep); mod_timer(&hwgroup->timer, sleep);
/* we purposely leave hwgroup->busy==1 /* we purposely leave hwgroup locked
* while sleeping */ * while sleeping */
} else { } else
/* Ugly, but how can we sleep for the lock ide_unlock_hwgroup(hwgroup);
* otherwise? perhaps from tq_disk?
*/
/* for atari only */
ide_release_lock();
hwgroup->busy = 0;
}
/* no more work for this hwgroup (for now) */ /* no more work for this hwgroup (for now) */
goto plug_device; goto plug_device;
...@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q) ...@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q)
*/ */
rq = elv_next_request(drive->queue); rq = elv_next_request(drive->queue);
if (!rq) { if (!rq) {
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
break; break;
} }
...@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q) ...@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q)
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
blk_pm_request(rq) == 0 && blk_pm_request(rq) == 0 &&
(rq->cmd_flags & REQ_PREEMPT) == 0) { (rq->cmd_flags & REQ_PREEMPT) == 0) {
/* We clear busy, there should be no pending ATA command at this point. */ /* there should be no pending command at this point */
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
goto plug_device; goto plug_device;
} }
...@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q) ...@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q)
spin_lock_irq(&hwgroup->lock); spin_lock_irq(&hwgroup->lock);
if (startstop == ide_stopped) { if (startstop == ide_stopped) {
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
if (!elv_queue_empty(orig_drive->queue)) if (!elv_queue_empty(orig_drive->queue))
blk_plug_device(orig_drive->queue); blk_plug_device(orig_drive->queue);
} }
...@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data) ...@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data)
*/ */
if (hwgroup->sleeping) { if (hwgroup->sleeping) {
hwgroup->sleeping = 0; hwgroup->sleeping = 0;
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
} }
} else { } else {
ide_drive_t *drive = hwgroup->drive; ide_drive_t *drive = hwgroup->drive;
...@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data) ...@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data)
spin_lock_irq(&hwgroup->lock); spin_lock_irq(&hwgroup->lock);
enable_irq(hwif->irq); enable_irq(hwif->irq);
if (startstop == ide_stopped) { if (startstop == ide_stopped) {
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
if (!elv_queue_empty(drive->queue)) if (!elv_queue_empty(drive->queue))
blk_plug_device(drive->queue); blk_plug_device(drive->queue);
} }
...@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) ...@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
drive->service_time = jiffies - drive->service_start; drive->service_time = jiffies - drive->service_start;
if (startstop == ide_stopped) { if (startstop == ide_stopped) {
if (hwgroup->handler == NULL) { /* paranoia */ if (hwgroup->handler == NULL) { /* paranoia */
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
if (!elv_queue_empty(drive->queue)) if (!elv_queue_empty(drive->queue))
blk_plug_device(drive->queue); blk_plug_device(drive->queue);
} else } else
......
...@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) ...@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
if (reset_timer && hwgroup->sleeping && if (reset_timer && hwgroup->sleeping &&
del_timer(&hwgroup->timer)) { del_timer(&hwgroup->timer)) {
hwgroup->sleeping = 0; hwgroup->sleeping = 0;
hwgroup->busy = 0; ide_unlock_hwgroup(hwgroup);
blk_start_queueing(q); blk_start_queueing(q);
} }
spin_unlock_irq(&hwgroup->lock); spin_unlock_irq(&hwgroup->lock);
......
...@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); ...@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
extern void ide_timer_expiry(unsigned long); extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id); extern irqreturn_t ide_intr(int irq, void *dev_id);
static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)
{
if (hwgroup->busy)
return 1;
hwgroup->busy = 1;
/* for atari only */
ide_get_lock(ide_intr, hwgroup);
return 0;
}
static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
{
/* for atari only */
ide_release_lock();
hwgroup->busy = 0;
}
extern void do_ide_request(struct request_queue *); extern void do_ide_request(struct request_queue *);
void ide_init_disk(struct gendisk *, ide_drive_t *); void ide_init_disk(struct gendisk *, ide_drive_t *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment