From: Bartlomiej Zolnierkiewicz Date: Wed, 23 Jul 2008 17:55:57 +0000 (+0200) Subject: ide: add struct ide_host (take 3) X-Git-Tag: v2.6.27-rc1~854^2~27 X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=48c3c1072651922ed153bcf0a33ea82cf20df390;hp=374e042c3e767ac2e5a40b78529220e0b3de793c;p=linux-2.6-omap-h63xx.git ide: add struct ide_host (take 3) * Add struct ide_host which keeps pointers to host's ports. * Add ide_host_alloc[_all]() and ide_host_remove() helpers. * Pass 'struct ide_host *host' instead of 'u8 *idx' to ide_device_add[_all]() and rename it to ide_host_register[_all](). * Convert host drivers and core code to use struct ide_host. * Remove no longer needed ide_find_port(). * Make ide_find_port_slot() static. * Unexport ide_unregister(). v2: * Add missing 'struct ide_host *host' to macide.c. v3: * Fix build problem in pmac.c (s/ide_alloc_host/ide_host_alloc/) (Noticed by Stephen Rothwell). Signed-off-by: Bartlomiej Zolnierkiewicz --- diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 0283d162f7f..6fa58425466 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -72,7 +72,7 @@ struct icside_state { void __iomem *ioc_base; unsigned int sel; unsigned int type; - ide_hwif_t *hwif[2]; + struct ide_host *host; }; #define ICS_TYPE_A3IN 0 @@ -442,10 +442,9 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base, static int __init icside_register_v5(struct icside_state *state, struct expansion_card *ec) { - ide_hwif_t *hwif; void __iomem *base; + struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); if (!base) @@ -465,17 +464,15 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec); - hwif = ide_find_port(); - if (!hwif) + host = ide_host_alloc(NULL, hws); + if (host == NULL) return -ENODEV; - state->hwif[0] = hwif; + state->host = host; ecard_set_drvdata(ec, state); - idx[0] = hwif->index; - - ide_device_add(idx, NULL, hws); + ide_host_register(host, NULL, hws); return 0; } @@ -492,12 +489,11 @@ static const struct ide_port_info icside_v6_port_info __initdata = { static int __init icside_register_v6(struct icside_state *state, struct expansion_card *ec) { - ide_hwif_t *hwif, *mate; void __iomem *ioc_base, *easi_base; + struct ide_host *host; unsigned int sel = 0; int ret; hw_regs_t hw[2], *hws[] = { &hw[0], NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = icside_v6_port_info; ioc_base = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); @@ -537,25 +533,11 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) icside_setup_ports(&hw[0], easi_base, &icside_cardinfo_v6_1, ec); icside_setup_ports(&hw[1], easi_base, &icside_cardinfo_v6_2, ec); - /* - * Find and register the interfaces. - */ - hwif = ide_find_port(); - if (hwif == NULL) + host = ide_host_alloc(&d, hws); + if (host == NULL) return -ENODEV; - hwif->chipset = ide_acorn; - - idx[0] = hwif->index; - - mate = ide_find_port(); - if (mate) { - hws[1] = &hw[1]; - idx[1] = mate->index; - } - - state->hwif[0] = hwif; - state->hwif[1] = mate; + state->host = host; ecard_set_drvdata(ec, state); @@ -565,7 +547,7 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) d.dma_ops = NULL; } - ide_device_add(idx, &d, hws); + ide_host_register(host, &d, hws); return 0; diff --git a/drivers/ide/arm/ide_arm.c b/drivers/ide/arm/ide_arm.c index e9831bbd988..9efd7a86db4 100644 --- a/drivers/ide/arm/ide_arm.c +++ b/drivers/ide/arm/ide_arm.c @@ -28,10 +28,9 @@ static int __init ide_arm_init(void) { - ide_hwif_t *hwif; + struct ide_host *host; unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!request_region(base, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", @@ -51,12 +50,9 @@ static int __init ide_arm_init(void) hw.irq = IDE_ARM_IRQ; hw.chipset = ide_generic; - hwif = ide_find_port(); - if (hwif) { - idx[0] = hwif->index; - - ide_device_add(idx, NULL, hws); - } + host = ide_host_alloc(NULL, hws); + if (host) + ide_host_register(host, NULL, hws); return 0; } diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c index 545563bc7e2..24389a571c3 100644 --- a/drivers/ide/arm/palm_bk3710.c +++ b/drivers/ide/arm/palm_bk3710.c @@ -347,11 +347,10 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) { struct clk *clk; struct resource *mem, *irq; - ide_hwif_t *hwif; + struct ide_host *host; unsigned long base, rate; int i; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; clk = clk_get(NULL, "IDECLK"); if (IS_ERR(clk)) @@ -393,15 +392,11 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) hw.irq = irq->start; hw.chipset = ide_palm3710; - hwif = ide_find_port(); - if (hwif == NULL) + host = ide_host_alloc(&palm_bk3710_port_info, hws); + if (host == NULL) goto out; - i = hwif->index; - - idx[0] = i; - - ide_device_add(idx, &palm_bk3710_port_info, hws); + ide_host_register(host, &palm_bk3710_port_info, hws); return 0; out: diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c index a45c2f69494..11f3307385d 100644 --- a/drivers/ide/arm/rapide.c +++ b/drivers/ide/arm/rapide.c @@ -32,11 +32,10 @@ static void rapide_setup_ports(hw_regs_t *hw, void __iomem *base, static int __devinit rapide_probe(struct expansion_card *ec, const struct ecard_id *id) { - ide_hwif_t *hwif; void __iomem *base; + struct ide_host *host; int ret; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; ret = ecard_request_resources(ec); if (ret) @@ -53,17 +52,15 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) hw.chipset = ide_generic; hw.dev = &ec->dev; - hwif = ide_find_port(); - if (hwif == NULL) { + host = ide_host_alloc(&rapide_port_info, hws); + if (host == NULL) { ret = -ENOENT; goto release; } - idx[0] = hwif->index; + ide_host_register(host, &rapide_port_info, hws); - ide_device_add(idx, &rapide_port_info, hws); - - ecard_set_drvdata(ec, hwif); + ecard_set_drvdata(ec, host); goto out; release: @@ -74,11 +71,11 @@ rapide_probe(struct expansion_card *ec, const struct ecard_id *id) static void __devexit rapide_remove(struct expansion_card *ec) { - ide_hwif_t *hwif = ecard_get_drvdata(ec); + struct ide_host *host = ecard_get_drvdata(ec); ecard_set_drvdata(ec, NULL); - ide_unregister(hwif); + ide_host_remove(host); ecard_release_resources(ec); } diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c index 84644e15053..15f76690a48 100644 --- a/drivers/ide/h8300/ide-h8300.c +++ b/drivers/ide/h8300/ide-h8300.c @@ -191,10 +191,8 @@ static const struct ide_port_info h8300_port_info = { static int __init h8300_ide_init(void) { - ide_hwif_t *hwif; - int index; + struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; printk(KERN_INFO DRV_NAME ": H8/300 generic IDE interface\n"); @@ -207,15 +205,11 @@ static int __init h8300_ide_init(void) hw_setup(&hw); - hwif = ide_find_port_slot(&h8300_port_info); - if (hwif == NULL) + host = ide_host_alloc(&h8300_port_info, hws); + if (host == NULL) return -ENOENT; - index = hwif->index; - - idx[0] = index; - - ide_device_add(idx, &h8300_port_info, hws); + ide_host_register(host, &h8300_port_info, hws); return 0; diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index a5c352abff5..e8818362eb4 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c @@ -28,27 +28,24 @@ MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); static ssize_t store_add(struct class *cls, const char *buf, size_t n) { - ide_hwif_t *hwif; + struct ide_host *host; unsigned int base, ctl; int irq; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) return -EINVAL; - hwif = ide_find_port(); - if (hwif == NULL) - return -ENOENT; - memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = irq; hw.chipset = ide_generic; - idx[0] = hwif->index; + host = ide_host_alloc(NULL, hws); + if (host == NULL) + return -ENOENT; - ide_device_add(idx, NULL, hws); + ide_host_register(host, NULL, hws); return n; }; @@ -89,18 +86,16 @@ static int __init ide_generic_sysfs_init(void) static int __init ide_generic_init(void) { hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; - u8 idx[MAX_HWIFS]; + struct ide_host *host; int i; printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " "parameter for probing all legacy ISA IDE ports\n"); for (i = 0; i < MAX_HWIFS; i++) { - ide_hwif_t *hwif; unsigned long io_addr = ide_default_io_base(i); hws[i] = NULL; - idx[i] = 0xff; if ((probe_mask & (1 << i)) && io_addr) { if (!request_region(io_addr, 8, DRV_NAME)) { @@ -118,23 +113,18 @@ static int __init ide_generic_init(void) continue; } - hwif = ide_find_port(); - if (hwif == NULL) - continue; - - hwif->chipset = ide_generic; - memset(&hw[i], 0, sizeof(hw[i])); ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); hw[i].irq = ide_default_irq(io_addr); hw[i].chipset = ide_generic; hws[i] = &hw[i]; - idx[i] = i; } } - ide_device_add_all(idx, NULL, hws); + host = ide_host_alloc_all(NULL, hws); + if (host) + ide_host_register(host, NULL, hws); if (ide_generic_sysfs_init()) printk(KERN_ERR DRV_NAME ": failed to create ide_generic " diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c index 89cd5cbe857..4458ca61897 100644 --- a/drivers/ide/ide-pnp.c +++ b/drivers/ide/ide-pnp.c @@ -29,7 +29,7 @@ static struct pnp_device_id idepnp_devices[] = { static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { - ide_hwif_t *hwif; + struct ide_host *host; unsigned long base, ctl; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; @@ -59,14 +59,11 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) hw.irq = pnp_irq(dev, 0); hw.chipset = ide_generic; - hwif = ide_find_port(); - if (hwif) { - u8 index = hwif->index; - u8 idx[4] = { index, 0xff, 0xff, 0xff }; + host = ide_host_alloc(NULL, hws); + if (host) { + pnp_set_drvdata(dev, host); - pnp_set_drvdata(dev, hwif); - - ide_device_add(idx, NULL, hws); + ide_host_register(host, NULL, hws); return 0; } @@ -79,9 +76,9 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) static void idepnp_remove(struct pnp_dev *dev) { - ide_hwif_t *hwif = pnp_get_drvdata(dev); + struct ide_host *host = pnp_get_drvdata(dev); - ide_unregister(hwif); + ide_host_remove(host); release_region(pnp_port_start(dev, 1), 1); release_region(pnp_port_start(dev, 0), 8); diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index c588066295d..84a89561ec0 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1477,7 +1477,7 @@ static int ide_sysfs_register_port(ide_hwif_t *hwif) * Return the new hwif. If we are out of free slots return NULL. */ -ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) +static ide_hwif_t *ide_find_port_slot(const struct ide_port_info *d) { ide_hwif_t *hwif; int i; @@ -1523,14 +1523,63 @@ 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, hw_regs_t **hws) +struct ide_host *ide_host_alloc_all(const struct ide_port_info *d, + hw_regs_t **hws) +{ + struct ide_host *host; + int i; + + host = kzalloc(sizeof(*host), GFP_KERNEL); + if (host == NULL) + return NULL; + + for (i = 0; i < MAX_HWIFS; i++) { + ide_hwif_t *hwif; + + if (hws[i] == NULL) + continue; + + hwif = ide_find_port_slot(d); + if (hwif) { + hwif->chipset = hws[i]->chipset; + + host->ports[i] = hwif; + host->n_ports++; + } + } + + if (host->n_ports == 0) { + kfree(host); + return NULL; + } + + return host; +} +EXPORT_SYMBOL_GPL(ide_host_alloc_all); + +struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) +{ + hw_regs_t *hws_all[MAX_HWIFS]; + int i; + + for (i = 0; i < MAX_HWIFS; i++) + hws_all[i] = (i < 4) ? hws[i] : NULL; + + return ide_host_alloc_all(d, hws_all); +} +EXPORT_SYMBOL_GPL(ide_host_alloc); + +int ide_host_register(struct ide_host *host, const struct ide_port_info *d, + hw_regs_t **hws) { ide_hwif_t *hwif, *mate = NULL; + u8 idx[MAX_HWIFS]; int i, rc = 0; for (i = 0; i < MAX_HWIFS; i++) { + idx[i] = host->ports[i] ? host->ports[i]->index : 0xff; + if (idx[i] == 0xff) { mate = NULL; continue; @@ -1626,22 +1675,20 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d, hw_regs_t **hws) return rc; } -EXPORT_SYMBOL_GPL(ide_device_add_all); +EXPORT_SYMBOL_GPL(ide_host_register); -int ide_device_add(u8 *idx, const struct ide_port_info *d, hw_regs_t **hws) +void ide_host_remove(struct ide_host *host) { - hw_regs_t *hws_all[MAX_HWIFS]; - u8 idx_all[MAX_HWIFS]; int i; for (i = 0; i < MAX_HWIFS; i++) { - hws_all[i] = (i < 4) ? hws[i] : NULL; - idx_all[i] = (i < 4) ? idx[i] : 0xff; + if (host->ports[i]) + ide_unregister(host->ports[i]); } - return ide_device_add_all(idx_all, d, hws_all); + kfree(host); } -EXPORT_SYMBOL_GPL(ide_device_add); +EXPORT_SYMBOL_GPL(ide_host_remove); void ide_port_scan(ide_hwif_t *hwif) { @@ -1662,11 +1709,10 @@ 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 **hws, hw_regs_t *hw, +static void ide_legacy_init_one(hw_regs_t **hws, hw_regs_t *hw, u8 port_no, const struct ide_port_info *d, unsigned long config) { - ide_hwif_t *hwif; unsigned long base, ctl; int irq; @@ -1698,31 +1744,29 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t **hws, hw_regs_t *hw, hw->chipset = d->chipset; hw->config = config; - hwif = ide_find_port_slot(d); - if (hwif) { - hwif->chipset = hw->chipset; - - hws[port_no] = hw; - idx[port_no] = hwif->index; - } + hws[port_no] = hw; } int ide_legacy_device_add(const struct ide_port_info *d, unsigned long config) { - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + struct ide_host *host; 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, hws, &hw[0], 0, d, config); - ide_legacy_init_one(idx, hws, &hw[1], 1, d, config); + ide_legacy_init_one(hws, &hw[0], 0, d, config); + ide_legacy_init_one(hws, &hw[1], 1, d, config); - if (idx[0] == 0xff && idx[1] == 0xff && + if (hws[0] == NULL && hws[1] == NULL && (d->host_flags & IDE_HFLAG_SINGLE)) return -ENOENT; - ide_device_add(idx, d, hws); + host = ide_host_alloc(d, hws); + if (host == NULL) + return -ENOMEM; + + ide_host_register(host, d, hws); return 0; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 132b504168e..7e9575d1aee 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -276,8 +276,6 @@ void ide_unregister(ide_hwif_t *hwif) mutex_unlock(&ide_cfg_mtx); } -EXPORT_SYMBOL(ide_unregister); - void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) { memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports)); diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index c61bc6a1db3..2625667fab4 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c @@ -150,18 +150,15 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, static int __init buddha_init(void) { - ide_hwif_t *hwif; - int i; - struct zorro_dev *z = NULL; + struct ide_host *host; u_long buddha_board = 0; BuddhaType type; - int buddha_num_hwifs; + int buddha_num_hwifs, i; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { unsigned long board; hw_regs_t hw[MAX_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { buddha_num_hwifs = BUDDHA_NUM_HWIFS; @@ -226,16 +223,12 @@ fail_base2: buddha_setup_ports(&hw[i], base, ctl, irq_port, ack_intr); - hwif = ide_find_port(); - if (hwif) { - hwif->chipset = ide_generic; - - hws[i] = &hw[i]; - idx[i] = hwif->index; - } + hws[i] = &hw[i]; } - ide_device_add(idx, NULL, hws); + host = ide_host_alloc(NULL, hws); + if (host) + ide_host_register(host, NULL, hws); } return 0; diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 3e2c6125f03..4eb5c3f9fec 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c @@ -112,7 +112,7 @@ static void __init falconide_setup_ports(hw_regs_t *hw) static int __init falconide_init(void) { - ide_hwif_t *hwif; + struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) @@ -127,13 +127,10 @@ static int __init falconide_init(void) falconide_setup_ports(&hw); - hwif = ide_find_port(); - if (hwif) { - u8 index = hwif->index; - u8 idx[4] = { index, 0xff, 0xff, 0xff }; - + host = ide_host_alloc(&falconide_port_info, hws); + if (host) { ide_get_lock(NULL, NULL); - ide_device_add(idx, &falconide_port_info, hws); + ide_host_register(host, &falconide_port_info, hws); ide_release_lock(); } diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index 7baeefa870f..13d22bded6b 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c @@ -127,9 +127,9 @@ static int __init gayle_init(void) unsigned long phys_base, res_start, res_n; unsigned long base, ctrlport, irqport; ide_ack_intr_t *ack_intr; + struct ide_host *host; int a4000, i; hw_regs_t hw[GAYLE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!MACH_IS_AMIGA) return -ENODEV; @@ -172,23 +172,17 @@ found: return -EBUSY; for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { - ide_hwif_t *hwif; - base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr); - hwif = ide_find_port(); - if (hwif) { - hwif->chipset = ide_generic; - - hws[i] = &hw[i]; - idx[i] = hwif->index; - } + hws[i] = &hw[i]; } - ide_device_add(idx, NULL, hws); + host = ide_host_alloc(NULL, hws); + if (host) + ide_host_register(host, NULL, hws); return 0; } diff --git a/drivers/ide/legacy/ide-4drives.c b/drivers/ide/legacy/ide-4drives.c index 6310dc50e3c..5935153ef2a 100644 --- a/drivers/ide/legacy/ide-4drives.c +++ b/drivers/ide/legacy/ide-4drives.c @@ -28,10 +28,9 @@ static const struct ide_port_info ide_4drives_port_info = { static int __init ide_4drives_init(void) { - ide_hwif_t *hwif, *mate; + struct ide_host *host; unsigned long base = 0x1f0, ctl = 0x3f6; - hw_regs_t hw, *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + hw_regs_t hw, *hws[] = { &hw, &hw, NULL, NULL }; if (probe_4drives == 0) return -ENODEV; @@ -55,21 +54,9 @@ static int __init ide_4drives_init(void) hw.irq = 14; hw.chipset = ide_4drives; - hwif = ide_find_port(); - if (hwif) { - hwif->chipset = ide_4drives; - - hws[0] = &hw; - idx[0] = hwif->index; - } - - mate = ide_find_port(); - if (mate) { - hws[1] = &hw; - idx[1] = mate->index; - } - - ide_device_add(idx, &ide_4drives_port_info, hws); + host = ide_host_alloc(&ide_4drives_port_info, hws); + if (host) + ide_host_register(host, &ide_4drives_port_info, hws); return 0; } diff --git a/drivers/ide/legacy/ide-cs.c b/drivers/ide/legacy/ide-cs.c index f93d5454ebf..1a4b9e6887f 100644 --- a/drivers/ide/legacy/ide-cs.c +++ b/drivers/ide/legacy/ide-cs.c @@ -74,7 +74,7 @@ INT_MODULE_PARM(pc_debug, 0); typedef struct ide_info_t { struct pcmcia_device *p_dev; - ide_hwif_t *hwif; + struct ide_host *host; int ndev; dev_node_t node; } ide_info_t; @@ -132,7 +132,7 @@ static int ide_probe(struct pcmcia_device *link) static void ide_detach(struct pcmcia_device *link) { ide_info_t *info = link->priv; - ide_hwif_t *hwif = info->hwif; + ide_hwif_t *hwif = info->host->ports[0]; unsigned long data_addr, ctl_addr; DEBUG(0, "ide_detach(0x%p)\n", link); @@ -157,13 +157,13 @@ static const struct ide_port_info idecs_port_info = { .host_flags = IDE_HFLAG_NO_DMA, }; -static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, +static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) { + struct ide_host *host; ide_hwif_t *hwif; int i; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!request_region(io, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", @@ -184,26 +184,26 @@ static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, hw.chipset = ide_pci; hw.dev = &handle->dev; - hwif = ide_find_port(); - if (hwif == NULL) + host = ide_host_alloc(&idecs_port_info, hws); + if (host == NULL) goto out_release; - idx[0] = hwif->index; + ide_host_register(host, &idecs_port_info, hws); - ide_device_add(idx, &idecs_port_info, hws); + hwif = host->ports[0]; if (hwif->present) - return hwif; + return host; /* retry registration in case device is still spinning up */ for (i = 0; i < 10; i++) { msleep(100); ide_port_scan(hwif); if (hwif->present) - return hwif; + return host; } - return hwif; + return host; out_release: release_region(ctl, 1); @@ -235,7 +235,7 @@ static int ide_config(struct pcmcia_device *link) cistpl_cftable_entry_t *cfg; int pass, last_ret = 0, last_fn = 0, is_kme = 0; unsigned long io_base, ctl_base; - ide_hwif_t *hwif; + struct ide_host *host; DEBUG(0, "ide_config(0x%p)\n", link); @@ -330,21 +330,21 @@ static int ide_config(struct pcmcia_device *link) if (is_kme) outb(0x81, ctl_base+1); - hwif = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); - if (hwif == NULL && link->io.NumPorts1 == 0x20) { + host = idecs_register(io_base, ctl_base, link->irq.AssignedIRQ, link); + if (host == NULL && link->io.NumPorts1 == 0x20) { outb(0x02, ctl_base + 0x10); - hwif = idecs_register(io_base + 0x10, ctl_base + 0x10, + host = idecs_register(io_base + 0x10, ctl_base + 0x10, link->irq.AssignedIRQ, link); } - if (hwif == NULL) + if (host == NULL) goto failed; info->ndev = 1; - sprintf(info->node.dev_name, "hd%c", 'a' + hwif->index * 2); - info->node.major = hwif->major; + sprintf(info->node.dev_name, "hd%c", 'a' + host->ports[0]->index * 2); + info->node.major = host->ports[0]->major; info->node.minor = 0; - info->hwif = hwif; + info->host = host; link->dev_node = &info->node; printk(KERN_INFO "ide-cs: %s: Vpp = %d.%d\n", info->node.dev_name, link->conf.Vpp / 10, link->conf.Vpp % 10); @@ -375,15 +375,15 @@ failed: static void ide_release(struct pcmcia_device *link) { ide_info_t *info = link->priv; - ide_hwif_t *hwif = info->hwif; + struct ide_host *host = info->host; DEBUG(0, "ide_release(0x%p)\n", link); - if (info->ndev) { + if (info->ndev) /* FIXME: if this fails we need to queue the cleanup somehow -- need to investigate the required PCMCIA magic */ - ide_unregister(hwif); - } + ide_host_remove(host); + info->ndev = 0; pcmcia_disable_device(link); diff --git a/drivers/ide/legacy/ide_platform.c b/drivers/ide/legacy/ide_platform.c index 3d71e336a22..58a942c6a13 100644 --- a/drivers/ide/legacy/ide_platform.c +++ b/drivers/ide/legacy/ide_platform.c @@ -52,11 +52,10 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) { struct resource *res_base, *res_alt, *res_irq; void __iomem *base, *alt_base; - ide_hwif_t *hwif; struct pata_platform_info *pdata; + struct ide_host *host; int ret = 0, mmio = 0; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = platform_ide_port_info; pdata = pdev->dev.platform_data; @@ -93,12 +92,6 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) res_alt->start, res_alt->end - res_alt->start + 1); } - hwif = ide_find_port(); - if (!hwif) { - ret = -ENODEV; - goto out; - } - memset(&hw, 0, sizeof(hw)); plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start); hw.dev = &pdev->dev; @@ -106,11 +99,15 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) if (mmio) d.host_flags |= IDE_HFLAG_MMIO; - idx[0] = hwif->index; + host = ide_host_alloc(&d, hws); + if (host == NULL) { + ret = -ENODEV; + goto out; + } - ide_device_add(idx, &d, hws); + ide_host_register(host, &d, hws); - platform_set_drvdata(pdev, hwif); + platform_set_drvdata(pdev, host); return 0; @@ -120,9 +117,9 @@ out: static int __devexit plat_ide_remove(struct platform_device *pdev) { - ide_hwif_t *hwif = pdev->dev.driver_data; + struct ide_host *host = pdev->dev.driver_data; - ide_unregister(hwif); + ide_host_remove(host); return 0; } diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index d839df2239f..b49cf8c2b91 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c @@ -91,8 +91,8 @@ static const char *mac_ide_name[] = static int __init macide_init(void) { - ide_hwif_t *hwif; ide_ack_intr_t *ack_intr; + struct ide_host *host; unsigned long base; int irq; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; @@ -125,13 +125,9 @@ static int __init macide_init(void) macide_setup_ports(&hw, base, irq, ack_intr); - hwif = ide_find_port(); - if (hwif) { - u8 index = hwif->index; - u8 idx[4] = { index, 0xff, 0xff, 0xff }; - - ide_device_add(idx, NULL, hws); - } + host = ide_host_alloc(NULL, hws); + if (host) + ide_host_register(host, NULL, hws); return 0; } diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 2dc306f852a..8fb4438a6af 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c @@ -131,10 +131,9 @@ static const char *q40_ide_names[Q40IDE_NUM_HWIFS]={ static int __init q40ide_init(void) { + struct ide_host *host; int i; - ide_hwif_t *hwif; hw_regs_t hw[Q40IDE_NUM_HWIFS], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!MACH_IS_Q40) return -ENODEV; @@ -158,16 +157,12 @@ static int __init q40ide_init(void) q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL, q40ide_default_irq(pcide_bases[i])); - hwif = ide_find_port(); - if (hwif) { - hwif->chipset = ide_generic; - - hws[i] = &hw[i]; - idx[i] = hwif->index; - } + hws[i] = &hw[i]; } - ide_device_add(idx, &q40ide_port_info, hws); + host = ide_host_alloc(&q40ide_port_info, hws); + if (host) + ide_host_register(host, &q40ide_port_info, hws); return 0; } diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index ed1c9a13407..903c628bddd 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -563,11 +563,10 @@ static int au_ide_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); _auide_hwif *ahwif = &auide_hwif; - ide_hwif_t *hwif; struct resource *res; + struct ide_host *host; int ret = 0; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) char *mode = "MWDMA2"; @@ -604,25 +603,23 @@ static int au_ide_probe(struct device *dev) goto out; } - hwif = ide_find_port(); - if (hwif == NULL) { - ret = -ENOENT; - goto out; - } - memset(&hw, 0, sizeof(hw)); auide_setup_ports(&hw, ahwif); hw.irq = ahwif->irq; hw.dev = dev; hw.chipset = ide_au1xxx; - auide_hwif.hwif = hwif; + host = ide_host_alloc(&au1xxx_port_info, hws); + if (host == NULL) { + ret = -ENOENT; + goto out; + } - idx[0] = hwif->index; + ide_host_register(host, &au1xxx_port_info, hws); - ide_device_add(idx, &au1xxx_port_info, hws); + auide_hwif.hwif = host->ports[0]; - dev_set_drvdata(dev, hwif); + dev_set_drvdata(dev, host); printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); @@ -634,10 +631,10 @@ static int au_ide_remove(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct resource *res; - ide_hwif_t *hwif = dev_get_drvdata(dev); + struct ide_host *host = dev_get_drvdata(dev); _auide_hwif *ahwif = &auide_hwif; - ide_unregister(hwif); + ide_host_remove(host); iounmap((void *)ahwif->regbase); diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index c1ffb83a2de..b12d9d22483 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -72,12 +72,11 @@ static const struct ide_port_info swarm_port_info = { */ static int __devinit swarm_ide_probe(struct device *dev) { - ide_hwif_t *hwif; u8 __iomem *base; + struct ide_host *host; phys_t offset, size; int i; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; if (!SIBYTE_HAVE_IDE) return -ENODEV; @@ -116,15 +115,13 @@ static int __devinit swarm_ide_probe(struct device *dev) hw.irq = K_INT_GB_IDE; hw.chipset = ide_generic; - hwif = ide_find_port_slot(&swarm_port_info); - if (hwif == NULL) + host = ide_host_alloc(&swarm_port_info, hws); + if (host == NULL) goto err; - idx[0] = hwif->index; + ide_host_register(host, &swarm_port_info, hws); - ide_device_add(idx, &swarm_port_info, hws); - - dev_set_drvdata(dev, hwif); + dev_set_drvdata(dev, host); return 0; err: diff --git a/drivers/ide/pci/cmd640.c b/drivers/ide/pci/cmd640.c index ccde1e444e1..013697b8cef 100644 --- a/drivers/ide/pci/cmd640.c +++ b/drivers/ide/pci/cmd640.c @@ -180,11 +180,6 @@ static u8 recovery_counts[4] = {16, 16, 16, 16}; /* Recovery count (encoded) */ static DEFINE_SPINLOCK(cmd640_lock); -/* - * These are initialized to point at the devices we control - */ -static ide_hwif_t *cmd_hwif0, *cmd_hwif1; - /* * Interface to access cmd640x registers */ @@ -714,11 +709,11 @@ static int cmd640x_init_one(unsigned long base, unsigned long ctl) */ static int __init cmd640x_init(void) { + struct ide_host *host; int second_port_cmd640 = 0, rc; const char *bus_type, *port2; u8 b, cfr; hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (cmd640_vlb && probe_for_cmd640_vlb()) { bus_type = "VLB"; @@ -781,17 +776,10 @@ static int __init cmd640x_init(void) printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); - cmd_hwif0 = ide_find_port(); - /* * Initialize data for primary port */ - if (cmd_hwif0) { - cmd_hwif0->chipset = ide_cmd640; - - hws[0] = &hw[0]; - idx[0] = cmd_hwif0->index; - } + hws[0] = &hw[0]; /* * Ensure compatibility by always using the slowest timings @@ -831,13 +819,9 @@ static int __init cmd640x_init(void) /* * Initialize data for secondary cmd640 port, if enabled */ - if (second_port_cmd640) { - cmd_hwif1 = ide_find_port(); - if (cmd_hwif1) { - hws[1] = &hw[1]; - idx[1] = cmd_hwif1->index; - } - } + if (second_port_cmd640) + hws[1] = &hw[1]; + printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", second_port_cmd640 ? "" : "not ", port2); @@ -845,7 +829,9 @@ static int __init cmd640x_init(void) cmd640_dump_regs(); #endif - ide_device_add(idx, &cmd640_port_info, hws); + host = ide_host_alloc(&cmd640_port_info, hws); + if (host) + ide_host_register(host, &cmd640_port_info, hws); return 1; } diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c index e8e7df1915b..b8ec06d22c6 100644 --- a/drivers/ide/pci/cs5520.c +++ b/drivers/ide/pci/cs5520.c @@ -114,9 +114,9 @@ static const struct ide_port_info cyrix_chipsets[] __devinitdata = { static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) { + struct ide_host *host; const struct ide_port_info *d = &cyrix_chipsets[id->driver_data]; hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; ide_setup_pci_noise(dev, d); @@ -138,9 +138,11 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic * do all the device setup for us */ - ide_pci_setup_ports(dev, d, 14, &idx[0], &hw[0], &hws[0]); + ide_pci_setup_ports(dev, d, 14, &hw[0], &hws[0]); - ide_device_add(idx, d, hws); + host = ide_host_alloc(d, hws); + if (host) + ide_host_register(host, d, hws); return 0; } diff --git a/drivers/ide/pci/delkin_cb.c b/drivers/ide/pci/delkin_cb.c index 33fe15db408..5eb9d932518 100644 --- a/drivers/ide/pci/delkin_cb.c +++ b/drivers/ide/pci/delkin_cb.c @@ -56,11 +56,10 @@ static const struct ide_port_info delkin_cb_port_info = { static int __devinit delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { + struct ide_host *host; unsigned long base; - ide_hwif_t *hwif = NULL; int i, rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; rc = pci_enable_device(dev); if (rc) { @@ -87,17 +86,13 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) hw.dev = &dev->dev; hw.chipset = ide_pci; /* this enables IRQ sharing */ - hwif = ide_find_port(); - if (hwif == NULL) + host = ide_host_alloc(&delkin_cb_port_info, hws); + if (host == NULL) goto out_disable; - i = hwif->index; + ide_host_register(host, &delkin_cb_port_info, hws); - idx[0] = i; - - ide_device_add(idx, &delkin_cb_port_info, hws); - - pci_set_drvdata(dev, hwif); + pci_set_drvdata(dev, host); return 0; @@ -110,9 +105,9 @@ out_disable: static void delkin_cb_remove (struct pci_dev *dev) { - ide_hwif_t *hwif = pci_get_drvdata(dev); + struct ide_host *host = pci_get_drvdata(dev); - ide_unregister(hwif); + ide_host_remove(host); pci_release_regions(dev); pci_disable_device(dev); diff --git a/drivers/ide/pci/scc_pata.c b/drivers/ide/pci/scc_pata.c index 5b1a0e950df..d5e2ba6bacd 100644 --- a/drivers/ide/pci/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c @@ -65,7 +65,7 @@ static struct scc_ports { unsigned long ctl, dma; - ide_hwif_t *hwif; /* for removing port from system */ + struct ide_host *host; /* for removing port from system */ } scc_ports[MAX_HWIFS]; /* PIO transfer mode table */ @@ -586,15 +586,10 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d) { struct scc_ports *ports = pci_get_drvdata(dev); - ide_hwif_t *hwif = NULL; + struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; int i; - hwif = ide_find_port_slot(d); - if (hwif == NULL) - return -ENOMEM; - memset(&hw, 0, sizeof(hw)); for (i = 0; i <= 8; i++) hw.io_ports_array[i] = ports->dma + 0x20 + i * 4; @@ -602,9 +597,13 @@ static int scc_ide_setup_pci_device(struct pci_dev *dev, hw.dev = &dev->dev; hw.chipset = ide_pci; - idx[0] = hwif->index; + host = ide_host_alloc(d, hws); + if (host == NULL) + return -ENOMEM; - ide_device_add(idx, d, hws); + ide_host_register(host, d, hws); + + ports->host = host; return 0; } @@ -848,8 +847,6 @@ static void __devinit init_hwif_scc(ide_hwif_t *hwif) { struct scc_ports *ports = ide_get_hwifdata(hwif); - ports->hwif = hwif; - /* PTERADD */ out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); @@ -932,7 +929,8 @@ static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_i static void __devexit scc_remove(struct pci_dev *dev) { struct scc_ports *ports = pci_get_drvdata(dev); - ide_hwif_t *hwif = ports->hwif; + struct ide_host *host = ports->host; + ide_hwif_t *hwif = host->ports[0]; if (hwif->dmatable_cpu) { pci_free_consistent(dev, PRD_ENTRIES * PRD_BYTES, @@ -940,7 +938,7 @@ static void __devexit scc_remove(struct pci_dev *dev) hwif->dmatable_cpu = NULL; } - ide_unregister(hwif); + ide_host_remove(host); iounmap((void*)ports->dma); iounmap((void*)ports->ctl); diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 5598bd5936d..440f43a86ad 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c @@ -600,9 +600,8 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) unsigned long cmd_base, irqport; unsigned long bar0, cmd_phys_base, ctl; void __iomem *virt_base; - ide_hwif_t *hwif; + struct ide_host *host; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = sgiioc4_port_info; /* Get the CmdBlk and CtrlBlk Base Registers */ @@ -635,16 +634,14 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) hw.chipset = ide_pci; hw.dev = &dev->dev; - hwif = ide_find_port_slot(&d); - if (hwif == NULL) - goto err; - /* Initializing chipset IRQ Registers */ writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); - idx[0] = hwif->index; + host = ide_host_alloc(&d, hws); + if (host == NULL) + goto err; - if (ide_device_add(idx, &d, hws)) + if (ide_host_register(host, &d, hws)) return -EIO; return 0; diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index ee557d10a76..ecd2f28da1b 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1039,9 +1039,9 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw) { struct device_node *np = pmif->node; const int *bidp; + struct ide_host *host; ide_hwif_t *hwif; hw_regs_t *hws[] = { hw, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; struct ide_port_info d = pmac_port_info; pmif->broken_dma = pmif->broken_dma_warn = 0; @@ -1118,13 +1118,13 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw) pmif->mdev ? "macio" : "PCI", pmif->aapl_bus_id, pmif->mediabay ? " (mediabay)" : "", hw->irq); - hwif = ide_find_port_slot(&d); - if (hwif == NULL) + host = ide_host_alloc(&d, hws); + if (host == NULL) return -ENOENT; - idx[0] = hwif->index; + ide_host_register(host, &d, hws); - ide_device_add(idx, &d, hws); + hwif = host->ports[0]; return 0; } diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 804c3ef245f..1c0c5570dec 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -289,7 +289,7 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * } /** - * ide_hwif_configure - configure an IDE interface + * ide_hw_configure - configure a hw_regs_t instance * @dev: PCI device holding interface * @d: IDE port info * @port: port number @@ -300,23 +300,20 @@ static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info * * is done per interface port rather than per PCI device. There may be * more than one port per device. * - * Returns the new hardware interface structure, or NULL on a failure + * Returns zero on success or an error code. */ -static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, - const struct ide_port_info *d, - unsigned int port, int irq, - hw_regs_t *hw) +static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d, + unsigned int port, int irq, hw_regs_t *hw) { unsigned long ctl = 0, base = 0; - ide_hwif_t *hwif; if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) { if (ide_pci_check_iomem(dev, d, 2 * port) || ide_pci_check_iomem(dev, d, 2 * port + 1)) { printk(KERN_ERR "%s: I/O baseregs (BIOS) are reported " "as MEM for port %d!\n", d->name, port); - return NULL; + return -EINVAL; } ctl = pci_resource_start(dev, 2*port+1); @@ -330,7 +327,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, if (!base || !ctl) { printk(KERN_ERR "%s: bad PCI BARs for port %d, skipping\n", d->name, port); - return NULL; + return -EINVAL; } memset(hw, 0, sizeof(*hw)); @@ -339,13 +336,7 @@ static ide_hwif_t *ide_hwif_configure(struct pci_dev *dev, hw->chipset = d->chipset ? d->chipset : ide_pci; ide_std_init_ports(hw, base, ctl | 2); - hwif = ide_find_port_slot(d); - if (hwif == NULL) - return NULL; - - hwif->chipset = hw->chipset; - - return hwif; + return 0; } #ifdef CONFIG_BLK_DEV_IDEDMA_PCI @@ -443,7 +434,6 @@ out: * @dev: PCI device * @d: IDE port info * @pciirq: IRQ line - * @idx: ATA index table to update * @hw: hw_regs_t instances corresponding to this PCI IDE device * @hws: hw_regs_t pointers table to update * @@ -457,10 +447,9 @@ out: */ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, - int pciirq, u8 *idx, hw_regs_t *hw, hw_regs_t **hws) + int pciirq, hw_regs_t *hw, hw_regs_t **hws) { int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port; - ide_hwif_t *hwif; u8 tmp; /* @@ -476,12 +465,10 @@ void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d, continue; /* port not enabled */ } - hwif = ide_hwif_configure(dev, d, port, pciirq, hw + port); - if (hwif == NULL) + if (ide_hw_configure(dev, d, port, pciirq, hw + port)) continue; *(hws + port) = hw + port; - *(idx + port) = hwif->index; } } EXPORT_SYMBOL_GPL(ide_pci_setup_ports); @@ -554,7 +541,7 @@ out: int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d) { - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; + struct ide_host *host; hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL }; int ret; @@ -562,9 +549,11 @@ int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d) if (ret >= 0) { /* FIXME: silent failure can happen */ - ide_pci_setup_ports(dev, d, ret, &idx[0], &hw[0], &hws[0]); + ide_pci_setup_ports(dev, d, ret, &hw[0], &hws[0]); - ide_device_add(idx, d, hws); + host = ide_host_alloc(d, hws); + if (host) + ide_host_register(host, d, hws); } return ret; @@ -575,9 +564,9 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, const struct ide_port_info *d) { struct pci_dev *pdev[] = { dev1, dev2 }; + struct ide_host *host; int ret, i; hw_regs_t hw[4], *hws[] = { NULL, NULL, NULL, NULL }; - u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; for (i = 0; i < 2; i++) { ret = do_ide_setup_pci_device(pdev[i], d, !i); @@ -590,11 +579,12 @@ int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2, goto out; /* FIXME: silent failure can happen */ - ide_pci_setup_ports(pdev[i], d, ret, &idx[i*2], &hw[i*2], - &hws[i*2]); + ide_pci_setup_ports(pdev[i], d, ret, &hw[i*2], &hws[i*2]); } - ide_device_add(idx, d, hws); + host = ide_host_alloc(d, hws); + if (host) + ide_host_register(host, d, hws); out: return ret; } diff --git a/include/linux/ide.h b/include/linux/ide.h index 1286a2275ef..a41ae57fafc 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -558,6 +558,11 @@ typedef struct hwif_s { #endif } ____cacheline_internodealigned_in_smp ide_hwif_t; +struct ide_host { + ide_hwif_t *ports[MAX_HWIFS]; + unsigned int n_ports; +}; + /* * internal ide interrupt handler type */ @@ -813,13 +818,6 @@ int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsig extern int ide_vlb_clk; extern int ide_pci_clk; -ide_hwif_t *ide_find_port_slot(const struct ide_port_info *); - -static inline ide_hwif_t *ide_find_port(void) -{ - return ide_find_port_slot(NULL); -} - extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq, int uptodate, int nr_sectors); @@ -1024,7 +1022,7 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o #endif void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, - u8 *, hw_regs_t *, hw_regs_t **); + hw_regs_t *, hw_regs_t **); void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); #ifdef CONFIG_BLK_DEV_IDEDMA_PCI @@ -1236,8 +1234,11 @@ void ide_undecoded_slave(ide_drive_t *); void ide_port_apply_params(ide_hwif_t *); -int ide_device_add_all(u8 *, const struct ide_port_info *, hw_regs_t **); -int ide_device_add(u8 *, const struct ide_port_info *, hw_regs_t **); +struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); +struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); +int ide_host_register(struct ide_host *, const struct ide_port_info *, + hw_regs_t **); +void ide_host_remove(struct ide_host *); int ide_legacy_device_add(const struct ide_port_info *, unsigned long); void ide_port_unregister_devices(ide_hwif_t *); void ide_port_scan(ide_hwif_t *);