aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-dma-sff.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-dma-sff.c')
-rw-r--r--drivers/ide/ide-dma-sff.c105
1 files changed, 53 insertions, 52 deletions
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index cac431f0df17..123d393658af 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -50,6 +50,27 @@ int config_drive_for_dma(ide_drive_t *drive)
50 return 0; 50 return 0;
51} 51}
52 52
53u8 ide_dma_sff_read_status(ide_hwif_t *hwif)
54{
55 unsigned long addr = hwif->dma_base + ATA_DMA_STATUS;
56
57 if (hwif->host_flags & IDE_HFLAG_MMIO)
58 return readb((void __iomem *)addr);
59 else
60 return inb(addr);
61}
62EXPORT_SYMBOL_GPL(ide_dma_sff_read_status);
63
64static void ide_dma_sff_write_status(ide_hwif_t *hwif, u8 val)
65{
66 unsigned long addr = hwif->dma_base + ATA_DMA_STATUS;
67
68 if (hwif->host_flags & IDE_HFLAG_MMIO)
69 writeb(val, (void __iomem *)addr);
70 else
71 outb(val, addr);
72}
73
53/** 74/**
54 * ide_dma_host_set - Enable/disable DMA on a host 75 * ide_dma_host_set - Enable/disable DMA on a host
55 * @drive: drive to control 76 * @drive: drive to control
@@ -62,18 +83,14 @@ void ide_dma_host_set(ide_drive_t *drive, int on)
62{ 83{
63 ide_hwif_t *hwif = drive->hwif; 84 ide_hwif_t *hwif = drive->hwif;
64 u8 unit = drive->dn & 1; 85 u8 unit = drive->dn & 1;
65 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 86 u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
66 87
67 if (on) 88 if (on)
68 dma_stat |= (1 << (5 + unit)); 89 dma_stat |= (1 << (5 + unit));
69 else 90 else
70 dma_stat &= ~(1 << (5 + unit)); 91 dma_stat &= ~(1 << (5 + unit));
71 92
72 if (hwif->host_flags & IDE_HFLAG_MMIO) 93 ide_dma_sff_write_status(hwif, dma_stat);
73 writeb(dma_stat,
74 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
75 else
76 outb(dma_stat, hwif->dma_base + ATA_DMA_STATUS);
77} 94}
78EXPORT_SYMBOL_GPL(ide_dma_host_set); 95EXPORT_SYMBOL_GPL(ide_dma_host_set);
79 96
@@ -98,10 +115,10 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
98{ 115{
99 ide_hwif_t *hwif = drive->hwif; 116 ide_hwif_t *hwif = drive->hwif;
100 __le32 *table = (__le32 *)hwif->dmatable_cpu; 117 __le32 *table = (__le32 *)hwif->dmatable_cpu;
101 unsigned int is_trm290 = (hwif->chipset == ide_trm290) ? 1 : 0;
102 unsigned int count = 0; 118 unsigned int count = 0;
103 int i; 119 int i;
104 struct scatterlist *sg; 120 struct scatterlist *sg;
121 u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
105 122
106 hwif->sg_nents = ide_build_sglist(drive, rq); 123 hwif->sg_nents = ide_build_sglist(drive, rq);
107 if (hwif->sg_nents == 0) 124 if (hwif->sg_nents == 0)
@@ -175,16 +192,11 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
175int ide_dma_setup(ide_drive_t *drive) 192int ide_dma_setup(ide_drive_t *drive)
176{ 193{
177 ide_hwif_t *hwif = drive->hwif; 194 ide_hwif_t *hwif = drive->hwif;
178 struct request *rq = hwif->hwgroup->rq; 195 struct request *rq = hwif->rq;
179 unsigned int reading; 196 unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
180 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 197 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
181 u8 dma_stat; 198 u8 dma_stat;
182 199
183 if (rq_data_dir(rq))
184 reading = 0;
185 else
186 reading = 1 << 3;
187
188 /* fall back to pio! */ 200 /* fall back to pio! */
189 if (!ide_build_dmatable(drive, rq)) { 201 if (!ide_build_dmatable(drive, rq)) {
190 ide_map_sg(drive, rq); 202 ide_map_sg(drive, rq);
@@ -192,7 +204,7 @@ int ide_dma_setup(ide_drive_t *drive)
192 } 204 }
193 205
194 /* PRD table */ 206 /* PRD table */
195 if (hwif->host_flags & IDE_HFLAG_MMIO) 207 if (mmio)
196 writel(hwif->dmatable_dma, 208 writel(hwif->dmatable_dma,
197 (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); 209 (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
198 else 210 else
@@ -205,14 +217,10 @@ int ide_dma_setup(ide_drive_t *drive)
205 outb(reading, hwif->dma_base + ATA_DMA_CMD); 217 outb(reading, hwif->dma_base + ATA_DMA_CMD);
206 218
207 /* read DMA status for INTR & ERROR flags */ 219 /* read DMA status for INTR & ERROR flags */
208 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 220 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
209 221
210 /* clear INTR & ERROR flags */ 222 /* clear INTR & ERROR flags */
211 if (mmio) 223 ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
212 writeb(dma_stat | 6,
213 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
214 else
215 outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
216 224
217 drive->waiting_for_dma = 1; 225 drive->waiting_for_dma = 1;
218 return 0; 226 return 0;
@@ -236,7 +244,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
236static int dma_timer_expiry(ide_drive_t *drive) 244static int dma_timer_expiry(ide_drive_t *drive)
237{ 245{
238 ide_hwif_t *hwif = drive->hwif; 246 ide_hwif_t *hwif = drive->hwif;
239 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 247 u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
240 248
241 printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", 249 printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
242 drive->name, __func__, dma_stat); 250 drive->name, __func__, dma_stat);
@@ -244,16 +252,15 @@ static int dma_timer_expiry(ide_drive_t *drive)
244 if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ 252 if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */
245 return WAIT_CMD; 253 return WAIT_CMD;
246 254
247 hwif->hwgroup->expiry = NULL; /* one free ride for now */ 255 hwif->expiry = NULL; /* one free ride for now */
248 256
249 /* 1 dmaing, 2 error, 4 intr */ 257 if (dma_stat & ATA_DMA_ERR) /* ERROR */
250 if (dma_stat & 2) /* ERROR */
251 return -1; 258 return -1;
252 259
253 if (dma_stat & 1) /* DMAing */ 260 if (dma_stat & ATA_DMA_ACTIVE) /* DMAing */
254 return WAIT_CMD; 261 return WAIT_CMD;
255 262
256 if (dma_stat & 4) /* Got an Interrupt */ 263 if (dma_stat & ATA_DMA_INTR) /* Got an Interrupt */
257 return WAIT_CMD; 264 return WAIT_CMD;
258 265
259 return 0; /* Status is unknown -- reset the bus */ 266 return 0; /* Status is unknown -- reset the bus */
@@ -279,12 +286,11 @@ void ide_dma_start(ide_drive_t *drive)
279 */ 286 */
280 if (hwif->host_flags & IDE_HFLAG_MMIO) { 287 if (hwif->host_flags & IDE_HFLAG_MMIO) {
281 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 288 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
282 /* start DMA */ 289 writeb(dma_cmd | ATA_DMA_START,
283 writeb(dma_cmd | 1,
284 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 290 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
285 } else { 291 } else {
286 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); 292 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
287 outb(dma_cmd | 1, hwif->dma_base + ATA_DMA_CMD); 293 outb(dma_cmd | ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
288 } 294 }
289 295
290 wmb(); 296 wmb();
@@ -295,37 +301,35 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
295int ide_dma_end(ide_drive_t *drive) 301int ide_dma_end(ide_drive_t *drive)
296{ 302{
297 ide_hwif_t *hwif = drive->hwif; 303 ide_hwif_t *hwif = drive->hwif;
298 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; 304 u8 dma_stat = 0, dma_cmd = 0, mask;
299 u8 dma_stat = 0, dma_cmd = 0;
300 305
301 drive->waiting_for_dma = 0; 306 drive->waiting_for_dma = 0;
302 307
303 if (mmio) { 308 /* stop DMA */
304 /* get DMA command mode */ 309 if (hwif->host_flags & IDE_HFLAG_MMIO) {
305 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 310 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
306 /* stop DMA */ 311 writeb(dma_cmd & ~ATA_DMA_START,
307 writeb(dma_cmd & ~1,
308 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 312 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
309 } else { 313 } else {
310 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD); 314 dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
311 outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD); 315 outb(dma_cmd & ~ATA_DMA_START, hwif->dma_base + ATA_DMA_CMD);
312 } 316 }
313 317
314 /* get DMA status */ 318 /* get DMA status */
315 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 319 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
316 320
317 if (mmio) 321 /* clear INTR & ERROR bits */
318 /* clear the INTR & ERROR bits */ 322 ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
319 writeb(dma_stat | 6,
320 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
321 else
322 outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
323 323
324 /* purge DMA mappings */ 324 /* purge DMA mappings */
325 ide_destroy_dmatable(drive); 325 ide_destroy_dmatable(drive);
326 /* verify good DMA status */
327 wmb(); 326 wmb();
328 return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; 327
328 /* verify good DMA status */
329 mask = ATA_DMA_ACTIVE | ATA_DMA_ERR | ATA_DMA_INTR;
330 if ((dma_stat & mask) != ATA_DMA_INTR)
331 return 0x10 | dma_stat;
332 return 0;
329} 333}
330EXPORT_SYMBOL_GPL(ide_dma_end); 334EXPORT_SYMBOL_GPL(ide_dma_end);
331 335
@@ -333,13 +337,9 @@ EXPORT_SYMBOL_GPL(ide_dma_end);
333int ide_dma_test_irq(ide_drive_t *drive) 337int ide_dma_test_irq(ide_drive_t *drive)
334{ 338{
335 ide_hwif_t *hwif = drive->hwif; 339 ide_hwif_t *hwif = drive->hwif;
336 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 340 u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
337 341
338 /* return 1 if INTR asserted */ 342 return (dma_stat & ATA_DMA_INTR) ? 1 : 0;
339 if ((dma_stat & 4) == 4)
340 return 1;
341
342 return 0;
343} 343}
344EXPORT_SYMBOL_GPL(ide_dma_test_irq); 344EXPORT_SYMBOL_GPL(ide_dma_test_irq);
345 345
@@ -352,5 +352,6 @@ const struct ide_dma_ops sff_dma_ops = {
352 .dma_test_irq = ide_dma_test_irq, 352 .dma_test_irq = ide_dma_test_irq,
353 .dma_timeout = ide_dma_timeout, 353 .dma_timeout = ide_dma_timeout,
354 .dma_lost_irq = ide_dma_lost_irq, 354 .dma_lost_irq = ide_dma_lost_irq,
355 .dma_sff_read_status = ide_dma_sff_read_status,
355}; 356};
356EXPORT_SYMBOL_GPL(sff_dma_ops); 357EXPORT_SYMBOL_GPL(sff_dma_ops);