aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hisax')
-rw-r--r--drivers/isdn/hisax/avma1_cs.c182
-rw-r--r--drivers/isdn/hisax/elsa_cs.c112
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c143
-rw-r--r--drivers/isdn/hisax/teles_cs.c121
4 files changed, 194 insertions, 364 deletions
diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c
index 969da40c4248..ac28e3278ad9 100644
--- a/drivers/isdn/hisax/avma1_cs.c
+++ b/drivers/isdn/hisax/avma1_cs.c
@@ -67,8 +67,8 @@ module_param(isdnprot, int, 0);
67 handler. 67 handler.
68*/ 68*/
69 69
70static void avma1cs_config(dev_link_t *link); 70static int avma1cs_config(struct pcmcia_device *link);
71static void avma1cs_release(dev_link_t *link); 71static void avma1cs_release(struct pcmcia_device *link);
72 72
73/* 73/*
74 The attach() and detach() entry points are used to create and destroy 74 The attach() and detach() entry points are used to create and destroy
@@ -82,10 +82,10 @@ static void avma1cs_detach(struct pcmcia_device *p_dev);
82/* 82/*
83 A linked list of "instances" of the skeleton device. Each actual 83 A linked list of "instances" of the skeleton device. Each actual
84 PCMCIA card corresponds to one device instance, and is described 84 PCMCIA card corresponds to one device instance, and is described
85 by one dev_link_t structure (defined in ds.h). 85 by one struct pcmcia_device structure (defined in ds.h).
86 86
87 You may not want to use a linked list for this -- for example, the 87 You may not want to use a linked list for this -- for example, the
88 memory card driver uses an array of dev_link_t pointers, where minor 88 memory card driver uses an array of struct pcmcia_device pointers, where minor
89 device numbers are used to derive the corresponding array index. 89 device numbers are used to derive the corresponding array index.
90*/ 90*/
91 91
@@ -95,7 +95,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev);
95 example, ethernet cards, modems). In other cases, there may be 95 example, ethernet cards, modems). In other cases, there may be
96 many actual or logical devices (SCSI adapters, memory cards with 96 many actual or logical devices (SCSI adapters, memory cards with
97 multiple partitions). The dev_node_t structures need to be kept 97 multiple partitions). The dev_node_t structures need to be kept
98 in a linked list starting at the 'dev' field of a dev_link_t 98 in a linked list starting at the 'dev' field of a struct pcmcia_device
99 structure. We allocate them in the card's private data structure, 99 structure. We allocate them in the card's private data structure,
100 because they generally can't be allocated dynamically. 100 because they generally can't be allocated dynamically.
101*/ 101*/
@@ -116,55 +116,40 @@ typedef struct local_info_t {
116 116
117======================================================================*/ 117======================================================================*/
118 118
119static int avma1cs_attach(struct pcmcia_device *p_dev) 119static int avma1cs_probe(struct pcmcia_device *p_dev)
120{ 120{
121 dev_link_t *link;
122 local_info_t *local; 121 local_info_t *local;
123 122
124 DEBUG(0, "avma1cs_attach()\n"); 123 DEBUG(0, "avma1cs_attach()\n");
125 124
126 /* Initialize the dev_link_t structure */
127 link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
128 if (!link)
129 return -ENOMEM;
130 memset(link, 0, sizeof(struct dev_link_t));
131
132 /* Allocate space for private device-specific data */ 125 /* Allocate space for private device-specific data */
133 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 126 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
134 if (!local) { 127 if (!local)
135 kfree(link);
136 return -ENOMEM; 128 return -ENOMEM;
137 } 129
138 memset(local, 0, sizeof(local_info_t)); 130 memset(local, 0, sizeof(local_info_t));
139 link->priv = local; 131 p_dev->priv = local;
140 132
141 /* The io structure describes IO port mapping */ 133 /* The io structure describes IO port mapping */
142 link->io.NumPorts1 = 16; 134 p_dev->io.NumPorts1 = 16;
143 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 135 p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
144 link->io.NumPorts2 = 16; 136 p_dev->io.NumPorts2 = 16;
145 link->io.Attributes2 = IO_DATA_PATH_WIDTH_16; 137 p_dev->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
146 link->io.IOAddrLines = 5; 138 p_dev->io.IOAddrLines = 5;
147 139
148 /* Interrupt setup */ 140 /* Interrupt setup */
149 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 141 p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
150 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 142 p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
151 143
152 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 144 p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
153 145
154 /* General socket configuration */ 146 /* General socket configuration */
155 link->conf.Attributes = CONF_ENABLE_IRQ; 147 p_dev->conf.Attributes = CONF_ENABLE_IRQ;
156 link->conf.Vcc = 50; 148 p_dev->conf.IntType = INT_MEMORY_AND_IO;
157 link->conf.IntType = INT_MEMORY_AND_IO; 149 p_dev->conf.ConfigIndex = 1;
158 link->conf.ConfigIndex = 1; 150 p_dev->conf.Present = PRESENT_OPTION;
159 link->conf.Present = PRESENT_OPTION;
160 151
161 link->handle = p_dev; 152 return avma1cs_config(p_dev);
162 p_dev->instance = link;
163
164 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
165 avma1cs_config(link);
166
167 return 0;
168} /* avma1cs_attach */ 153} /* avma1cs_attach */
169 154
170/*====================================================================== 155/*======================================================================
@@ -176,17 +161,11 @@ static int avma1cs_attach(struct pcmcia_device *p_dev)
176 161
177======================================================================*/ 162======================================================================*/
178 163
179static void avma1cs_detach(struct pcmcia_device *p_dev) 164static void avma1cs_detach(struct pcmcia_device *link)
180{ 165{
181 dev_link_t *link = dev_to_instance(p_dev); 166 DEBUG(0, "avma1cs_detach(0x%p)\n", link);
182 167 avma1cs_release(link);
183 DEBUG(0, "avma1cs_detach(0x%p)\n", link); 168 kfree(link->priv);
184
185 if (link->state & DEV_CONFIG)
186 avma1cs_release(link);
187
188 kfree(link->priv);
189 kfree(link);
190} /* avma1cs_detach */ 169} /* avma1cs_detach */
191 170
192/*====================================================================== 171/*======================================================================
@@ -197,7 +176,7 @@ static void avma1cs_detach(struct pcmcia_device *p_dev)
197 176
198======================================================================*/ 177======================================================================*/
199 178
200static int get_tuple(client_handle_t handle, tuple_t *tuple, 179static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
201 cisparse_t *parse) 180 cisparse_t *parse)
202{ 181{
203 int i = pcmcia_get_tuple_data(handle, tuple); 182 int i = pcmcia_get_tuple_data(handle, tuple);
@@ -205,7 +184,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
205 return pcmcia_parse_tuple(handle, tuple, parse); 184 return pcmcia_parse_tuple(handle, tuple, parse);
206} 185}
207 186
208static int first_tuple(client_handle_t handle, tuple_t *tuple, 187static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
209 cisparse_t *parse) 188 cisparse_t *parse)
210{ 189{
211 int i = pcmcia_get_first_tuple(handle, tuple); 190 int i = pcmcia_get_first_tuple(handle, tuple);
@@ -213,7 +192,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
213 return get_tuple(handle, tuple, parse); 192 return get_tuple(handle, tuple, parse);
214} 193}
215 194
216static int next_tuple(client_handle_t handle, tuple_t *tuple, 195static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
217 cisparse_t *parse) 196 cisparse_t *parse)
218{ 197{
219 int i = pcmcia_get_next_tuple(handle, tuple); 198 int i = pcmcia_get_next_tuple(handle, tuple);
@@ -221,9 +200,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
221 return get_tuple(handle, tuple, parse); 200 return get_tuple(handle, tuple, parse);
222} 201}
223 202
224static void avma1cs_config(dev_link_t *link) 203static int avma1cs_config(struct pcmcia_device *link)
225{ 204{
226 client_handle_t handle;
227 tuple_t tuple; 205 tuple_t tuple;
228 cisparse_t parse; 206 cisparse_t parse;
229 cistpl_cftable_entry_t *cf = &parse.cftable_entry; 207 cistpl_cftable_entry_t *cf = &parse.cftable_entry;
@@ -233,8 +211,7 @@ static void avma1cs_config(dev_link_t *link)
233 char devname[128]; 211 char devname[128];
234 IsdnCard_t icard; 212 IsdnCard_t icard;
235 int busy = 0; 213 int busy = 0;
236 214
237 handle = link->handle;
238 dev = link->priv; 215 dev = link->priv;
239 216
240 DEBUG(0, "avma1cs_config(0x%p)\n", link); 217 DEBUG(0, "avma1cs_config(0x%p)\n", link);
@@ -245,25 +222,21 @@ static void avma1cs_config(dev_link_t *link)
245 */ 222 */
246 do { 223 do {
247 tuple.DesiredTuple = CISTPL_CONFIG; 224 tuple.DesiredTuple = CISTPL_CONFIG;
248 i = pcmcia_get_first_tuple(handle, &tuple); 225 i = pcmcia_get_first_tuple(link, &tuple);
249 if (i != CS_SUCCESS) break; 226 if (i != CS_SUCCESS) break;
250 tuple.TupleData = buf; 227 tuple.TupleData = buf;
251 tuple.TupleDataMax = 64; 228 tuple.TupleDataMax = 64;
252 tuple.TupleOffset = 0; 229 tuple.TupleOffset = 0;
253 i = pcmcia_get_tuple_data(handle, &tuple); 230 i = pcmcia_get_tuple_data(link, &tuple);
254 if (i != CS_SUCCESS) break; 231 if (i != CS_SUCCESS) break;
255 i = pcmcia_parse_tuple(handle, &tuple, &parse); 232 i = pcmcia_parse_tuple(link, &tuple, &parse);
256 if (i != CS_SUCCESS) break; 233 if (i != CS_SUCCESS) break;
257 link->conf.ConfigBase = parse.config.base; 234 link->conf.ConfigBase = parse.config.base;
258 } while (0); 235 } while (0);
259 if (i != CS_SUCCESS) { 236 if (i != CS_SUCCESS) {
260 cs_error(link->handle, ParseTuple, i); 237 cs_error(link, ParseTuple, i);
261 link->state &= ~DEV_CONFIG_PENDING; 238 return -ENODEV;
262 return;
263 } 239 }
264
265 /* Configure card */
266 link->state |= DEV_CONFIG;
267 240
268 do { 241 do {
269 242
@@ -274,7 +247,7 @@ static void avma1cs_config(dev_link_t *link)
274 tuple.DesiredTuple = CISTPL_VERS_1; 247 tuple.DesiredTuple = CISTPL_VERS_1;
275 248
276 devname[0] = 0; 249 devname[0] = 0;
277 if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { 250 if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) {
278 strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], 251 strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1],
279 sizeof(devname)); 252 sizeof(devname));
280 } 253 }
@@ -285,7 +258,7 @@ static void avma1cs_config(dev_link_t *link)
285 tuple.TupleOffset = 0; tuple.TupleDataMax = 255; 258 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
286 tuple.Attributes = 0; 259 tuple.Attributes = 0;
287 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 260 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
288 i = first_tuple(handle, &tuple, &parse); 261 i = first_tuple(link, &tuple, &parse);
289 while (i == CS_SUCCESS) { 262 while (i == CS_SUCCESS) {
290 if (cf->io.nwin > 0) { 263 if (cf->io.nwin > 0) {
291 link->conf.ConfigIndex = cf->index; 264 link->conf.ConfigIndex = cf->index;
@@ -295,36 +268,36 @@ static void avma1cs_config(dev_link_t *link)
295 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", 268 printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",
296 link->io.BasePort1, 269 link->io.BasePort1,
297 link->io.BasePort1+link->io.NumPorts1 - 1); 270 link->io.BasePort1+link->io.NumPorts1 - 1);
298 i = pcmcia_request_io(link->handle, &link->io); 271 i = pcmcia_request_io(link, &link->io);
299 if (i == CS_SUCCESS) goto found_port; 272 if (i == CS_SUCCESS) goto found_port;
300 } 273 }
301 i = next_tuple(handle, &tuple, &parse); 274 i = next_tuple(link, &tuple, &parse);
302 } 275 }
303 276
304found_port: 277found_port:
305 if (i != CS_SUCCESS) { 278 if (i != CS_SUCCESS) {
306 cs_error(link->handle, RequestIO, i); 279 cs_error(link, RequestIO, i);
307 break; 280 break;
308 } 281 }
309 282
310 /* 283 /*
311 * allocate an interrupt line 284 * allocate an interrupt line
312 */ 285 */
313 i = pcmcia_request_irq(link->handle, &link->irq); 286 i = pcmcia_request_irq(link, &link->irq);
314 if (i != CS_SUCCESS) { 287 if (i != CS_SUCCESS) {
315 cs_error(link->handle, RequestIRQ, i); 288 cs_error(link, RequestIRQ, i);
316 pcmcia_release_io(link->handle, &link->io); 289 /* undo */
290 pcmcia_disable_device(link);
317 break; 291 break;
318 } 292 }
319 293
320 /* 294 /*
321 * configure the PCMCIA socket 295 * configure the PCMCIA socket
322 */ 296 */
323 i = pcmcia_request_configuration(link->handle, &link->conf); 297 i = pcmcia_request_configuration(link, &link->conf);
324 if (i != CS_SUCCESS) { 298 if (i != CS_SUCCESS) {
325 cs_error(link->handle, RequestConfiguration, i); 299 cs_error(link, RequestConfiguration, i);
326 pcmcia_release_io(link->handle, &link->io); 300 pcmcia_disable_device(link);
327 pcmcia_release_irq(link->handle, &link->irq);
328 break; 301 break;
329 } 302 }
330 303
@@ -336,13 +309,12 @@ found_port:
336 strcpy(dev->node.dev_name, "A1"); 309 strcpy(dev->node.dev_name, "A1");
337 dev->node.major = 45; 310 dev->node.major = 45;
338 dev->node.minor = 0; 311 dev->node.minor = 0;
339 link->dev = &dev->node; 312 link->dev_node = &dev->node;
340 313
341 link->state &= ~DEV_CONFIG_PENDING;
342 /* If any step failed, release any partially configured state */ 314 /* If any step failed, release any partially configured state */
343 if (i != 0) { 315 if (i != 0) {
344 avma1cs_release(link); 316 avma1cs_release(link);
345 return; 317 return -ENODEV;
346 } 318 }
347 319
348 printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", 320 printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",
@@ -357,10 +329,11 @@ found_port:
357 if (i < 0) { 329 if (i < 0) {
358 printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); 330 printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);
359 avma1cs_release(link); 331 avma1cs_release(link);
360 return; 332 return -ENODEV;
361 } 333 }
362 dev->node.minor = i; 334 dev->node.minor = i;
363 335
336 return 0;
364} /* avma1cs_config */ 337} /* avma1cs_config */
365 338
366/*====================================================================== 339/*======================================================================
@@ -371,47 +344,18 @@ found_port:
371 344
372======================================================================*/ 345======================================================================*/
373 346
374static void avma1cs_release(dev_link_t *link) 347static void avma1cs_release(struct pcmcia_device *link)
375{ 348{
376 local_info_t *local = link->priv; 349 local_info_t *local = link->priv;
377 350
378 DEBUG(0, "avma1cs_release(0x%p)\n", link); 351 DEBUG(0, "avma1cs_release(0x%p)\n", link);
379 352
380 /* no unregister function with hisax */ 353 /* now unregister function with hisax */
381 HiSax_closecard(local->node.minor); 354 HiSax_closecard(local->node.minor);
382 355
383 /* Unlink the device chain */ 356 pcmcia_disable_device(link);
384 link->dev = NULL;
385
386 /* Don't bother checking to see if these succeed or not */
387 pcmcia_release_configuration(link->handle);
388 pcmcia_release_io(link->handle, &link->io);
389 pcmcia_release_irq(link->handle, &link->irq);
390 link->state &= ~DEV_CONFIG;
391} /* avma1cs_release */ 357} /* avma1cs_release */
392 358
393static int avma1cs_suspend(struct pcmcia_device *dev)
394{
395 dev_link_t *link = dev_to_instance(dev);
396
397 link->state |= DEV_SUSPEND;
398 if (link->state & DEV_CONFIG)
399 pcmcia_release_configuration(link->handle);
400
401 return 0;
402}
403
404static int avma1cs_resume(struct pcmcia_device *dev)
405{
406 dev_link_t *link = dev_to_instance(dev);
407
408 link->state &= ~DEV_SUSPEND;
409 if (link->state & DEV_CONFIG)
410 pcmcia_request_configuration(link->handle, &link->conf);
411
412 return 0;
413}
414
415 359
416static struct pcmcia_device_id avma1cs_ids[] = { 360static struct pcmcia_device_id avma1cs_ids[] = {
417 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), 361 PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
@@ -425,13 +369,11 @@ static struct pcmcia_driver avma1cs_driver = {
425 .drv = { 369 .drv = {
426 .name = "avma1_cs", 370 .name = "avma1_cs",
427 }, 371 },
428 .probe = avma1cs_attach, 372 .probe = avma1cs_probe,
429 .remove = avma1cs_detach, 373 .remove = avma1cs_detach,
430 .id_table = avma1cs_ids, 374 .id_table = avma1cs_ids,
431 .suspend = avma1cs_suspend,
432 .resume = avma1cs_resume,
433}; 375};
434 376
435/*====================================================================*/ 377/*====================================================================*/
436 378
437static int __init init_avma1_cs(void) 379static int __init init_avma1_cs(void)
diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c
index 062fb8f0739f..e18e75be8ed3 100644
--- a/drivers/isdn/hisax/elsa_cs.c
+++ b/drivers/isdn/hisax/elsa_cs.c
@@ -94,8 +94,8 @@ module_param(protocol, int, 0);
94 handler. 94 handler.
95*/ 95*/
96 96
97static void elsa_cs_config(dev_link_t *link); 97static int elsa_cs_config(struct pcmcia_device *link);
98static void elsa_cs_release(dev_link_t *link); 98static void elsa_cs_release(struct pcmcia_device *link);
99 99
100/* 100/*
101 The attach() and detach() entry points are used to create and destroy 101 The attach() and detach() entry points are used to create and destroy
@@ -111,7 +111,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev);
111 example, ethernet cards, modems). In other cases, there may be 111 example, ethernet cards, modems). In other cases, there may be
112 many actual or logical devices (SCSI adapters, memory cards with 112 many actual or logical devices (SCSI adapters, memory cards with
113 multiple partitions). The dev_node_t structures need to be kept 113 multiple partitions). The dev_node_t structures need to be kept
114 in a linked list starting at the 'dev' field of a dev_link_t 114 in a linked list starting at the 'dev' field of a struct pcmcia_device
115 structure. We allocate them in the card's private data structure, 115 structure. We allocate them in the card's private data structure,
116 because they generally shouldn't be allocated dynamically. 116 because they generally shouldn't be allocated dynamically.
117 In this case, we also provide a flag to indicate if a device is 117 In this case, we also provide a flag to indicate if a device is
@@ -121,7 +121,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev);
121*/ 121*/
122 122
123typedef struct local_info_t { 123typedef struct local_info_t {
124 dev_link_t link; 124 struct pcmcia_device *p_dev;
125 dev_node_t node; 125 dev_node_t node;
126 int busy; 126 int busy;
127 int cardnr; 127 int cardnr;
@@ -139,9 +139,8 @@ typedef struct local_info_t {
139 139
140======================================================================*/ 140======================================================================*/
141 141
142static int elsa_cs_attach(struct pcmcia_device *p_dev) 142static int elsa_cs_probe(struct pcmcia_device *link)
143{ 143{
144 dev_link_t *link;
145 local_info_t *local; 144 local_info_t *local;
146 145
147 DEBUG(0, "elsa_cs_attach()\n"); 146 DEBUG(0, "elsa_cs_attach()\n");
@@ -150,8 +149,11 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
150 local = kmalloc(sizeof(local_info_t), GFP_KERNEL); 149 local = kmalloc(sizeof(local_info_t), GFP_KERNEL);
151 if (!local) return -ENOMEM; 150 if (!local) return -ENOMEM;
152 memset(local, 0, sizeof(local_info_t)); 151 memset(local, 0, sizeof(local_info_t));
152
153 local->p_dev = link;
154 link->priv = local;
155
153 local->cardnr = -1; 156 local->cardnr = -1;
154 link = &local->link; link->priv = local;
155 157
156 /* Interrupt setup */ 158 /* Interrupt setup */
157 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 159 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
@@ -170,16 +172,9 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
170 link->io.IOAddrLines = 3; 172 link->io.IOAddrLines = 3;
171 173
172 link->conf.Attributes = CONF_ENABLE_IRQ; 174 link->conf.Attributes = CONF_ENABLE_IRQ;
173 link->conf.Vcc = 50;
174 link->conf.IntType = INT_MEMORY_AND_IO; 175 link->conf.IntType = INT_MEMORY_AND_IO;
175 176
176 link->handle = p_dev; 177 return elsa_cs_config(link);
177 p_dev->instance = link;
178
179 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
180 elsa_cs_config(link);
181
182 return 0;
183} /* elsa_cs_attach */ 178} /* elsa_cs_attach */
184 179
185/*====================================================================== 180/*======================================================================
@@ -191,20 +186,16 @@ static int elsa_cs_attach(struct pcmcia_device *p_dev)
191 186
192======================================================================*/ 187======================================================================*/
193 188
194static void elsa_cs_detach(struct pcmcia_device *p_dev) 189static void elsa_cs_detach(struct pcmcia_device *link)
195{ 190{
196 dev_link_t *link = dev_to_instance(p_dev); 191 local_info_t *info = link->priv;
197 local_info_t *info = link->priv;
198 192
199 DEBUG(0, "elsa_cs_detach(0x%p)\n", link); 193 DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
200 194
201 if (link->state & DEV_CONFIG) { 195 info->busy = 1;
202 info->busy = 1; 196 elsa_cs_release(link);
203 elsa_cs_release(link);
204 }
205
206 kfree(info);
207 197
198 kfree(info);
208} /* elsa_cs_detach */ 199} /* elsa_cs_detach */
209 200
210/*====================================================================== 201/*======================================================================
@@ -214,7 +205,7 @@ static void elsa_cs_detach(struct pcmcia_device *p_dev)
214 device available to the system. 205 device available to the system.
215 206
216======================================================================*/ 207======================================================================*/
217static int get_tuple(client_handle_t handle, tuple_t *tuple, 208static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
218 cisparse_t *parse) 209 cisparse_t *parse)
219{ 210{
220 int i = pcmcia_get_tuple_data(handle, tuple); 211 int i = pcmcia_get_tuple_data(handle, tuple);
@@ -222,7 +213,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
222 return pcmcia_parse_tuple(handle, tuple, parse); 213 return pcmcia_parse_tuple(handle, tuple, parse);
223} 214}
224 215
225static int first_tuple(client_handle_t handle, tuple_t *tuple, 216static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
226 cisparse_t *parse) 217 cisparse_t *parse)
227{ 218{
228 int i = pcmcia_get_first_tuple(handle, tuple); 219 int i = pcmcia_get_first_tuple(handle, tuple);
@@ -230,7 +221,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
230 return get_tuple(handle, tuple, parse); 221 return get_tuple(handle, tuple, parse);
231} 222}
232 223
233static int next_tuple(client_handle_t handle, tuple_t *tuple, 224static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
234 cisparse_t *parse) 225 cisparse_t *parse)
235{ 226{
236 int i = pcmcia_get_next_tuple(handle, tuple); 227 int i = pcmcia_get_next_tuple(handle, tuple);
@@ -238,9 +229,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
238 return get_tuple(handle, tuple, parse); 229 return get_tuple(handle, tuple, parse);
239} 230}
240 231
241static void elsa_cs_config(dev_link_t *link) 232static int elsa_cs_config(struct pcmcia_device *link)
242{ 233{
243 client_handle_t handle;
244 tuple_t tuple; 234 tuple_t tuple;
245 cisparse_t parse; 235 cisparse_t parse;
246 local_info_t *dev; 236 local_info_t *dev;
@@ -250,7 +240,6 @@ static void elsa_cs_config(dev_link_t *link)
250 IsdnCard_t icard; 240 IsdnCard_t icard;
251 241
252 DEBUG(0, "elsa_config(0x%p)\n", link); 242 DEBUG(0, "elsa_config(0x%p)\n", link);
253 handle = link->handle;
254 dev = link->priv; 243 dev = link->priv;
255 244
256 /* 245 /*
@@ -262,7 +251,7 @@ static void elsa_cs_config(dev_link_t *link)
262 tuple.TupleDataMax = 255; 251 tuple.TupleDataMax = 255;
263 tuple.TupleOffset = 0; 252 tuple.TupleOffset = 0;
264 tuple.Attributes = 0; 253 tuple.Attributes = 0;
265 i = first_tuple(handle, &tuple, &parse); 254 i = first_tuple(link, &tuple, &parse);
266 if (i != CS_SUCCESS) { 255 if (i != CS_SUCCESS) {
267 last_fn = ParseTuple; 256 last_fn = ParseTuple;
268 goto cs_failed; 257 goto cs_failed;
@@ -270,32 +259,29 @@ static void elsa_cs_config(dev_link_t *link)
270 link->conf.ConfigBase = parse.config.base; 259 link->conf.ConfigBase = parse.config.base;
271 link->conf.Present = parse.config.rmask[0]; 260 link->conf.Present = parse.config.rmask[0];
272 261
273 /* Configure card */
274 link->state |= DEV_CONFIG;
275
276 tuple.TupleData = (cisdata_t *)buf; 262 tuple.TupleData = (cisdata_t *)buf;
277 tuple.TupleOffset = 0; tuple.TupleDataMax = 255; 263 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
278 tuple.Attributes = 0; 264 tuple.Attributes = 0;
279 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 265 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
280 i = first_tuple(handle, &tuple, &parse); 266 i = first_tuple(link, &tuple, &parse);
281 while (i == CS_SUCCESS) { 267 while (i == CS_SUCCESS) {
282 if ( (cf->io.nwin > 0) && cf->io.win[0].base) { 268 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
283 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); 269 printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n");
284 link->conf.ConfigIndex = cf->index; 270 link->conf.ConfigIndex = cf->index;
285 link->io.BasePort1 = cf->io.win[0].base; 271 link->io.BasePort1 = cf->io.win[0].base;
286 i = pcmcia_request_io(link->handle, &link->io); 272 i = pcmcia_request_io(link, &link->io);
287 if (i == CS_SUCCESS) break; 273 if (i == CS_SUCCESS) break;
288 } else { 274 } else {
289 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); 275 printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n");
290 link->conf.ConfigIndex = cf->index; 276 link->conf.ConfigIndex = cf->index;
291 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { 277 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
292 link->io.BasePort1 = j; 278 link->io.BasePort1 = j;
293 i = pcmcia_request_io(link->handle, &link->io); 279 i = pcmcia_request_io(link, &link->io);
294 if (i == CS_SUCCESS) break; 280 if (i == CS_SUCCESS) break;
295 } 281 }
296 break; 282 break;
297 } 283 }
298 i = next_tuple(handle, &tuple, &parse); 284 i = next_tuple(link, &tuple, &parse);
299 } 285 }
300 286
301 if (i != CS_SUCCESS) { 287 if (i != CS_SUCCESS) {
@@ -303,14 +289,14 @@ static void elsa_cs_config(dev_link_t *link)
303 goto cs_failed; 289 goto cs_failed;
304 } 290 }
305 291
306 i = pcmcia_request_irq(link->handle, &link->irq); 292 i = pcmcia_request_irq(link, &link->irq);
307 if (i != CS_SUCCESS) { 293 if (i != CS_SUCCESS) {
308 link->irq.AssignedIRQ = 0; 294 link->irq.AssignedIRQ = 0;
309 last_fn = RequestIRQ; 295 last_fn = RequestIRQ;
310 goto cs_failed; 296 goto cs_failed;
311 } 297 }
312 298
313 i = pcmcia_request_configuration(link->handle, &link->conf); 299 i = pcmcia_request_configuration(link, &link->conf);
314 if (i != CS_SUCCESS) { 300 if (i != CS_SUCCESS) {
315 last_fn = RequestConfiguration; 301 last_fn = RequestConfiguration;
316 goto cs_failed; 302 goto cs_failed;
@@ -321,14 +307,11 @@ static void elsa_cs_config(dev_link_t *link)
321 sprintf(dev->node.dev_name, "elsa"); 307 sprintf(dev->node.dev_name, "elsa");
322 dev->node.major = dev->node.minor = 0x0; 308 dev->node.major = dev->node.minor = 0x0;
323 309
324 link->dev = &dev->node; 310 link->dev_node = &dev->node;
325 311
326 /* Finally, report what we've done */ 312 /* Finally, report what we've done */
327 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 313 printk(KERN_INFO "%s: index 0x%02x: ",
328 dev->node.dev_name, link->conf.ConfigIndex, 314 dev->node.dev_name, link->conf.ConfigIndex);
329 link->conf.Vcc/10, link->conf.Vcc%10);
330 if (link->conf.Vpp1)
331 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
332 if (link->conf.Attributes & CONF_ENABLE_IRQ) 315 if (link->conf.Attributes & CONF_ENABLE_IRQ)
333 printk(", irq %d", link->irq.AssignedIRQ); 316 printk(", irq %d", link->irq.AssignedIRQ);
334 if (link->io.NumPorts1) 317 if (link->io.NumPorts1)
@@ -339,8 +322,6 @@ static void elsa_cs_config(dev_link_t *link)
339 link->io.BasePort2+link->io.NumPorts2-1); 322 link->io.BasePort2+link->io.NumPorts2-1);
340 printk("\n"); 323 printk("\n");
341 324
342 link->state &= ~DEV_CONFIG_PENDING;
343
344 icard.para[0] = link->irq.AssignedIRQ; 325 icard.para[0] = link->irq.AssignedIRQ;
345 icard.para[1] = link->io.BasePort1; 326 icard.para[1] = link->io.BasePort1;
346 icard.protocol = protocol; 327 icard.protocol = protocol;
@@ -354,10 +335,11 @@ static void elsa_cs_config(dev_link_t *link)
354 } else 335 } else
355 ((local_info_t*)link->priv)->cardnr = i; 336 ((local_info_t*)link->priv)->cardnr = i;
356 337
357 return; 338 return 0;
358cs_failed: 339cs_failed:
359 cs_error(link->handle, last_fn, i); 340 cs_error(link, last_fn, i);
360 elsa_cs_release(link); 341 elsa_cs_release(link);
342 return -ENODEV;
361} /* elsa_cs_config */ 343} /* elsa_cs_config */
362 344
363/*====================================================================== 345/*======================================================================
@@ -368,7 +350,7 @@ cs_failed:
368 350
369======================================================================*/ 351======================================================================*/
370 352
371static void elsa_cs_release(dev_link_t *link) 353static void elsa_cs_release(struct pcmcia_device *link)
372{ 354{
373 local_info_t *local = link->priv; 355 local_info_t *local = link->priv;
374 356
@@ -380,39 +362,23 @@ static void elsa_cs_release(dev_link_t *link)
380 HiSax_closecard(local->cardnr); 362 HiSax_closecard(local->cardnr);
381 } 363 }
382 } 364 }
383 /* Unlink the device chain */ 365
384 link->dev = NULL; 366 pcmcia_disable_device(link);
385
386 /* Don't bother checking to see if these succeed or not */
387 if (link->win)
388 pcmcia_release_window(link->win);
389 pcmcia_release_configuration(link->handle);
390 pcmcia_release_io(link->handle, &link->io);
391 pcmcia_release_irq(link->handle, &link->irq);
392 link->state &= ~DEV_CONFIG;
393} /* elsa_cs_release */ 367} /* elsa_cs_release */
394 368
395static int elsa_suspend(struct pcmcia_device *p_dev) 369static int elsa_suspend(struct pcmcia_device *link)
396{ 370{
397 dev_link_t *link = dev_to_instance(p_dev);
398 local_info_t *dev = link->priv; 371 local_info_t *dev = link->priv;
399 372
400 link->state |= DEV_SUSPEND;
401 dev->busy = 1; 373 dev->busy = 1;
402 if (link->state & DEV_CONFIG)
403 pcmcia_release_configuration(link->handle);
404 374
405 return 0; 375 return 0;
406} 376}
407 377
408static int elsa_resume(struct pcmcia_device *p_dev) 378static int elsa_resume(struct pcmcia_device *link)
409{ 379{
410 dev_link_t *link = dev_to_instance(p_dev);
411 local_info_t *dev = link->priv; 380 local_info_t *dev = link->priv;
412 381
413 link->state &= ~DEV_SUSPEND;
414 if (link->state & DEV_CONFIG)
415 pcmcia_request_configuration(link->handle, &link->conf);
416 dev->busy = 0; 382 dev->busy = 0;
417 383
418 return 0; 384 return 0;
@@ -430,7 +396,7 @@ static struct pcmcia_driver elsa_cs_driver = {
430 .drv = { 396 .drv = {
431 .name = "elsa_cs", 397 .name = "elsa_cs",
432 }, 398 },
433 .probe = elsa_cs_attach, 399 .probe = elsa_cs_probe,
434 .remove = elsa_cs_detach, 400 .remove = elsa_cs_detach,
435 .id_table = elsa_ids, 401 .id_table = elsa_ids,
436 .suspend = elsa_suspend, 402 .suspend = elsa_suspend,
diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c
index 6f5213a18a8d..9bb18f3f7829 100644
--- a/drivers/isdn/hisax/sedlbauer_cs.c
+++ b/drivers/isdn/hisax/sedlbauer_cs.c
@@ -95,8 +95,8 @@ module_param(protocol, int, 0);
95 event handler. 95 event handler.
96*/ 96*/
97 97
98static void sedlbauer_config(dev_link_t *link); 98static int sedlbauer_config(struct pcmcia_device *link);
99static void sedlbauer_release(dev_link_t *link); 99static void sedlbauer_release(struct pcmcia_device *link);
100 100
101/* 101/*
102 The attach() and detach() entry points are used to create and destroy 102 The attach() and detach() entry points are used to create and destroy
@@ -119,7 +119,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev);
119 example, ethernet cards, modems). In other cases, there may be 119 example, ethernet cards, modems). In other cases, there may be
120 many actual or logical devices (SCSI adapters, memory cards with 120 many actual or logical devices (SCSI adapters, memory cards with
121 multiple partitions). The dev_node_t structures need to be kept 121 multiple partitions). The dev_node_t structures need to be kept
122 in a linked list starting at the 'dev' field of a dev_link_t 122 in a linked list starting at the 'dev' field of a struct pcmcia_device
123 structure. We allocate them in the card's private data structure, 123 structure. We allocate them in the card's private data structure,
124 because they generally shouldn't be allocated dynamically. 124 because they generally shouldn't be allocated dynamically.
125 125
@@ -130,7 +130,7 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev);
130*/ 130*/
131 131
132typedef struct local_info_t { 132typedef struct local_info_t {
133 dev_link_t link; 133 struct pcmcia_device *p_dev;
134 dev_node_t node; 134 dev_node_t node;
135 int stop; 135 int stop;
136 int cardnr; 136 int cardnr;
@@ -148,11 +148,10 @@ typedef struct local_info_t {
148 148
149======================================================================*/ 149======================================================================*/
150 150
151static int sedlbauer_attach(struct pcmcia_device *p_dev) 151static int sedlbauer_probe(struct pcmcia_device *link)
152{ 152{
153 local_info_t *local; 153 local_info_t *local;
154 dev_link_t *link; 154
155
156 DEBUG(0, "sedlbauer_attach()\n"); 155 DEBUG(0, "sedlbauer_attach()\n");
157 156
158 /* Allocate space for private device-specific data */ 157 /* Allocate space for private device-specific data */
@@ -160,8 +159,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
160 if (!local) return -ENOMEM; 159 if (!local) return -ENOMEM;
161 memset(local, 0, sizeof(local_info_t)); 160 memset(local, 0, sizeof(local_info_t));
162 local->cardnr = -1; 161 local->cardnr = -1;
163 link = &local->link; link->priv = local; 162
164 163 local->p_dev = link;
164 link->priv = local;
165
165 /* Interrupt setup */ 166 /* Interrupt setup */
166 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 167 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
167 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 168 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
@@ -182,18 +183,10 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
182 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 183 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
183 link->io.IOAddrLines = 3; 184 link->io.IOAddrLines = 3;
184 185
185
186 link->conf.Attributes = 0; 186 link->conf.Attributes = 0;
187 link->conf.Vcc = 50;
188 link->conf.IntType = INT_MEMORY_AND_IO; 187 link->conf.IntType = INT_MEMORY_AND_IO;
189 188
190 link->handle = p_dev; 189 return sedlbauer_config(link);
191 p_dev->instance = link;
192
193 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
194 sedlbauer_config(link);
195
196 return 0;
197} /* sedlbauer_attach */ 190} /* sedlbauer_attach */
198 191
199/*====================================================================== 192/*======================================================================
@@ -205,19 +198,15 @@ static int sedlbauer_attach(struct pcmcia_device *p_dev)
205 198
206======================================================================*/ 199======================================================================*/
207 200
208static void sedlbauer_detach(struct pcmcia_device *p_dev) 201static void sedlbauer_detach(struct pcmcia_device *link)
209{ 202{
210 dev_link_t *link = dev_to_instance(p_dev); 203 DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
211
212 DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
213 204
214 if (link->state & DEV_CONFIG) { 205 ((local_info_t *)link->priv)->stop = 1;
215 ((local_info_t *)link->priv)->stop = 1; 206 sedlbauer_release(link);
216 sedlbauer_release(link);
217 }
218 207
219 /* This points to the parent local_info_t struct */ 208 /* This points to the parent local_info_t struct */
220 kfree(link->priv); 209 kfree(link->priv);
221} /* sedlbauer_detach */ 210} /* sedlbauer_detach */
222 211
223/*====================================================================== 212/*======================================================================
@@ -230,9 +219,8 @@ static void sedlbauer_detach(struct pcmcia_device *p_dev)
230#define CS_CHECK(fn, ret) \ 219#define CS_CHECK(fn, ret) \
231do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 220do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
232 221
233static void sedlbauer_config(dev_link_t *link) 222static int sedlbauer_config(struct pcmcia_device *link)
234{ 223{
235 client_handle_t handle = link->handle;
236 local_info_t *dev = link->priv; 224 local_info_t *dev = link->priv;
237 tuple_t tuple; 225 tuple_t tuple;
238 cisparse_t parse; 226 cisparse_t parse;
@@ -254,18 +242,13 @@ static void sedlbauer_config(dev_link_t *link)
254 tuple.TupleData = buf; 242 tuple.TupleData = buf;
255 tuple.TupleDataMax = sizeof(buf); 243 tuple.TupleDataMax = sizeof(buf);
256 tuple.TupleOffset = 0; 244 tuple.TupleOffset = 0;
257 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 245 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
258 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 246 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
259 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 247 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
260 link->conf.ConfigBase = parse.config.base; 248 link->conf.ConfigBase = parse.config.base;
261 link->conf.Present = parse.config.rmask[0]; 249 link->conf.Present = parse.config.rmask[0];
262
263 /* Configure card */
264 link->state |= DEV_CONFIG;
265 250
266 /* Look up the current Vcc */ 251 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
267 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
268 link->conf.Vcc = conf.Vcc;
269 252
270 /* 253 /*
271 In this loop, we scan the CIS for configuration table entries, 254 In this loop, we scan the CIS for configuration table entries,
@@ -280,12 +263,12 @@ static void sedlbauer_config(dev_link_t *link)
280 will only use the CIS to fill in implementation-defined details. 263 will only use the CIS to fill in implementation-defined details.
281 */ 264 */
282 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 265 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
283 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 266 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
284 while (1) { 267 while (1) {
285 cistpl_cftable_entry_t dflt = { 0 }; 268 cistpl_cftable_entry_t dflt = { 0 };
286 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 269 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
287 if (pcmcia_get_tuple_data(handle, &tuple) != 0 || 270 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
288 pcmcia_parse_tuple(handle, &tuple, &parse) != 0) 271 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
289 goto next_entry; 272 goto next_entry;
290 273
291 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg; 274 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
@@ -309,10 +292,10 @@ static void sedlbauer_config(dev_link_t *link)
309 } 292 }
310 293
311 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) 294 if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
312 link->conf.Vpp1 = link->conf.Vpp2 = 295 link->conf.Vpp =
313 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; 296 cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
314 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) 297 else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
315 link->conf.Vpp1 = link->conf.Vpp2 = 298 link->conf.Vpp =
316 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; 299 dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
317 300
318 /* Do we need to allocate an interrupt? */ 301 /* Do we need to allocate an interrupt? */
@@ -339,13 +322,13 @@ static void sedlbauer_config(dev_link_t *link)
339 link->io.NumPorts2 = io->win[1].len; 322 link->io.NumPorts2 = io->win[1].len;
340 } 323 }
341 /* This reserves IO space but doesn't actually enable it */ 324 /* This reserves IO space but doesn't actually enable it */
342 if (pcmcia_request_io(link->handle, &link->io) != 0) 325 if (pcmcia_request_io(link, &link->io) != 0)
343 goto next_entry; 326 goto next_entry;
344 } 327 }
345 328
346 /* 329 /*
347 Now set up a common memory window, if needed. There is room 330 Now set up a common memory window, if needed. There is room
348 in the dev_link_t structure for one memory window handle, 331 in the struct pcmcia_device structure for one memory window handle,
349 but if the base addresses need to be saved, or if multiple 332 but if the base addresses need to be saved, or if multiple
350 windows are needed, the info should go in the private data 333 windows are needed, the info should go in the private data
351 structure for this device. 334 structure for this device.
@@ -366,7 +349,7 @@ static void sedlbauer_config(dev_link_t *link)
366 req.Size = 0x1000; 349 req.Size = 0x1000;
367*/ 350*/
368 req.AccessSpeed = 0; 351 req.AccessSpeed = 0;
369 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0) 352 if (pcmcia_request_window(&link, &req, &link->win) != 0)
370 goto next_entry; 353 goto next_entry;
371 map.Page = 0; map.CardOffset = mem->win[0].card_addr; 354 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
372 if (pcmcia_map_mem_page(link->win, &map) != 0) 355 if (pcmcia_map_mem_page(link->win, &map) != 0)
@@ -374,29 +357,25 @@ static void sedlbauer_config(dev_link_t *link)
374 } 357 }
375 /* If we got this far, we're cool! */ 358 /* If we got this far, we're cool! */
376 break; 359 break;
377 360
378 next_entry: 361 next_entry:
379/* new in dummy.cs 2001/01/28 MN 362 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
380 if (link->io.NumPorts1)
381 pcmcia_release_io(link->handle, &link->io);
382*/
383 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
384 } 363 }
385 364
386 /* 365 /*
387 Allocate an interrupt line. Note that this does not assign a 366 Allocate an interrupt line. Note that this does not assign a
388 handler to the interrupt, unless the 'Handler' member of the 367 handler to the interrupt, unless the 'Handler' member of the
389 irq structure is initialized. 368 irq structure is initialized.
390 */ 369 */
391 if (link->conf.Attributes & CONF_ENABLE_IRQ) 370 if (link->conf.Attributes & CONF_ENABLE_IRQ)
392 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 371 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
393 372
394 /* 373 /*
395 This actually configures the PCMCIA socket -- setting up 374 This actually configures the PCMCIA socket -- setting up
396 the I/O windows and the interrupt mapping, and putting the 375 the I/O windows and the interrupt mapping, and putting the
397 card and host interface into "Memory and IO" mode. 376 card and host interface into "Memory and IO" mode.
398 */ 377 */
399 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); 378 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
400 379
401 /* 380 /*
402 At this point, the dev_node_t structure(s) need to be 381 At this point, the dev_node_t structure(s) need to be
@@ -404,14 +383,13 @@ static void sedlbauer_config(dev_link_t *link)
404 */ 383 */
405 sprintf(dev->node.dev_name, "sedlbauer"); 384 sprintf(dev->node.dev_name, "sedlbauer");
406 dev->node.major = dev->node.minor = 0; 385 dev->node.major = dev->node.minor = 0;
407 link->dev = &dev->node; 386 link->dev_node = &dev->node;
408 387
409 /* Finally, report what we've done */ 388 /* Finally, report what we've done */
410 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 389 printk(KERN_INFO "%s: index 0x%02x:",
411 dev->node.dev_name, link->conf.ConfigIndex, 390 dev->node.dev_name, link->conf.ConfigIndex);
412 link->conf.Vcc/10, link->conf.Vcc%10); 391 if (link->conf.Vpp)
413 if (link->conf.Vpp1) 392 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
414 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
415 if (link->conf.Attributes & CONF_ENABLE_IRQ) 393 if (link->conf.Attributes & CONF_ENABLE_IRQ)
416 printk(", irq %d", link->irq.AssignedIRQ); 394 printk(", irq %d", link->irq.AssignedIRQ);
417 if (link->io.NumPorts1) 395 if (link->io.NumPorts1)
@@ -424,8 +402,6 @@ static void sedlbauer_config(dev_link_t *link)
424 printk(", mem 0x%06lx-0x%06lx", req.Base, 402 printk(", mem 0x%06lx-0x%06lx", req.Base,
425 req.Base+req.Size-1); 403 req.Base+req.Size-1);
426 printk("\n"); 404 printk("\n");
427
428 link->state &= ~DEV_CONFIG_PENDING;
429 405
430 icard.para[0] = link->irq.AssignedIRQ; 406 icard.para[0] = link->irq.AssignedIRQ;
431 icard.para[1] = link->io.BasePort1; 407 icard.para[1] = link->io.BasePort1;
@@ -437,14 +413,16 @@ static void sedlbauer_config(dev_link_t *link)
437 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n", 413 printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
438 last_ret, link->io.BasePort1); 414 last_ret, link->io.BasePort1);
439 sedlbauer_release(link); 415 sedlbauer_release(link);
416 return -ENODEV;
440 } else 417 } else
441 ((local_info_t*)link->priv)->cardnr = last_ret; 418 ((local_info_t*)link->priv)->cardnr = last_ret;
442 419
443 return; 420 return 0;
444 421
445cs_failed: 422cs_failed:
446 cs_error(link->handle, last_fn, last_ret); 423 cs_error(link, last_fn, last_ret);
447 sedlbauer_release(link); 424 sedlbauer_release(link);
425 return -ENODEV;
448 426
449} /* sedlbauer_config */ 427} /* sedlbauer_config */
450 428
@@ -456,7 +434,7 @@ cs_failed:
456 434
457======================================================================*/ 435======================================================================*/
458 436
459static void sedlbauer_release(dev_link_t *link) 437static void sedlbauer_release(struct pcmcia_device *link)
460{ 438{
461 local_info_t *local = link->priv; 439 local_info_t *local = link->priv;
462 DEBUG(0, "sedlbauer_release(0x%p)\n", link); 440 DEBUG(0, "sedlbauer_release(0x%p)\n", link);
@@ -467,46 +445,23 @@ static void sedlbauer_release(dev_link_t *link)
467 HiSax_closecard(local->cardnr); 445 HiSax_closecard(local->cardnr);
468 } 446 }
469 } 447 }
470 /* Unlink the device chain */
471 link->dev = NULL;
472 448
473 /* 449 pcmcia_disable_device(link);
474 In a normal driver, additional code may be needed to release
475 other kernel data structures associated with this device.
476 */
477
478 /* Don't bother checking to see if these succeed or not */
479 if (link->win)
480 pcmcia_release_window(link->win);
481 pcmcia_release_configuration(link->handle);
482 if (link->io.NumPorts1)
483 pcmcia_release_io(link->handle, &link->io);
484 if (link->irq.AssignedIRQ)
485 pcmcia_release_irq(link->handle, &link->irq);
486 link->state &= ~DEV_CONFIG;
487} /* sedlbauer_release */ 450} /* sedlbauer_release */
488 451
489static int sedlbauer_suspend(struct pcmcia_device *p_dev) 452static int sedlbauer_suspend(struct pcmcia_device *link)
490{ 453{
491 dev_link_t *link = dev_to_instance(p_dev);
492 local_info_t *dev = link->priv; 454 local_info_t *dev = link->priv;
493 455
494 link->state |= DEV_SUSPEND;
495 dev->stop = 1; 456 dev->stop = 1;
496 if (link->state & DEV_CONFIG)
497 pcmcia_release_configuration(link->handle);
498 457
499 return 0; 458 return 0;
500} 459}
501 460
502static int sedlbauer_resume(struct pcmcia_device *p_dev) 461static int sedlbauer_resume(struct pcmcia_device *link)
503{ 462{
504 dev_link_t *link = dev_to_instance(p_dev);
505 local_info_t *dev = link->priv; 463 local_info_t *dev = link->priv;
506 464
507 link->state &= ~DEV_SUSPEND;
508 if (link->state & DEV_CONFIG)
509 pcmcia_request_configuration(link->handle, &link->conf);
510 dev->stop = 0; 465 dev->stop = 0;
511 466
512 return 0; 467 return 0;
@@ -530,7 +485,7 @@ static struct pcmcia_driver sedlbauer_driver = {
530 .drv = { 485 .drv = {
531 .name = "sedlbauer_cs", 486 .name = "sedlbauer_cs",
532 }, 487 },
533 .probe = sedlbauer_attach, 488 .probe = sedlbauer_probe,
534 .remove = sedlbauer_detach, 489 .remove = sedlbauer_detach,
535 .id_table = sedlbauer_ids, 490 .id_table = sedlbauer_ids,
536 .suspend = sedlbauer_suspend, 491 .suspend = sedlbauer_suspend,
diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c
index 4e5c14c7240e..afcc2aeadb34 100644
--- a/drivers/isdn/hisax/teles_cs.c
+++ b/drivers/isdn/hisax/teles_cs.c
@@ -75,8 +75,8 @@ module_param(protocol, int, 0);
75 handler. 75 handler.
76*/ 76*/
77 77
78static void teles_cs_config(dev_link_t *link); 78static int teles_cs_config(struct pcmcia_device *link);
79static void teles_cs_release(dev_link_t *link); 79static void teles_cs_release(struct pcmcia_device *link);
80 80
81/* 81/*
82 The attach() and detach() entry points are used to create and destroy 82 The attach() and detach() entry points are used to create and destroy
@@ -89,10 +89,10 @@ static void teles_detach(struct pcmcia_device *p_dev);
89/* 89/*
90 A linked list of "instances" of the teles_cs device. Each actual 90 A linked list of "instances" of the teles_cs device. Each actual
91 PCMCIA card corresponds to one device instance, and is described 91 PCMCIA card corresponds to one device instance, and is described
92 by one dev_link_t structure (defined in ds.h). 92 by one struct pcmcia_device structure (defined in ds.h).
93 93
94 You may not want to use a linked list for this -- for example, the 94 You may not want to use a linked list for this -- for example, the
95 memory card driver uses an array of dev_link_t pointers, where minor 95 memory card driver uses an array of struct pcmcia_device pointers, where minor
96 device numbers are used to derive the corresponding array index. 96 device numbers are used to derive the corresponding array index.
97*/ 97*/
98 98
@@ -102,7 +102,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
102 example, ethernet cards, modems). In other cases, there may be 102 example, ethernet cards, modems). In other cases, there may be
103 many actual or logical devices (SCSI adapters, memory cards with 103 many actual or logical devices (SCSI adapters, memory cards with
104 multiple partitions). The dev_node_t structures need to be kept 104 multiple partitions). The dev_node_t structures need to be kept
105 in a linked list starting at the 'dev' field of a dev_link_t 105 in a linked list starting at the 'dev' field of a struct pcmcia_device
106 structure. We allocate them in the card's private data structure, 106 structure. We allocate them in the card's private data structure,
107 because they generally shouldn't be allocated dynamically. 107 because they generally shouldn't be allocated dynamically.
108 In this case, we also provide a flag to indicate if a device is 108 In this case, we also provide a flag to indicate if a device is
@@ -112,7 +112,7 @@ static void teles_detach(struct pcmcia_device *p_dev);
112*/ 112*/
113 113
114typedef struct local_info_t { 114typedef struct local_info_t {
115 dev_link_t link; 115 struct pcmcia_device *p_dev;
116 dev_node_t node; 116 dev_node_t node;
117 int busy; 117 int busy;
118 int cardnr; 118 int cardnr;
@@ -130,9 +130,8 @@ typedef struct local_info_t {
130 130
131======================================================================*/ 131======================================================================*/
132 132
133static int teles_attach(struct pcmcia_device *p_dev) 133static int teles_probe(struct pcmcia_device *link)
134{ 134{
135 dev_link_t *link;
136 local_info_t *local; 135 local_info_t *local;
137 136
138 DEBUG(0, "teles_attach()\n"); 137 DEBUG(0, "teles_attach()\n");
@@ -142,7 +141,9 @@ static int teles_attach(struct pcmcia_device *p_dev)
142 if (!local) return -ENOMEM; 141 if (!local) return -ENOMEM;
143 memset(local, 0, sizeof(local_info_t)); 142 memset(local, 0, sizeof(local_info_t));
144 local->cardnr = -1; 143 local->cardnr = -1;
145 link = &local->link; link->priv = local; 144
145 local->p_dev = link;
146 link->priv = local;
146 147
147 /* Interrupt setup */ 148 /* Interrupt setup */
148 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 149 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
@@ -161,16 +162,9 @@ static int teles_attach(struct pcmcia_device *p_dev)
161 link->io.IOAddrLines = 5; 162 link->io.IOAddrLines = 5;
162 163
163 link->conf.Attributes = CONF_ENABLE_IRQ; 164 link->conf.Attributes = CONF_ENABLE_IRQ;
164 link->conf.Vcc = 50;
165 link->conf.IntType = INT_MEMORY_AND_IO; 165 link->conf.IntType = INT_MEMORY_AND_IO;
166 166
167 link->handle = p_dev; 167 return teles_cs_config(link);
168 p_dev->instance = link;
169
170 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
171 teles_cs_config(link);
172
173 return 0;
174} /* teles_attach */ 168} /* teles_attach */
175 169
176/*====================================================================== 170/*======================================================================
@@ -182,20 +176,16 @@ static int teles_attach(struct pcmcia_device *p_dev)
182 176
183======================================================================*/ 177======================================================================*/
184 178
185static void teles_detach(struct pcmcia_device *p_dev) 179static void teles_detach(struct pcmcia_device *link)
186{ 180{
187 dev_link_t *link = dev_to_instance(p_dev); 181 local_info_t *info = link->priv;
188 local_info_t *info = link->priv;
189
190 DEBUG(0, "teles_detach(0x%p)\n", link);
191 182
192 if (link->state & DEV_CONFIG) { 183 DEBUG(0, "teles_detach(0x%p)\n", link);
193 info->busy = 1;
194 teles_cs_release(link);
195 }
196 184
197 kfree(info); 185 info->busy = 1;
186 teles_cs_release(link);
198 187
188 kfree(info);
199} /* teles_detach */ 189} /* teles_detach */
200 190
201/*====================================================================== 191/*======================================================================
@@ -205,7 +195,7 @@ static void teles_detach(struct pcmcia_device *p_dev)
205 device available to the system. 195 device available to the system.
206 196
207======================================================================*/ 197======================================================================*/
208static int get_tuple(client_handle_t handle, tuple_t *tuple, 198static int get_tuple(struct pcmcia_device *handle, tuple_t *tuple,
209 cisparse_t *parse) 199 cisparse_t *parse)
210{ 200{
211 int i = pcmcia_get_tuple_data(handle, tuple); 201 int i = pcmcia_get_tuple_data(handle, tuple);
@@ -213,7 +203,7 @@ static int get_tuple(client_handle_t handle, tuple_t *tuple,
213 return pcmcia_parse_tuple(handle, tuple, parse); 203 return pcmcia_parse_tuple(handle, tuple, parse);
214} 204}
215 205
216static int first_tuple(client_handle_t handle, tuple_t *tuple, 206static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
217 cisparse_t *parse) 207 cisparse_t *parse)
218{ 208{
219 int i = pcmcia_get_first_tuple(handle, tuple); 209 int i = pcmcia_get_first_tuple(handle, tuple);
@@ -221,7 +211,7 @@ static int first_tuple(client_handle_t handle, tuple_t *tuple,
221 return get_tuple(handle, tuple, parse); 211 return get_tuple(handle, tuple, parse);
222} 212}
223 213
224static int next_tuple(client_handle_t handle, tuple_t *tuple, 214static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
225 cisparse_t *parse) 215 cisparse_t *parse)
226{ 216{
227 int i = pcmcia_get_next_tuple(handle, tuple); 217 int i = pcmcia_get_next_tuple(handle, tuple);
@@ -229,9 +219,8 @@ static int next_tuple(client_handle_t handle, tuple_t *tuple,
229 return get_tuple(handle, tuple, parse); 219 return get_tuple(handle, tuple, parse);
230} 220}
231 221
232static void teles_cs_config(dev_link_t *link) 222static int teles_cs_config(struct pcmcia_device *link)
233{ 223{
234 client_handle_t handle;
235 tuple_t tuple; 224 tuple_t tuple;
236 cisparse_t parse; 225 cisparse_t parse;
237 local_info_t *dev; 226 local_info_t *dev;
@@ -241,7 +230,6 @@ static void teles_cs_config(dev_link_t *link)
241 IsdnCard_t icard; 230 IsdnCard_t icard;
242 231
243 DEBUG(0, "teles_config(0x%p)\n", link); 232 DEBUG(0, "teles_config(0x%p)\n", link);
244 handle = link->handle;
245 dev = link->priv; 233 dev = link->priv;
246 234
247 /* 235 /*
@@ -253,7 +241,7 @@ static void teles_cs_config(dev_link_t *link)
253 tuple.TupleDataMax = 255; 241 tuple.TupleDataMax = 255;
254 tuple.TupleOffset = 0; 242 tuple.TupleOffset = 0;
255 tuple.Attributes = 0; 243 tuple.Attributes = 0;
256 i = first_tuple(handle, &tuple, &parse); 244 i = first_tuple(link, &tuple, &parse);
257 if (i != CS_SUCCESS) { 245 if (i != CS_SUCCESS) {
258 last_fn = ParseTuple; 246 last_fn = ParseTuple;
259 goto cs_failed; 247 goto cs_failed;
@@ -261,32 +249,29 @@ static void teles_cs_config(dev_link_t *link)
261 link->conf.ConfigBase = parse.config.base; 249 link->conf.ConfigBase = parse.config.base;
262 link->conf.Present = parse.config.rmask[0]; 250 link->conf.Present = parse.config.rmask[0];
263 251
264 /* Configure card */
265 link->state |= DEV_CONFIG;
266
267 tuple.TupleData = (cisdata_t *)buf; 252 tuple.TupleData = (cisdata_t *)buf;
268 tuple.TupleOffset = 0; tuple.TupleDataMax = 255; 253 tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
269 tuple.Attributes = 0; 254 tuple.Attributes = 0;
270 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 255 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
271 i = first_tuple(handle, &tuple, &parse); 256 i = first_tuple(link, &tuple, &parse);
272 while (i == CS_SUCCESS) { 257 while (i == CS_SUCCESS) {
273 if ( (cf->io.nwin > 0) && cf->io.win[0].base) { 258 if ( (cf->io.nwin > 0) && cf->io.win[0].base) {
274 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n"); 259 printk(KERN_INFO "(teles_cs: looks like the 96 model)\n");
275 link->conf.ConfigIndex = cf->index; 260 link->conf.ConfigIndex = cf->index;
276 link->io.BasePort1 = cf->io.win[0].base; 261 link->io.BasePort1 = cf->io.win[0].base;
277 i = pcmcia_request_io(link->handle, &link->io); 262 i = pcmcia_request_io(link, &link->io);
278 if (i == CS_SUCCESS) break; 263 if (i == CS_SUCCESS) break;
279 } else { 264 } else {
280 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n"); 265 printk(KERN_INFO "(teles_cs: looks like the 97 model)\n");
281 link->conf.ConfigIndex = cf->index; 266 link->conf.ConfigIndex = cf->index;
282 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { 267 for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) {
283 link->io.BasePort1 = j; 268 link->io.BasePort1 = j;
284 i = pcmcia_request_io(link->handle, &link->io); 269 i = pcmcia_request_io(link, &link->io);
285 if (i == CS_SUCCESS) break; 270 if (i == CS_SUCCESS) break;
286 } 271 }
287 break; 272 break;
288 } 273 }
289 i = next_tuple(handle, &tuple, &parse); 274 i = next_tuple(link, &tuple, &parse);
290 } 275 }
291 276
292 if (i != CS_SUCCESS) { 277 if (i != CS_SUCCESS) {
@@ -294,14 +279,14 @@ static void teles_cs_config(dev_link_t *link)
294 goto cs_failed; 279 goto cs_failed;
295 } 280 }
296 281
297 i = pcmcia_request_irq(link->handle, &link->irq); 282 i = pcmcia_request_irq(link, &link->irq);
298 if (i != CS_SUCCESS) { 283 if (i != CS_SUCCESS) {
299 link->irq.AssignedIRQ = 0; 284 link->irq.AssignedIRQ = 0;
300 last_fn = RequestIRQ; 285 last_fn = RequestIRQ;
301 goto cs_failed; 286 goto cs_failed;
302 } 287 }
303 288
304 i = pcmcia_request_configuration(link->handle, &link->conf); 289 i = pcmcia_request_configuration(link, &link->conf);
305 if (i != CS_SUCCESS) { 290 if (i != CS_SUCCESS) {
306 last_fn = RequestConfiguration; 291 last_fn = RequestConfiguration;
307 goto cs_failed; 292 goto cs_failed;
@@ -312,14 +297,11 @@ static void teles_cs_config(dev_link_t *link)
312 sprintf(dev->node.dev_name, "teles"); 297 sprintf(dev->node.dev_name, "teles");
313 dev->node.major = dev->node.minor = 0x0; 298 dev->node.major = dev->node.minor = 0x0;
314 299
315 link->dev = &dev->node; 300 link->dev_node = &dev->node;
316 301
317 /* Finally, report what we've done */ 302 /* Finally, report what we've done */
318 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 303 printk(KERN_INFO "%s: index 0x%02x:",
319 dev->node.dev_name, link->conf.ConfigIndex, 304 dev->node.dev_name, link->conf.ConfigIndex);
320 link->conf.Vcc/10, link->conf.Vcc%10);
321 if (link->conf.Vpp1)
322 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
323 if (link->conf.Attributes & CONF_ENABLE_IRQ) 305 if (link->conf.Attributes & CONF_ENABLE_IRQ)
324 printk(", irq %d", link->irq.AssignedIRQ); 306 printk(", irq %d", link->irq.AssignedIRQ);
325 if (link->io.NumPorts1) 307 if (link->io.NumPorts1)
@@ -330,8 +312,6 @@ static void teles_cs_config(dev_link_t *link)
330 link->io.BasePort2+link->io.NumPorts2-1); 312 link->io.BasePort2+link->io.NumPorts2-1);
331 printk("\n"); 313 printk("\n");
332 314
333 link->state &= ~DEV_CONFIG_PENDING;
334
335 icard.para[0] = link->irq.AssignedIRQ; 315 icard.para[0] = link->irq.AssignedIRQ;
336 icard.para[1] = link->io.BasePort1; 316 icard.para[1] = link->io.BasePort1;
337 icard.protocol = protocol; 317 icard.protocol = protocol;
@@ -342,13 +322,16 @@ static void teles_cs_config(dev_link_t *link)
342 printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n", 322 printk(KERN_ERR "teles_cs: failed to initialize Teles PCMCIA %d at i/o %#x\n",
343 i, link->io.BasePort1); 323 i, link->io.BasePort1);
344 teles_cs_release(link); 324 teles_cs_release(link);
345 } else 325 return -ENODEV;
346 ((local_info_t*)link->priv)->cardnr = i; 326 }
327
328 ((local_info_t*)link->priv)->cardnr = i;
329 return 0;
347 330
348 return;
349cs_failed: 331cs_failed:
350 cs_error(link->handle, last_fn, i); 332 cs_error(link, last_fn, i);
351 teles_cs_release(link); 333 teles_cs_release(link);
334 return -ENODEV;
352} /* teles_cs_config */ 335} /* teles_cs_config */
353 336
354/*====================================================================== 337/*======================================================================
@@ -359,7 +342,7 @@ cs_failed:
359 342
360======================================================================*/ 343======================================================================*/
361 344
362static void teles_cs_release(dev_link_t *link) 345static void teles_cs_release(struct pcmcia_device *link)
363{ 346{
364 local_info_t *local = link->priv; 347 local_info_t *local = link->priv;
365 348
@@ -371,39 +354,23 @@ static void teles_cs_release(dev_link_t *link)
371 HiSax_closecard(local->cardnr); 354 HiSax_closecard(local->cardnr);
372 } 355 }
373 } 356 }
374 /* Unlink the device chain */ 357
375 link->dev = NULL; 358 pcmcia_disable_device(link);
376
377 /* Don't bother checking to see if these succeed or not */
378 if (link->win)
379 pcmcia_release_window(link->win);
380 pcmcia_release_configuration(link->handle);
381 pcmcia_release_io(link->handle, &link->io);
382 pcmcia_release_irq(link->handle, &link->irq);
383 link->state &= ~DEV_CONFIG;
384} /* teles_cs_release */ 359} /* teles_cs_release */
385 360
386static int teles_suspend(struct pcmcia_device *p_dev) 361static int teles_suspend(struct pcmcia_device *link)
387{ 362{
388 dev_link_t *link = dev_to_instance(p_dev);
389 local_info_t *dev = link->priv; 363 local_info_t *dev = link->priv;
390 364
391 link->state |= DEV_SUSPEND;
392 dev->busy = 1; 365 dev->busy = 1;
393 if (link->state & DEV_CONFIG)
394 pcmcia_release_configuration(link->handle);
395 366
396 return 0; 367 return 0;
397} 368}
398 369
399static int teles_resume(struct pcmcia_device *p_dev) 370static int teles_resume(struct pcmcia_device *link)
400{ 371{
401 dev_link_t *link = dev_to_instance(p_dev);
402 local_info_t *dev = link->priv; 372 local_info_t *dev = link->priv;
403 373
404 link->state &= ~DEV_SUSPEND;
405 if (link->state & DEV_CONFIG)
406 pcmcia_request_configuration(link->handle, &link->conf);
407 dev->busy = 0; 374 dev->busy = 0;
408 375
409 return 0; 376 return 0;
@@ -421,7 +388,7 @@ static struct pcmcia_driver teles_cs_driver = {
421 .drv = { 388 .drv = {
422 .name = "teles_cs", 389 .name = "teles_cs",
423 }, 390 },
424 .probe = teles_attach, 391 .probe = teles_probe,
425 .remove = teles_detach, 392 .remove = teles_detach,
426 .id_table = teles_ids, 393 .id_table = teles_ids,
427 .suspend = teles_suspend, 394 .suspend = teles_suspend,