diff options
| -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 | ||
