ide: pass hw_regs_t-s to ide_device_add[_all]() (take 3)
[pandora-kernel.git] / drivers / ide / ide-probe.c
index 26e68b6..9d8686a 100644 (file)
@@ -39,6 +39,8 @@
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
+static ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
+
 /**
  *     generic_id              -       add a generic drive id
  *     @drive: drive to make an ID block for
@@ -293,7 +295,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd)
                hwif->OUTB(0, io_ports->feature_addr);
 
        /* ask drive for ID */
-       hwif->OUTBSYNC(drive, cmd, io_ports->command_addr);
+       hwif->OUTBSYNC(hwif, cmd, hwif->io_ports.command_addr);
 
        timeout = ((cmd == WIN_IDENTIFY) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
        timeout += jiffies;
@@ -478,9 +480,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
                        printk(KERN_ERR "%s: no response (status = 0x%02x), "
                                        "resetting drive\n", drive->name, stat);
                        msleep(50);
-                       hwif->OUTB(drive->select.all, io_ports->device_addr);
+                       SELECT_DRIVE(drive);
                        msleep(50);
-                       hwif->OUTBSYNC(drive, WIN_SRST, io_ports->command_addr);
+                       hwif->OUTBSYNC(hwif, WIN_SRST, io_ports->command_addr);
                        (void)ide_busy_sleep(hwif);
                        rc = try_to_identify(drive, cmd);
                }
@@ -516,7 +518,7 @@ static void enable_nest (ide_drive_t *drive)
        printk("%s: enabling %s -- ", hwif->name, drive->id->model);
        SELECT_DRIVE(drive);
        msleep(50);
-       hwif->OUTBSYNC(drive, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
+       hwif->OUTBSYNC(hwif, EXABYTE_ENABLE_NEST, hwif->io_ports.command_addr);
 
        if (ide_busy_sleep(hwif)) {
                printk(KERN_CONT "failed (timeout)\n");
@@ -1065,7 +1067,7 @@ static int init_irq (ide_hwif_t *hwif)
 
                if (io_ports->ctl_addr)
                        /* clear nIEN */
-                       hwif->OUTB(0x08, io_ports->ctl_addr);
+                       hwif->OUTBSYNC(hwif, ATA_DEVCTL_OBS, io_ports->ctl_addr);
 
                if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
                        goto out_unlink;
@@ -1318,10 +1320,10 @@ static void ide_port_init_devices(ide_hwif_t *hwif)
                        drive->unmask = 1;
                if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
                        drive->no_unmask = 1;
-       }
 
-       if (port_ops && port_ops->port_init_devs)
-               port_ops->port_init_devs(hwif);
+               if (port_ops && port_ops->init_dev)
+                       port_ops->init_dev(drive);
+       }
 }
 
 static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
@@ -1473,26 +1475,33 @@ ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d)
                for (; i < MAX_HWIFS; i++) {
                        hwif = &ide_hwifs[i];
                        if (hwif->chipset == ide_unknown)
-                               return hwif;
+                               goto out_found;
                }
        } else {
                for (i = 2; i < MAX_HWIFS; i++) {
                        hwif = &ide_hwifs[i];
                        if (hwif->chipset == ide_unknown)
-                               return hwif;
+                               goto out_found;
                }
                for (i = 0; i < 2 && i < MAX_HWIFS; i++) {
                        hwif = &ide_hwifs[i];
                        if (hwif->chipset == ide_unknown)
-                               return hwif;
+                               goto out_found;
                }
        }
 
+       printk(KERN_ERR "%s: no free slot for interface\n",
+                       d ? d->name : "ide");
+
        return NULL;
+
+out_found:
+       ide_init_port_data(hwif, i);
+       return hwif;
 }
 EXPORT_SYMBOL_GPL(ide_find_port_slot);
 
-int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
+int ide_device_add_all(u8 *idx, const struct ide_port_info *d, hw_regs_t **hws)
 {
        ide_hwif_t *hwif, *mate = NULL;
        int i, rc = 0;
@@ -1505,6 +1514,7 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
 
                hwif = &ide_hwifs[idx[i]];
 
+               ide_init_port_hw(hwif, hws[i]);
                ide_port_apply_params(hwif);
 
                if (d == NULL) {
@@ -1594,15 +1604,18 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d)
 }
 EXPORT_SYMBOL_GPL(ide_device_add_all);
 
-int ide_device_add(u8 idx[4], const struct ide_port_info *d)
+int ide_device_add(u8 *idx, const struct ide_port_info *d, hw_regs_t **hws)
 {
+       hw_regs_t *hws_all[MAX_HWIFS];
        u8 idx_all[MAX_HWIFS];
        int i;
 
-       for (i = 0; i < MAX_HWIFS; i++)
+       for (i = 0; i < MAX_HWIFS; i++) {
+               hws_all[i] = (i < 4) ? hws[i] : NULL;
                idx_all[i] = (i < 4) ? idx[i] : 0xff;
+       }
 
-       return ide_device_add_all(idx_all, d);
+       return ide_device_add_all(idx_all, d, hws_all);
 }
 EXPORT_SYMBOL_GPL(ide_device_add);
 
@@ -1625,8 +1638,8 @@ void ide_port_scan(ide_hwif_t *hwif)
 }
 EXPORT_SYMBOL_GPL(ide_port_scan);
 
-static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
-                               const struct ide_port_info *d,
+static void ide_legacy_init_one(u8 *idx, hw_regs_t **hws, hw_regs_t *hw,
+                               u8 port_no, const struct ide_port_info *d,
                                unsigned long config)
 {
        ide_hwif_t *hwif;
@@ -1662,9 +1675,12 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
 
        hwif = ide_find_port_slot(d);
        if (hwif) {
-               ide_init_port_hw(hwif, hw);
+               hwif->chipset = hw->chipset;
+
                if (config)
                        hwif->config_data = config;
+
+               hws[port_no] = hw;
                idx[port_no] = hwif->index;
        }
 }
@@ -1672,19 +1688,19 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no,
 int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config)
 {
        u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
-       hw_regs_t hw[2];
+       hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL };
 
        memset(&hw, 0, sizeof(hw));
 
        if ((d->host_flags & IDE_HFLAG_QD_2ND_PORT) == 0)
-               ide_legacy_init_one(idx, &hw[0], 0, d, config);
-       ide_legacy_init_one(idx, &hw[1], 1, d, config);
+               ide_legacy_init_one(idx, hws, &hw[0], 0, d, config);
+       ide_legacy_init_one(idx, hws, &hw[1], 1, d, config);
 
        if (idx[0] == 0xff && idx[1] == 0xff &&
            (d->host_flags & IDE_HFLAG_SINGLE))
                return -ENOENT;
 
-       ide_device_add(idx, d);
+       ide_device_add(idx, d, hws);
 
        return 0;
 }