aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/hisax/sedlbauer_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/isdn/hisax/sedlbauer_cs.c')
-rw-r--r--drivers/isdn/hisax/sedlbauer_cs.c143
1 files changed, 49 insertions, 94 deletions
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,