diff options
Diffstat (limited to 'drivers/ide/ide-dma-sff.c')
-rw-r--r-- | drivers/ide/ide-dma-sff.c | 63 |
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 | ||
53 | u8 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 | } | ||
62 | EXPORT_SYMBOL_GPL(ide_dma_sff_read_status); | ||
63 | |||
64 | static 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 | } |
78 | EXPORT_SYMBOL_GPL(ide_dma_host_set); | 95 | EXPORT_SYMBOL_GPL(ide_dma_host_set); |
79 | 96 | ||
@@ -175,7 +192,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable); | |||
175 | int ide_dma_setup(ide_drive_t *drive) | 192 | int 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); | |||
232 | static int dma_timer_expiry(ide_drive_t *drive) | 244 | static 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); | |||
289 | int ide_dma_end(ide_drive_t *drive) | 301 | int 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); | |||
331 | int ide_dma_test_irq(ide_drive_t *drive) | 337 | int 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 | }; |
350 | EXPORT_SYMBOL_GPL(sff_dma_ops); | 357 | EXPORT_SYMBOL_GPL(sff_dma_ops); |