diff options
Diffstat (limited to 'drivers/scsi/pcmcia/aha152x_stub.c')
-rw-r--r-- | drivers/scsi/pcmcia/aha152x_stub.c | 112 |
1 files changed, 32 insertions, 80 deletions
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c index 5609847e254a..ee449b29fc82 100644 --- a/drivers/scsi/pcmcia/aha152x_stub.c +++ b/drivers/scsi/pcmcia/aha152x_stub.c | |||
@@ -89,29 +89,29 @@ MODULE_LICENSE("Dual MPL/GPL"); | |||
89 | /*====================================================================*/ | 89 | /*====================================================================*/ |
90 | 90 | ||
91 | typedef struct scsi_info_t { | 91 | typedef struct scsi_info_t { |
92 | dev_link_t link; | 92 | struct pcmcia_device *p_dev; |
93 | dev_node_t node; | 93 | dev_node_t node; |
94 | struct Scsi_Host *host; | 94 | struct Scsi_Host *host; |
95 | } scsi_info_t; | 95 | } scsi_info_t; |
96 | 96 | ||
97 | static void aha152x_release_cs(dev_link_t *link); | 97 | static void aha152x_release_cs(struct pcmcia_device *link); |
98 | static void aha152x_detach(struct pcmcia_device *p_dev); | 98 | static void aha152x_detach(struct pcmcia_device *p_dev); |
99 | static void aha152x_config_cs(dev_link_t *link); | 99 | static int aha152x_config_cs(struct pcmcia_device *link); |
100 | 100 | ||
101 | static dev_link_t *dev_list; | 101 | static struct pcmcia_device *dev_list; |
102 | 102 | ||
103 | static int aha152x_attach(struct pcmcia_device *p_dev) | 103 | static int aha152x_probe(struct pcmcia_device *link) |
104 | { | 104 | { |
105 | scsi_info_t *info; | 105 | scsi_info_t *info; |
106 | dev_link_t *link; | 106 | |
107 | |||
108 | DEBUG(0, "aha152x_attach()\n"); | 107 | DEBUG(0, "aha152x_attach()\n"); |
109 | 108 | ||
110 | /* Create new SCSI device */ | 109 | /* Create new SCSI device */ |
111 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 110 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
112 | if (!info) return -ENOMEM; | 111 | if (!info) return -ENOMEM; |
113 | memset(info, 0, sizeof(*info)); | 112 | memset(info, 0, sizeof(*info)); |
114 | link = &info->link; link->priv = info; | 113 | info->p_dev = link; |
114 | link->priv = info; | ||
115 | 115 | ||
116 | link->io.NumPorts1 = 0x20; | 116 | link->io.NumPorts1 = 0x20; |
117 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; | 117 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; |
@@ -119,41 +119,22 @@ static int aha152x_attach(struct pcmcia_device *p_dev) | |||
119 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | 119 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; |
120 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; | 120 | link->irq.IRQInfo1 = IRQ_LEVEL_ID; |
121 | link->conf.Attributes = CONF_ENABLE_IRQ; | 121 | link->conf.Attributes = CONF_ENABLE_IRQ; |
122 | link->conf.Vcc = 50; | ||
123 | link->conf.IntType = INT_MEMORY_AND_IO; | 122 | link->conf.IntType = INT_MEMORY_AND_IO; |
124 | link->conf.Present = PRESENT_OPTION; | 123 | link->conf.Present = PRESENT_OPTION; |
125 | 124 | ||
126 | link->handle = p_dev; | 125 | return aha152x_config_cs(link); |
127 | p_dev->instance = link; | ||
128 | |||
129 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
130 | aha152x_config_cs(link); | ||
131 | |||
132 | return 0; | ||
133 | } /* aha152x_attach */ | 126 | } /* aha152x_attach */ |
134 | 127 | ||
135 | /*====================================================================*/ | 128 | /*====================================================================*/ |
136 | 129 | ||
137 | static void aha152x_detach(struct pcmcia_device *p_dev) | 130 | static void aha152x_detach(struct pcmcia_device *link) |
138 | { | 131 | { |
139 | dev_link_t *link = dev_to_instance(p_dev); | ||
140 | dev_link_t **linkp; | ||
141 | |||
142 | DEBUG(0, "aha152x_detach(0x%p)\n", link); | 132 | DEBUG(0, "aha152x_detach(0x%p)\n", link); |
143 | |||
144 | /* Locate device structure */ | ||
145 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
146 | if (*linkp == link) break; | ||
147 | if (*linkp == NULL) | ||
148 | return; | ||
149 | 133 | ||
150 | if (link->state & DEV_CONFIG) | 134 | aha152x_release_cs(link); |
151 | aha152x_release_cs(link); | ||
152 | 135 | ||
153 | /* Unlink device structure, free bits */ | 136 | /* Unlink device structure, free bits */ |
154 | *linkp = link->next; | ||
155 | kfree(link->priv); | 137 | kfree(link->priv); |
156 | |||
157 | } /* aha152x_detach */ | 138 | } /* aha152x_detach */ |
158 | 139 | ||
159 | /*====================================================================*/ | 140 | /*====================================================================*/ |
@@ -161,9 +142,8 @@ static void aha152x_detach(struct pcmcia_device *p_dev) | |||
161 | #define CS_CHECK(fn, ret) \ | 142 | #define CS_CHECK(fn, ret) \ |
162 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 143 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
163 | 144 | ||
164 | static void aha152x_config_cs(dev_link_t *link) | 145 | static int aha152x_config_cs(struct pcmcia_device *link) |
165 | { | 146 | { |
166 | client_handle_t handle = link->handle; | ||
167 | scsi_info_t *info = link->priv; | 147 | scsi_info_t *info = link->priv; |
168 | struct aha152x_setup s; | 148 | struct aha152x_setup s; |
169 | tuple_t tuple; | 149 | tuple_t tuple; |
@@ -178,19 +158,16 @@ static void aha152x_config_cs(dev_link_t *link) | |||
178 | tuple.TupleData = tuple_data; | 158 | tuple.TupleData = tuple_data; |
179 | tuple.TupleDataMax = 64; | 159 | tuple.TupleDataMax = 64; |
180 | tuple.TupleOffset = 0; | 160 | tuple.TupleOffset = 0; |
181 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 161 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
182 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | 162 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple)); |
183 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | 163 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse)); |
184 | link->conf.ConfigBase = parse.config.base; | 164 | link->conf.ConfigBase = parse.config.base; |
185 | 165 | ||
186 | /* Configure card */ | ||
187 | link->state |= DEV_CONFIG; | ||
188 | |||
189 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | 166 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; |
190 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | 167 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); |
191 | while (1) { | 168 | while (1) { |
192 | if (pcmcia_get_tuple_data(handle, &tuple) != 0 || | 169 | if (pcmcia_get_tuple_data(link, &tuple) != 0 || |
193 | pcmcia_parse_tuple(handle, &tuple, &parse) != 0) | 170 | pcmcia_parse_tuple(link, &tuple, &parse) != 0) |
194 | goto next_entry; | 171 | goto next_entry; |
195 | /* For New Media T&J, look for a SCSI window */ | 172 | /* For New Media T&J, look for a SCSI window */ |
196 | if (parse.cftable_entry.io.win[0].len >= 0x20) | 173 | if (parse.cftable_entry.io.win[0].len >= 0x20) |
@@ -201,15 +178,15 @@ static void aha152x_config_cs(dev_link_t *link) | |||
201 | if ((parse.cftable_entry.io.nwin > 0) && | 178 | if ((parse.cftable_entry.io.nwin > 0) && |
202 | (link->io.BasePort1 < 0xffff)) { | 179 | (link->io.BasePort1 < 0xffff)) { |
203 | link->conf.ConfigIndex = parse.cftable_entry.index; | 180 | link->conf.ConfigIndex = parse.cftable_entry.index; |
204 | i = pcmcia_request_io(handle, &link->io); | 181 | i = pcmcia_request_io(link, &link->io); |
205 | if (i == CS_SUCCESS) break; | 182 | if (i == CS_SUCCESS) break; |
206 | } | 183 | } |
207 | next_entry: | 184 | next_entry: |
208 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple)); | 185 | CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); |
209 | } | 186 | } |
210 | 187 | ||
211 | CS_CHECK(RequestIRQ, pcmcia_request_irq(handle, &link->irq)); | 188 | CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); |
212 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf)); | 189 | CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); |
213 | 190 | ||
214 | /* Set configuration options for the aha152x driver */ | 191 | /* Set configuration options for the aha152x driver */ |
215 | memset(&s, 0, sizeof(s)); | 192 | memset(&s, 0, sizeof(s)); |
@@ -231,53 +208,30 @@ static void aha152x_config_cs(dev_link_t *link) | |||
231 | } | 208 | } |
232 | 209 | ||
233 | sprintf(info->node.dev_name, "scsi%d", host->host_no); | 210 | sprintf(info->node.dev_name, "scsi%d", host->host_no); |
234 | link->dev = &info->node; | 211 | link->dev_node = &info->node; |
235 | info->host = host; | 212 | info->host = host; |
236 | 213 | ||
237 | link->state &= ~DEV_CONFIG_PENDING; | 214 | return 0; |
238 | return; | 215 | |
239 | |||
240 | cs_failed: | 216 | cs_failed: |
241 | cs_error(link->handle, last_fn, last_ret); | 217 | cs_error(link, last_fn, last_ret); |
242 | aha152x_release_cs(link); | 218 | aha152x_release_cs(link); |
243 | return; | 219 | return -ENODEV; |
244 | } | 220 | } |
245 | 221 | ||
246 | static void aha152x_release_cs(dev_link_t *link) | 222 | static void aha152x_release_cs(struct pcmcia_device *link) |
247 | { | 223 | { |
248 | scsi_info_t *info = link->priv; | 224 | scsi_info_t *info = link->priv; |
249 | 225 | ||
250 | aha152x_release(info->host); | 226 | aha152x_release(info->host); |
251 | link->dev = NULL; | 227 | pcmcia_disable_device(link); |
252 | |||
253 | pcmcia_release_configuration(link->handle); | ||
254 | pcmcia_release_io(link->handle, &link->io); | ||
255 | pcmcia_release_irq(link->handle, &link->irq); | ||
256 | |||
257 | link->state &= ~DEV_CONFIG; | ||
258 | } | 228 | } |
259 | 229 | ||
260 | static int aha152x_suspend(struct pcmcia_device *dev) | 230 | static int aha152x_resume(struct pcmcia_device *link) |
261 | { | 231 | { |
262 | dev_link_t *link = dev_to_instance(dev); | ||
263 | |||
264 | link->state |= DEV_SUSPEND; | ||
265 | if (link->state & DEV_CONFIG) | ||
266 | pcmcia_release_configuration(link->handle); | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int aha152x_resume(struct pcmcia_device *dev) | ||
272 | { | ||
273 | dev_link_t *link = dev_to_instance(dev); | ||
274 | scsi_info_t *info = link->priv; | 232 | scsi_info_t *info = link->priv; |
275 | 233 | ||
276 | link->state &= ~DEV_SUSPEND; | 234 | aha152x_host_reset_host(info->host); |
277 | if (link->state & DEV_CONFIG) { | ||
278 | pcmcia_request_configuration(link->handle, &link->conf); | ||
279 | aha152x_host_reset_host(info->host); | ||
280 | } | ||
281 | 235 | ||
282 | return 0; | 236 | return 0; |
283 | } | 237 | } |
@@ -297,10 +251,9 @@ static struct pcmcia_driver aha152x_cs_driver = { | |||
297 | .drv = { | 251 | .drv = { |
298 | .name = "aha152x_cs", | 252 | .name = "aha152x_cs", |
299 | }, | 253 | }, |
300 | .probe = aha152x_attach, | 254 | .probe = aha152x_probe, |
301 | .remove = aha152x_detach, | 255 | .remove = aha152x_detach, |
302 | .id_table = aha152x_ids, | 256 | .id_table = aha152x_ids, |
303 | .suspend = aha152x_suspend, | ||
304 | .resume = aha152x_resume, | 257 | .resume = aha152x_resume, |
305 | }; | 258 | }; |
306 | 259 | ||
@@ -317,4 +270,3 @@ static void __exit exit_aha152x_cs(void) | |||
317 | 270 | ||
318 | module_init(init_aha152x_cs); | 271 | module_init(init_aha152x_cs); |
319 | module_exit(exit_aha152x_cs); | 272 | module_exit(exit_aha152x_cs); |
320 | |||