aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/alim15x3.c7
-rw-r--r--drivers/ide/au1xxx-ide.c15
-rw-r--r--drivers/ide/icside.c7
-rw-r--r--drivers/ide/ide-atapi.c16
-rw-r--r--drivers/ide/ide-disk.c10
-rw-r--r--drivers/ide/ide-dma-sff.c18
-rw-r--r--drivers/ide/ide-dma.c15
-rw-r--r--drivers/ide/ide-floppy.c6
-rw-r--r--drivers/ide/ide-io.c6
-rw-r--r--drivers/ide/ide-taskfile.c4
-rw-r--r--drivers/ide/ns87415.c4
-rw-r--r--drivers/ide/pmac.c19
-rw-r--r--drivers/ide/scc_pata.c19
-rw-r--r--drivers/ide/sgiioc4.c21
-rw-r--r--drivers/ide/trm290.c10
-rw-r--r--drivers/ide/tx4939ide.c26
-rw-r--r--include/linux/ide.h12
17 files changed, 101 insertions, 114 deletions
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index d3513b6b8530..e837fd9f196f 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -191,17 +191,18 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
191/** 191/**
192 * ali15x3_dma_setup - begin a DMA phase 192 * ali15x3_dma_setup - begin a DMA phase
193 * @drive: target device 193 * @drive: target device
194 * @cmd: command
194 * 195 *
195 * Returns 1 if the DMA cannot be performed, zero on success. 196 * Returns 1 if the DMA cannot be performed, zero on success.
196 */ 197 */
197 198
198static int ali15x3_dma_setup(ide_drive_t *drive) 199static int ali15x3_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
199{ 200{
200 if (m5229_revision < 0xC2 && drive->media != ide_disk) { 201 if (m5229_revision < 0xC2 && drive->media != ide_disk) {
201 if (rq_data_dir(drive->hwif->rq)) 202 if (cmd->tf_flags & IDE_TFLAG_WRITE)
202 return 1; /* try PIO instead of DMA */ 203 return 1; /* try PIO instead of DMA */
203 } 204 }
204 return ide_dma_setup(drive); 205 return ide_dma_setup(drive, cmd);
205} 206}
206 207
207/** 208/**
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 3ace0cda5452..58485d6cb026 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -209,15 +209,14 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
209 */ 209 */
210 210
211#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 211#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
212static int auide_build_dmatable(ide_drive_t *drive) 212static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
213{ 213{
214 ide_hwif_t *hwif = drive->hwif; 214 ide_hwif_t *hwif = drive->hwif;
215 struct request *rq = hwif->rq;
216 _auide_hwif *ahwif = &auide_hwif; 215 _auide_hwif *ahwif = &auide_hwif;
217 struct scatterlist *sg; 216 struct scatterlist *sg;
218 int i = hwif->cmd.sg_nents, iswrite, count = 0; 217 int i = cmd->sg_nents, count = 0;
218 int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
219 219
220 iswrite = (rq_data_dir(rq) == WRITE);
221 /* Save for interrupt context */ 220 /* Save for interrupt context */
222 ahwif->drive = drive; 221 ahwif->drive = drive;
223 222
@@ -298,12 +297,10 @@ static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
298 (2*WAIT_CMD), NULL); 297 (2*WAIT_CMD), NULL);
299} 298}
300 299
301static int auide_dma_setup(ide_drive_t *drive) 300static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
302{ 301{
303 struct request *rq = drive->hwif->rq; 302 if (auide_build_dmatable(drive, cmd) == 0) {
304 303 ide_map_sg(drive, cmd);
305 if (!auide_build_dmatable(drive)) {
306 ide_map_sg(drive, rq);
307 return 1; 304 return 1;
308 } 305 }
309 306
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index bdfeb1222d52..3628b2147902 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -307,15 +307,14 @@ static void icside_dma_start(ide_drive_t *drive)
307 enable_dma(ec->dma); 307 enable_dma(ec->dma);
308} 308}
309 309
310static int icside_dma_setup(ide_drive_t *drive) 310static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
311{ 311{
312 ide_hwif_t *hwif = drive->hwif; 312 ide_hwif_t *hwif = drive->hwif;
313 struct expansion_card *ec = ECARD_DEV(hwif->dev); 313 struct expansion_card *ec = ECARD_DEV(hwif->dev);
314 struct icside_state *state = ecard_get_drvdata(ec); 314 struct icside_state *state = ecard_get_drvdata(ec);
315 struct request *rq = hwif->rq;
316 unsigned int dma_mode; 315 unsigned int dma_mode;
317 316
318 if (rq_data_dir(rq)) 317 if (cmd->tf_flags & IDE_TFLAG_WRITE)
319 dma_mode = DMA_MODE_WRITE; 318 dma_mode = DMA_MODE_WRITE;
320 else 319 else
321 dma_mode = DMA_MODE_READ; 320 dma_mode = DMA_MODE_READ;
@@ -344,7 +343,7 @@ static int icside_dma_setup(ide_drive_t *drive)
344 * Tell the DMA engine about the SG table and 343 * Tell the DMA engine about the SG table and
345 * data direction. 344 * data direction.
346 */ 345 */
347 set_dma_sg(ec->dma, hwif->sg_table, hwif->cmd.sg_nents); 346 set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
348 set_dma_mode(ec->dma, dma_mode); 347 set_dma_mode(ec->dma, dma_mode);
349 348
350 drive->waiting_for_dma = 1; 349 drive->waiting_for_dma = 1;
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index c3fd528a1b4d..b56af49f876b 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -638,12 +638,20 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
638{ 638{
639 struct ide_atapi_pc *pc; 639 struct ide_atapi_pc *pc;
640 ide_hwif_t *hwif = drive->hwif; 640 ide_hwif_t *hwif = drive->hwif;
641 const struct ide_dma_ops *dma_ops = hwif->dma_ops;
642 struct ide_cmd *cmd = &hwif->cmd;
641 ide_expiry_t *expiry = NULL; 643 ide_expiry_t *expiry = NULL;
642 struct request *rq = hwif->rq; 644 struct request *rq = hwif->rq;
643 unsigned int timeout; 645 unsigned int timeout;
644 u32 tf_flags; 646 u32 tf_flags;
645 u16 bcount; 647 u16 bcount;
646 648
649 if (drive->media != ide_floppy) {
650 if (rq_data_dir(rq))
651 cmd->tf_flags |= IDE_TFLAG_WRITE;
652 cmd->rq = rq;
653 }
654
647 if (dev_is_idecd(drive)) { 655 if (dev_is_idecd(drive)) {
648 tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL; 656 tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
649 bcount = ide_cd_get_xferlen(rq); 657 bcount = ide_cd_get_xferlen(rq);
@@ -651,8 +659,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
651 timeout = ATAPI_WAIT_PC; 659 timeout = ATAPI_WAIT_PC;
652 660
653 if (drive->dma) { 661 if (drive->dma) {
654 if (ide_build_sglist(drive, rq)) 662 if (ide_build_sglist(drive, cmd))
655 drive->dma = !hwif->dma_ops->dma_setup(drive); 663 drive->dma = !dma_ops->dma_setup(drive, cmd);
656 else 664 else
657 drive->dma = 0; 665 drive->dma = 0;
658 } 666 }
@@ -675,8 +683,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
675 683
676 if ((pc->flags & PC_FLAG_DMA_OK) && 684 if ((pc->flags & PC_FLAG_DMA_OK) &&
677 (drive->dev_flags & IDE_DFLAG_USING_DMA)) { 685 (drive->dev_flags & IDE_DFLAG_USING_DMA)) {
678 if (ide_build_sglist(drive, rq)) 686 if (ide_build_sglist(drive, cmd))
679 drive->dma = !hwif->dma_ops->dma_setup(drive); 687 drive->dma = !dma_ops->dma_setup(drive, cmd);
680 else 688 else
681 drive->dma = 0; 689 drive->dma = 0;
682 } 690 }
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index d8caa65ca7a5..4b32c4eb7b82 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -99,11 +99,6 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
99 memset(&cmd, 0, sizeof(cmd)); 99 memset(&cmd, 0, sizeof(cmd));
100 cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; 100 cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
101 101
102 if (dma == 0) {
103 ide_init_sg_cmd(&cmd, nsectors);
104 ide_map_sg(drive, rq);
105 }
106
107 if (drive->dev_flags & IDE_DFLAG_LBA) { 102 if (drive->dev_flags & IDE_DFLAG_LBA) {
108 if (lba48) { 103 if (lba48) {
109 pr_debug("%s: LBA=0x%012llx\n", drive->name, 104 pr_debug("%s: LBA=0x%012llx\n", drive->name,
@@ -156,6 +151,11 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
156 ide_tf_set_cmd(drive, &cmd, dma); 151 ide_tf_set_cmd(drive, &cmd, dma);
157 cmd.rq = rq; 152 cmd.rq = rq;
158 153
154 if (dma == 0) {
155 ide_init_sg_cmd(&cmd, nsectors);
156 ide_map_sg(drive, &cmd);
157 }
158
159 rc = do_rw_taskfile(drive, &cmd); 159 rc = do_rw_taskfile(drive, &cmd);
160 160
161 if (rc == ide_stopped && dma) { 161 if (rc == ide_stopped && dma) {
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 7bf28a9b6f65..b7eb810c7b8f 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
111 * May also be invoked from trm290.c 111 * May also be invoked from trm290.c
112 */ 112 */
113 113
114int ide_build_dmatable(ide_drive_t *drive, struct request *rq) 114int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
115{ 115{
116 ide_hwif_t *hwif = drive->hwif; 116 ide_hwif_t *hwif = drive->hwif;
117 __le32 *table = (__le32 *)hwif->dmatable_cpu; 117 __le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,7 +120,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
120 struct scatterlist *sg; 120 struct scatterlist *sg;
121 u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290); 121 u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
122 122
123 for_each_sg(hwif->sg_table, sg, hwif->cmd.sg_nents, i) { 123 for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
124 u32 cur_addr, cur_len, xcount, bcount; 124 u32 cur_addr, cur_len, xcount, bcount;
125 125
126 cur_addr = sg_dma_address(sg); 126 cur_addr = sg_dma_address(sg);
@@ -175,6 +175,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
175/** 175/**
176 * ide_dma_setup - begin a DMA phase 176 * ide_dma_setup - begin a DMA phase
177 * @drive: target device 177 * @drive: target device
178 * @cmd: command
178 * 179 *
179 * Build an IDE DMA PRD (IDE speak for scatter gather table) 180 * Build an IDE DMA PRD (IDE speak for scatter gather table)
180 * and then set up the DMA transfer registers for a device 181 * and then set up the DMA transfer registers for a device
@@ -185,17 +186,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
185 * is returned. 186 * is returned.
186 */ 187 */
187 188
188int ide_dma_setup(ide_drive_t *drive) 189int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
189{ 190{
190 ide_hwif_t *hwif = drive->hwif; 191 ide_hwif_t *hwif = drive->hwif;
191 struct request *rq = hwif->rq;
192 unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
193 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 192 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
193 u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
194 u8 dma_stat; 194 u8 dma_stat;
195 195
196 /* fall back to pio! */ 196 /* fall back to pio! */
197 if (!ide_build_dmatable(drive, rq)) { 197 if (ide_build_dmatable(drive, cmd) == 0) {
198 ide_map_sg(drive, rq); 198 ide_map_sg(drive, cmd);
199 return 1; 199 return 1;
200 } 200 }
201 201
@@ -208,9 +208,9 @@ int ide_dma_setup(ide_drive_t *drive)
208 208
209 /* specify r/w */ 209 /* specify r/w */
210 if (mmio) 210 if (mmio)
211 writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 211 writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
212 else 212 else
213 outb(reading, hwif->dma_base + ATA_DMA_CMD); 213 outb(rw, hwif->dma_base + ATA_DMA_CMD);
214 214
215 /* read DMA status for INTR & ERROR flags */ 215 /* read DMA status for INTR & ERROR flags */
216 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif); 216 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 8f5e32e692f0..ad4edab9b0a9 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -120,7 +120,7 @@ int ide_dma_good_drive(ide_drive_t *drive)
120/** 120/**
121 * ide_build_sglist - map IDE scatter gather for DMA I/O 121 * ide_build_sglist - map IDE scatter gather for DMA I/O
122 * @drive: the drive to build the DMA table for 122 * @drive: the drive to build the DMA table for
123 * @rq: the request holding the sg list 123 * @cmd: command
124 * 124 *
125 * Perform the DMA mapping magic necessary to access the source or 125 * Perform the DMA mapping magic necessary to access the source or
126 * target buffers of a request via DMA. The lower layers of the 126 * target buffers of a request via DMA. The lower layers of the
@@ -128,23 +128,22 @@ int ide_dma_good_drive(ide_drive_t *drive)
128 * operate in a portable fashion. 128 * operate in a portable fashion.
129 */ 129 */
130 130
131int ide_build_sglist(ide_drive_t *drive, struct request *rq) 131int ide_build_sglist(ide_drive_t *drive, struct ide_cmd *cmd)
132{ 132{
133 ide_hwif_t *hwif = drive->hwif; 133 ide_hwif_t *hwif = drive->hwif;
134 struct scatterlist *sg = hwif->sg_table; 134 struct scatterlist *sg = hwif->sg_table;
135 struct ide_cmd *cmd = &hwif->cmd;
136 int i; 135 int i;
137 136
138 ide_map_sg(drive, rq); 137 ide_map_sg(drive, cmd);
139 138
140 if (rq_data_dir(rq) == READ) 139 if (cmd->tf_flags & IDE_TFLAG_WRITE)
141 cmd->sg_dma_direction = DMA_FROM_DEVICE;
142 else
143 cmd->sg_dma_direction = DMA_TO_DEVICE; 140 cmd->sg_dma_direction = DMA_TO_DEVICE;
141 else
142 cmd->sg_dma_direction = DMA_FROM_DEVICE;
144 143
145 i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction); 144 i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
146 if (i == 0) 145 if (i == 0)
147 ide_map_sg(drive, rq); 146 ide_map_sg(drive, cmd);
148 else { 147 else {
149 cmd->orig_sg_nents = cmd->sg_nents; 148 cmd->orig_sg_nents = cmd->sg_nents;
150 cmd->sg_nents = i; 149 cmd->sg_nents = i;
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 8c518c6a6477..ee3e77a7a727 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -285,9 +285,13 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
285 goto out_end; 285 goto out_end;
286 } 286 }
287 287
288 if (rq_data_dir(rq))
289 cmd->tf_flags |= IDE_TFLAG_WRITE;
290 cmd->rq = rq;
291
288 if (blk_fs_request(rq) || pc->req_xfer) { 292 if (blk_fs_request(rq) || pc->req_xfer) {
289 ide_init_sg_cmd(cmd, rq->nr_sectors); 293 ide_init_sg_cmd(cmd, rq->nr_sectors);
290 ide_map_sg(drive, rq); 294 ide_map_sg(drive, cmd);
291 } 295 }
292 296
293 pc->sg = hwif->sg_table; 297 pc->sg = hwif->sg_table;
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index f59c709052d2..47404f5526f1 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -228,11 +228,11 @@ static ide_startstop_t do_special (ide_drive_t *drive)
228 return ide_stopped; 228 return ide_stopped;
229} 229}
230 230
231void ide_map_sg(ide_drive_t *drive, struct request *rq) 231void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
232{ 232{
233 ide_hwif_t *hwif = drive->hwif; 233 ide_hwif_t *hwif = drive->hwif;
234 struct ide_cmd *cmd = &hwif->cmd;
235 struct scatterlist *sg = hwif->sg_table; 234 struct scatterlist *sg = hwif->sg_table;
235 struct request *rq = cmd->rq;
236 236
237 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 237 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
238 sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE); 238 sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
@@ -273,7 +273,7 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
273 if (cmd) { 273 if (cmd) {
274 if (cmd->protocol == ATA_PROT_PIO) { 274 if (cmd->protocol == ATA_PROT_PIO) {
275 ide_init_sg_cmd(cmd, rq->nr_sectors); 275 ide_init_sg_cmd(cmd, rq->nr_sectors);
276 ide_map_sg(drive, rq); 276 ide_map_sg(drive, cmd);
277 } 277 }
278 278
279 return do_rw_taskfile(drive, cmd); 279 return do_rw_taskfile(drive, cmd);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index db6d7821e45b..3b23bd11945e 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -102,8 +102,8 @@ ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
102 return ide_started; 102 return ide_started;
103 default: 103 default:
104 if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 || 104 if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
105 ide_build_sglist(drive, hwif->rq) == 0 || 105 ide_build_sglist(drive, cmd) == 0 ||
106 dma_ops->dma_setup(drive)) 106 dma_ops->dma_setup(drive, cmd))
107 return ide_stopped; 107 return ide_stopped;
108 dma_ops->dma_exec_cmd(drive, tf->command); 108 dma_ops->dma_exec_cmd(drive, tf->command);
109 dma_ops->dma_start(drive); 109 dma_ops->dma_start(drive);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index d93c80016326..cf6d9a9c8a27 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -216,11 +216,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
216 return (dma_stat & 7) != 4; 216 return (dma_stat & 7) != 4;
217} 217}
218 218
219static int ns87415_dma_setup(ide_drive_t *drive) 219static int ns87415_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
220{ 220{
221 /* select DMA xfer */ 221 /* select DMA xfer */
222 ns87415_prepare_drive(drive, 1); 222 ns87415_prepare_drive(drive, 1);
223 if (!ide_dma_setup(drive)) 223 if (ide_dma_setup(drive, cmd) == 0)
224 return 0; 224 return 0;
225 /* DMA failed: select PIO xfer */ 225 /* DMA failed: select PIO xfer */
226 ns87415_prepare_drive(drive, 0); 226 ns87415_prepare_drive(drive, 0);
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index f5b85f4c1b65..337d2d5b3028 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -404,7 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
404#define IDE_WAKEUP_DELAY (1*HZ) 404#define IDE_WAKEUP_DELAY (1*HZ)
405 405
406static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *); 406static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
407static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
408static void pmac_ide_selectproc(ide_drive_t *drive); 407static void pmac_ide_selectproc(ide_drive_t *drive);
409static void pmac_ide_kauai_selectproc(ide_drive_t *drive); 408static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
410 409
@@ -1422,8 +1421,7 @@ out:
1422 * pmac_ide_build_dmatable builds the DBDMA command list 1421 * pmac_ide_build_dmatable builds the DBDMA command list
1423 * for a transfer and sets the DBDMA channel to point to it. 1422 * for a transfer and sets the DBDMA channel to point to it.
1424 */ 1423 */
1425static int 1424static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
1426pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
1427{ 1425{
1428 ide_hwif_t *hwif = drive->hwif; 1426 ide_hwif_t *hwif = drive->hwif;
1429 pmac_ide_hwif_t *pmif = 1427 pmac_ide_hwif_t *pmif =
@@ -1431,8 +1429,8 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
1431 struct dbdma_cmd *table; 1429 struct dbdma_cmd *table;
1432 volatile struct dbdma_regs __iomem *dma = pmif->dma_regs; 1430 volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
1433 struct scatterlist *sg; 1431 struct scatterlist *sg;
1434 int wr = (rq_data_dir(rq) == WRITE); 1432 int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1435 int i = hwif->cmd.sg_nents, count = 0; 1433 int i = cmd->sg_nents, count = 0;
1436 1434
1437 /* DMA table is already aligned */ 1435 /* DMA table is already aligned */
1438 table = (struct dbdma_cmd *) pmif->dma_table_cpu; 1436 table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1504,23 +1502,22 @@ use_pio_instead:
1504 * Prepare a DMA transfer. We build the DMA table, adjust the timings for 1502 * Prepare a DMA transfer. We build the DMA table, adjust the timings for
1505 * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion 1503 * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
1506 */ 1504 */
1507static int 1505static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
1508pmac_ide_dma_setup(ide_drive_t *drive)
1509{ 1506{
1510 ide_hwif_t *hwif = drive->hwif; 1507 ide_hwif_t *hwif = drive->hwif;
1511 pmac_ide_hwif_t *pmif = 1508 pmac_ide_hwif_t *pmif =
1512 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent); 1509 (pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
1513 struct request *rq = hwif->rq;
1514 u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4); 1510 u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
1511 u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1515 1512
1516 if (!pmac_ide_build_dmatable(drive, rq)) { 1513 if (pmac_ide_build_dmatable(drive, cmd) == 0) {
1517 ide_map_sg(drive, rq); 1514 ide_map_sg(drive, cmd);
1518 return 1; 1515 return 1;
1519 } 1516 }
1520 1517
1521 /* Apple adds 60ns to wrDataSetup on reads */ 1518 /* Apple adds 60ns to wrDataSetup on reads */
1522 if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) { 1519 if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
1523 writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0), 1520 writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
1524 PMAC_IDE_REG(IDE_TIMING_CONFIG)); 1521 PMAC_IDE_REG(IDE_TIMING_CONFIG));
1525 (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG)); 1522 (void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
1526 } 1523 }
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index ada866744622..1f2805ce9889 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -303,8 +303,9 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
303} 303}
304 304
305/** 305/**
306 * scc_ide_dma_setup - begin a DMA phase 306 * scc_dma_setup - begin a DMA phase
307 * @drive: target device 307 * @drive: target device
308 * @cmd: command
308 * 309 *
309 * Build an IDE DMA PRD (IDE speak for scatter gather table) 310 * Build an IDE DMA PRD (IDE speak for scatter gather table)
310 * and then set up the DMA transfer registers. 311 * and then set up the DMA transfer registers.
@@ -313,21 +314,15 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
313 * is returned. 314 * is returned.
314 */ 315 */
315 316
316static int scc_dma_setup(ide_drive_t *drive) 317static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
317{ 318{
318 ide_hwif_t *hwif = drive->hwif; 319 ide_hwif_t *hwif = drive->hwif;
319 struct request *rq = hwif->rq; 320 u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
320 unsigned int reading;
321 u8 dma_stat; 321 u8 dma_stat;
322 322
323 if (rq_data_dir(rq))
324 reading = 0;
325 else
326 reading = 1 << 3;
327
328 /* fall back to pio! */ 323 /* fall back to pio! */
329 if (!ide_build_dmatable(drive, rq)) { 324 if (ide_build_dmatable(drive, cmd) == 0) {
330 ide_map_sg(drive, rq); 325 ide_map_sg(drive, cmd);
331 return 1; 326 return 1;
332 } 327 }
333 328
@@ -335,7 +330,7 @@ static int scc_dma_setup(ide_drive_t *drive)
335 out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma); 330 out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
336 331
337 /* specify r/w */ 332 /* specify r/w */
338 out_be32((void __iomem *)hwif->dma_base, reading); 333 out_be32((void __iomem *)hwif->dma_base, rw);
339 334
340 /* read DMA status for INTR & ERROR flags */ 335 /* read DMA status for INTR & ERROR flags */
341 dma_stat = scc_dma_sff_read_status(hwif); 336 dma_stat = scc_dma_sff_read_status(hwif);
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index b0769e96d32f..b12de8346c73 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -424,12 +424,11 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
424/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ 424/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
425/* --------------------------------------------------------------------- */ 425/* --------------------------------------------------------------------- */
426/* Creates the scatter gather list, DMA Table */ 426/* Creates the scatter gather list, DMA Table */
427static unsigned int 427static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
428sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
429{ 428{
430 ide_hwif_t *hwif = drive->hwif; 429 ide_hwif_t *hwif = drive->hwif;
431 unsigned int *table = hwif->dmatable_cpu; 430 unsigned int *table = hwif->dmatable_cpu;
432 unsigned int count = 0, i = hwif->cmd.sg_nents; 431 unsigned int count = 0, i = cmd->sg_nents;
433 struct scatterlist *sg = hwif->sg_table; 432 struct scatterlist *sg = hwif->sg_table;
434 433
435 while (i && sg_dma_len(sg)) { 434 while (i && sg_dma_len(sg)) {
@@ -484,24 +483,18 @@ use_pio_instead:
484 return 0; /* revert to PIO for this request */ 483 return 0; /* revert to PIO for this request */
485} 484}
486 485
487static int sgiioc4_dma_setup(ide_drive_t *drive) 486static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
488{ 487{
489 struct request *rq = drive->hwif->rq;
490 unsigned int count = 0;
491 int ddir; 488 int ddir;
489 u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
492 490
493 if (rq_data_dir(rq)) 491 if (sgiioc4_build_dmatable(drive, cmd) == 0) {
494 ddir = PCI_DMA_TODEVICE;
495 else
496 ddir = PCI_DMA_FROMDEVICE;
497
498 if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
499 /* try PIO instead of DMA */ 492 /* try PIO instead of DMA */
500 ide_map_sg(drive, rq); 493 ide_map_sg(drive, cmd);
501 return 1; 494 return 1;
502 } 495 }
503 496
504 if (rq_data_dir(rq)) 497 if (write)
505 /* Writes TO the IOC4 FROM Main Memory */ 498 /* Writes TO the IOC4 FROM Main Memory */
506 ddir = IOC4_DMA_READ; 499 ddir = IOC4_DMA_READ;
507 else 500 else
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index e8279f32f9a2..746858a7338d 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -181,13 +181,12 @@ static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
181 ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL); 181 ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
182} 182}
183 183
184static int trm290_dma_setup(ide_drive_t *drive) 184static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
185{ 185{
186 ide_hwif_t *hwif = drive->hwif; 186 ide_hwif_t *hwif = drive->hwif;
187 struct request *rq = hwif->rq;
188 unsigned int count, rw; 187 unsigned int count, rw;
189 188
190 if (rq_data_dir(rq)) { 189 if (cmd->tf_flags & IDE_TFLAG_WRITE) {
191#ifdef TRM290_NO_DMA_WRITES 190#ifdef TRM290_NO_DMA_WRITES
192 /* always use PIO for writes */ 191 /* always use PIO for writes */
193 trm290_prepare_drive(drive, 0); /* select PIO xfer */ 192 trm290_prepare_drive(drive, 0); /* select PIO xfer */
@@ -197,8 +196,9 @@ static int trm290_dma_setup(ide_drive_t *drive)
197 } else 196 } else
198 rw = 2; 197 rw = 2;
199 198
200 if (!(count = ide_build_dmatable(drive, rq))) { 199 count = ide_build_dmatable(drive, cmd);
201 ide_map_sg(drive, rq); 200 if (count == 0) {
201 ide_map_sg(drive, cmd);
202 /* try PIO instead of DMA */ 202 /* try PIO instead of DMA */
203 trm290_prepare_drive(drive, 0); /* select PIO xfer */ 203 trm290_prepare_drive(drive, 0); /* select PIO xfer */
204 return 1; 204 return 1;
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 8d155ec8cca9..39e3316ab63f 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -232,7 +232,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base)
232 232
233#ifdef __BIG_ENDIAN 233#ifdef __BIG_ENDIAN
234/* custom ide_build_dmatable to handle swapped layout */ 234/* custom ide_build_dmatable to handle swapped layout */
235static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq) 235static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
236{ 236{
237 ide_hwif_t *hwif = drive->hwif; 237 ide_hwif_t *hwif = drive->hwif;
238 u32 *table = (u32 *)hwif->dmatable_cpu; 238 u32 *table = (u32 *)hwif->dmatable_cpu;
@@ -240,7 +240,7 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
240 int i; 240 int i;
241 struct scatterlist *sg; 241 struct scatterlist *sg;
242 242
243 for_each_sg(hwif->sg_table, sg, hwif->cmd.sg_nents, i) { 243 for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
244 u32 cur_addr, cur_len, bcount; 244 u32 cur_addr, cur_len, bcount;
245 245
246 cur_addr = sg_dma_address(sg); 246 cur_addr = sg_dma_address(sg);
@@ -287,23 +287,15 @@ use_pio_instead:
287#define tx4939ide_build_dmatable ide_build_dmatable 287#define tx4939ide_build_dmatable ide_build_dmatable
288#endif 288#endif
289 289
290static int tx4939ide_dma_setup(ide_drive_t *drive) 290static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
291{ 291{
292 ide_hwif_t *hwif = drive->hwif; 292 ide_hwif_t *hwif = drive->hwif;
293 void __iomem *base = TX4939IDE_BASE(hwif); 293 void __iomem *base = TX4939IDE_BASE(hwif);
294 struct request *rq = hwif->rq; 294 u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
295 u8 reading;
296 int nent;
297
298 if (rq_data_dir(rq))
299 reading = 0;
300 else
301 reading = ATA_DMA_WR;
302 295
303 /* fall back to PIO! */ 296 /* fall back to PIO! */
304 nent = tx4939ide_build_dmatable(drive, rq); 297 if (tx4939ide_build_dmatable(drive, cmd) == 0) {
305 if (!nent) { 298 ide_map_sg(drive, cmd);
306 ide_map_sg(drive, rq);
307 return 1; 299 return 1;
308 } 300 }
309 301
@@ -311,7 +303,7 @@ static int tx4939ide_dma_setup(ide_drive_t *drive)
311 tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr); 303 tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
312 304
313 /* specify r/w */ 305 /* specify r/w */
314 tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd); 306 tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd);
315 307
316 /* clear INTR & ERROR flags */ 308 /* clear INTR & ERROR flags */
317 tx4939ide_clear_dma_status(base); 309 tx4939ide_clear_dma_status(base);
@@ -320,7 +312,9 @@ static int tx4939ide_dma_setup(ide_drive_t *drive)
320 312
321 tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ? 313 tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
322 TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1); 314 TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
323 tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt); 315
316 tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
317
324 return 0; 318 return 0;
325} 319}
326 320
diff --git a/include/linux/ide.h b/include/linux/ide.h
index b6142171baf0..b30e79c6ff57 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -714,7 +714,7 @@ struct ide_port_ops {
714 714
715struct ide_dma_ops { 715struct ide_dma_ops {
716 void (*dma_host_set)(struct ide_drive_s *, int); 716 void (*dma_host_set)(struct ide_drive_s *, int);
717 int (*dma_setup)(struct ide_drive_s *); 717 int (*dma_setup)(struct ide_drive_s *, struct ide_cmd *);
718 void (*dma_exec_cmd)(struct ide_drive_s *, u8); 718 void (*dma_exec_cmd)(struct ide_drive_s *, u8);
719 void (*dma_start)(struct ide_drive_s *); 719 void (*dma_start)(struct ide_drive_s *);
720 int (*dma_end)(struct ide_drive_s *); 720 int (*dma_end)(struct ide_drive_s *);
@@ -1412,7 +1412,7 @@ int ide_pci_resume(struct pci_dev *);
1412#define ide_pci_resume NULL 1412#define ide_pci_resume NULL
1413#endif 1413#endif
1414 1414
1415void ide_map_sg(ide_drive_t *, struct request *); 1415void ide_map_sg(ide_drive_t *, struct ide_cmd *);
1416void ide_init_sg_cmd(struct ide_cmd *, int); 1416void ide_init_sg_cmd(struct ide_cmd *, int);
1417 1417
1418#define BAD_DMA_DRIVE 0 1418#define BAD_DMA_DRIVE 0
@@ -1447,14 +1447,14 @@ ide_startstop_t ide_dma_intr(ide_drive_t *);
1447int ide_allocate_dma_engine(ide_hwif_t *); 1447int ide_allocate_dma_engine(ide_hwif_t *);
1448void ide_release_dma_engine(ide_hwif_t *); 1448void ide_release_dma_engine(ide_hwif_t *);
1449 1449
1450int ide_build_sglist(ide_drive_t *, struct request *); 1450int ide_build_sglist(ide_drive_t *, struct ide_cmd *);
1451void ide_destroy_dmatable(ide_drive_t *); 1451void ide_destroy_dmatable(ide_drive_t *);
1452 1452
1453#ifdef CONFIG_BLK_DEV_IDEDMA_SFF 1453#ifdef CONFIG_BLK_DEV_IDEDMA_SFF
1454int config_drive_for_dma(ide_drive_t *); 1454int config_drive_for_dma(ide_drive_t *);
1455extern int ide_build_dmatable(ide_drive_t *, struct request *); 1455int ide_build_dmatable(ide_drive_t *, struct ide_cmd *);
1456void ide_dma_host_set(ide_drive_t *, int); 1456void ide_dma_host_set(ide_drive_t *, int);
1457extern int ide_dma_setup(ide_drive_t *); 1457int ide_dma_setup(ide_drive_t *, struct ide_cmd *);
1458void ide_dma_exec_cmd(ide_drive_t *, u8); 1458void ide_dma_exec_cmd(ide_drive_t *, u8);
1459extern void ide_dma_start(ide_drive_t *); 1459extern void ide_dma_start(ide_drive_t *);
1460int ide_dma_end(ide_drive_t *); 1460int ide_dma_end(ide_drive_t *);
@@ -1482,7 +1482,7 @@ static inline void ide_check_dma_crc(ide_drive_t *drive) { ; }
1482static inline ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { return ide_stopped; } 1482static inline ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) { return ide_stopped; }
1483static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } 1483static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; }
1484static inline int ide_build_sglist(ide_drive_t *drive, 1484static inline int ide_build_sglist(ide_drive_t *drive,
1485 struct request *rq) { return 0; } 1485 struct ide_cmd *cmd) { return 0; }
1486#endif /* CONFIG_BLK_DEV_IDEDMA */ 1486#endif /* CONFIG_BLK_DEV_IDEDMA */
1487 1487
1488#ifdef CONFIG_BLK_DEV_IDEACPI 1488#ifdef CONFIG_BLK_DEV_IDEACPI