diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-12-29 14:27:31 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-12-29 14:27:31 -0500 |
commit | 2a2ca6a96194c4744a2adeefbc09ce881f3c5abe (patch) | |
tree | 50b43d823d4a589fbfb8f8751278d6101cd3ecf3 /drivers/ide/ide-io.c | |
parent | 6ea52226ca131a99bb619bd56fbeee566ea5a966 (diff) |
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 <vaibhav.nivargi@gmail.com>
Cc: Alok N. Kataria <alokk@calsoftinc.com>
Cc: Shai Fultheim <shai@scalex86.org>
Signed-off-by: Ravikiran Thirumalai <kiran@scalex86.org>
Cc: Elias Oltmanns <eo@nebensachen.de>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 33 |
1 files changed, 16 insertions, 17 deletions
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: | |||
907 | 907 | ||
908 | /* | 908 | /* |
909 | * Issue a new request to a drive from hwgroup | 909 | * Issue a new request to a drive from hwgroup |
910 | * Caller must have already done spin_lock_irqsave(&ide_lock, ..); | 910 | * Caller must have already done spin_lock_irqsave(&hwgroup->lock, ..); |
911 | * | 911 | * |
912 | * A hwgroup is a serialized group of IDE interfaces. Usually there is | 912 | * A hwgroup is a serialized group of IDE interfaces. Usually there is |
913 | * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) | 913 | * exactly one hwif (interface) per hwgroup, but buggy controllers (eg. CMD640) |
@@ -919,7 +919,7 @@ repeat: | |||
919 | * possibly along with many other devices. This is especially common in | 919 | * possibly along with many other devices. This is especially common in |
920 | * PCI-based systems with off-board IDE controller cards. | 920 | * PCI-based systems with off-board IDE controller cards. |
921 | * | 921 | * |
922 | * The IDE driver uses the single global ide_lock spinlock to protect | 922 | * The IDE driver uses a per-hwgroup spinlock to protect |
923 | * access to the request queues, and to protect the hwgroup->busy flag. | 923 | * access to the request queues, and to protect the hwgroup->busy flag. |
924 | * | 924 | * |
925 | * The first thread into the driver for a particular hwgroup sets the | 925 | * The first thread into the driver for a particular hwgroup sets the |
@@ -935,7 +935,7 @@ repeat: | |||
935 | * will start the next request from the queue. If no more work remains, | 935 | * will start the next request from the queue. If no more work remains, |
936 | * the driver will clear the hwgroup->busy flag and exit. | 936 | * the driver will clear the hwgroup->busy flag and exit. |
937 | * | 937 | * |
938 | * The ide_lock (spinlock) is used to protect all access to the | 938 | * The per-hwgroup spinlock is used to protect all access to the |
939 | * hwgroup->busy flag, but is otherwise not needed for most processing in | 939 | * hwgroup->busy flag, but is otherwise not needed for most processing in |
940 | * the driver. This makes the driver much more friendlier to shared IRQs | 940 | * the driver. This makes the driver much more friendlier to shared IRQs |
941 | * than previous designs, while remaining 100% (?) SMP safe and capable. | 941 | * 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) | |||
948 | ide_startstop_t startstop; | 948 | ide_startstop_t startstop; |
949 | int loops = 0; | 949 | int loops = 0; |
950 | 950 | ||
951 | /* caller must own ide_lock */ | 951 | /* caller must own hwgroup->lock */ |
952 | BUG_ON(!irqs_disabled()); | 952 | BUG_ON(!irqs_disabled()); |
953 | 953 | ||
954 | while (!hwgroup->busy) { | 954 | while (!hwgroup->busy) { |
@@ -1070,11 +1070,11 @@ static void ide_do_request (ide_hwgroup_t *hwgroup, int masked_irq) | |||
1070 | */ | 1070 | */ |
1071 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | 1071 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) |
1072 | disable_irq_nosync(hwif->irq); | 1072 | disable_irq_nosync(hwif->irq); |
1073 | spin_unlock(&ide_lock); | 1073 | spin_unlock(&hwgroup->lock); |
1074 | local_irq_enable_in_hardirq(); | 1074 | local_irq_enable_in_hardirq(); |
1075 | /* allow other IRQs while we start this request */ | 1075 | /* allow other IRQs while we start this request */ |
1076 | startstop = start_request(drive, rq); | 1076 | startstop = start_request(drive, rq); |
1077 | spin_lock_irq(&ide_lock); | 1077 | spin_lock_irq(&hwgroup->lock); |
1078 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) | 1078 | if (masked_irq != IDE_NO_IRQ && hwif->irq != masked_irq) |
1079 | enable_irq(hwif->irq); | 1079 | enable_irq(hwif->irq); |
1080 | if (startstop == ide_stopped) | 1080 | if (startstop == ide_stopped) |
@@ -1172,7 +1172,7 @@ void ide_timer_expiry (unsigned long data) | |||
1172 | unsigned long flags; | 1172 | unsigned long flags; |
1173 | unsigned long wait = -1; | 1173 | unsigned long wait = -1; |
1174 | 1174 | ||
1175 | spin_lock_irqsave(&ide_lock, flags); | 1175 | spin_lock_irqsave(&hwgroup->lock, flags); |
1176 | 1176 | ||
1177 | if (((handler = hwgroup->handler) == NULL) || | 1177 | if (((handler = hwgroup->handler) == NULL) || |
1178 | (hwgroup->req_gen != hwgroup->req_gen_timer)) { | 1178 | (hwgroup->req_gen != hwgroup->req_gen_timer)) { |
@@ -1205,7 +1205,7 @@ void ide_timer_expiry (unsigned long data) | |||
1205 | hwgroup->timer.expires = jiffies + wait; | 1205 | hwgroup->timer.expires = jiffies + wait; |
1206 | hwgroup->req_gen_timer = hwgroup->req_gen; | 1206 | hwgroup->req_gen_timer = hwgroup->req_gen; |
1207 | add_timer(&hwgroup->timer); | 1207 | add_timer(&hwgroup->timer); |
1208 | spin_unlock_irqrestore(&ide_lock, flags); | 1208 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
1209 | return; | 1209 | return; |
1210 | } | 1210 | } |
1211 | } | 1211 | } |
@@ -1215,7 +1215,7 @@ void ide_timer_expiry (unsigned long data) | |||
1215 | * the handler() function, which means we need to | 1215 | * the handler() function, which means we need to |
1216 | * globally mask the specific IRQ: | 1216 | * globally mask the specific IRQ: |
1217 | */ | 1217 | */ |
1218 | spin_unlock(&ide_lock); | 1218 | spin_unlock(&hwgroup->lock); |
1219 | hwif = HWIF(drive); | 1219 | hwif = HWIF(drive); |
1220 | /* disable_irq_nosync ?? */ | 1220 | /* disable_irq_nosync ?? */ |
1221 | disable_irq(hwif->irq); | 1221 | disable_irq(hwif->irq); |
@@ -1239,14 +1239,14 @@ void ide_timer_expiry (unsigned long data) | |||
1239 | hwif->tp_ops->read_status(hwif)); | 1239 | hwif->tp_ops->read_status(hwif)); |
1240 | } | 1240 | } |
1241 | drive->service_time = jiffies - drive->service_start; | 1241 | drive->service_time = jiffies - drive->service_start; |
1242 | spin_lock_irq(&ide_lock); | 1242 | spin_lock_irq(&hwgroup->lock); |
1243 | enable_irq(hwif->irq); | 1243 | enable_irq(hwif->irq); |
1244 | if (startstop == ide_stopped) | 1244 | if (startstop == ide_stopped) |
1245 | hwgroup->busy = 0; | 1245 | hwgroup->busy = 0; |
1246 | } | 1246 | } |
1247 | } | 1247 | } |
1248 | ide_do_request(hwgroup, IDE_NO_IRQ); | 1248 | ide_do_request(hwgroup, IDE_NO_IRQ); |
1249 | spin_unlock_irqrestore(&ide_lock, flags); | 1249 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
1250 | } | 1250 | } |
1251 | 1251 | ||
1252 | /** | 1252 | /** |
@@ -1339,14 +1339,13 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1339 | { | 1339 | { |
1340 | unsigned long flags; | 1340 | unsigned long flags; |
1341 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; | 1341 | ide_hwgroup_t *hwgroup = (ide_hwgroup_t *)dev_id; |
1342 | ide_hwif_t *hwif; | 1342 | ide_hwif_t *hwif = hwgroup->hwif; |
1343 | ide_drive_t *drive; | 1343 | ide_drive_t *drive; |
1344 | ide_handler_t *handler; | 1344 | ide_handler_t *handler; |
1345 | ide_startstop_t startstop; | 1345 | ide_startstop_t startstop; |
1346 | irqreturn_t irq_ret = IRQ_NONE; | 1346 | irqreturn_t irq_ret = IRQ_NONE; |
1347 | 1347 | ||
1348 | spin_lock_irqsave(&ide_lock, flags); | 1348 | spin_lock_irqsave(&hwgroup->lock, flags); |
1349 | hwif = hwgroup->hwif; | ||
1350 | 1349 | ||
1351 | if (!ide_ack_intr(hwif)) | 1350 | if (!ide_ack_intr(hwif)) |
1352 | goto out; | 1351 | goto out; |
@@ -1416,7 +1415,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1416 | hwgroup->handler = NULL; | 1415 | hwgroup->handler = NULL; |
1417 | hwgroup->req_gen++; | 1416 | hwgroup->req_gen++; |
1418 | del_timer(&hwgroup->timer); | 1417 | del_timer(&hwgroup->timer); |
1419 | spin_unlock(&ide_lock); | 1418 | spin_unlock(&hwgroup->lock); |
1420 | 1419 | ||
1421 | if (hwif->port_ops && hwif->port_ops->clear_irq) | 1420 | if (hwif->port_ops && hwif->port_ops->clear_irq) |
1422 | hwif->port_ops->clear_irq(drive); | 1421 | hwif->port_ops->clear_irq(drive); |
@@ -1427,7 +1426,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1427 | /* service this interrupt, may set handler for next interrupt */ | 1426 | /* service this interrupt, may set handler for next interrupt */ |
1428 | startstop = handler(drive); | 1427 | startstop = handler(drive); |
1429 | 1428 | ||
1430 | spin_lock_irq(&ide_lock); | 1429 | spin_lock_irq(&hwgroup->lock); |
1431 | /* | 1430 | /* |
1432 | * Note that handler() may have set things up for another | 1431 | * Note that handler() may have set things up for another |
1433 | * interrupt to occur soon, but it cannot happen until | 1432 | * interrupt to occur soon, but it cannot happen until |
@@ -1448,7 +1447,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1448 | out_handled: | 1447 | out_handled: |
1449 | irq_ret = IRQ_HANDLED; | 1448 | irq_ret = IRQ_HANDLED; |
1450 | out: | 1449 | out: |
1451 | spin_unlock_irqrestore(&ide_lock, flags); | 1450 | spin_unlock_irqrestore(&hwgroup->lock, flags); |
1452 | return irq_ret; | 1451 | return irq_ret; |
1453 | } | 1452 | } |
1454 | 1453 | ||