[PATCH] sgiioc4: fixup use of mmio ops

Fix some bugs in the patch that converted the IOC4 driver from port IO ops to
memio ops.

http://marc.theaimsgroup.com/?l=linux-ide&m=114895892231438&w=2

Problems fixed are:
- Call to default_hwif_mmiops() was not being done until _after_
first IO operation, resulting in the first IO operation being
done as a port IO op, instead of memio.
- request_region() calls needed to be request_mem_region()
- Incomplete error case handling.
- Non-usage of ioremap() and __iomem.

Signed-off-by: John Keller <jpk@sgi.com>
Signed-off-by: Jeremy Higdon <jeremy@sgi.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Bartlomiej Zolnierkiewicz <B.Zolnierkiewicz@elka.pw.edu.pl>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by John Keller and committed by Linus Torvalds 1678df37 7931e2a9

+42 -18
+42 -18
drivers/ide/pci/sgiioc4.c
··· 367 static void __devinit 368 ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) 369 { 370 int num_ports = sizeof (ioc4_dma_regs_t); 371 372 printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, 373 dma_base, dma_base + num_ports - 1); 374 375 - if (!request_region(dma_base, num_ports, hwif->name)) { 376 printk(KERN_ERR 377 "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " 378 "ALREADY in use\n", ··· 382 goto dma_alloc_failure; 383 } 384 385 - hwif->dma_base = dma_base; 386 hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, 387 IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, 388 &hwif->dmatable_dma); 389 390 if (!hwif->dmatable_cpu) 391 - goto dma_alloc_failure; 392 393 hwif->sg_max_nents = IOC4_PRD_ENTRIES; 394 ··· 419 __FUNCTION__, hwif->name); 420 printk(KERN_INFO 421 "Changing from DMA to PIO mode for Drive %s\n", hwif->name); 422 423 dma_alloc_failure: 424 /* Disable DMA because we couldnot allocate any DMA maps */ ··· 622 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; 623 hwif->ide_dma_timeout = &__ide_dma_timeout; 624 625 - /* 626 - * The IOC4 uses MMIO rather than Port IO. 627 - * It also needs special workarounds for INB. 628 - */ 629 - default_hwif_mmiops(hwif); 630 hwif->INB = &sgiioc4_INB; 631 } 632 633 static int __devinit 634 sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) 635 { 636 - unsigned long base, ctl, dma_base, irqport; 637 ide_hwif_t *hwif; 638 int h; 639 ··· 648 } 649 650 /* Get the CmdBlk and CtrlBlk Base Registers */ 651 - base = pci_resource_start(dev, 0) + IOC4_CMD_OFFSET; 652 - ctl = pci_resource_start(dev, 0) + IOC4_CTRL_OFFSET; 653 - irqport = pci_resource_start(dev, 0) + IOC4_INTR_OFFSET; 654 dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; 655 656 - if (!request_region(base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) { 657 printk(KERN_ERR 658 - "%s : %s -- ERROR, Port Addresses " 659 "0x%p to 0x%p ALREADY in use\n", 660 - __FUNCTION__, hwif->name, (void *) base, 661 - (void *) base + IOC4_CMD_CTL_BLK_SIZE); 662 return -ENOMEM; 663 } 664 665 - if (hwif->io_ports[IDE_DATA_OFFSET] != base) { 666 /* Initialize the IO registers */ 667 - sgiioc4_init_hwif_ports(&hwif->hw, base, ctl, irqport); 668 memcpy(hwif->io_ports, hwif->hw.io_ports, 669 sizeof (hwif->io_ports)); 670 hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; ··· 685 hwif->channel = 0; /* Single Channel chip */ 686 hwif->cds = (struct ide_pci_device_s *) d; 687 hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ 688 689 /* Initializing chipset IRQ Registers */ 690 hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);
··· 367 static void __devinit 368 ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base) 369 { 370 + void __iomem *virt_dma_base; 371 int num_ports = sizeof (ioc4_dma_regs_t); 372 373 printk(KERN_INFO "%s: BM-DMA at 0x%04lx-0x%04lx\n", hwif->name, 374 dma_base, dma_base + num_ports - 1); 375 376 + if (!request_mem_region(dma_base, num_ports, hwif->name)) { 377 printk(KERN_ERR 378 "%s(%s) -- ERROR, Addresses 0x%p to 0x%p " 379 "ALREADY in use\n", ··· 381 goto dma_alloc_failure; 382 } 383 384 + virt_dma_base = ioremap(dma_base, num_ports); 385 + if (virt_dma_base == NULL) { 386 + printk(KERN_ERR 387 + "%s(%s) -- ERROR, Unable to map addresses 0x%lx to 0x%lx\n", 388 + __FUNCTION__, hwif->name, dma_base, dma_base + num_ports - 1); 389 + goto dma_remap_failure; 390 + } 391 + hwif->dma_base = (unsigned long) virt_dma_base; 392 + 393 hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, 394 IOC4_PRD_ENTRIES * IOC4_PRD_BYTES, 395 &hwif->dmatable_dma); 396 397 if (!hwif->dmatable_cpu) 398 + goto dma_pci_alloc_failure; 399 400 hwif->sg_max_nents = IOC4_PRD_ENTRIES; 401 ··· 410 __FUNCTION__, hwif->name); 411 printk(KERN_INFO 412 "Changing from DMA to PIO mode for Drive %s\n", hwif->name); 413 + 414 + dma_pci_alloc_failure: 415 + iounmap(virt_dma_base); 416 + 417 + dma_remap_failure: 418 + release_mem_region(dma_base, num_ports); 419 420 dma_alloc_failure: 421 /* Disable DMA because we couldnot allocate any DMA maps */ ··· 607 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; 608 hwif->ide_dma_timeout = &__ide_dma_timeout; 609 610 hwif->INB = &sgiioc4_INB; 611 } 612 613 static int __devinit 614 sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) 615 { 616 + unsigned long cmd_base, dma_base, irqport; 617 + unsigned long bar0, cmd_phys_base, ctl; 618 + void __iomem *virt_base; 619 ide_hwif_t *hwif; 620 int h; 621 ··· 636 } 637 638 /* Get the CmdBlk and CtrlBlk Base Registers */ 639 + bar0 = pci_resource_start(dev, 0); 640 + virt_base = ioremap(bar0, pci_resource_len(dev, 0)); 641 + if (virt_base == NULL) { 642 + printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", 643 + d->name, bar0); 644 + return -ENOMEM; 645 + } 646 + cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; 647 + ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; 648 + irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; 649 dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; 650 651 + cmd_phys_base = bar0 + IOC4_CMD_OFFSET; 652 + if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, 653 + hwif->name)) { 654 printk(KERN_ERR 655 + "%s : %s -- ERROR, Addresses " 656 "0x%p to 0x%p ALREADY in use\n", 657 + __FUNCTION__, hwif->name, (void *) cmd_phys_base, 658 + (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); 659 return -ENOMEM; 660 } 661 662 + if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) { 663 /* Initialize the IO registers */ 664 + sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport); 665 memcpy(hwif->io_ports, hwif->hw.io_ports, 666 sizeof (hwif->io_ports)); 667 hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; ··· 664 hwif->channel = 0; /* Single Channel chip */ 665 hwif->cds = (struct ide_pci_device_s *) d; 666 hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ 667 + 668 + /* The IOC4 uses MMIO rather than Port IO. */ 669 + default_hwif_mmiops(hwif); 670 671 /* Initializing chipset IRQ Registers */ 672 hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4);