aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-23 13:55:59 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-23 13:55:59 -0400
commit8a69580e1ea9516caada5eed202afd39546e9809 (patch)
treefb300fb7d67e09470a2654811baaa7832fec2fae
parent18de10170df31d34b342612f1c896a16a52f0a5c (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.c21
-rw-r--r--drivers/ide/ide-generic.c27
-rw-r--r--drivers/ide/ide-probe.c23
-rw-r--r--drivers/ide/legacy/falconide.c22
-rw-r--r--drivers/ide/pci/sgiioc4.c14
-rw-r--r--include/linux/ide.h1
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;
481err_free:
482 ide_host_free(host);
483 ecard_set_drvdata(ec, NULL);
484 return ret;
478} 485}
479 486
480static const struct ide_port_info icside_v6_port_info __initdata = { 487static 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 562err_free:
554 out: 563 ide_host_free(host);
564 if (d.dma_ops)
565 free_dma(ec->dma);
566 ecard_set_drvdata(ec, NULL);
567out:
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;
138err_free:
139 ide_host_free(host);
140err:
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
133module_init(ide_generic_init); 152module_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}
1744EXPORT_SYMBOL_GPL(ide_host_add); 1749EXPORT_SYMBOL_GPL(ide_host_add);
1745 1750
1746void ide_host_remove(struct ide_host *host) 1751void 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}
1768EXPORT_SYMBOL_GPL(ide_host_free);
1769
1770void 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}
1764EXPORT_SYMBOL_GPL(ide_host_remove); 1781EXPORT_SYMBOL_GPL(ide_host_remove);
1765 1782
1766void ide_port_scan(ide_hwif_t *hwif) 1783void 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;
145err_free:
146 ide_host_free(host);
147err:
148 release_mem_region(ATA_HD_BASE, 0x40);
149 return rc;
138} 150}
139 151
140module_init(falconide_init); 152module_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;
652err_free:
653 ide_host_free(host);
648err: 654err:
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
654static unsigned int __devinit 660static 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
1237struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); 1237struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **);
1238struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); 1238struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **);
1239void ide_host_free(struct ide_host *);
1239int ide_host_register(struct ide_host *, const struct ide_port_info *, 1240int ide_host_register(struct ide_host *, const struct ide_port_info *,
1240 hw_regs_t **); 1241 hw_regs_t **);
1241int ide_host_add(const struct ide_port_info *, hw_regs_t **, 1242int ide_host_add(const struct ide_port_info *, hw_regs_t **,