diff options
Diffstat (limited to 'drivers/ide/ide-dma-sff.c')
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 52 |
1 files changed, 23 insertions, 29 deletions
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c index 1f2a5f56f81c..f6d2d44d8a9a 100644 --- a/drivers/ide/ide-dma-sff.c +++ b/drivers/ide/ide-dma-sff.c | |||
@@ -176,15 +176,10 @@ int ide_dma_setup(ide_drive_t *drive) | |||
176 | { | 176 | { |
177 | ide_hwif_t *hwif = drive->hwif; | 177 | ide_hwif_t *hwif = drive->hwif; |
178 | struct request *rq = hwif->hwgroup->rq; | 178 | struct request *rq = hwif->hwgroup->rq; |
179 | unsigned int reading; | 179 | unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR; |
180 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | 180 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; |
181 | u8 dma_stat; | 181 | u8 dma_stat; |
182 | 182 | ||
183 | if (rq_data_dir(rq)) | ||
184 | reading = 0; | ||
185 | else | ||
186 | reading = 1 << 3; | ||
187 | |||
188 | /* fall back to pio! */ | 183 | /* fall back to pio! */ |
189 | if (!ide_build_dmatable(drive, rq)) { | 184 | if (!ide_build_dmatable(drive, rq)) { |
190 | ide_map_sg(drive, rq); | 185 | ide_map_sg(drive, rq); |
@@ -209,10 +204,11 @@ int ide_dma_setup(ide_drive_t *drive) | |||
209 | 204 | ||
210 | /* clear INTR & ERROR flags */ | 205 | /* clear INTR & ERROR flags */ |
211 | if (mmio) | 206 | if (mmio) |
212 | writeb(dma_stat | 6, | 207 | writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, |
213 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | 208 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); |
214 | else | 209 | else |
215 | outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); | 210 | outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, |
211 | hwif->dma_base + ATA_DMA_STATUS); | ||
216 | 212 | ||
217 | drive->waiting_for_dma = 1; | 213 | drive->waiting_for_dma = 1; |
218 | return 0; | 214 | return 0; |
@@ -246,14 +242,13 @@ static int dma_timer_expiry(ide_drive_t *drive) | |||
246 | 242 | ||
247 | hwif->hwgroup->expiry = NULL; /* one free ride for now */ | 243 | hwif->hwgroup->expiry = NULL; /* one free ride for now */ |
248 | 244 | ||
249 | /* 1 dmaing, 2 error, 4 intr */ | 245 | if (dma_stat & ATA_DMA_ERR) /* ERROR */ |
250 | if (dma_stat & 2) /* ERROR */ | ||
251 | return -1; | 246 | return -1; |
252 | 247 | ||
253 | if (dma_stat & 1) /* DMAing */ | 248 | if (dma_stat & ATA_DMA_ACTIVE) /* DMAing */ |
254 | return WAIT_CMD; | 249 | return WAIT_CMD; |
255 | 250 | ||
256 | if (dma_stat & 4) /* Got an Interrupt */ | 251 | if (dma_stat & ATA_DMA_INTR) /* Got an Interrupt */ |
257 | return WAIT_CMD; | 252 | return WAIT_CMD; |
258 | 253 | ||
259 | return 0; /* Status is unknown -- reset the bus */ | 254 | return 0; /* Status is unknown -- reset the bus */ |
@@ -279,12 +274,11 @@ void ide_dma_start(ide_drive_t *drive) | |||
279 | */ | 274 | */ |
280 | if (hwif->host_flags & IDE_HFLAG_MMIO) { | 275 | if (hwif->host_flags & IDE_HFLAG_MMIO) { |
281 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 276 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
282 | /* start DMA */ | 277 | writeb(dma_cmd | ATA_DMA_START, |
283 | writeb(dma_cmd | 1, | ||
284 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 278 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
285 | } else { | 279 | } else { |
286 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | 280 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); |
287 | outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); | 281 | outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); |
288 | } | 282 | } |
289 | 283 | ||
290 | wmb(); | 284 | wmb(); |
@@ -296,19 +290,18 @@ int ide_dma_end(ide_drive_t *drive) | |||
296 | { | 290 | { |
297 | ide_hwif_t *hwif = drive->hwif; | 291 | ide_hwif_t *hwif = drive->hwif; |
298 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; | 292 | u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; |
299 | u8 dma_stat = 0, dma_cmd = 0; | 293 | u8 dma_stat = 0, dma_cmd = 0, mask; |
300 | 294 | ||
301 | drive->waiting_for_dma = 0; | 295 | drive->waiting_for_dma = 0; |
302 | 296 | ||
297 | /* stop DMA */ | ||
303 | if (mmio) { | 298 | if (mmio) { |
304 | /* get DMA command mode */ | ||
305 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 299 | dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
306 | /* stop DMA */ | 300 | writeb(dma_cmd & ~ATA_DMA_START, |
307 | writeb(dma_cmd & ~1, | ||
308 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); | 301 | (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); |
309 | } else { | 302 | } else { |
310 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); | 303 | dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); |
311 | outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); | 304 | outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD); |
312 | } | 305 | } |
313 | 306 | ||
314 | /* get DMA status */ | 307 | /* get DMA status */ |
@@ -316,16 +309,21 @@ int ide_dma_end(ide_drive_t *drive) | |||
316 | 309 | ||
317 | if (mmio) | 310 | if (mmio) |
318 | /* clear the INTR & ERROR bits */ | 311 | /* clear the INTR & ERROR bits */ |
319 | writeb(dma_stat | 6, | 312 | writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, |
320 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); | 313 | (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)); |
321 | else | 314 | else |
322 | outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS); | 315 | outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR, |
316 | hwif->dma_base + ATA_DMA_STATUS); | ||
323 | 317 | ||
324 | /* purge DMA mappings */ | 318 | /* purge DMA mappings */ |
325 | ide_destroy_dmatable(drive); | 319 | ide_destroy_dmatable(drive); |
326 | /* verify good DMA status */ | ||
327 | wmb(); | 320 | wmb(); |
328 | return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; | 321 | |
322 | /* verify good DMA status */ | ||
323 | mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR; | ||
324 | if ((dma_stat & mask) != ATA_DMA_INTR) | ||
325 | return 0x10 | dma_stat; | ||
326 | return 0; | ||
329 | } | 327 | } |
330 | EXPORT_SYMBOL_GPL(ide_dma_end); | 328 | EXPORT_SYMBOL_GPL(ide_dma_end); |
331 | 329 | ||
@@ -335,11 +333,7 @@ int ide_dma_test_irq(ide_drive_t *drive) | |||
335 | ide_hwif_t *hwif = drive->hwif; | 333 | ide_hwif_t *hwif = drive->hwif; |
336 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); | 334 | u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); |
337 | 335 | ||
338 | /* return 1 if INTR asserted */ | 336 | return (dma_stat & ATA_DMA_INTR) ? 1 : 0; |
339 | if ((dma_stat & 4) == 4) | ||
340 | return 1; | ||
341 | |||
342 | return 0; | ||
343 | } | 337 | } |
344 | EXPORT_SYMBOL_GPL(ide_dma_test_irq); | 338 | EXPORT_SYMBOL_GPL(ide_dma_test_irq); |
345 | 339 | ||