#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
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;
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);
}
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");
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;
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,
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;
hwif = &ide_hwifs[idx[i]];
+ ide_init_port_hw(hwif, hws[i]);
ide_port_apply_params(hwif);
if (d == NULL) {
}
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);
}
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;
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;
}
}
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;
}