diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 19:18:30 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-02-27 19:18:30 -0500 |
commit | 8d37a371b6869920e6c40c495c68eabba1ef3909 (patch) | |
tree | dad784512b13832f4f5494cfe0791965c6a2b0f6 /drivers/pcmcia/ds.c | |
parent | ef1a8de8ea004a689b2aa9f5cefcba2b1a0262f2 (diff) | |
parent | 7b4884ca8853a638df0eb5d251d80d67777b8b1a (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: (49 commits)
pcmcia: validate late-added resources
pcmcia: allow for extension of resource interval
pcmcia: remove useless msleep in ds.c
pcmcia: use read_cis_mem return value
pcmcia: handle error in serial_cs config calls
pcmcia: add locking to pcmcia_{read,write}_cis_mem
pcmcia: avoid prod_id memleak
pcmcia: avoid sysfs-related lockup for cardbus
pcmcia: use state machine for extended requery
pcmcia: delay re-scanning and re-querying of PCMCIA bus
pcmcia: use pccardd to handle eject, insert, suspend and resume requests
pcmcia: use ops_mutex for rsrc_{mgr,nonstatic} locking
pcmcia: use mutex for dynid lock
pcmcia: assert locking to struct pcmcia_device
pcmcia: add locking documentation
pcmcia: simplify locking
pcmcia: add locking to struct pcmcia_socket->pcmcia_state()
pcmcia: protect s->device_count
pcmcia: properly lock skt->irq, skt->irq_mask
pcmcia: lock ops->set_socket
...
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 333 |
1 files changed, 190 insertions, 143 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 1a4a3c49cc15..0f98be4450b7 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -42,8 +42,6 @@ MODULE_DESCRIPTION("PCMCIA Driver Services"); | |||
42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
43 | 43 | ||
44 | 44 | ||
45 | spinlock_t pcmcia_dev_list_lock; | ||
46 | |||
47 | /*====================================================================*/ | 45 | /*====================================================================*/ |
48 | 46 | ||
49 | static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | 47 | static void pcmcia_check_driver(struct pcmcia_driver *p_drv) |
@@ -126,9 +124,9 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) | |||
126 | dynid->id.device_no = device_no; | 124 | dynid->id.device_no = device_no; |
127 | memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4); | 125 | memcpy(dynid->id.prod_id_hash, prod_id_hash, sizeof(__u32) * 4); |
128 | 126 | ||
129 | spin_lock(&pdrv->dynids.lock); | 127 | mutex_lock(&pdrv->dynids.lock); |
130 | list_add_tail(&dynid->node, &pdrv->dynids.list); | 128 | list_add_tail(&dynid->node, &pdrv->dynids.list); |
131 | spin_unlock(&pdrv->dynids.lock); | 129 | mutex_unlock(&pdrv->dynids.lock); |
132 | 130 | ||
133 | if (get_driver(&pdrv->drv)) { | 131 | if (get_driver(&pdrv->drv)) { |
134 | retval = driver_attach(&pdrv->drv); | 132 | retval = driver_attach(&pdrv->drv); |
@@ -146,12 +144,12 @@ pcmcia_free_dynids(struct pcmcia_driver *drv) | |||
146 | { | 144 | { |
147 | struct pcmcia_dynid *dynid, *n; | 145 | struct pcmcia_dynid *dynid, *n; |
148 | 146 | ||
149 | spin_lock(&drv->dynids.lock); | 147 | mutex_lock(&drv->dynids.lock); |
150 | list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { | 148 | list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { |
151 | list_del(&dynid->node); | 149 | list_del(&dynid->node); |
152 | kfree(dynid); | 150 | kfree(dynid); |
153 | } | 151 | } |
154 | spin_unlock(&drv->dynids.lock); | 152 | mutex_unlock(&drv->dynids.lock); |
155 | } | 153 | } |
156 | 154 | ||
157 | static int | 155 | static int |
@@ -182,7 +180,7 @@ int pcmcia_register_driver(struct pcmcia_driver *driver) | |||
182 | /* initialize common fields */ | 180 | /* initialize common fields */ |
183 | driver->drv.bus = &pcmcia_bus_type; | 181 | driver->drv.bus = &pcmcia_bus_type; |
184 | driver->drv.owner = driver->owner; | 182 | driver->drv.owner = driver->owner; |
185 | spin_lock_init(&driver->dynids.lock); | 183 | mutex_init(&driver->dynids.lock); |
186 | INIT_LIST_HEAD(&driver->dynids.list); | 184 | INIT_LIST_HEAD(&driver->dynids.list); |
187 | 185 | ||
188 | pr_debug("registering driver %s\n", driver->drv.name); | 186 | pr_debug("registering driver %s\n", driver->drv.name); |
@@ -239,30 +237,21 @@ static void pcmcia_release_function(struct kref *ref) | |||
239 | static void pcmcia_release_dev(struct device *dev) | 237 | static void pcmcia_release_dev(struct device *dev) |
240 | { | 238 | { |
241 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 239 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
240 | int i; | ||
242 | dev_dbg(dev, "releasing device\n"); | 241 | dev_dbg(dev, "releasing device\n"); |
243 | pcmcia_put_socket(p_dev->socket); | 242 | pcmcia_put_socket(p_dev->socket); |
243 | for (i = 0; i < 4; i++) | ||
244 | kfree(p_dev->prod_id[i]); | ||
244 | kfree(p_dev->devname); | 245 | kfree(p_dev->devname); |
245 | kref_put(&p_dev->function_config->ref, pcmcia_release_function); | 246 | kref_put(&p_dev->function_config->ref, pcmcia_release_function); |
246 | kfree(p_dev); | 247 | kfree(p_dev); |
247 | } | 248 | } |
248 | 249 | ||
249 | static void pcmcia_add_device_later(struct pcmcia_socket *s, int mfc) | ||
250 | { | ||
251 | if (!s->pcmcia_state.device_add_pending) { | ||
252 | dev_dbg(&s->dev, "scheduling to add %s secondary" | ||
253 | " device to %d\n", mfc ? "mfc" : "pfc", s->sock); | ||
254 | s->pcmcia_state.device_add_pending = 1; | ||
255 | s->pcmcia_state.mfc_pfc = mfc; | ||
256 | schedule_work(&s->device_add); | ||
257 | } | ||
258 | return; | ||
259 | } | ||
260 | 250 | ||
261 | static int pcmcia_device_probe(struct device *dev) | 251 | static int pcmcia_device_probe(struct device *dev) |
262 | { | 252 | { |
263 | struct pcmcia_device *p_dev; | 253 | struct pcmcia_device *p_dev; |
264 | struct pcmcia_driver *p_drv; | 254 | struct pcmcia_driver *p_drv; |
265 | struct pcmcia_device_id *did; | ||
266 | struct pcmcia_socket *s; | 255 | struct pcmcia_socket *s; |
267 | cistpl_config_t cis_config; | 256 | cistpl_config_t cis_config; |
268 | int ret = 0; | 257 | int ret = 0; |
@@ -275,18 +264,6 @@ static int pcmcia_device_probe(struct device *dev) | |||
275 | p_drv = to_pcmcia_drv(dev->driver); | 264 | p_drv = to_pcmcia_drv(dev->driver); |
276 | s = p_dev->socket; | 265 | s = p_dev->socket; |
277 | 266 | ||
278 | /* The PCMCIA code passes the match data in via dev_set_drvdata(dev) | ||
279 | * which is an ugly hack. Once the driver probe is called it may | ||
280 | * and often will overwrite the match data so we must save it first | ||
281 | * | ||
282 | * handle pseudo multifunction devices: | ||
283 | * there are at most two pseudo multifunction devices. | ||
284 | * if we're matching against the first, schedule a | ||
285 | * call which will then check whether there are two | ||
286 | * pseudo devices, and if not, add the second one. | ||
287 | */ | ||
288 | did = dev_get_drvdata(&p_dev->dev); | ||
289 | |||
290 | dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); | 267 | dev_dbg(dev, "trying to bind to %s\n", p_drv->drv.name); |
291 | 268 | ||
292 | if ((!p_drv->probe) || (!p_dev->function_config) || | 269 | if ((!p_drv->probe) || (!p_dev->function_config) || |
@@ -315,9 +292,11 @@ static int pcmcia_device_probe(struct device *dev) | |||
315 | goto put_module; | 292 | goto put_module; |
316 | } | 293 | } |
317 | 294 | ||
318 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 295 | mutex_lock(&s->ops_mutex); |
296 | if ((s->pcmcia_state.has_pfc) && | ||
319 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | 297 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) |
320 | pcmcia_add_device_later(p_dev->socket, 0); | 298 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY); |
299 | mutex_unlock(&s->ops_mutex); | ||
321 | 300 | ||
322 | put_module: | 301 | put_module: |
323 | if (ret) | 302 | if (ret) |
@@ -336,26 +315,27 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
336 | { | 315 | { |
337 | struct pcmcia_device *p_dev; | 316 | struct pcmcia_device *p_dev; |
338 | struct pcmcia_device *tmp; | 317 | struct pcmcia_device *tmp; |
339 | unsigned long flags; | ||
340 | 318 | ||
341 | dev_dbg(leftover ? &leftover->dev : &s->dev, | 319 | dev_dbg(leftover ? &leftover->dev : &s->dev, |
342 | "pcmcia_card_remove(%d) %s\n", s->sock, | 320 | "pcmcia_card_remove(%d) %s\n", s->sock, |
343 | leftover ? leftover->devname : ""); | 321 | leftover ? leftover->devname : ""); |
344 | 322 | ||
323 | mutex_lock(&s->ops_mutex); | ||
345 | if (!leftover) | 324 | if (!leftover) |
346 | s->device_count = 0; | 325 | s->device_count = 0; |
347 | else | 326 | else |
348 | s->device_count = 1; | 327 | s->device_count = 1; |
328 | mutex_unlock(&s->ops_mutex); | ||
349 | 329 | ||
350 | /* unregister all pcmcia_devices registered with this socket, except leftover */ | 330 | /* unregister all pcmcia_devices registered with this socket, except leftover */ |
351 | list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { | 331 | list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { |
352 | if (p_dev == leftover) | 332 | if (p_dev == leftover) |
353 | continue; | 333 | continue; |
354 | 334 | ||
355 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 335 | mutex_lock(&s->ops_mutex); |
356 | list_del(&p_dev->socket_device_list); | 336 | list_del(&p_dev->socket_device_list); |
357 | p_dev->_removed = 1; | 337 | p_dev->_removed = 1; |
358 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 338 | mutex_unlock(&s->ops_mutex); |
359 | 339 | ||
360 | dev_dbg(&p_dev->dev, "unregistering device\n"); | 340 | dev_dbg(&p_dev->dev, "unregistering device\n"); |
361 | device_unregister(&p_dev->dev); | 341 | device_unregister(&p_dev->dev); |
@@ -368,7 +348,6 @@ static int pcmcia_device_remove(struct device *dev) | |||
368 | { | 348 | { |
369 | struct pcmcia_device *p_dev; | 349 | struct pcmcia_device *p_dev; |
370 | struct pcmcia_driver *p_drv; | 350 | struct pcmcia_driver *p_drv; |
371 | struct pcmcia_device_id *did; | ||
372 | int i; | 351 | int i; |
373 | 352 | ||
374 | p_dev = to_pcmcia_dev(dev); | 353 | p_dev = to_pcmcia_dev(dev); |
@@ -380,9 +359,8 @@ static int pcmcia_device_remove(struct device *dev) | |||
380 | * pseudo multi-function card, we need to unbind | 359 | * pseudo multi-function card, we need to unbind |
381 | * all devices | 360 | * all devices |
382 | */ | 361 | */ |
383 | did = dev_get_drvdata(&p_dev->dev); | 362 | if ((p_dev->socket->pcmcia_state.has_pfc) && |
384 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 363 | (p_dev->socket->device_count > 0) && |
385 | (p_dev->socket->device_count != 0) && | ||
386 | (p_dev->device_no == 0)) | 364 | (p_dev->device_no == 0)) |
387 | pcmcia_card_remove(p_dev->socket, p_dev); | 365 | pcmcia_card_remove(p_dev->socket, p_dev); |
388 | 366 | ||
@@ -431,16 +409,20 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
431 | 409 | ||
432 | if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, | 410 | if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, |
433 | CISTPL_MANFID, &manf_id)) { | 411 | CISTPL_MANFID, &manf_id)) { |
412 | mutex_lock(&p_dev->socket->ops_mutex); | ||
434 | p_dev->manf_id = manf_id.manf; | 413 | p_dev->manf_id = manf_id.manf; |
435 | p_dev->card_id = manf_id.card; | 414 | p_dev->card_id = manf_id.card; |
436 | p_dev->has_manf_id = 1; | 415 | p_dev->has_manf_id = 1; |
437 | p_dev->has_card_id = 1; | 416 | p_dev->has_card_id = 1; |
417 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
438 | } | 418 | } |
439 | 419 | ||
440 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, | 420 | if (!pccard_read_tuple(p_dev->socket, p_dev->func, |
441 | CISTPL_FUNCID, &func_id)) { | 421 | CISTPL_FUNCID, &func_id)) { |
422 | mutex_lock(&p_dev->socket->ops_mutex); | ||
442 | p_dev->func_id = func_id.func; | 423 | p_dev->func_id = func_id.func; |
443 | p_dev->has_func_id = 1; | 424 | p_dev->has_func_id = 1; |
425 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
444 | } else { | 426 | } else { |
445 | /* rule of thumb: cards with no FUNCID, but with | 427 | /* rule of thumb: cards with no FUNCID, but with |
446 | * common memory device geometry information, are | 428 | * common memory device geometry information, are |
@@ -457,17 +439,21 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
457 | dev_dbg(&p_dev->dev, | 439 | dev_dbg(&p_dev->dev, |
458 | "mem device geometry probably means " | 440 | "mem device geometry probably means " |
459 | "FUNCID_MEMORY\n"); | 441 | "FUNCID_MEMORY\n"); |
442 | mutex_lock(&p_dev->socket->ops_mutex); | ||
460 | p_dev->func_id = CISTPL_FUNCID_MEMORY; | 443 | p_dev->func_id = CISTPL_FUNCID_MEMORY; |
461 | p_dev->has_func_id = 1; | 444 | p_dev->has_func_id = 1; |
445 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
462 | } | 446 | } |
463 | kfree(devgeo); | 447 | kfree(devgeo); |
464 | } | 448 | } |
465 | 449 | ||
466 | if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1, | 450 | if (!pccard_read_tuple(p_dev->socket, BIND_FN_ALL, CISTPL_VERS_1, |
467 | vers1)) { | 451 | vers1)) { |
452 | mutex_lock(&p_dev->socket->ops_mutex); | ||
468 | for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) { | 453 | for (i = 0; i < min_t(unsigned int, 4, vers1->ns); i++) { |
469 | char *tmp; | 454 | char *tmp; |
470 | unsigned int length; | 455 | unsigned int length; |
456 | char *new; | ||
471 | 457 | ||
472 | tmp = vers1->str + vers1->ofs[i]; | 458 | tmp = vers1->str + vers1->ofs[i]; |
473 | 459 | ||
@@ -475,14 +461,17 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
475 | if ((length < 2) || (length > 255)) | 461 | if ((length < 2) || (length > 255)) |
476 | continue; | 462 | continue; |
477 | 463 | ||
478 | p_dev->prod_id[i] = kmalloc(sizeof(char) * length, | 464 | new = kmalloc(sizeof(char) * length, GFP_KERNEL); |
479 | GFP_KERNEL); | 465 | if (!new) |
480 | if (!p_dev->prod_id[i]) | ||
481 | continue; | 466 | continue; |
482 | 467 | ||
483 | p_dev->prod_id[i] = strncpy(p_dev->prod_id[i], | 468 | new = strncpy(new, tmp, length); |
484 | tmp, length); | 469 | |
470 | tmp = p_dev->prod_id[i]; | ||
471 | p_dev->prod_id[i] = new; | ||
472 | kfree(tmp); | ||
485 | } | 473 | } |
474 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
486 | } | 475 | } |
487 | 476 | ||
488 | kfree(vers1); | 477 | kfree(vers1); |
@@ -502,7 +491,7 @@ static DEFINE_MUTEX(device_add_lock); | |||
502 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) | 491 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) |
503 | { | 492 | { |
504 | struct pcmcia_device *p_dev, *tmp_dev; | 493 | struct pcmcia_device *p_dev, *tmp_dev; |
505 | unsigned long flags; | 494 | int i; |
506 | 495 | ||
507 | s = pcmcia_get_socket(s); | 496 | s = pcmcia_get_socket(s); |
508 | if (!s) | 497 | if (!s) |
@@ -512,16 +501,19 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
512 | 501 | ||
513 | pr_debug("adding device to %d, function %d\n", s->sock, function); | 502 | pr_debug("adding device to %d, function %d\n", s->sock, function); |
514 | 503 | ||
515 | /* max of 4 devices per card */ | ||
516 | if (s->device_count == 4) | ||
517 | goto err_put; | ||
518 | |||
519 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); | 504 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); |
520 | if (!p_dev) | 505 | if (!p_dev) |
521 | goto err_put; | 506 | goto err_put; |
522 | 507 | ||
523 | p_dev->socket = s; | 508 | mutex_lock(&s->ops_mutex); |
524 | p_dev->device_no = (s->device_count++); | 509 | p_dev->device_no = (s->device_count++); |
510 | mutex_unlock(&s->ops_mutex); | ||
511 | |||
512 | /* max of 2 devices per card */ | ||
513 | if (p_dev->device_no >= 2) | ||
514 | goto err_free; | ||
515 | |||
516 | p_dev->socket = s; | ||
525 | p_dev->func = function; | 517 | p_dev->func = function; |
526 | 518 | ||
527 | p_dev->dev.bus = &pcmcia_bus_type; | 519 | p_dev->dev.bus = &pcmcia_bus_type; |
@@ -538,7 +530,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
538 | goto err_free; | 530 | goto err_free; |
539 | dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname); | 531 | dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname); |
540 | 532 | ||
541 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 533 | mutex_lock(&s->ops_mutex); |
542 | 534 | ||
543 | /* | 535 | /* |
544 | * p_dev->function_config must be the same for all card functions. | 536 | * p_dev->function_config must be the same for all card functions. |
@@ -556,7 +548,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
556 | /* Add to the list in pcmcia_bus_socket */ | 548 | /* Add to the list in pcmcia_bus_socket */ |
557 | list_add(&p_dev->socket_device_list, &s->devices_list); | 549 | list_add(&p_dev->socket_device_list, &s->devices_list); |
558 | 550 | ||
559 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 551 | mutex_unlock(&s->ops_mutex); |
560 | 552 | ||
561 | if (!p_dev->function_config) { | 553 | if (!p_dev->function_config) { |
562 | dev_dbg(&p_dev->dev, "creating config_t\n"); | 554 | dev_dbg(&p_dev->dev, "creating config_t\n"); |
@@ -581,14 +573,19 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
581 | return p_dev; | 573 | return p_dev; |
582 | 574 | ||
583 | err_unreg: | 575 | err_unreg: |
584 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 576 | mutex_lock(&s->ops_mutex); |
585 | list_del(&p_dev->socket_device_list); | 577 | list_del(&p_dev->socket_device_list); |
586 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 578 | mutex_unlock(&s->ops_mutex); |
587 | 579 | ||
588 | err_free: | 580 | err_free: |
581 | mutex_lock(&s->ops_mutex); | ||
582 | s->device_count--; | ||
583 | mutex_unlock(&s->ops_mutex); | ||
584 | |||
585 | for (i = 0; i < 4; i++) | ||
586 | kfree(p_dev->prod_id[i]); | ||
589 | kfree(p_dev->devname); | 587 | kfree(p_dev->devname); |
590 | kfree(p_dev); | 588 | kfree(p_dev); |
591 | s->device_count--; | ||
592 | err_put: | 589 | err_put: |
593 | mutex_unlock(&device_add_lock); | 590 | mutex_unlock(&device_add_lock); |
594 | pcmcia_put_socket(s); | 591 | pcmcia_put_socket(s); |
@@ -601,19 +598,23 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
601 | { | 598 | { |
602 | cistpl_longlink_mfc_t mfc; | 599 | cistpl_longlink_mfc_t mfc; |
603 | unsigned int no_funcs, i, no_chains; | 600 | unsigned int no_funcs, i, no_chains; |
604 | int ret = 0; | 601 | int ret = -EAGAIN; |
605 | 602 | ||
603 | mutex_lock(&s->ops_mutex); | ||
606 | if (!(s->resource_setup_done)) { | 604 | if (!(s->resource_setup_done)) { |
607 | dev_dbg(&s->dev, | 605 | dev_dbg(&s->dev, |
608 | "no resources available, delaying card_add\n"); | 606 | "no resources available, delaying card_add\n"); |
607 | mutex_unlock(&s->ops_mutex); | ||
609 | return -EAGAIN; /* try again, but later... */ | 608 | return -EAGAIN; /* try again, but later... */ |
610 | } | 609 | } |
611 | 610 | ||
612 | if (pcmcia_validate_mem(s)) { | 611 | if (pcmcia_validate_mem(s)) { |
613 | dev_dbg(&s->dev, "validating mem resources failed, " | 612 | dev_dbg(&s->dev, "validating mem resources failed, " |
614 | "delaying card_add\n"); | 613 | "delaying card_add\n"); |
614 | mutex_unlock(&s->ops_mutex); | ||
615 | return -EAGAIN; /* try again, but later... */ | 615 | return -EAGAIN; /* try again, but later... */ |
616 | } | 616 | } |
617 | mutex_unlock(&s->ops_mutex); | ||
617 | 618 | ||
618 | ret = pccard_validate_cis(s, &no_chains); | 619 | ret = pccard_validate_cis(s, &no_chains); |
619 | if (ret || !no_chains) { | 620 | if (ret || !no_chains) { |
@@ -634,17 +635,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
634 | } | 635 | } |
635 | 636 | ||
636 | 637 | ||
637 | static void pcmcia_delayed_add_device(struct work_struct *work) | 638 | static int pcmcia_requery_callback(struct device *dev, void * _data) |
638 | { | ||
639 | struct pcmcia_socket *s = | ||
640 | container_of(work, struct pcmcia_socket, device_add); | ||
641 | dev_dbg(&s->dev, "adding additional device to %d\n", s->sock); | ||
642 | pcmcia_device_add(s, s->pcmcia_state.mfc_pfc); | ||
643 | s->pcmcia_state.device_add_pending = 0; | ||
644 | s->pcmcia_state.mfc_pfc = 0; | ||
645 | } | ||
646 | |||
647 | static int pcmcia_requery(struct device *dev, void * _data) | ||
648 | { | 639 | { |
649 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 640 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
650 | if (!p_dev->dev.driver) { | 641 | if (!p_dev->dev.driver) { |
@@ -655,45 +646,67 @@ static int pcmcia_requery(struct device *dev, void * _data) | |||
655 | return 0; | 646 | return 0; |
656 | } | 647 | } |
657 | 648 | ||
658 | static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) | ||
659 | { | ||
660 | int no_devices = 0; | ||
661 | int ret = 0; | ||
662 | unsigned long flags; | ||
663 | 649 | ||
664 | /* must be called with skt_mutex held */ | 650 | static void pcmcia_requery(struct pcmcia_socket *s) |
665 | dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock); | 651 | { |
652 | int present, has_pfc; | ||
666 | 653 | ||
667 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 654 | mutex_lock(&s->ops_mutex); |
668 | if (list_empty(&skt->devices_list)) | 655 | present = s->pcmcia_state.present; |
669 | no_devices = 1; | 656 | mutex_unlock(&s->ops_mutex); |
670 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
671 | 657 | ||
672 | /* If this is because of a CIS override, start over */ | 658 | if (!present) |
673 | if (new_cis && !no_devices) | 659 | return; |
674 | pcmcia_card_remove(skt, NULL); | ||
675 | 660 | ||
676 | /* if no devices were added for this socket yet because of | 661 | if (s->functions == 0) { |
677 | * missing resource information or other trouble, we need to | 662 | pcmcia_card_add(s); |
678 | * do this now. */ | 663 | return; |
679 | if (no_devices || new_cis) { | ||
680 | ret = pcmcia_card_add(skt); | ||
681 | if (ret) | ||
682 | return; | ||
683 | } | 664 | } |
684 | 665 | ||
685 | /* some device information might have changed because of a CIS | 666 | /* some device information might have changed because of a CIS |
686 | * update or because we can finally read it correctly... so | 667 | * update or because we can finally read it correctly... so |
687 | * determine it again, overwriting old values if necessary. */ | 668 | * determine it again, overwriting old values if necessary. */ |
688 | bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery); | 669 | bus_for_each_dev(&pcmcia_bus_type, NULL, NULL, pcmcia_requery_callback); |
670 | |||
671 | /* if the CIS changed, we need to check whether the number of | ||
672 | * functions changed. */ | ||
673 | if (s->fake_cis) { | ||
674 | int old_funcs, new_funcs; | ||
675 | cistpl_longlink_mfc_t mfc; | ||
676 | |||
677 | /* does this cis override add or remove functions? */ | ||
678 | old_funcs = s->functions; | ||
679 | |||
680 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, | ||
681 | &mfc)) | ||
682 | new_funcs = mfc.nfn; | ||
683 | else | ||
684 | new_funcs = 1; | ||
685 | if (old_funcs > new_funcs) { | ||
686 | pcmcia_card_remove(s, NULL); | ||
687 | pcmcia_card_add(s); | ||
688 | } else if (new_funcs > old_funcs) { | ||
689 | s->functions = new_funcs; | ||
690 | pcmcia_device_add(s, 1); | ||
691 | } | ||
692 | } | ||
693 | |||
694 | /* If the PCMCIA device consists of two pseudo devices, | ||
695 | * call pcmcia_device_add() -- which will fail if both | ||
696 | * devices are already registered. */ | ||
697 | mutex_lock(&s->ops_mutex); | ||
698 | has_pfc = s->pcmcia_state.has_pfc; | ||
699 | mutex_unlock(&s->ops_mutex); | ||
700 | if (has_pfc) | ||
701 | pcmcia_device_add(s, 0); | ||
689 | 702 | ||
690 | /* we re-scan all devices, not just the ones connected to this | 703 | /* we re-scan all devices, not just the ones connected to this |
691 | * socket. This does not matter, though. */ | 704 | * socket. This does not matter, though. */ |
692 | ret = bus_rescan_devices(&pcmcia_bus_type); | 705 | if (bus_rescan_devices(&pcmcia_bus_type)) |
693 | if (ret) | 706 | dev_warn(&s->dev, "rescanning the bus failed\n"); |
694 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed\n"); | ||
695 | } | 707 | } |
696 | 708 | ||
709 | |||
697 | #ifdef CONFIG_PCMCIA_LOAD_CIS | 710 | #ifdef CONFIG_PCMCIA_LOAD_CIS |
698 | 711 | ||
699 | /** | 712 | /** |
@@ -710,9 +723,6 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
710 | struct pcmcia_socket *s = dev->socket; | 723 | struct pcmcia_socket *s = dev->socket; |
711 | const struct firmware *fw; | 724 | const struct firmware *fw; |
712 | int ret = -ENOMEM; | 725 | int ret = -ENOMEM; |
713 | int no_funcs; | ||
714 | int old_funcs; | ||
715 | cistpl_longlink_mfc_t mfc; | ||
716 | 726 | ||
717 | if (!filename) | 727 | if (!filename) |
718 | return -EINVAL; | 728 | return -EINVAL; |
@@ -739,19 +749,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
739 | /* update information */ | 749 | /* update information */ |
740 | pcmcia_device_query(dev); | 750 | pcmcia_device_query(dev); |
741 | 751 | ||
742 | /* does this cis override add or remove functions? */ | 752 | /* requery (as number of functions might have changed) */ |
743 | old_funcs = s->functions; | 753 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY); |
744 | |||
745 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, &mfc)) | ||
746 | no_funcs = mfc.nfn; | ||
747 | else | ||
748 | no_funcs = 1; | ||
749 | s->functions = no_funcs; | ||
750 | |||
751 | if (old_funcs > no_funcs) | ||
752 | pcmcia_card_remove(s, dev); | ||
753 | else if (no_funcs > old_funcs) | ||
754 | pcmcia_add_device_later(s, 1); | ||
755 | } | 754 | } |
756 | release: | 755 | release: |
757 | release_firmware(fw); | 756 | release_firmware(fw); |
@@ -818,9 +817,14 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
818 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { | 817 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { |
819 | if (dev->device_no != did->device_no) | 818 | if (dev->device_no != did->device_no) |
820 | return 0; | 819 | return 0; |
820 | mutex_lock(&dev->socket->ops_mutex); | ||
821 | dev->socket->pcmcia_state.has_pfc = 1; | ||
822 | mutex_unlock(&dev->socket->ops_mutex); | ||
821 | } | 823 | } |
822 | 824 | ||
823 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { | 825 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { |
826 | int ret; | ||
827 | |||
824 | if ((!dev->has_func_id) || (dev->func_id != did->func_id)) | 828 | if ((!dev->has_func_id) || (dev->func_id != did->func_id)) |
825 | return 0; | 829 | return 0; |
826 | 830 | ||
@@ -835,10 +839,15 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
835 | * after it has re-checked that there is no possible module | 839 | * after it has re-checked that there is no possible module |
836 | * with a prod_id/manf_id/card_id match. | 840 | * with a prod_id/manf_id/card_id match. |
837 | */ | 841 | */ |
838 | dev_dbg(&dev->dev, | 842 | mutex_lock(&dev->socket->ops_mutex); |
839 | "skipping FUNC_ID match until userspace interaction\n"); | 843 | ret = dev->allow_func_id_match; |
840 | if (!dev->allow_func_id_match) | 844 | mutex_unlock(&dev->socket->ops_mutex); |
845 | |||
846 | if (!ret) { | ||
847 | dev_dbg(&dev->dev, | ||
848 | "skipping FUNC_ID match until userspace ACK\n"); | ||
841 | return 0; | 849 | return 0; |
850 | } | ||
842 | } | 851 | } |
843 | 852 | ||
844 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 853 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
@@ -859,8 +868,6 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
859 | return 0; | 868 | return 0; |
860 | } | 869 | } |
861 | 870 | ||
862 | dev_set_drvdata(&dev->dev, did); | ||
863 | |||
864 | return 1; | 871 | return 1; |
865 | } | 872 | } |
866 | 873 | ||
@@ -873,16 +880,16 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) | |||
873 | struct pcmcia_dynid *dynid; | 880 | struct pcmcia_dynid *dynid; |
874 | 881 | ||
875 | /* match dynamic devices first */ | 882 | /* match dynamic devices first */ |
876 | spin_lock(&p_drv->dynids.lock); | 883 | mutex_lock(&p_drv->dynids.lock); |
877 | list_for_each_entry(dynid, &p_drv->dynids.list, node) { | 884 | list_for_each_entry(dynid, &p_drv->dynids.list, node) { |
878 | dev_dbg(dev, "trying to match to %s\n", drv->name); | 885 | dev_dbg(dev, "trying to match to %s\n", drv->name); |
879 | if (pcmcia_devmatch(p_dev, &dynid->id)) { | 886 | if (pcmcia_devmatch(p_dev, &dynid->id)) { |
880 | dev_dbg(dev, "matched to %s\n", drv->name); | 887 | dev_dbg(dev, "matched to %s\n", drv->name); |
881 | spin_unlock(&p_drv->dynids.lock); | 888 | mutex_unlock(&p_drv->dynids.lock); |
882 | return 1; | 889 | return 1; |
883 | } | 890 | } |
884 | } | 891 | } |
885 | spin_unlock(&p_drv->dynids.lock); | 892 | mutex_unlock(&p_drv->dynids.lock); |
886 | 893 | ||
887 | #ifdef CONFIG_PCMCIA_IOCTL | 894 | #ifdef CONFIG_PCMCIA_IOCTL |
888 | /* matching by cardmgr */ | 895 | /* matching by cardmgr */ |
@@ -970,13 +977,14 @@ static int runtime_suspend(struct device *dev) | |||
970 | return rc; | 977 | return rc; |
971 | } | 978 | } |
972 | 979 | ||
973 | static void runtime_resume(struct device *dev) | 980 | static int runtime_resume(struct device *dev) |
974 | { | 981 | { |
975 | int rc; | 982 | int rc; |
976 | 983 | ||
977 | down(&dev->sem); | 984 | down(&dev->sem); |
978 | rc = pcmcia_dev_resume(dev); | 985 | rc = pcmcia_dev_resume(dev); |
979 | up(&dev->sem); | 986 | up(&dev->sem); |
987 | return rc; | ||
980 | } | 988 | } |
981 | 989 | ||
982 | /************************ per-device sysfs output ***************************/ | 990 | /************************ per-device sysfs output ***************************/ |
@@ -1027,7 +1035,7 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute | |||
1027 | if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) | 1035 | if ((!p_dev->suspended) && !strncmp(buf, "off", 3)) |
1028 | ret = runtime_suspend(dev); | 1036 | ret = runtime_suspend(dev); |
1029 | else if (p_dev->suspended && !strncmp(buf, "on", 2)) | 1037 | else if (p_dev->suspended && !strncmp(buf, "on", 2)) |
1030 | runtime_resume(dev); | 1038 | ret = runtime_resume(dev); |
1031 | 1039 | ||
1032 | return ret ? ret : count; | 1040 | return ret ? ret : count; |
1033 | } | 1041 | } |
@@ -1059,19 +1067,14 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, | |||
1059 | struct device_attribute *attr, const char *buf, size_t count) | 1067 | struct device_attribute *attr, const char *buf, size_t count) |
1060 | { | 1068 | { |
1061 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 1069 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
1062 | int ret; | ||
1063 | 1070 | ||
1064 | if (!count) | 1071 | if (!count) |
1065 | return -EINVAL; | 1072 | return -EINVAL; |
1066 | 1073 | ||
1067 | mutex_lock(&p_dev->socket->skt_mutex); | 1074 | mutex_lock(&p_dev->socket->ops_mutex); |
1068 | p_dev->allow_func_id_match = 1; | 1075 | p_dev->allow_func_id_match = 1; |
1069 | mutex_unlock(&p_dev->socket->skt_mutex); | 1076 | mutex_unlock(&p_dev->socket->ops_mutex); |
1070 | 1077 | pcmcia_parse_uevents(p_dev->socket, PCMCIA_UEVENT_REQUERY); | |
1071 | ret = bus_rescan_devices(&pcmcia_bus_type); | ||
1072 | if (ret) | ||
1073 | printk(KERN_INFO "pcmcia: bus_rescan_devices failed after " | ||
1074 | "allowing func_id matches\n"); | ||
1075 | 1078 | ||
1076 | return count; | 1079 | return count; |
1077 | } | 1080 | } |
@@ -1099,8 +1102,13 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) | |||
1099 | struct pcmcia_driver *p_drv = NULL; | 1102 | struct pcmcia_driver *p_drv = NULL; |
1100 | int ret = 0; | 1103 | int ret = 0; |
1101 | 1104 | ||
1102 | if (p_dev->suspended) | 1105 | mutex_lock(&p_dev->socket->ops_mutex); |
1106 | if (p_dev->suspended) { | ||
1107 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1103 | return 0; | 1108 | return 0; |
1109 | } | ||
1110 | p_dev->suspended = 1; | ||
1111 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1104 | 1112 | ||
1105 | dev_dbg(dev, "suspending\n"); | 1113 | dev_dbg(dev, "suspending\n"); |
1106 | 1114 | ||
@@ -1117,6 +1125,9 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) | |||
1117 | "pcmcia: device %s (driver %s) did " | 1125 | "pcmcia: device %s (driver %s) did " |
1118 | "not want to go to sleep (%d)\n", | 1126 | "not want to go to sleep (%d)\n", |
1119 | p_dev->devname, p_drv->drv.name, ret); | 1127 | p_dev->devname, p_drv->drv.name, ret); |
1128 | mutex_lock(&p_dev->socket->ops_mutex); | ||
1129 | p_dev->suspended = 0; | ||
1130 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1120 | goto out; | 1131 | goto out; |
1121 | } | 1132 | } |
1122 | } | 1133 | } |
@@ -1127,8 +1138,6 @@ static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) | |||
1127 | } | 1138 | } |
1128 | 1139 | ||
1129 | out: | 1140 | out: |
1130 | if (!ret) | ||
1131 | p_dev->suspended = 1; | ||
1132 | return ret; | 1141 | return ret; |
1133 | } | 1142 | } |
1134 | 1143 | ||
@@ -1139,8 +1148,13 @@ static int pcmcia_dev_resume(struct device *dev) | |||
1139 | struct pcmcia_driver *p_drv = NULL; | 1148 | struct pcmcia_driver *p_drv = NULL; |
1140 | int ret = 0; | 1149 | int ret = 0; |
1141 | 1150 | ||
1142 | if (!p_dev->suspended) | 1151 | mutex_lock(&p_dev->socket->ops_mutex); |
1152 | if (!p_dev->suspended) { | ||
1153 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1143 | return 0; | 1154 | return 0; |
1155 | } | ||
1156 | p_dev->suspended = 0; | ||
1157 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1144 | 1158 | ||
1145 | dev_dbg(dev, "resuming\n"); | 1159 | dev_dbg(dev, "resuming\n"); |
1146 | 1160 | ||
@@ -1161,8 +1175,6 @@ static int pcmcia_dev_resume(struct device *dev) | |||
1161 | ret = p_drv->resume(p_dev); | 1175 | ret = p_drv->resume(p_dev); |
1162 | 1176 | ||
1163 | out: | 1177 | out: |
1164 | if (!ret) | ||
1165 | p_dev->suspended = 0; | ||
1166 | return ret; | 1178 | return ret; |
1167 | } | 1179 | } |
1168 | 1180 | ||
@@ -1237,13 +1249,22 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1237 | 1249 | ||
1238 | switch (event) { | 1250 | switch (event) { |
1239 | case CS_EVENT_CARD_REMOVAL: | 1251 | case CS_EVENT_CARD_REMOVAL: |
1252 | mutex_lock(&s->ops_mutex); | ||
1240 | s->pcmcia_state.present = 0; | 1253 | s->pcmcia_state.present = 0; |
1254 | mutex_unlock(&s->ops_mutex); | ||
1241 | pcmcia_card_remove(skt, NULL); | 1255 | pcmcia_card_remove(skt, NULL); |
1242 | handle_event(skt, event); | 1256 | handle_event(skt, event); |
1257 | mutex_lock(&s->ops_mutex); | ||
1258 | destroy_cis_cache(s); | ||
1259 | mutex_unlock(&s->ops_mutex); | ||
1243 | break; | 1260 | break; |
1244 | 1261 | ||
1245 | case CS_EVENT_CARD_INSERTION: | 1262 | case CS_EVENT_CARD_INSERTION: |
1263 | mutex_lock(&s->ops_mutex); | ||
1264 | s->pcmcia_state.has_pfc = 0; | ||
1246 | s->pcmcia_state.present = 1; | 1265 | s->pcmcia_state.present = 1; |
1266 | destroy_cis_cache(s); /* to be on the safe side... */ | ||
1267 | mutex_unlock(&s->ops_mutex); | ||
1247 | pcmcia_card_add(skt); | 1268 | pcmcia_card_add(skt); |
1248 | handle_event(skt, event); | 1269 | handle_event(skt, event); |
1249 | break; | 1270 | break; |
@@ -1251,8 +1272,24 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1251 | case CS_EVENT_EJECTION_REQUEST: | 1272 | case CS_EVENT_EJECTION_REQUEST: |
1252 | break; | 1273 | break; |
1253 | 1274 | ||
1254 | case CS_EVENT_PM_SUSPEND: | ||
1255 | case CS_EVENT_PM_RESUME: | 1275 | case CS_EVENT_PM_RESUME: |
1276 | if (verify_cis_cache(skt) != 0) { | ||
1277 | dev_dbg(&skt->dev, "cis mismatch - different card\n"); | ||
1278 | /* first, remove the card */ | ||
1279 | ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); | ||
1280 | mutex_lock(&s->ops_mutex); | ||
1281 | destroy_cis_cache(skt); | ||
1282 | kfree(skt->fake_cis); | ||
1283 | skt->fake_cis = NULL; | ||
1284 | mutex_unlock(&s->ops_mutex); | ||
1285 | /* now, add the new card */ | ||
1286 | ds_event(skt, CS_EVENT_CARD_INSERTION, | ||
1287 | CS_EVENT_PRI_LOW); | ||
1288 | } | ||
1289 | handle_event(skt, event); | ||
1290 | break; | ||
1291 | |||
1292 | case CS_EVENT_PM_SUSPEND: | ||
1256 | case CS_EVENT_RESET_PHYSICAL: | 1293 | case CS_EVENT_RESET_PHYSICAL: |
1257 | case CS_EVENT_CARD_RESET: | 1294 | case CS_EVENT_CARD_RESET: |
1258 | default: | 1295 | default: |
@@ -1275,9 +1312,13 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
1275 | if (!p_dev) | 1312 | if (!p_dev) |
1276 | return NULL; | 1313 | return NULL; |
1277 | 1314 | ||
1315 | mutex_lock(&p_dev->socket->ops_mutex); | ||
1278 | if (!p_dev->socket->pcmcia_state.present) | 1316 | if (!p_dev->socket->pcmcia_state.present) |
1279 | goto out; | 1317 | goto out; |
1280 | 1318 | ||
1319 | if (p_dev->socket->pcmcia_state.dead) | ||
1320 | goto out; | ||
1321 | |||
1281 | if (p_dev->_removed) | 1322 | if (p_dev->_removed) |
1282 | goto out; | 1323 | goto out; |
1283 | 1324 | ||
@@ -1286,6 +1327,7 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
1286 | 1327 | ||
1287 | ret = p_dev; | 1328 | ret = p_dev; |
1288 | out: | 1329 | out: |
1330 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1289 | pcmcia_put_dev(p_dev); | 1331 | pcmcia_put_dev(p_dev); |
1290 | return ret; | 1332 | return ret; |
1291 | } | 1333 | } |
@@ -1295,7 +1337,8 @@ EXPORT_SYMBOL(pcmcia_dev_present); | |||
1295 | static struct pcmcia_callback pcmcia_bus_callback = { | 1337 | static struct pcmcia_callback pcmcia_bus_callback = { |
1296 | .owner = THIS_MODULE, | 1338 | .owner = THIS_MODULE, |
1297 | .event = ds_event, | 1339 | .event = ds_event, |
1298 | .requery = pcmcia_bus_rescan, | 1340 | .requery = pcmcia_requery, |
1341 | .validate = pccard_validate_cis, | ||
1299 | .suspend = pcmcia_bus_suspend, | 1342 | .suspend = pcmcia_bus_suspend, |
1300 | .resume = pcmcia_bus_resume, | 1343 | .resume = pcmcia_bus_resume, |
1301 | }; | 1344 | }; |
@@ -1313,17 +1356,17 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, | |||
1313 | return -ENODEV; | 1356 | return -ENODEV; |
1314 | } | 1357 | } |
1315 | 1358 | ||
1316 | /* | 1359 | ret = sysfs_create_bin_file(&dev->kobj, &pccard_cis_attr); |
1317 | * Ugly. But we want to wait for the socket threads to have started up. | 1360 | if (ret) { |
1318 | * We really should let the drivers themselves drive some of this.. | 1361 | dev_printk(KERN_ERR, dev, "PCMCIA registration failed\n"); |
1319 | */ | 1362 | pcmcia_put_socket(socket); |
1320 | msleep(250); | 1363 | return ret; |
1364 | } | ||
1321 | 1365 | ||
1322 | #ifdef CONFIG_PCMCIA_IOCTL | 1366 | #ifdef CONFIG_PCMCIA_IOCTL |
1323 | init_waitqueue_head(&socket->queue); | 1367 | init_waitqueue_head(&socket->queue); |
1324 | #endif | 1368 | #endif |
1325 | INIT_LIST_HEAD(&socket->devices_list); | 1369 | INIT_LIST_HEAD(&socket->devices_list); |
1326 | INIT_WORK(&socket->device_add, pcmcia_delayed_add_device); | ||
1327 | memset(&socket->pcmcia_state, 0, sizeof(u8)); | 1370 | memset(&socket->pcmcia_state, 0, sizeof(u8)); |
1328 | socket->device_count = 0; | 1371 | socket->device_count = 0; |
1329 | 1372 | ||
@@ -1345,14 +1388,20 @@ static void pcmcia_bus_remove_socket(struct device *dev, | |||
1345 | if (!socket) | 1388 | if (!socket) |
1346 | return; | 1389 | return; |
1347 | 1390 | ||
1391 | mutex_lock(&socket->ops_mutex); | ||
1348 | socket->pcmcia_state.dead = 1; | 1392 | socket->pcmcia_state.dead = 1; |
1393 | mutex_unlock(&socket->ops_mutex); | ||
1394 | |||
1349 | pccard_register_pcmcia(socket, NULL); | 1395 | pccard_register_pcmcia(socket, NULL); |
1350 | 1396 | ||
1351 | /* unregister any unbound devices */ | 1397 | /* unregister any unbound devices */ |
1352 | mutex_lock(&socket->skt_mutex); | 1398 | mutex_lock(&socket->skt_mutex); |
1353 | pcmcia_card_remove(socket, NULL); | 1399 | pcmcia_card_remove(socket, NULL); |
1400 | release_cis_mem(socket); | ||
1354 | mutex_unlock(&socket->skt_mutex); | 1401 | mutex_unlock(&socket->skt_mutex); |
1355 | 1402 | ||
1403 | sysfs_remove_bin_file(&dev->kobj, &pccard_cis_attr); | ||
1404 | |||
1356 | pcmcia_put_socket(socket); | 1405 | pcmcia_put_socket(socket); |
1357 | 1406 | ||
1358 | return; | 1407 | return; |
@@ -1383,8 +1432,6 @@ static int __init init_pcmcia_bus(void) | |||
1383 | { | 1432 | { |
1384 | int ret; | 1433 | int ret; |
1385 | 1434 | ||
1386 | spin_lock_init(&pcmcia_dev_list_lock); | ||
1387 | |||
1388 | ret = bus_register(&pcmcia_bus_type); | 1435 | ret = bus_register(&pcmcia_bus_type); |
1389 | if (ret < 0) { | 1436 | if (ret < 0) { |
1390 | printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); | 1437 | printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); |