diff options
Diffstat (limited to 'drivers/ide/ide-generic.c')
-rw-r--r-- | drivers/ide/ide-generic.c | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index 2d92214096ab..31d98fec775f 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -28,29 +28,21 @@ MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports"); | |||
28 | 28 | ||
29 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) | 29 | static ssize_t store_add(struct class *cls, const char *buf, size_t n) |
30 | { | 30 | { |
31 | ide_hwif_t *hwif; | ||
32 | unsigned int base, ctl; | 31 | unsigned int base, ctl; |
33 | int irq; | 32 | int irq, rc; |
34 | hw_regs_t hw; | 33 | hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; |
35 | u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; | ||
36 | 34 | ||
37 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) | 35 | if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3) |
38 | return -EINVAL; | 36 | return -EINVAL; |
39 | 37 | ||
40 | hwif = ide_find_port(); | ||
41 | if (hwif == NULL) | ||
42 | return -ENOENT; | ||
43 | |||
44 | memset(&hw, 0, sizeof(hw)); | 38 | memset(&hw, 0, sizeof(hw)); |
45 | ide_std_init_ports(&hw, base, ctl); | 39 | ide_std_init_ports(&hw, base, ctl); |
46 | hw.irq = irq; | 40 | hw.irq = irq; |
47 | hw.chipset = ide_generic; | 41 | hw.chipset = ide_generic; |
48 | 42 | ||
49 | ide_init_port_hw(hwif, &hw); | 43 | rc = ide_host_add(NULL, hws, NULL); |
50 | 44 | if (rc) | |
51 | idx[0] = hwif->index; | 45 | return rc; |
52 | |||
53 | ide_device_add(idx, NULL); | ||
54 | 46 | ||
55 | return n; | 47 | return n; |
56 | }; | 48 | }; |
@@ -90,18 +82,18 @@ static int __init ide_generic_sysfs_init(void) | |||
90 | 82 | ||
91 | static int __init ide_generic_init(void) | 83 | static int __init ide_generic_init(void) |
92 | { | 84 | { |
93 | u8 idx[MAX_HWIFS]; | 85 | hw_regs_t hw[MAX_HWIFS], *hws[MAX_HWIFS]; |
94 | int i; | 86 | struct ide_host *host; |
87 | unsigned long io_addr; | ||
88 | int i, rc; | ||
95 | 89 | ||
96 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " | 90 | printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" module " |
97 | "parameter for probing all legacy ISA IDE ports\n"); | 91 | "parameter for probing all legacy ISA IDE ports\n"); |
98 | 92 | ||
99 | for (i = 0; i < MAX_HWIFS; i++) { | 93 | for (i = 0; i < MAX_HWIFS; i++) { |
100 | ide_hwif_t *hwif; | 94 | io_addr = ide_default_io_base(i); |
101 | unsigned long io_addr = ide_default_io_base(i); | ||
102 | hw_regs_t hw; | ||
103 | 95 | ||
104 | idx[i] = 0xff; | 96 | hws[i] = NULL; |
105 | 97 | ||
106 | if ((probe_mask & (1 << i)) && io_addr) { | 98 | if ((probe_mask & (1 << i)) && io_addr) { |
107 | if (!request_region(io_addr, 8, DRV_NAME)) { | 99 | if (!request_region(io_addr, 8, DRV_NAME)) { |
@@ -119,33 +111,42 @@ static int __init ide_generic_init(void) | |||
119 | continue; | 111 | continue; |
120 | } | 112 | } |
121 | 113 | ||
122 | /* | 114 | memset(&hw[i], 0, sizeof(hw[i])); |
123 | * Skip probing if the corresponding | 115 | ide_std_init_ports(&hw[i], io_addr, io_addr + 0x206); |
124 | * slot is already occupied. | 116 | hw[i].irq = ide_default_irq(io_addr); |
125 | */ | 117 | hw[i].chipset = ide_generic; |
126 | hwif = ide_find_port(); | ||
127 | if (hwif == NULL || hwif->index != i) { | ||
128 | idx[i] = 0xff; | ||
129 | continue; | ||
130 | } | ||
131 | |||
132 | memset(&hw, 0, sizeof(hw)); | ||
133 | ide_std_init_ports(&hw, io_addr, io_addr + 0x206); | ||
134 | hw.irq = ide_default_irq(io_addr); | ||
135 | hw.chipset = ide_generic; | ||
136 | ide_init_port_hw(hwif, &hw); | ||
137 | 118 | ||
138 | idx[i] = i; | 119 | hws[i] = &hw[i]; |
139 | } | 120 | } |
140 | } | 121 | } |
141 | 122 | ||
142 | ide_device_add_all(idx, NULL); | 123 | host = ide_host_alloc_all(NULL, hws); |
124 | if (host == NULL) { | ||
125 | rc = -ENOMEM; | ||
126 | goto err; | ||
127 | } | ||
128 | |||
129 | rc = ide_host_register(host, NULL, hws); | ||
130 | if (rc) | ||
131 | goto err_free; | ||
143 | 132 | ||
144 | if (ide_generic_sysfs_init()) | 133 | if (ide_generic_sysfs_init()) |
145 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " | 134 | printk(KERN_ERR DRV_NAME ": failed to create ide_generic " |
146 | "class\n"); | 135 | "class\n"); |
147 | 136 | ||
148 | 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; | ||
149 | } | 150 | } |
150 | 151 | ||
151 | module_init(ide_generic_init); | 152 | module_init(ide_generic_init); |