diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-02-02 20:12:21 +0100 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-02-02 20:12:21 +0100 |
commit | 9a100f4b78c4c59fdd1cc38c5fa6a1ec66f23d9a (patch) | |
tree | c7444871700b74d3f26d3c15d7ee78b6a85eb201 /drivers/ide/ide-probe.c | |
parent | e5461f38b43d5658087a598c8deb2a9928d6b92b (diff) | |
download | lwn-9a100f4b78c4c59fdd1cc38c5fa6a1ec66f23d9a.tar.gz lwn-9a100f4b78c4c59fdd1cc38c5fa6a1ec66f23d9a.zip |
ide: fix ide_register_port() failure handling
* Factor out port freeing from ide_host_free() to ide_free_port().
* Add ide_disable_port() and use it on ide_register_port() failure.
Cc: Ian Campbell <Ian.Campbell@citrix.com>
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 0db1ed9f5fc2..6bab2ac1f5b9 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c @@ -1467,6 +1467,30 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) } EXPORT_SYMBOL_GPL(ide_host_alloc); +static void ide_port_free(ide_hwif_t *hwif) +{ + ide_port_free_devices(hwif); + ide_free_port_slot(hwif->index); + kfree(hwif); +} + +static void ide_disable_port(ide_hwif_t *hwif) +{ + struct ide_host *host = hwif->host; + int i; + + printk(KERN_INFO "%s: disabling port\n", hwif->name); + + for (i = 0; i < MAX_HOST_PORTS; i++) { + if (host->ports[i] == hwif) { + host->ports[i] = NULL; + host->n_ports--; + } + } + + ide_port_free(hwif); +} + int ide_host_register(struct ide_host *host, const struct ide_port_info *d, hw_regs_t **hws) { @@ -1507,8 +1531,12 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, hwif->present = 1; if (hwif->chipset != ide_4drives || !hwif->mate || - !hwif->mate->present) - ide_register_port(hwif); + !hwif->mate->present) { + if (ide_register_port(hwif)) { + ide_disable_port(hwif); + continue; + } + } if (hwif->present) ide_port_tune_devices(hwif); @@ -1660,12 +1688,8 @@ void ide_host_free(struct ide_host *host) int i; ide_host_for_each_port(i, hwif, host) { - if (hwif == NULL) - continue; - - ide_port_free_devices(hwif); - ide_free_port_slot(hwif->index); - kfree(hwif); + if (hwif) + ide_port_free(hwif); } kfree(host); |