aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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/**