diff options
author | Alan <alan@lxorguk.ukuu.org.uk> | 2007-01-05 19:36:27 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:22 -0500 |
commit | 6c5f8cc33eb2e10b6ab788bbe259fc142a068627 (patch) | |
tree | ed96223e8d35c12e7ab7b2edbd4b5648acfe8f13 | |
parent | 406c9b605cbc45151c03ac9a3f95e9acf050808c (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.c | 18 |
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 | ||
47 | static int save_mdma_mode[4]; | 47 | static int save_mdma_mode[4]; |
48 | 48 | ||
49 | static 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); |