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.c63
1 files changed, 35 insertions, 28 deletions
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index f6d2d44d8a9a..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
@@ -175,7 +192,7 @@ 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 = rq_data_dir(rq) ? 0 : ATA_DMA_WR; 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;
@@ -187,7 +204,7 @@ int ide_dma_setup(ide_drive_t *drive)
187 } 204 }
188 205
189 /* PRD table */ 206 /* PRD table */
190 if (hwif->host_flags & IDE_HFLAG_MMIO) 207 if (mmio)
191 writel(hwif->dmatable_dma, 208 writel(hwif->dmatable_dma,
192 (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS)); 209 (void __iomem *)(hwif->dma_base + ATA_DMA_TABLE_OFS));
193 else 210 else
@@ -200,15 +217,10 @@ int ide_dma_setup(ide_drive_t *drive)
200 outb(reading, hwif->dma_base + ATA_DMA_CMD); 217 outb(reading, hwif->dma_base + ATA_DMA_CMD);
201 218
202 /* read DMA status for INTR & ERROR flags */ 219 /* read DMA status for INTR & ERROR flags */
203 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 220 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
204 221
205 /* clear INTR & ERROR flags */ 222 /* clear INTR & ERROR flags */
206 if (mmio) 223 ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
207 writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
208 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
209 else
210 outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
211 hwif->dma_base + ATA_DMA_STATUS);
212 224
213 drive->waiting_for_dma = 1; 225 drive->waiting_for_dma = 1;
214 return 0; 226 return 0;
@@ -232,7 +244,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
232static int dma_timer_expiry(ide_drive_t *drive) 244static int dma_timer_expiry(ide_drive_t *drive)
233{ 245{
234 ide_hwif_t *hwif = drive->hwif; 246 ide_hwif_t *hwif = drive->hwif;
235 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 247 u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
236 248
237 printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n", 249 printk(KERN_WARNING "%s: %s: DMA status (0x%02x)\n",
238 drive->name, __func__, dma_stat); 250 drive->name, __func__, dma_stat);
@@ -240,7 +252,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
240 if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */ 252 if ((dma_stat & 0x18) == 0x18) /* BUSY Stupid Early Timer !! */
241 return WAIT_CMD; 253 return WAIT_CMD;
242 254
243 hwif->hwgroup->expiry = NULL; /* one free ride for now */ 255 hwif->expiry = NULL; /* one free ride for now */
244 256
245 if (dma_stat & ATA_DMA_ERR) /* ERROR */ 257 if (dma_stat & ATA_DMA_ERR) /* ERROR */
246 return -1; 258 return -1;
@@ -289,13 +301,12 @@ EXPORT_SYMBOL_GPL(ide_dma_start);
289int ide_dma_end(ide_drive_t *drive) 301int ide_dma_end(ide_drive_t *drive)
290{ 302{
291 ide_hwif_t *hwif = drive->hwif; 303 ide_hwif_t *hwif = drive->hwif;
292 u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
293 u8 dma_stat = 0, dma_cmd = 0, mask; 304 u8 dma_stat = 0, dma_cmd = 0, mask;
294 305
295 drive->waiting_for_dma = 0; 306 drive->waiting_for_dma = 0;
296 307
297 /* stop DMA */ 308 /* stop DMA */
298 if (mmio) { 309 if (hwif->host_flags & IDE_HFLAG_MMIO) {
299 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 310 dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
300 writeb(dma_cmd & ~ATA_DMA_START, 311 writeb(dma_cmd & ~ATA_DMA_START,
301 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD)); 312 (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -305,15 +316,10 @@ int ide_dma_end(ide_drive_t *drive)
305 } 316 }
306 317
307 /* get DMA status */ 318 /* get DMA status */
308 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 319 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
309 320
310 if (mmio) 321 /* clear INTR & ERROR bits */
311 /* clear the INTR & ERROR bits */ 322 ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
312 writeb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
313 (void __iomem *)(hwif->dma_base + ATA_DMA_STATUS));
314 else
315 outb(dma_stat | ATA_DMA_ERR | ATA_DMA_INTR,
316 hwif->dma_base + ATA_DMA_STATUS);
317 323
318 /* purge DMA mappings */ 324 /* purge DMA mappings */
319 ide_destroy_dmatable(drive); 325 ide_destroy_dmatable(drive);
@@ -331,7 +337,7 @@ EXPORT_SYMBOL_GPL(ide_dma_end);
331int ide_dma_test_irq(ide_drive_t *drive) 337int ide_dma_test_irq(ide_drive_t *drive)
332{ 338{
333 ide_hwif_t *hwif = drive->hwif; 339 ide_hwif_t *hwif = drive->hwif;
334 u8 dma_stat = hwif->tp_ops->read_sff_dma_status(hwif); 340 u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
335 341
336 return (dma_stat & ATA_DMA_INTR) ? 1 : 0; 342 return (dma_stat & ATA_DMA_INTR) ? 1 : 0;
337} 343}
@@ -346,5 +352,6 @@ const struct ide_dma_ops sff_dma_ops = {
346 .dma_test_irq = ide_dma_test_irq, 352 .dma_test_irq = ide_dma_test_irq,
347 .dma_timeout = ide_dma_timeout, 353 .dma_timeout = ide_dma_timeout,
348 .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,
349}; 356};
350EXPORT_SYMBOL_GPL(sff_dma_ops); 357EXPORT_SYMBOL_GPL(sff_dma_ops);