diff options
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r-- | drivers/ide/ide-probe.c | 46 |
1 files changed, 36 insertions, 10 deletions
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 312127ea443a..ce0818a993f6 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -649,7 +649,8 @@ static int ide_register_port(ide_hwif_t *hwif) | |||
649 | /* register with global device tree */ | 649 | /* register with global device tree */ |
650 | dev_set_name(&hwif->gendev, hwif->name); | 650 | dev_set_name(&hwif->gendev, hwif->name); |
651 | hwif->gendev.driver_data = hwif; | 651 | hwif->gendev.driver_data = hwif; |
652 | hwif->gendev.parent = hwif->dev; | 652 | if (hwif->gendev.parent == NULL) |
653 | hwif->gendev.parent = hwif->dev; | ||
653 | hwif->gendev.release = hwif_release_dev; | 654 | hwif->gendev.release = hwif_release_dev; |
654 | 655 | ||
655 | ret = device_register(&hwif->gendev); | 656 | ret = device_register(&hwif->gendev); |
@@ -1466,6 +1467,30 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws) | |||
1466 | } | 1467 | } |
1467 | EXPORT_SYMBOL_GPL(ide_host_alloc); | 1468 | EXPORT_SYMBOL_GPL(ide_host_alloc); |
1468 | 1469 | ||
1470 | static void ide_port_free(ide_hwif_t *hwif) | ||
1471 | { | ||
1472 | ide_port_free_devices(hwif); | ||
1473 | ide_free_port_slot(hwif->index); | ||
1474 | kfree(hwif); | ||
1475 | } | ||
1476 | |||
1477 | static void ide_disable_port(ide_hwif_t *hwif) | ||
1478 | { | ||
1479 | struct ide_host *host = hwif->host; | ||
1480 | int i; | ||
1481 | |||
1482 | printk(KERN_INFO "%s: disabling port\n", hwif->name); | ||
1483 | |||
1484 | for (i = 0; i < MAX_HOST_PORTS; i++) { | ||
1485 | if (host->ports[i] == hwif) { | ||
1486 | host->ports[i] = NULL; | ||
1487 | host->n_ports--; | ||
1488 | } | ||
1489 | } | ||
1490 | |||
1491 | ide_port_free(hwif); | ||
1492 | } | ||
1493 | |||
1469 | int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | 1494 | int ide_host_register(struct ide_host *host, const struct ide_port_info *d, |
1470 | hw_regs_t **hws) | 1495 | hw_regs_t **hws) |
1471 | { | 1496 | { |
@@ -1506,8 +1531,12 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1506 | hwif->present = 1; | 1531 | hwif->present = 1; |
1507 | 1532 | ||
1508 | if (hwif->chipset != ide_4drives || !hwif->mate || | 1533 | if (hwif->chipset != ide_4drives || !hwif->mate || |
1509 | !hwif->mate->present) | 1534 | !hwif->mate->present) { |
1510 | ide_register_port(hwif); | 1535 | if (ide_register_port(hwif)) { |
1536 | ide_disable_port(hwif); | ||
1537 | continue; | ||
1538 | } | ||
1539 | } | ||
1511 | 1540 | ||
1512 | if (hwif->present) | 1541 | if (hwif->present) |
1513 | ide_port_tune_devices(hwif); | 1542 | ide_port_tune_devices(hwif); |
@@ -1520,7 +1549,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1520 | if (hwif_init(hwif) == 0) { | 1549 | if (hwif_init(hwif) == 0) { |
1521 | printk(KERN_INFO "%s: failed to initialize IDE " | 1550 | printk(KERN_INFO "%s: failed to initialize IDE " |
1522 | "interface\n", hwif->name); | 1551 | "interface\n", hwif->name); |
1523 | hwif->present = 0; | 1552 | device_unregister(&hwif->gendev); |
1553 | ide_disable_port(hwif); | ||
1524 | continue; | 1554 | continue; |
1525 | } | 1555 | } |
1526 | 1556 | ||
@@ -1659,12 +1689,8 @@ void ide_host_free(struct ide_host *host) | |||
1659 | int i; | 1689 | int i; |
1660 | 1690 | ||
1661 | ide_host_for_each_port(i, hwif, host) { | 1691 | ide_host_for_each_port(i, hwif, host) { |
1662 | if (hwif == NULL) | 1692 | if (hwif) |
1663 | continue; | 1693 | ide_port_free(hwif); |
1664 | |||
1665 | ide_port_free_devices(hwif); | ||
1666 | ide_free_port_slot(hwif->index); | ||
1667 | kfree(hwif); | ||
1668 | } | 1694 | } |
1669 | 1695 | ||
1670 | kfree(host); | 1696 | kfree(host); |