aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan <alan@lxorguk.ukuu.org.uk>2007-01-05 19:36:27 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2007-01-06 02:55:22 -0500
commit6c5f8cc33eb2e10b6ab788bbe259fc142a068627 (patch)
treeed96223e8d35c12e7ab7b2edbd4b5648acfe8f13
parent406c9b605cbc45151c03ac9a3f95e9acf050808c (diff)
[PATCH] atiixp: Old drivers/ide layer driver for the ATIIXP hang fix
When the old IDE layer calls into methods in the driver during error handling it is essentially random whether ide_lock is already held. This causes a deadlock in the atiixp driver which also uses ide_lock internally for locking. Switch to a private lock instead. [akpm@osl.org: cleanup] Signed-off-by: Alan Cox <alan@redhat.com> Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--drivers/ide/pci/atiixp.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index ffdffb6379ef..524e65de4398 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -46,6 +46,8 @@ static atiixp_ide_timing mdma_timing[] = {
46 46
47static int save_mdma_mode[4]; 47static int save_mdma_mode[4];
48 48
49static DEFINE_SPINLOCK(atiixp_lock);
50
49/** 51/**
50 * atiixp_ratemask - compute rate mask for ATIIXP IDE 52 * atiixp_ratemask - compute rate mask for ATIIXP IDE
51 * @drive: IDE drive to compute for 53 * @drive: IDE drive to compute for
@@ -105,7 +107,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
105 unsigned long flags; 107 unsigned long flags;
106 u16 tmp16; 108 u16 tmp16;
107 109
108 spin_lock_irqsave(&ide_lock, flags); 110 spin_lock_irqsave(&atiixp_lock, flags);
109 111
110 pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); 112 pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
111 if (save_mdma_mode[drive->dn]) 113 if (save_mdma_mode[drive->dn])
@@ -114,7 +116,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
114 tmp16 |= (1 << drive->dn); 116 tmp16 |= (1 << drive->dn);
115 pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); 117 pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
116 118
117 spin_unlock_irqrestore(&ide_lock, flags); 119 spin_unlock_irqrestore(&atiixp_lock, flags);
118 120
119 return __ide_dma_host_on(drive); 121 return __ide_dma_host_on(drive);
120} 122}
@@ -125,13 +127,13 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive)
125 unsigned long flags; 127 unsigned long flags;
126 u16 tmp16; 128 u16 tmp16;
127 129
128 spin_lock_irqsave(&ide_lock, flags); 130 spin_lock_irqsave(&atiixp_lock, flags);
129 131
130 pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16); 132 pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
131 tmp16 &= ~(1 << drive->dn); 133 tmp16 &= ~(1 << drive->dn);
132 pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16); 134 pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);
133 135
134 spin_unlock_irqrestore(&ide_lock, flags); 136 spin_unlock_irqrestore(&atiixp_lock, flags);
135 137
136 return __ide_dma_host_off(drive); 138 return __ide_dma_host_off(drive);
137} 139}
@@ -152,7 +154,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
152 u32 pio_timing_data; 154 u32 pio_timing_data;
153 u16 pio_mode_data; 155 u16 pio_mode_data;
154 156
155 spin_lock_irqsave(&ide_lock, flags); 157 spin_lock_irqsave(&atiixp_lock, flags);
156 158
157 pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data); 159 pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
158 pio_mode_data &= ~(0x07 << (drive->dn * 4)); 160 pio_mode_data &= ~(0x07 << (drive->dn * 4));
@@ -165,7 +167,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
165 (pio_timing[pio].command_width << (timing_shift + 4)); 167 (pio_timing[pio].command_width << (timing_shift + 4));
166 pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data); 168 pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
167 169
168 spin_unlock_irqrestore(&ide_lock, flags); 170 spin_unlock_irqrestore(&atiixp_lock, flags);
169} 171}
170 172
171/** 173/**
@@ -189,7 +191,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
189 191
190 speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed); 192 speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed);
191 193
192 spin_lock_irqsave(&ide_lock, flags); 194 spin_lock_irqsave(&atiixp_lock, flags);
193 195
194 save_mdma_mode[drive->dn] = 0; 196 save_mdma_mode[drive->dn] = 0;
195 if (speed >= XFER_UDMA_0) { 197 if (speed >= XFER_UDMA_0) {
@@ -208,7 +210,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
208 } 210 }
209 } 211 }
210 212
211 spin_unlock_irqrestore(&ide_lock, flags); 213 spin_unlock_irqrestore(&atiixp_lock, flags);
212 214
213 if (speed >= XFER_SW_DMA_0) 215 if (speed >= XFER_SW_DMA_0)
214 pio = atiixp_dma_2_pio(speed); 216 pio = atiixp_dma_2_pio(speed);