diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-23 13:55:59 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-07-23 13:55:59 -0400 |
commit | 8a69580e1ea9516caada5eed202afd39546e9809 (patch) | |
tree | fb300fb7d67e09470a2654811baaa7832fec2fae | |
parent | 18de10170df31d34b342612f1c896a16a52f0a5c (diff) |
ide: add ide_host_free() helper (take 2)
* Add ide_host_free() helper and convert ide_host_remove() to use it.
* Fix handling of ide_host_register() failure in ide_host_add(),
icside.c, ide-generic.c, falconide.c and sgiioc4.c.
While at it:
* Fix handling of ide_host_alloc_all() failure in ide-generic.c.
* Fix handling of ide_host_alloc() failure in falconide.c
(also return the correct error value if no device is found).
v2:
* falconide build fix. (From Stephen Rothwell)
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/arm/icside.c | 21 | ||||
-rw-r--r-- | drivers/ide/ide-generic.c | 27 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 23 | ||||
-rw-r--r-- | drivers/ide/legacy/falconide.c | 22 | ||||
-rw-r--r-- | drivers/ide/pci/sgiioc4.c | 14 | ||||
-rw-r--r-- | include/linux/ide.h | 1 |
6 files changed, 88 insertions, 20 deletions
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 6fa58425466a..f575e8341aec 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
@@ -445,6 +445,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
445 | void __iomem *base; | 445 | void __iomem *base; |
446 | struct ide_host *host; | 446 | struct ide_host *host; |
447 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 447 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
448 | int ret; | ||
448 | 449 | ||
449 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); | 450 | base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); |
450 | if (!base) | 451 | if (!base) |
@@ -472,9 +473,15 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec) | |||
472 | 473 | ||
473 | ecard_set_drvdata(ec, state); | 474 | ecard_set_drvdata(ec, state); |
474 | 475 | ||
475 | ide_host_register(host, NULL, hws); | 476 | ret = ide_host_register(host, NULL, hws); |
477 | if (ret) | ||
478 | goto err_free; | ||
476 | 479 | ||
477 | return 0; | 480 | return 0; |
481 | err_free: | ||
482 | ide_host_free(host); | ||
483 | ecard_set_drvdata(ec, NULL); | ||
484 | return ret; | ||
478 | } | 485 | } |
479 | 486 | ||
480 | static const struct ide_port_info icside_v6_port_info __initdata = { | 487 | static const struct ide_port_info icside_v6_port_info __initdata = { |
@@ -547,11 +554,17 @@ icside_register_v6(struct icside_state *state, struct expansion_card *ec) | |||
547 | d.dma_ops = NULL; | 554 | d.dma_ops = NULL; |
548 | } | 555 | } |
549 | 556 | ||
550 | ide_host_register(host, &d, hws); | 557 | ret = ide_host_register(host, NULL, hws); |
558 | if (ret) | ||
559 | goto err_free; | ||
551 | 560 | ||
552 | return 0; | 561 | return 0; |
553 | 562 | err_free: | |
554 | out: | 563 | ide_host_free(host); |
564 | if (d.dma_ops) | ||
565 | free_dma(ec->dma); | ||
566 | ecard_set_drvdata(ec, NULL); | ||
567 | out: | ||
555 | return ret; | 568 | return ret; |
556 | } | 569 | } |
557 | 570 | ||
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index a7082c28d06f..31d98fec775f 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -84,13 +84,14 @@ static int __init ide_generic_init(void) | |||
84 | { | 84 | { |
85 | hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; | 85 | hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; |
86 | struct ide_host *host; | 86 | struct ide_host *host; |
87 | int i; | 87 | unsigned long io_addr; |
88 | int i, rc; | ||
88 | 89 | ||
89 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " | 90 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " |
90 | "parameter for probing all legacy ISA IDE ports\n"); | 91 | "parameter for probing all legacy ISA IDE ports\n"); |
91 | 92 | ||
92 | for (i = 0; i < MAX_HWIFS; i++) { | 93 | for (i = 0; i < MAX_HWIFS; i++) { |
93 | unsigned long io_addr = ide_default_io_base(i); | 94 | io_addr = ide_default_io_base(i); |
94 | 95 | ||
95 | hws[i] = NULL; | 96 | hws[i] = NULL; |
96 | 97 | ||
@@ -120,14 +121,32 @@ static int __init ide_generic_init(void) | |||
120 | } | 121 | } |
121 | 122 | ||
122 | host = ide_host_alloc_all(NULL, hws); | 123 | host = ide_host_alloc_all(NULL, hws); |
123 | if (host) | 124 | if (host == NULL) { |
124 | ide_host_register(host, NULL, hws); | 125 | rc = -ENOMEM; |
126 | goto err; | ||
127 | } | ||
128 | |||
129 | rc = ide_host_register(host, NULL, hws); | ||
130 | if (rc) | ||
131 | goto err_free; | ||
125 | 132 | ||
126 | if (ide_generic_sysfs_init()) | 133 | if (ide_generic_sysfs_init()) |
127 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " | 134 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " |
128 | "class\n"); | 135 | "class\n"); |
129 | 136 | ||
130 | return 0; | 137 | return 0; |
138 | err_free: | ||
139 | ide_host_free(host); | ||
140 | err: | ||
141 | for (i = 0; i < MAX_HWIFS; i++) { | ||
142 | if (hws[i] == NULL) | ||
143 | continue; | ||
144 | |||
145 | io_addr = hws[i]->io_ports.data_addr; | ||
146 | release_region(io_addr + 0x206, 1); | ||
147 | release_region(io_addr, 8); | ||
148 | } | ||
149 | return rc; | ||
131 | } | 150 | } |
132 | 151 | ||
133 | module_init(ide_generic_init); | 152 | module_init(ide_generic_init); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 6d57b7cd5424..0ead4537fc63 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -1729,12 +1729,17 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws, | |||
1729 | struct ide_host **hostp) | 1729 | struct ide_host **hostp) |
1730 | { | 1730 | { |
1731 | struct ide_host *host; | 1731 | struct ide_host *host; |
1732 | int rc; | ||
1732 | 1733 | ||
1733 | host = ide_host_alloc(d, hws); | 1734 | host = ide_host_alloc(d, hws); |
1734 | if (host == NULL) | 1735 | if (host == NULL) |
1735 | return -ENOMEM; | 1736 | return -ENOMEM; |
1736 | 1737 | ||
1737 | ide_host_register(host, d, hws); | 1738 | rc = ide_host_register(host, d, hws); |
1739 | if (rc) { | ||
1740 | ide_host_free(host); | ||
1741 | return rc; | ||
1742 | } | ||
1738 | 1743 | ||
1739 | if (hostp) | 1744 | if (hostp) |
1740 | *hostp = host; | 1745 | *hostp = host; |
@@ -1743,7 +1748,7 @@ int ide_host_add(const struct ide_port_info *d, hw_regs_t **hws, | |||
1743 | } | 1748 | } |
1744 | EXPORT_SYMBOL_GPL(ide_host_add); | 1749 | EXPORT_SYMBOL_GPL(ide_host_add); |
1745 | 1750 | ||
1746 | void ide_host_remove(struct ide_host *host) | 1751 | void ide_host_free(struct ide_host *host) |
1747 | { | 1752 | { |
1748 | ide_hwif_t *hwif; | 1753 | ide_hwif_t *hwif; |
1749 | int i; | 1754 | int i; |
@@ -1754,13 +1759,25 @@ void ide_host_remove(struct ide_host *host) | |||
1754 | if (hwif == NULL) | 1759 | if (hwif == NULL) |
1755 | continue; | 1760 | continue; |
1756 | 1761 | ||
1757 | ide_unregister(hwif); | ||
1758 | ide_free_port_slot(hwif->index); | 1762 | ide_free_port_slot(hwif->index); |
1759 | kfree(hwif); | 1763 | kfree(hwif); |
1760 | } | 1764 | } |
1761 | 1765 | ||
1762 | kfree(host); | 1766 | kfree(host); |
1763 | } | 1767 | } |
1768 | EXPORT_SYMBOL_GPL(ide_host_free); | ||
1769 | |||
1770 | void ide_host_remove(struct ide_host *host) | ||
1771 | { | ||
1772 | int i; | ||
1773 | |||
1774 | for (i = 0; i < MAX_HWIFS; i++) { | ||
1775 | if (host->ports[i]) | ||
1776 | ide_unregister(host->ports[i]); | ||
1777 | } | ||
1778 | |||
1779 | ide_host_free(host); | ||
1780 | } | ||
1764 | EXPORT_SYMBOL_GPL(ide_host_remove); | 1781 | EXPORT_SYMBOL_GPL(ide_host_remove); |
1765 | 1782 | ||
1766 | void ide_port_scan(ide_hwif_t *hwif) | 1783 | void ide_port_scan(ide_hwif_t *hwif) |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 4eb5c3f9fecc..724f95073d80 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -114,9 +114,10 @@ static int __init falconide_init(void) | |||
114 | { | 114 | { |
115 | struct ide_host *host; | 115 | struct ide_host *host; |
116 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 116 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
117 | int rc; | ||
117 | 118 | ||
118 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) | 119 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) |
119 | return 0; | 120 | return -ENODEV; |
120 | 121 | ||
121 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | 122 | printk(KERN_INFO "ide: Falcon IDE controller\n"); |
122 | 123 | ||
@@ -128,13 +129,24 @@ static int __init falconide_init(void) | |||
128 | falconide_setup_ports(&hw); | 129 | falconide_setup_ports(&hw); |
129 | 130 | ||
130 | host = ide_host_alloc(&falconide_port_info, hws); | 131 | host = ide_host_alloc(&falconide_port_info, hws); |
131 | if (host) { | 132 | if (host == NULL) { |
132 | ide_get_lock(NULL, NULL); | 133 | rc = -ENOMEM; |
133 | ide_host_register(host, &falconide_port_info, hws); | 134 | goto err; |
134 | ide_release_lock(); | ||
135 | } | 135 | } |
136 | 136 | ||
137 | ide_get_lock(NULL, NULL); | ||
138 | rc = ide_host_register(host, &falconide_port_info, hws); | ||
139 | ide_release_lock(); | ||
140 | |||
141 | if (rc) | ||
142 | goto err_free; | ||
143 | |||
137 | return 0; | 144 | return 0; |
145 | err_free: | ||
146 | ide_host_free(host); | ||
147 | err: | ||
148 | release_mem_region(ATA_HD_BASE, 0x40); | ||
149 | return rc; | ||
138 | } | 150 | } |
139 | 151 | ||
140 | module_init(falconide_init); | 152 | module_init(falconide_init); |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 440f43a86ad3..42eef19a18f1 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
@@ -603,6 +603,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
603 | struct ide_host *host; | 603 | struct ide_host *host; |
604 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; | 604 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
605 | struct ide_port_info d = sgiioc4_port_info; | 605 | struct ide_port_info d = sgiioc4_port_info; |
606 | int rc; | ||
606 | 607 | ||
607 | /* Get the CmdBlk and CtrlBlk Base Registers */ | 608 | /* Get the CmdBlk and CtrlBlk Base Registers */ |
608 | bar0 = pci_resource_start(dev, 0); | 609 | bar0 = pci_resource_start(dev, 0); |
@@ -638,17 +639,22 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
638 | writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); | 639 | writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); |
639 | 640 | ||
640 | host = ide_host_alloc(&d, hws); | 641 | host = ide_host_alloc(&d, hws); |
641 | if (host == NULL) | 642 | if (host == NULL) { |
643 | rc = -ENOMEM; | ||
642 | goto err; | 644 | goto err; |
645 | } | ||
643 | 646 | ||
644 | if (ide_host_register(host, &d, hws)) | 647 | rc = ide_host_register(host, &d, hws); |
645 | return -EIO; | 648 | if (rc) |
649 | goto err_free; | ||
646 | 650 | ||
647 | return 0; | 651 | return 0; |
652 | err_free: | ||
653 | ide_host_free(host); | ||
648 | err: | 654 | err: |
649 | release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE); | 655 | release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE); |
650 | iounmap(virt_base); | 656 | iounmap(virt_base); |
651 | return -ENOMEM; | 657 | return rc; |
652 | } | 658 | } |
653 | 659 | ||
654 | static unsigned int __devinit | 660 | static unsigned int __devinit |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 764afd94b917..46d5bfe2fefb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1236,6 +1236,7 @@ void ide_port_apply_params(ide_hwif_t *); | |||
1236 | 1236 | ||
1237 | struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); | 1237 | struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); |
1238 | struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); | 1238 | struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); |
1239 | void ide_host_free(struct ide_host *); | ||
1239 | int ide_host_register(struct ide_host *, const struct ide_port_info *, | 1240 | int ide_host_register(struct ide_host *, const struct ide_port_info *, |
1240 | hw_regs_t **); | 1241 | hw_regs_t **); |
1241 | int ide_host_add(const struct ide_port_info *, hw_regs_t **, | 1242 | int ide_host_add(const struct ide_port_info *, hw_regs_t **, |