ide: add ide_[un]lock_hwgroup() helpers
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 2 Jan 2009 15:12:50 +0000 (16:12 +0100)
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Fri, 2 Jan 2009 15:12:50 +0000 (16:12 +0100)
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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
drivers/ide/ide-io.c
drivers/ide/ide-park.c
include/linux/ide.h

index c60512196f61e35076281bc0bf74e05b460429ff..ab480042757ad722a3bf40052f5d24d0d31a7be6 100644 (file)
@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q)
        /* caller must own hwgroup->lock */
        BUG_ON(!irqs_disabled());
 
-       while (!hwgroup->busy) {
-               hwgroup->busy = 1;
-               /* for atari only */
-               ide_get_lock(ide_intr, hwgroup);
+       while (!ide_lock_hwgroup(hwgroup)) {
                drive = choose_drive(hwgroup);
                if (drive == NULL) {
                        int sleeping = 0;
@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q)
                                hwgroup->sleeping = 1;
                                hwgroup->req_gen_timer = hwgroup->req_gen;
                                mod_timer(&hwgroup->timer, sleep);
-                               /* we purposely leave hwgroup->busy==1
+                               /* we purposely leave hwgroup locked
                                 * while sleeping */
-                       } else {
-                               /* Ugly, but how can we sleep for the lock
-                                * otherwise? perhaps from tq_disk?
-                                */
-
-                               /* for atari only */
-                               ide_release_lock();
-                               hwgroup->busy = 0;
-                       }
+                       } else
+                               ide_unlock_hwgroup(hwgroup);
 
                        /* no more work for this hwgroup (for now) */
                        goto plug_device;
@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q)
                 */
                rq = elv_next_request(drive->queue);
                if (!rq) {
-                       hwgroup->busy = 0;
+                       ide_unlock_hwgroup(hwgroup);
                        break;
                }
 
@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q)
                if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
                    blk_pm_request(rq) == 0 &&
                    (rq->cmd_flags & REQ_PREEMPT) == 0) {
-                       /* We clear busy, there should be no pending ATA command at this point. */
-                       hwgroup->busy = 0;
+                       /* there should be no pending command at this point */
+                       ide_unlock_hwgroup(hwgroup);
                        goto plug_device;
                }
 
@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q)
                spin_lock_irq(&hwgroup->lock);
 
                if (startstop == ide_stopped) {
-                       hwgroup->busy = 0;
+                       ide_unlock_hwgroup(hwgroup);
                        if (!elv_queue_empty(orig_drive->queue))
                                blk_plug_device(orig_drive->queue);
                }
@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data)
                 */
                if (hwgroup->sleeping) {
                        hwgroup->sleeping = 0;
-                       hwgroup->busy = 0;
+                       ide_unlock_hwgroup(hwgroup);
                }
        } else {
                ide_drive_t *drive = hwgroup->drive;
@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data)
                        spin_lock_irq(&hwgroup->lock);
                        enable_irq(hwif->irq);
                        if (startstop == ide_stopped) {
-                               hwgroup->busy = 0;
+                               ide_unlock_hwgroup(hwgroup);
                                if (!elv_queue_empty(drive->queue))
                                        blk_plug_device(drive->queue);
                        }
@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
        drive->service_time = jiffies - drive->service_start;
        if (startstop == ide_stopped) {
                if (hwgroup->handler == NULL) { /* paranoia */
-                       hwgroup->busy = 0;
+                       ide_unlock_hwgroup(hwgroup);
                        if (!elv_queue_empty(drive->queue))
                                blk_plug_device(drive->queue);
                } else
index 63d01c55f865504fa06b9562acf7021b4bb3c8ae..44c6787f8aeb9a3a76b361a538860a5ae30be4cf 100644 (file)
@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
                if (reset_timer && hwgroup->sleeping &&
                    del_timer(&hwgroup->timer)) {
                        hwgroup->sleeping = 0;
-                       hwgroup->busy = 0;
+                       ide_unlock_hwgroup(hwgroup);
                        blk_start_queueing(q);
                }
                spin_unlock_irq(&hwgroup->lock);
index 968ca8f60531fd247bd1a585dff9068797be277e..f408d6123f14e5159a363259199c7435452fd2cc 100644 (file)
@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
 
 extern void ide_timer_expiry(unsigned long);
 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 *);
 
 void ide_init_disk(struct gendisk *, ide_drive_t *);