ide: pass hw_regs_t-s to ide_device_add[_all]() (take 3)
[deliverable/linux.git] / drivers / ide / pci / sgiioc4.c
index 321a4e28ac19fa0698f20d21d573296b6b3dc73f..76afa1f9c59952241621fd89523e46d324f85549 100644 (file)
@@ -98,28 +98,28 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
        int i;
 
        /* Registers are word (32 bit) aligned */
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
-               hw->io_ports[i] = reg + i * 4;
+       for (i = 0; i <= 7; i++)
+               hw->io_ports_array[i] = reg + i * 4;
 
        if (ctrl_port)
-               hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
+               hw->io_ports.ctl_addr = ctrl_port;
 
        if (irq_port)
-               hw->io_ports[IDE_IRQ_OFFSET] = irq_port;
+               hw->io_ports.irq_addr = irq_port;
 }
 
 static void
 sgiioc4_maskproc(ide_drive_t * drive, int mask)
 {
-       writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
-              (void __iomem *)drive->hwif->io_ports[IDE_CONTROL_OFFSET]);
+       writeb(ATA_DEVCTL_OBS | (mask ? 2 : 0),
+              (void __iomem *)drive->hwif->io_ports.ctl_addr);
 }
 
 static int
 sgiioc4_checkirq(ide_hwif_t * hwif)
 {
        unsigned long intr_addr =
-               hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
+               hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
 
        if ((u8)readl((void __iomem *)intr_addr) & 0x03)
                return 1;
@@ -134,8 +134,8 @@ sgiioc4_clearirq(ide_drive_t * drive)
 {
        u32 intr_reg;
        ide_hwif_t *hwif = HWIF(drive);
-       unsigned long other_ir =
-           hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
+       struct ide_io_ports *io_ports = &hwif->io_ports;
+       unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
 
        /* Code to check for PCI error conditions */
        intr_reg = readl((void __iomem *)other_ir);
@@ -147,12 +147,12 @@ sgiioc4_clearirq(ide_drive_t * drive)
                 * a "clear" status if it got cleared.  If not, then spin
                 * for a bit trying to clear it.
                 */
-               u8 stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               u8 stat = sgiioc4_INB(io_ports->status_addr);
                int count = 0;
-               stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+               stat = sgiioc4_INB(io_ports->status_addr);
                while ((stat & 0x80) && (count++ < 100)) {
                        udelay(1);
-                       stat = sgiioc4_INB(hwif->io_ports[IDE_STATUS_OFFSET]);
+                       stat = sgiioc4_INB(io_ports->status_addr);
                }
 
                if (intr_reg & 0x02) {
@@ -162,9 +162,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
                            pci_stat_cmd_reg;
 
                        pci_err_addr_low =
-                               readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
+                               readl((void __iomem *)io_ports->irq_addr);
                        pci_err_addr_high =
-                               readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
+                               readl((void __iomem *)(io_ports->irq_addr + 4));
                        pci_read_config_dword(dev, PCI_COMMAND,
                                              &pci_stat_cmd_reg);
                        printk(KERN_ERR
@@ -369,8 +369,7 @@ ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
        hwif->sg_max_nents = IOC4_PRD_ENTRIES;
 
        pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE,
-                                  (dma_addr_t *) &(hwif->dma_status));
-
+                                  (dma_addr_t *)&hwif->extra_base);
        if (pad) {
                ide_set_hwifdata(hwif, pad);
                return 0;
@@ -439,7 +438,7 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
 
        /* Address of the Ending DMA */
        memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
-       ending_dma_addr = cpu_to_le32(hwif->dma_status);
+       ending_dma_addr = cpu_to_le32(hwif->extra_base);
        writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
 
        writel(dma_direction, (void __iomem *)ioc4_dma_addr);
@@ -569,11 +568,12 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
 };
 
 static const struct ide_port_info sgiioc4_port_info __devinitdata = {
+       .name                   = DRV_NAME,
        .chipset                = ide_pci,
        .init_dma               = ide_dma_sgiioc4,
        .port_ops               = &sgiioc4_port_ops,
        .dma_ops                = &sgiioc4_dma_ops,
-       .host_flags             = IDE_HFLAG_NO_AUTOTUNE,
+       .host_flags             = IDE_HFLAG_MMIO,
        .mwdma_mask             = ATA_MWDMA2_ONLY,
 };
 
@@ -584,17 +584,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        unsigned long bar0, cmd_phys_base, ctl;
        void __iomem *virt_base;
        ide_hwif_t *hwif;
+       hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
        u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw;
        struct ide_port_info d = sgiioc4_port_info;
 
-       hwif = ide_find_port();
-       if (hwif == NULL) {
-               printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n",
-                               DRV_NAME);
-               return -ENOMEM;
-       }
-
        /*  Get the CmdBlk and CtrlBlk Base Registers */
        bar0 = pci_resource_start(dev, 0);
        virt_base = ioremap(bar0, pci_resource_len(dev, 0));
@@ -609,11 +602,11 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 
        cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
        if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
-           hwif->name)) {
+           DRV_NAME)) {
                printk(KERN_ERR
                        "%s : %s -- ERROR, Addresses "
                        "0x%p to 0x%p ALREADY in use\n",
-                      __func__, hwif->name, (void *) cmd_phys_base,
+                      __func__, DRV_NAME, (void *) cmd_phys_base,
                       (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
                return -ENOMEM;
        }
@@ -624,9 +617,10 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
        hw.irq = dev->irq;
        hw.chipset = ide_pci;
        hw.dev = &dev->dev;
-       ide_init_port_hw(hwif, &hw);
 
-       hwif->dev = &dev->dev;
+       hwif = ide_find_port_slot(&d);
+       if (hwif == NULL)
+               goto err;
 
        /* The IOC4 uses MMIO rather than Port IO. */
        default_hwif_mmiops(hwif);
@@ -638,10 +632,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
 
        idx[0] = hwif->index;
 
-       if (ide_device_add(idx, &d))
+       if (ide_device_add(idx, &d, hws))
                return -EIO;
 
        return 0;
+err:
+       release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
+       iounmap(virt_base);
+       return -ENOMEM;
 }
 
 static unsigned int __devinit
This page took 0.029475 seconds and 5 git commands to generate.