aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-12-29 14:27:31 -0500
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-12-29 14:27:31 -0500
commit2a2ca6a96194c4744a2adeefbc09ce881f3c5abe (patch)
tree50b43d823d4a589fbfb8f8751278d6101cd3ecf3 /drivers/ide/ide-io.c
parent6ea52226ca131a99bb619bd56fbeee566ea5a966 (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.c33
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)
1448out_handled: 1447out_handled:
1449 irq_ret = IRQ_HANDLED; 1448 irq_ret = IRQ_HANDLED;
1450out: 1449out:
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