aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@redhat.com>2006-06-26 03:26:12 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-26 12:58:27 -0400
commit4fb0f76d8cf4f7a3ffc36dd5e1bc8ca977b68824 (patch)
tree6ba26f667cdddae3aea67253ae6c2fce0c1dffc8
parentb5cdccf841d7d29fb96e03de5a64ed395e0fde61 (diff)
[PATCH] Fix IDE locking error
This bit us a few kernels ago, and for some reason never made it's way upstream. https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=144743 Kernel panic - not syncing: drivers/ide/pci/piix.c:231: spin_lock(drivers/ide/ide.c:c03cef28) already locked by driver/ide/ide-iops.c/1153. Signed-off-by: Dave Jones <davej@redhat.com> Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl> Cc: Dave Jones <davej@redhat.com> Cc: Jens Axboe <axboe@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/ide/pci/piix.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index e9b83e1a3028..7fac6f57b5d6 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -222,6 +222,8 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
222 unsigned long flags; 222 unsigned long flags;
223 u16 master_data; 223 u16 master_data;
224 u8 slave_data; 224 u8 slave_data;
225 static DEFINE_SPINLOCK(tune_lock);
226
225 /* ISP RTC */ 227 /* ISP RTC */
226 u8 timings[][2] = { { 0, 0 }, 228 u8 timings[][2] = { { 0, 0 },
227 { 0, 0 }, 229 { 0, 0 },
@@ -230,7 +232,13 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
230 { 2, 3 }, }; 232 { 2, 3 }, };
231 233
232 pio = ide_get_best_pio_mode(drive, pio, 5, NULL); 234 pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
233 spin_lock_irqsave(&ide_lock, flags); 235
236 /*
237 * Master vs slave is synchronized above us but the slave register is
238 * shared by the two hwifs so the corner case of two slave timeouts in
239 * parallel must be locked.
240 */
241 spin_lock_irqsave(&tune_lock, flags);
234 pci_read_config_word(dev, master_port, &master_data); 242 pci_read_config_word(dev, master_port, &master_data);
235 if (is_slave) { 243 if (is_slave) {
236 master_data = master_data | 0x4000; 244 master_data = master_data | 0x4000;
@@ -250,7 +258,7 @@ static void piix_tune_drive (ide_drive_t *drive, u8 pio)
250 pci_write_config_word(dev, master_port, master_data); 258 pci_write_config_word(dev, master_port, master_data);
251 if (is_slave) 259 if (is_slave)
252 pci_write_config_byte(dev, slave_port, slave_data); 260 pci_write_config_byte(dev, slave_port, slave_data);
253 spin_unlock_irqrestore(&ide_lock, flags); 261 spin_unlock_irqrestore(&tune_lock, flags);
254} 262}
255 263
256/** 264/**