diff options
| -rw-r--r-- | drivers/ide/ide-atapi.c | 3 | ||||
| -rw-r--r-- | drivers/ide/ide-cd.c | 2 | ||||
| -rw-r--r-- | drivers/ide/ide-dma.c | 50 | ||||
| -rw-r--r-- | drivers/ide/sgiioc4.c | 7 | ||||
| -rw-r--r-- | include/linux/ide.h | 6 |
5 files changed, 35 insertions, 33 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index db6e617790bd..3f3fc7c7b2fe 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
| @@ -326,6 +326,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 326 | { | 326 | { |
| 327 | struct ide_atapi_pc *pc = drive->pc; | 327 | struct ide_atapi_pc *pc = drive->pc; |
| 328 | ide_hwif_t *hwif = drive->hwif; | 328 | ide_hwif_t *hwif = drive->hwif; |
| 329 | struct ide_cmd *cmd = &hwif->cmd; | ||
| 329 | struct request *rq = hwif->rq; | 330 | struct request *rq = hwif->rq; |
| 330 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; | 331 | const struct ide_tp_ops *tp_ops = hwif->tp_ops; |
| 331 | xfer_func_t *xferfunc; | 332 | xfer_func_t *xferfunc; |
| @@ -346,7 +347,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 346 | 347 | ||
| 347 | drive->waiting_for_dma = 0; | 348 | drive->waiting_for_dma = 0; |
| 348 | rc = hwif->dma_ops->dma_end(drive); | 349 | rc = hwif->dma_ops->dma_end(drive); |
| 349 | ide_destroy_dmatable(drive); | 350 | ide_dma_unmap_sg(drive, cmd); |
| 350 | 351 | ||
| 351 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { | 352 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { |
| 352 | if (drive->media == ide_floppy) | 353 | if (drive->media == ide_floppy) |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index f5c7bb739f45..35729a47f797 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -640,7 +640,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 640 | drive->dma = 0; | 640 | drive->dma = 0; |
| 641 | drive->waiting_for_dma = 0; | 641 | drive->waiting_for_dma = 0; |
| 642 | dma_error = hwif->dma_ops->dma_end(drive); | 642 | dma_error = hwif->dma_ops->dma_end(drive); |
| 643 | ide_destroy_dmatable(drive); | 643 | ide_dma_unmap_sg(drive, cmd); |
| 644 | if (dma_error) { | 644 | if (dma_error) { |
| 645 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, | 645 | printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name, |
| 646 | write ? "write" : "read"); | 646 | write ? "write" : "read"); |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 4d3102887d9c..a5612eadc306 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
| @@ -89,17 +89,16 @@ static const struct drive_list_entry drive_blacklist[] = { | |||
| 89 | ide_startstop_t ide_dma_intr(ide_drive_t *drive) | 89 | ide_startstop_t ide_dma_intr(ide_drive_t *drive) |
| 90 | { | 90 | { |
| 91 | ide_hwif_t *hwif = drive->hwif; | 91 | ide_hwif_t *hwif = drive->hwif; |
| 92 | struct ide_cmd *cmd = &hwif->cmd; | ||
| 92 | u8 stat = 0, dma_stat = 0; | 93 | u8 stat = 0, dma_stat = 0; |
| 93 | 94 | ||
| 94 | drive->waiting_for_dma = 0; | 95 | drive->waiting_for_dma = 0; |
| 95 | dma_stat = hwif->dma_ops->dma_end(drive); | 96 | dma_stat = hwif->dma_ops->dma_end(drive); |
| 96 | ide_destroy_dmatable(drive); | 97 | ide_dma_unmap_sg(drive, cmd); |
| 97 | stat = hwif->tp_ops->read_status(hwif); | 98 | stat = hwif->tp_ops->read_status(hwif); |
| 98 | 99 | ||
| 99 | if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { | 100 | if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) { |
| 100 | if (!dma_stat) { | 101 | if (!dma_stat) { |
| 101 | struct ide_cmd *cmd = &hwif->cmd; | ||
| 102 | |||
| 103 | if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) | 102 | if ((cmd->tf_flags & IDE_TFLAG_FS) == 0) |
| 104 | ide_finish_cmd(drive, cmd, stat); | 103 | ide_finish_cmd(drive, cmd, stat); |
| 105 | else | 104 | else |
| @@ -119,8 +118,8 @@ int ide_dma_good_drive(ide_drive_t *drive) | |||
| 119 | } | 118 | } |
| 120 | 119 | ||
| 121 | /** | 120 | /** |
| 122 | * ide_build_sglist - map IDE scatter gather for DMA I/O | 121 | * ide_dma_map_sg - map IDE scatter gather for DMA I/O |
| 123 | * @drive: the drive to build the DMA table for | 122 | * @drive: the drive to map the DMA table for |
| 124 | * @cmd: command | 123 | * @cmd: command |
| 125 | * | 124 | * |
| 126 | * Perform the DMA mapping magic necessary to access the source or | 125 | * Perform the DMA mapping magic necessary to access the source or |
| @@ -129,23 +128,19 @@ int ide_dma_good_drive(ide_drive_t *drive) | |||
| 129 | * operate in a portable fashion. | 128 | * operate in a portable fashion. |
| 130 | */ | 129 | */ |
| 131 | 130 | ||
| 132 | static int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd) | 131 | static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd) |
| 133 | { | 132 | { |
| 134 | ide_hwif_t *hwif = drive->hwif; | 133 | ide_hwif_t *hwif = drive->hwif; |
| 135 | struct scatterlist *sg = hwif->sg_table; | 134 | struct scatterlist *sg = hwif->sg_table; |
| 136 | int i; | 135 | int i; |
| 137 | 136 | ||
| 138 | ide_map_sg(drive, cmd); | ||
| 139 | |||
| 140 | if (cmd->tf_flags & IDE_TFLAG_WRITE) | 137 | if (cmd->tf_flags & IDE_TFLAG_WRITE) |
| 141 | cmd->sg_dma_direction = DMA_TO_DEVICE; | 138 | cmd->sg_dma_direction = DMA_TO_DEVICE; |
| 142 | else | 139 | else |
| 143 | cmd->sg_dma_direction = DMA_FROM_DEVICE; | 140 | cmd->sg_dma_direction = DMA_FROM_DEVICE; |
| 144 | 141 | ||
| 145 | i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction); | 142 | i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction); |
| 146 | if (i == 0) | 143 | if (i) { |
| 147 | ide_map_sg(drive, cmd); | ||
| 148 | else { | ||
| 149 | cmd->orig_sg_nents = cmd->sg_nents; | 144 | cmd->orig_sg_nents = cmd->sg_nents; |
| 150 | cmd->sg_nents = i; | 145 | cmd->sg_nents = i; |
| 151 | } | 146 | } |
| @@ -154,7 +149,7 @@ static int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 154 | } | 149 | } |
| 155 | 150 | ||
| 156 | /** | 151 | /** |
| 157 | * ide_destroy_dmatable - clean up DMA mapping | 152 | * ide_dma_unmap_sg - clean up DMA mapping |
| 158 | * @drive: The drive to unmap | 153 | * @drive: The drive to unmap |
| 159 | * | 154 | * |
| 160 | * Teardown mappings after DMA has completed. This must be called | 155 | * Teardown mappings after DMA has completed. This must be called |
| @@ -164,15 +159,14 @@ static int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 164 | * time. | 159 | * time. |
| 165 | */ | 160 | */ |
| 166 | 161 | ||
| 167 | void ide_destroy_dmatable(ide_drive_t *drive) | 162 | void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd) |
| 168 | { | 163 | { |
| 169 | ide_hwif_t *hwif = drive->hwif; | 164 | ide_hwif_t *hwif = drive->hwif; |
| 170 | struct ide_cmd *cmd = &hwif->cmd; | ||
| 171 | 165 | ||
| 172 | dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents, | 166 | dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents, |
| 173 | cmd->sg_dma_direction); | 167 | cmd->sg_dma_direction); |
| 174 | } | 168 | } |
| 175 | EXPORT_SYMBOL_GPL(ide_destroy_dmatable); | 169 | EXPORT_SYMBOL_GPL(ide_dma_unmap_sg); |
| 176 | 170 | ||
| 177 | /** | 171 | /** |
| 178 | * ide_dma_off_quietly - Generic DMA kill | 172 | * ide_dma_off_quietly - Generic DMA kill |
| @@ -471,6 +465,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
| 471 | { | 465 | { |
| 472 | ide_hwif_t *hwif = drive->hwif; | 466 | ide_hwif_t *hwif = drive->hwif; |
| 473 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; | 467 | const struct ide_dma_ops *dma_ops = hwif->dma_ops; |
| 468 | struct ide_cmd *cmd = &hwif->cmd; | ||
| 474 | struct request *rq; | 469 | struct request *rq; |
| 475 | ide_startstop_t ret = ide_stopped; | 470 | ide_startstop_t ret = ide_stopped; |
| 476 | 471 | ||
| @@ -482,7 +477,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
| 482 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); | 477 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); |
| 483 | drive->waiting_for_dma = 0; | 478 | drive->waiting_for_dma = 0; |
| 484 | (void)dma_ops->dma_end(drive); | 479 | (void)dma_ops->dma_end(drive); |
| 485 | ide_destroy_dmatable(drive); | 480 | ide_dma_unmap_sg(drive, cmd); |
| 486 | ret = ide_error(drive, "dma timeout error", | 481 | ret = ide_error(drive, "dma timeout error", |
| 487 | hwif->tp_ops->read_status(hwif)); | 482 | hwif->tp_ops->read_status(hwif)); |
| 488 | } else { | 483 | } else { |
| @@ -495,7 +490,7 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
| 495 | hwif->tp_ops->read_status(hwif)); | 490 | hwif->tp_ops->read_status(hwif)); |
| 496 | drive->waiting_for_dma = 0; | 491 | drive->waiting_for_dma = 0; |
| 497 | (void)dma_ops->dma_end(drive); | 492 | (void)dma_ops->dma_end(drive); |
| 498 | ide_destroy_dmatable(drive); | 493 | ide_dma_unmap_sg(drive, cmd); |
| 499 | } | 494 | } |
| 500 | } | 495 | } |
| 501 | 496 | ||
| @@ -572,14 +567,19 @@ int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 572 | const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops; | 567 | const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops; |
| 573 | 568 | ||
| 574 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || | 569 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || |
| 575 | (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)) || | 570 | (dma_ops->dma_check && dma_ops->dma_check(drive, cmd))) |
| 576 | ide_build_sglist(drive, cmd) == 0) | 571 | goto out; |
| 577 | return 1; | 572 | ide_map_sg(drive, cmd); |
| 578 | if (dma_ops->dma_setup(drive, cmd)) { | 573 | if (ide_dma_map_sg(drive, cmd) == 0) |
| 579 | ide_destroy_dmatable(drive); | 574 | goto out_map; |
| 580 | ide_map_sg(drive, cmd); | 575 | if (dma_ops->dma_setup(drive, cmd)) |
| 581 | return 1; | 576 | goto out_dma_unmap; |
| 582 | } | ||
| 583 | drive->waiting_for_dma = 1; | 577 | drive->waiting_for_dma = 1; |
| 584 | return 0; | 578 | return 0; |
| 579 | out_dma_unmap: | ||
| 580 | ide_dma_unmap_sg(drive, cmd); | ||
| 581 | out_map: | ||
| 582 | ide_map_sg(drive, cmd); | ||
| 583 | out: | ||
| 584 | return 1; | ||
| 585 | } | 585 | } |
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c index cb2657c4c976..6ef5a567d377 100644 --- a/drivers/ide/sgiioc4.c +++ b/drivers/ide/sgiioc4.c | |||
| @@ -277,11 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on) | |||
| 277 | sgiioc4_clearirq(drive); | 277 | sgiioc4_clearirq(drive); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | static void | 280 | static void sgiioc4_resetproc(ide_drive_t *drive) |
| 281 | sgiioc4_resetproc(ide_drive_t * drive) | ||
| 282 | { | 281 | { |
| 282 | struct ide_cmd *cmd = &drive->hwif->cmd; | ||
| 283 | |||
| 283 | sgiioc4_dma_end(drive); | 284 | sgiioc4_dma_end(drive); |
| 284 | ide_destroy_dmatable(drive); | 285 | ide_dma_unmap_sg(drive, cmd); |
| 285 | sgiioc4_clearirq(drive); | 286 | sgiioc4_clearirq(drive); |
| 286 | } | 287 | } |
| 287 | 288 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index b350667b83ad..03c520917b7a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -1445,8 +1445,7 @@ int ide_allocate_dma_engine(ide_hwif_t *); | |||
| 1445 | void ide_release_dma_engine(ide_hwif_t *); | 1445 | void ide_release_dma_engine(ide_hwif_t *); |
| 1446 | 1446 | ||
| 1447 | int ide_dma_prepare(ide_drive_t *, struct ide_cmd *); | 1447 | int ide_dma_prepare(ide_drive_t *, struct ide_cmd *); |
| 1448 | 1448 | void ide_dma_unmap_sg(ide_drive_t *, struct ide_cmd *); | |
| 1449 | void ide_destroy_dmatable(ide_drive_t *); | ||
| 1450 | 1449 | ||
| 1451 | #ifdef CONFIG_BLK_DEV_IDEDMA_SFF | 1450 | #ifdef CONFIG_BLK_DEV_IDEDMA_SFF |
| 1452 | int config_drive_for_dma(ide_drive_t *); | 1451 | int config_drive_for_dma(ide_drive_t *); |
| @@ -1481,7 +1480,8 @@ static inline ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int erro | |||
| 1481 | static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } | 1480 | static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } |
| 1482 | static inline int ide_dma_prepare(ide_drive_t *drive, | 1481 | static inline int ide_dma_prepare(ide_drive_t *drive, |
| 1483 | struct ide_cmd *cmd) { return 1; } | 1482 | struct ide_cmd *cmd) { return 1; } |
| 1484 | static inline void ide_destroy_dmatable(ide_drive_t *drive) { ; } | 1483 | static inline void ide_dma_unmap_sg(ide_drive_t *drive, |
| 1484 | struct ide_cmd *cmd) { ; } | ||
| 1485 | #endif /* CONFIG_BLK_DEV_IDEDMA */ | 1485 | #endif /* CONFIG_BLK_DEV_IDEDMA */ |
| 1486 | 1486 | ||
| 1487 | #ifdef CONFIG_BLK_DEV_IDEACPI | 1487 | #ifdef CONFIG_BLK_DEV_IDEACPI |
