diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-02 10:12:50 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-02 10:12:50 -0500 |
commit | 631de3708d595d153e8a510a3608689290f4c0ed (patch) | |
tree | dbecf12cccac76e89cf1908f80b4f515cada731e | |
parent | b2cfb05a701809abee591265a198afa029d68bff (diff) |
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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-io.c | 32 | ||||
-rw-r--r-- | drivers/ide/ide-park.c | 2 | ||||
-rw-r--r-- | include/linux/ide.h | 20 |
3 files changed, 32 insertions, 22 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index c60512196f61..ab480042757a 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q) | |||
790 | /* caller must own hwgroup->lock */ | 790 | /* caller must own hwgroup->lock */ |
791 | BUG_ON(!irqs_disabled()); | 791 | BUG_ON(!irqs_disabled()); |
792 | 792 | ||
793 | while (!hwgroup->busy) { | 793 | while (!ide_lock_hwgroup(hwgroup)) { |
794 | hwgroup->busy = 1; | ||
795 | /* for atari only */ | ||
796 | ide_get_lock(ide_intr, hwgroup); | ||
797 | drive = choose_drive(hwgroup); | 794 | drive = choose_drive(hwgroup); |
798 | if (drive == NULL) { | 795 | if (drive == NULL) { |
799 | int sleeping = 0; | 796 | int sleeping = 0; |
@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q) | |||
825 | hwgroup->sleeping = 1; | 822 | hwgroup->sleeping = 1; |
826 | hwgroup->req_gen_timer = hwgroup->req_gen; | 823 | hwgroup->req_gen_timer = hwgroup->req_gen; |
827 | mod_timer(&hwgroup->timer, sleep); | 824 | mod_timer(&hwgroup->timer, sleep); |
828 | /* we purposely leave hwgroup->busy==1 | 825 | /* we purposely leave hwgroup locked |
829 | * while sleeping */ | 826 | * while sleeping */ |
830 | } else { | 827 | } else |
831 | /* Ugly, but how can we sleep for the lock | 828 | ide_unlock_hwgroup(hwgroup); |
832 | * otherwise? perhaps from tq_disk? | ||
833 | */ | ||
834 | |||
835 | /* for atari only */ | ||
836 | ide_release_lock(); | ||
837 | hwgroup->busy = 0; | ||
838 | } | ||
839 | 829 | ||
840 | /* no more work for this hwgroup (for now) */ | 830 | /* no more work for this hwgroup (for now) */ |
841 | goto plug_device; | 831 | goto plug_device; |
@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q) | |||
865 | */ | 855 | */ |
866 | rq = elv_next_request(drive->queue); | 856 | rq = elv_next_request(drive->queue); |
867 | if (!rq) { | 857 | if (!rq) { |
868 | hwgroup->busy = 0; | 858 | ide_unlock_hwgroup(hwgroup); |
869 | break; | 859 | break; |
870 | } | 860 | } |
871 | 861 | ||
@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q) | |||
885 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && | 875 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
886 | blk_pm_request(rq) == 0 && | 876 | blk_pm_request(rq) == 0 && |
887 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | 877 | (rq->cmd_flags & REQ_PREEMPT) == 0) { |
888 | /* We clear busy, there should be no pending ATA command at this point. */ | 878 | /* there should be no pending command at this point */ |
889 | hwgroup->busy = 0; | 879 | ide_unlock_hwgroup(hwgroup); |
890 | goto plug_device; | 880 | goto plug_device; |
891 | } | 881 | } |
892 | 882 | ||
@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q) | |||
897 | spin_lock_irq(&hwgroup->lock); | 887 | spin_lock_irq(&hwgroup->lock); |
898 | 888 | ||
899 | if (startstop == ide_stopped) { | 889 | if (startstop == ide_stopped) { |
900 | hwgroup->busy = 0; | 890 | ide_unlock_hwgroup(hwgroup); |
901 | if (!elv_queue_empty(orig_drive->queue)) | 891 | if (!elv_queue_empty(orig_drive->queue)) |
902 | blk_plug_device(orig_drive->queue); | 892 | blk_plug_device(orig_drive->queue); |
903 | } | 893 | } |
@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data) | |||
1001 | */ | 991 | */ |
1002 | if (hwgroup->sleeping) { | 992 | if (hwgroup->sleeping) { |
1003 | hwgroup->sleeping = 0; | 993 | hwgroup->sleeping = 0; |
1004 | hwgroup->busy = 0; | 994 | ide_unlock_hwgroup(hwgroup); |
1005 | } | 995 | } |
1006 | } else { | 996 | } else { |
1007 | ide_drive_t *drive = hwgroup->drive; | 997 | ide_drive_t *drive = hwgroup->drive; |
@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data) | |||
1056 | spin_lock_irq(&hwgroup->lock); | 1046 | spin_lock_irq(&hwgroup->lock); |
1057 | enable_irq(hwif->irq); | 1047 | enable_irq(hwif->irq); |
1058 | if (startstop == ide_stopped) { | 1048 | if (startstop == ide_stopped) { |
1059 | hwgroup->busy = 0; | 1049 | ide_unlock_hwgroup(hwgroup); |
1060 | if (!elv_queue_empty(drive->queue)) | 1050 | if (!elv_queue_empty(drive->queue)) |
1061 | blk_plug_device(drive->queue); | 1051 | blk_plug_device(drive->queue); |
1062 | } | 1052 | } |
@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1249 | drive->service_time = jiffies - drive->service_start; | 1239 | drive->service_time = jiffies - drive->service_start; |
1250 | if (startstop == ide_stopped) { | 1240 | if (startstop == ide_stopped) { |
1251 | if (hwgroup->handler == NULL) { /* paranoia */ | 1241 | if (hwgroup->handler == NULL) { /* paranoia */ |
1252 | hwgroup->busy = 0; | 1242 | ide_unlock_hwgroup(hwgroup); |
1253 | if (!elv_queue_empty(drive->queue)) | 1243 | if (!elv_queue_empty(drive->queue)) |
1254 | blk_plug_device(drive->queue); | 1244 | blk_plug_device(drive->queue); |
1255 | } else | 1245 | } else |
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c index 63d01c55f865..44c6787f8aeb 100644 --- a/drivers/ide/ide-park.c +++ b/drivers/ide/ide-park.c | |||
@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout) | |||
22 | if (reset_timer && hwgroup->sleeping && | 22 | if (reset_timer && hwgroup->sleeping && |
23 | del_timer(&hwgroup->timer)) { | 23 | del_timer(&hwgroup->timer)) { |
24 | hwgroup->sleeping = 0; | 24 | hwgroup->sleeping = 0; |
25 | hwgroup->busy = 0; | 25 | ide_unlock_hwgroup(hwgroup); |
26 | blk_start_queueing(q); | 26 | blk_start_queueing(q); |
27 | } | 27 | } |
28 | spin_unlock_irq(&hwgroup->lock); | 28 | spin_unlock_irq(&hwgroup->lock); |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 968ca8f60531..f408d6123f14 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); | |||
1280 | 1280 | ||
1281 | extern void ide_timer_expiry(unsigned long); | 1281 | extern void ide_timer_expiry(unsigned long); |
1282 | extern irqreturn_t ide_intr(int irq, void *dev_id); | 1282 | extern irqreturn_t ide_intr(int irq, void *dev_id); |
1283 | |||
1284 | static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup) | ||
1285 | { | ||
1286 | if (hwgroup->busy) | ||
1287 | return 1; | ||
1288 | |||
1289 | hwgroup->busy = 1; | ||
1290 | /* for atari only */ | ||
1291 | ide_get_lock(ide_intr, hwgroup); | ||
1292 | |||
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup) | ||
1297 | { | ||
1298 | /* for atari only */ | ||
1299 | ide_release_lock(); | ||
1300 | hwgroup->busy = 0; | ||
1301 | } | ||
1302 | |||
1283 | extern void do_ide_request(struct request_queue *); | 1303 | extern void do_ide_request(struct request_queue *); |
1284 | 1304 | ||
1285 | void ide_init_disk(struct gendisk *, ide_drive_t *); | 1305 | void ide_init_disk(struct gendisk *, ide_drive_t *); |