aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/pci/sgiioc4.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/pci/sgiioc4.c')
-rw-r--r--drivers/ide/pci/sgiioc4.c125
1 files changed, 56 insertions, 69 deletions
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index b0bf01809279..fd09b295a69d 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -110,24 +110,24 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
110static void 110static void
111sgiioc4_maskproc(ide_drive_t * drive, int mask) 111sgiioc4_maskproc(ide_drive_t * drive, int mask)
112{ 112{
113 ide_hwif_t *hwif = HWIF(drive); 113 writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
114 hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), 114 (void __iomem *)IDE_CONTROL_REG);
115 IDE_CONTROL_REG);
116} 115}
117 116
118 117
119static int 118static int
120sgiioc4_checkirq(ide_hwif_t * hwif) 119sgiioc4_checkirq(ide_hwif_t * hwif)
121{ 120{
122 u8 intr_reg = 121 unsigned long intr_addr =
123 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4); 122 hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
124 123
125 if (intr_reg & 0x03) 124 if ((u8)readl((void __iomem *)intr_addr) & 0x03)
126 return 1; 125 return 1;
127 126
128 return 0; 127 return 0;
129} 128}
130 129
130static u8 sgiioc4_INB(unsigned long);
131 131
132static int 132static int
133sgiioc4_clearirq(ide_drive_t * drive) 133sgiioc4_clearirq(ide_drive_t * drive)
@@ -138,21 +138,21 @@ sgiioc4_clearirq(ide_drive_t * drive)
138 hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2); 138 hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
139 139
140 /* Code to check for PCI error conditions */ 140 /* Code to check for PCI error conditions */
141 intr_reg = hwif->INL(other_ir); 141 intr_reg = readl((void __iomem *)other_ir);
142 if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */ 142 if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
143 /* 143 /*
144 * Using hwif->INB to read the IDE_STATUS_REG has a side effect 144 * Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect
145 * of clearing the interrupt. The first read should clear it 145 * of clearing the interrupt. The first read should clear it
146 * if it is set. The second read should return a "clear" status 146 * if it is set. The second read should return a "clear" status
147 * if it got cleared. If not, then spin for a bit trying to 147 * if it got cleared. If not, then spin for a bit trying to
148 * clear it. 148 * clear it.
149 */ 149 */
150 u8 stat = hwif->INB(IDE_STATUS_REG); 150 u8 stat = sgiioc4_INB(IDE_STATUS_REG);
151 int count = 0; 151 int count = 0;
152 stat = hwif->INB(IDE_STATUS_REG); 152 stat = sgiioc4_INB(IDE_STATUS_REG);
153 while ((stat & 0x80) && (count++ < 100)) { 153 while ((stat & 0x80) && (count++ < 100)) {
154 udelay(1); 154 udelay(1);
155 stat = hwif->INB(IDE_STATUS_REG); 155 stat = sgiioc4_INB(IDE_STATUS_REG);
156 } 156 }
157 157
158 if (intr_reg & 0x02) { 158 if (intr_reg & 0x02) {
@@ -161,9 +161,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
161 pci_stat_cmd_reg; 161 pci_stat_cmd_reg;
162 162
163 pci_err_addr_low = 163 pci_err_addr_low =
164 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]); 164 readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
165 pci_err_addr_high = 165 pci_err_addr_high =
166 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4); 166 readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
167 pci_read_config_dword(hwif->pci_dev, PCI_COMMAND, 167 pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
168 &pci_stat_cmd_reg); 168 &pci_stat_cmd_reg);
169 printk(KERN_ERR 169 printk(KERN_ERR
@@ -180,9 +180,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
180 } 180 }
181 181
182 /* Clear the Interrupt, Error bits on the IOC4 */ 182 /* Clear the Interrupt, Error bits on the IOC4 */
183 hwif->OUTL(0x03, other_ir); 183 writel(0x03, (void __iomem *)other_ir);
184 184
185 intr_reg = hwif->INL(other_ir); 185 intr_reg = readl((void __iomem *)other_ir);
186 } 186 }
187 187
188 return intr_reg & 3; 188 return intr_reg & 3;
@@ -191,23 +191,25 @@ sgiioc4_clearirq(ide_drive_t * drive)
191static void sgiioc4_ide_dma_start(ide_drive_t * drive) 191static void sgiioc4_ide_dma_start(ide_drive_t * drive)
192{ 192{
193 ide_hwif_t *hwif = HWIF(drive); 193 ide_hwif_t *hwif = HWIF(drive);
194 unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4); 194 unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
195 unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
195 unsigned int temp_reg = reg | IOC4_S_DMA_START; 196 unsigned int temp_reg = reg | IOC4_S_DMA_START;
196 197
197 hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4); 198 writel(temp_reg, (void __iomem *)ioc4_dma_addr);
198} 199}
199 200
200static u32 201static u32
201sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) 202sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
202{ 203{
204 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
203 u32 ioc4_dma; 205 u32 ioc4_dma;
204 int count; 206 int count;
205 207
206 count = 0; 208 count = 0;
207 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 209 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
208 while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) { 210 while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
209 udelay(1); 211 udelay(1);
210 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 212 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
211 } 213 }
212 return ioc4_dma; 214 return ioc4_dma;
213} 215}
@@ -218,11 +220,11 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
218{ 220{
219 u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; 221 u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
220 ide_hwif_t *hwif = HWIF(drive); 222 ide_hwif_t *hwif = HWIF(drive);
221 u64 dma_base = hwif->dma_base; 223 unsigned long dma_base = hwif->dma_base;
222 int dma_stat = 0; 224 int dma_stat = 0;
223 unsigned long *ending_dma = ide_get_hwifdata(hwif); 225 unsigned long *ending_dma = ide_get_hwifdata(hwif);
224 226
225 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 227 writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
226 228
227 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 229 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
228 230
@@ -254,8 +256,8 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
254 dma_stat = 1; 256 dma_stat = 1;
255 } 257 }
256 258
257 bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4); 259 bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
258 bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4); 260 bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
259 261
260 if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) { 262 if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
261 if (bc_dev > bc_mem + 8) { 263 if (bc_dev > bc_mem + 8) {
@@ -273,34 +275,29 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
273} 275}
274 276
275static int 277static int
276sgiioc4_ide_dma_check(ide_drive_t * drive) 278sgiioc4_ide_dma_on(ide_drive_t * drive)
277{ 279{
278 if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { 280 drive->using_dma = 1;
279 printk(KERN_INFO
280 "Couldnot set %s in Multimode-2 DMA mode | "
281 "Drive %s using PIO instead\n",
282 drive->name, drive->name);
283 drive->using_dma = 0;
284 } else
285 drive->using_dma = 1;
286 281
287 return 0; 282 return 0;
288} 283}
289 284
290static int 285static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
291sgiioc4_ide_dma_on(ide_drive_t * drive)
292{ 286{
293 drive->using_dma = 1; 287 drive->using_dma = 0;
294 288
295 return HWIF(drive)->ide_dma_host_on(drive); 289 drive->hwif->dma_host_off(drive);
296} 290}
297 291
298static int 292static int sgiioc4_ide_dma_check(ide_drive_t *drive)
299sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
300{ 293{
301 drive->using_dma = 0; 294 /* FIXME: check for available DMA modes */
302 295 if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
303 return HWIF(drive)->ide_dma_host_off(drive); 296 printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
297 "using PIO instead\n", drive->name);
298 return -1;
299 } else
300 return 0;
304} 301}
305 302
306/* returns 1 if dma irq issued, 0 otherwise */ 303/* returns 1 if dma irq issued, 0 otherwise */
@@ -310,21 +307,13 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
310 return sgiioc4_checkirq(HWIF(drive)); 307 return sgiioc4_checkirq(HWIF(drive));
311} 308}
312 309
313static int 310static void sgiioc4_dma_host_on(ide_drive_t * drive)
314sgiioc4_ide_dma_host_on(ide_drive_t * drive)
315{ 311{
316 if (drive->using_dma)
317 return 0;
318
319 return 1;
320} 312}
321 313
322static int 314static void sgiioc4_dma_host_off(ide_drive_t * drive)
323sgiioc4_ide_dma_host_off(ide_drive_t * drive)
324{ 315{
325 sgiioc4_clearirq(drive); 316 sgiioc4_clearirq(drive);
326
327 return 0;
328} 317}
329 318
330static int 319static int
@@ -436,16 +425,17 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
436{ 425{
437 u32 ioc4_dma; 426 u32 ioc4_dma;
438 ide_hwif_t *hwif = HWIF(drive); 427 ide_hwif_t *hwif = HWIF(drive);
439 u64 dma_base = hwif->dma_base; 428 unsigned long dma_base = hwif->dma_base;
429 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
440 u32 dma_addr, ending_dma_addr; 430 u32 dma_addr, ending_dma_addr;
441 431
442 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 432 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
443 433
444 if (ioc4_dma & IOC4_S_DMA_ACTIVE) { 434 if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
445 printk(KERN_WARNING 435 printk(KERN_WARNING
446 "%s(%s):Warning!! DMA from previous transfer was still active\n", 436 "%s(%s):Warning!! DMA from previous transfer was still active\n",
447 __FUNCTION__, drive->name); 437 __FUNCTION__, drive->name);
448 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 438 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
449 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 439 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
450 440
451 if (ioc4_dma & IOC4_S_DMA_STOP) 441 if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -454,13 +444,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
454 __FUNCTION__, drive->name); 444 __FUNCTION__, drive->name);
455 } 445 }
456 446
457 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 447 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
458 if (ioc4_dma & IOC4_S_DMA_ERROR) { 448 if (ioc4_dma & IOC4_S_DMA_ERROR) {
459 printk(KERN_WARNING 449 printk(KERN_WARNING
460 "%s(%s) : Warning!! - DMA Error during Previous" 450 "%s(%s) : Warning!! - DMA Error during Previous"
461 " transfer | status 0x%x\n", 451 " transfer | status 0x%x\n",
462 __FUNCTION__, drive->name, ioc4_dma); 452 __FUNCTION__, drive->name, ioc4_dma);
463 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 453 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
464 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 454 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
465 455
466 if (ioc4_dma & IOC4_S_DMA_STOP) 456 if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -471,14 +461,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
471 461
472 /* Address of the Scatter Gather List */ 462 /* Address of the Scatter Gather List */
473 dma_addr = cpu_to_le32(hwif->dmatable_dma); 463 dma_addr = cpu_to_le32(hwif->dmatable_dma);
474 hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); 464 writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
475 465
476 /* Address of the Ending DMA */ 466 /* Address of the Ending DMA */
477 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); 467 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
478 ending_dma_addr = cpu_to_le32(hwif->dma_status); 468 ending_dma_addr = cpu_to_le32(hwif->dma_status);
479 hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); 469 writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
480 470
481 hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4); 471 writel(dma_direction, (void __iomem *)ioc4_dma_addr);
482 drive->waiting_for_dma = 1; 472 drive->waiting_for_dma = 1;
483} 473}
484 474
@@ -590,7 +580,7 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
590static void __devinit 580static void __devinit
591ide_init_sgiioc4(ide_hwif_t * hwif) 581ide_init_sgiioc4(ide_hwif_t * hwif)
592{ 582{
593 hwif->mmio = 2; 583 hwif->mmio = 1;
594 hwif->autodma = 1; 584 hwif->autodma = 1;
595 hwif->atapi_dma = 1; 585 hwif->atapi_dma = 1;
596 hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ 586 hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
@@ -613,10 +603,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
613 hwif->ide_dma_end = &sgiioc4_ide_dma_end; 603 hwif->ide_dma_end = &sgiioc4_ide_dma_end;
614 hwif->ide_dma_check = &sgiioc4_ide_dma_check; 604 hwif->ide_dma_check = &sgiioc4_ide_dma_check;
615 hwif->ide_dma_on = &sgiioc4_ide_dma_on; 605 hwif->ide_dma_on = &sgiioc4_ide_dma_on;
616 hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly; 606 hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
617 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; 607 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
618 hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on; 608 hwif->dma_host_on = &sgiioc4_dma_host_on;
619 hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off; 609 hwif->dma_host_off = &sgiioc4_dma_host_off;
620 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; 610 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
621 hwif->ide_dma_timeout = &__ide_dma_timeout; 611 hwif->ide_dma_timeout = &__ide_dma_timeout;
622 612
@@ -688,7 +678,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
688 default_hwif_mmiops(hwif); 678 default_hwif_mmiops(hwif);
689 679
690 /* Initializing chipset IRQ Registers */ 680 /* Initializing chipset IRQ Registers */
691 hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4); 681 writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
692 682
693 ide_init_sgiioc4(hwif); 683 ide_init_sgiioc4(hwif);
694 684
@@ -729,8 +719,7 @@ out:
729 return ret; 719 return ret;
730} 720}
731 721
732static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { 722static ide_pci_device_t sgiioc4_chipset __devinitdata = {
733 {
734 /* Channel 0 */ 723 /* Channel 0 */
735 .name = "SGIIOC4", 724 .name = "SGIIOC4",
736 .init_hwif = ide_init_sgiioc4, 725 .init_hwif = ide_init_sgiioc4,
@@ -739,7 +728,6 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
739 .autodma = AUTODMA, 728 .autodma = AUTODMA,
740 /* SGI IOC4 doesn't have enablebits. */ 729 /* SGI IOC4 doesn't have enablebits. */
741 .bootable = ON_BOARD, 730 .bootable = ON_BOARD,
742 }
743}; 731};
744 732
745int 733int
@@ -751,8 +739,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
751 if (idd->idd_variant == IOC4_VARIANT_PCI_RT) 739 if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
752 return 0; 740 return 0;
753 741
754 return pci_init_sgiioc4(idd->idd_pdev, 742 return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
755 &sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
756} 743}
757 744
758static struct ioc4_submodule ioc4_ide_submodule = { 745static struct ioc4_submodule ioc4_ide_submodule = {