diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 70 |
1 files changed, 27 insertions, 43 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 0eb242cbed17..4c40db8889d9 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) |
@@ -265,7 +263,6 @@ static int pcmcia_device_probe(struct device *dev) | |||
265 | struct pcmcia_device_id *did; | 263 | struct pcmcia_device_id *did; |
266 | struct pcmcia_socket *s; | 264 | struct pcmcia_socket *s; |
267 | cistpl_config_t cis_config; | 265 | cistpl_config_t cis_config; |
268 | unsigned long flags; | ||
269 | int ret = 0; | 266 | int ret = 0; |
270 | 267 | ||
271 | dev = get_device(dev); | 268 | dev = get_device(dev); |
@@ -316,11 +313,11 @@ static int pcmcia_device_probe(struct device *dev) | |||
316 | goto put_module; | 313 | goto put_module; |
317 | } | 314 | } |
318 | 315 | ||
319 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 316 | mutex_lock(&s->ops_mutex); |
320 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 317 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && |
321 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | 318 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) |
322 | pcmcia_add_device_later(p_dev->socket, 0); | 319 | pcmcia_add_device_later(p_dev->socket, 0); |
323 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 320 | mutex_unlock(&s->ops_mutex); |
324 | 321 | ||
325 | put_module: | 322 | put_module: |
326 | if (ret) | 323 | if (ret) |
@@ -339,28 +336,27 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
339 | { | 336 | { |
340 | struct pcmcia_device *p_dev; | 337 | struct pcmcia_device *p_dev; |
341 | struct pcmcia_device *tmp; | 338 | struct pcmcia_device *tmp; |
342 | unsigned long flags; | ||
343 | 339 | ||
344 | dev_dbg(leftover ? &leftover->dev : &s->dev, | 340 | dev_dbg(leftover ? &leftover->dev : &s->dev, |
345 | "pcmcia_card_remove(%d) %s\n", s->sock, | 341 | "pcmcia_card_remove(%d) %s\n", s->sock, |
346 | leftover ? leftover->devname : ""); | 342 | leftover ? leftover->devname : ""); |
347 | 343 | ||
348 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 344 | mutex_lock(&s->ops_mutex); |
349 | if (!leftover) | 345 | if (!leftover) |
350 | s->device_count = 0; | 346 | s->device_count = 0; |
351 | else | 347 | else |
352 | s->device_count = 1; | 348 | s->device_count = 1; |
353 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 349 | mutex_unlock(&s->ops_mutex); |
354 | 350 | ||
355 | /* unregister all pcmcia_devices registered with this socket, except leftover */ | 351 | /* unregister all pcmcia_devices registered with this socket, except leftover */ |
356 | list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { | 352 | list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) { |
357 | if (p_dev == leftover) | 353 | if (p_dev == leftover) |
358 | continue; | 354 | continue; |
359 | 355 | ||
360 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 356 | mutex_lock(&s->ops_mutex); |
361 | list_del(&p_dev->socket_device_list); | 357 | list_del(&p_dev->socket_device_list); |
362 | p_dev->_removed = 1; | 358 | p_dev->_removed = 1; |
363 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 359 | mutex_unlock(&s->ops_mutex); |
364 | 360 | ||
365 | dev_dbg(&p_dev->dev, "unregistering device\n"); | 361 | dev_dbg(&p_dev->dev, "unregistering device\n"); |
366 | device_unregister(&p_dev->dev); | 362 | device_unregister(&p_dev->dev); |
@@ -507,7 +503,6 @@ static DEFINE_MUTEX(device_add_lock); | |||
507 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) | 503 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) |
508 | { | 504 | { |
509 | struct pcmcia_device *p_dev, *tmp_dev; | 505 | struct pcmcia_device *p_dev, *tmp_dev; |
510 | unsigned long flags; | ||
511 | 506 | ||
512 | s = pcmcia_get_socket(s); | 507 | s = pcmcia_get_socket(s); |
513 | if (!s) | 508 | if (!s) |
@@ -521,9 +516,9 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
521 | if (!p_dev) | 516 | if (!p_dev) |
522 | goto err_put; | 517 | goto err_put; |
523 | 518 | ||
524 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 519 | mutex_lock(&s->ops_mutex); |
525 | p_dev->device_no = (s->device_count++); | 520 | p_dev->device_no = (s->device_count++); |
526 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 521 | mutex_unlock(&s->ops_mutex); |
527 | 522 | ||
528 | /* max of 4 devices per card */ | 523 | /* max of 4 devices per card */ |
529 | if (p_dev->device_no >= 4) | 524 | if (p_dev->device_no >= 4) |
@@ -546,7 +541,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
546 | goto err_free; | 541 | goto err_free; |
547 | dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname); | 542 | dev_dbg(&p_dev->dev, "devname is %s\n", p_dev->devname); |
548 | 543 | ||
549 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 544 | mutex_lock(&s->ops_mutex); |
550 | 545 | ||
551 | /* | 546 | /* |
552 | * p_dev->function_config must be the same for all card functions. | 547 | * p_dev->function_config must be the same for all card functions. |
@@ -564,7 +559,7 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
564 | /* Add to the list in pcmcia_bus_socket */ | 559 | /* Add to the list in pcmcia_bus_socket */ |
565 | list_add(&p_dev->socket_device_list, &s->devices_list); | 560 | list_add(&p_dev->socket_device_list, &s->devices_list); |
566 | 561 | ||
567 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 562 | mutex_unlock(&s->ops_mutex); |
568 | 563 | ||
569 | if (!p_dev->function_config) { | 564 | if (!p_dev->function_config) { |
570 | dev_dbg(&p_dev->dev, "creating config_t\n"); | 565 | dev_dbg(&p_dev->dev, "creating config_t\n"); |
@@ -589,14 +584,14 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
589 | return p_dev; | 584 | return p_dev; |
590 | 585 | ||
591 | err_unreg: | 586 | err_unreg: |
592 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 587 | mutex_lock(&s->ops_mutex); |
593 | list_del(&p_dev->socket_device_list); | 588 | list_del(&p_dev->socket_device_list); |
594 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 589 | mutex_unlock(&s->ops_mutex); |
595 | 590 | ||
596 | err_free: | 591 | err_free: |
597 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 592 | mutex_lock(&s->ops_mutex); |
598 | s->device_count--; | 593 | s->device_count--; |
599 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 594 | mutex_unlock(&s->ops_mutex); |
600 | 595 | ||
601 | kfree(p_dev->devname); | 596 | kfree(p_dev->devname); |
602 | kfree(p_dev); | 597 | kfree(p_dev); |
@@ -650,13 +645,12 @@ static void pcmcia_delayed_add_device(struct work_struct *work) | |||
650 | struct pcmcia_socket *s = | 645 | struct pcmcia_socket *s = |
651 | container_of(work, struct pcmcia_socket, device_add); | 646 | container_of(work, struct pcmcia_socket, device_add); |
652 | u8 mfc_pfc; | 647 | u8 mfc_pfc; |
653 | unsigned long flags; | ||
654 | 648 | ||
655 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 649 | mutex_lock(&s->ops_mutex); |
656 | mfc_pfc = s->pcmcia_state.mfc_pfc; | 650 | mfc_pfc = s->pcmcia_state.mfc_pfc; |
657 | s->pcmcia_state.device_add_pending = 0; | 651 | s->pcmcia_state.device_add_pending = 0; |
658 | s->pcmcia_state.mfc_pfc = 0; | 652 | s->pcmcia_state.mfc_pfc = 0; |
659 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 653 | mutex_unlock(&s->ops_mutex); |
660 | 654 | ||
661 | dev_dbg(&s->dev, "adding additional device to %d\n", s->sock); | 655 | dev_dbg(&s->dev, "adding additional device to %d\n", s->sock); |
662 | pcmcia_device_add(s, mfc_pfc); | 656 | pcmcia_device_add(s, mfc_pfc); |
@@ -677,15 +671,14 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt, int new_cis) | |||
677 | { | 671 | { |
678 | int no_devices = 0; | 672 | int no_devices = 0; |
679 | int ret = 0; | 673 | int ret = 0; |
680 | unsigned long flags; | ||
681 | 674 | ||
682 | /* must be called with skt_mutex held */ | 675 | /* must be called with skt_mutex held */ |
683 | dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock); | 676 | dev_dbg(&skt->dev, "re-scanning socket %d\n", skt->sock); |
684 | 677 | ||
685 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 678 | mutex_lock(&skt->ops_mutex); |
686 | if (list_empty(&skt->devices_list)) | 679 | if (list_empty(&skt->devices_list)) |
687 | no_devices = 1; | 680 | no_devices = 1; |
688 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 681 | mutex_unlock(&skt->ops_mutex); |
689 | 682 | ||
690 | /* If this is because of a CIS override, start over */ | 683 | /* If this is because of a CIS override, start over */ |
691 | if (new_cis && !no_devices) | 684 | if (new_cis && !no_devices) |
@@ -769,11 +762,9 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
769 | if (old_funcs > no_funcs) | 762 | if (old_funcs > no_funcs) |
770 | pcmcia_card_remove(s, dev); | 763 | pcmcia_card_remove(s, dev); |
771 | else if (no_funcs > old_funcs) { | 764 | else if (no_funcs > old_funcs) { |
772 | unsigned long flags; | 765 | mutex_lock(&s->ops_mutex); |
773 | |||
774 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
775 | pcmcia_add_device_later(s, 1); | 766 | pcmcia_add_device_later(s, 1); |
776 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 767 | mutex_unlock(&s->ops_mutex); |
777 | } | 768 | } |
778 | } | 769 | } |
779 | release: | 770 | release: |
@@ -1248,7 +1239,6 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt) | |||
1248 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | 1239 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) |
1249 | { | 1240 | { |
1250 | struct pcmcia_socket *s = pcmcia_get_socket(skt); | 1241 | struct pcmcia_socket *s = pcmcia_get_socket(skt); |
1251 | unsigned long flags; | ||
1252 | 1242 | ||
1253 | if (!s) { | 1243 | if (!s) { |
1254 | dev_printk(KERN_ERR, &skt->dev, | 1244 | dev_printk(KERN_ERR, &skt->dev, |
@@ -1262,9 +1252,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1262 | 1252 | ||
1263 | switch (event) { | 1253 | switch (event) { |
1264 | case CS_EVENT_CARD_REMOVAL: | 1254 | case CS_EVENT_CARD_REMOVAL: |
1265 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 1255 | mutex_lock(&s->ops_mutex); |
1266 | s->pcmcia_state.present = 0; | 1256 | s->pcmcia_state.present = 0; |
1267 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 1257 | mutex_unlock(&s->ops_mutex); |
1268 | pcmcia_card_remove(skt, NULL); | 1258 | pcmcia_card_remove(skt, NULL); |
1269 | handle_event(skt, event); | 1259 | handle_event(skt, event); |
1270 | mutex_lock(&s->ops_mutex); | 1260 | mutex_lock(&s->ops_mutex); |
@@ -1273,10 +1263,8 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1273 | break; | 1263 | break; |
1274 | 1264 | ||
1275 | case CS_EVENT_CARD_INSERTION: | 1265 | case CS_EVENT_CARD_INSERTION: |
1276 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | ||
1277 | s->pcmcia_state.present = 1; | ||
1278 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | ||
1279 | mutex_lock(&s->ops_mutex); | 1266 | mutex_lock(&s->ops_mutex); |
1267 | s->pcmcia_state.present = 1; | ||
1280 | destroy_cis_cache(s); /* to be on the safe side... */ | 1268 | destroy_cis_cache(s); /* to be on the safe side... */ |
1281 | mutex_unlock(&s->ops_mutex); | 1269 | mutex_unlock(&s->ops_mutex); |
1282 | pcmcia_card_add(skt); | 1270 | pcmcia_card_add(skt); |
@@ -1321,13 +1309,12 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
1321 | { | 1309 | { |
1322 | struct pcmcia_device *p_dev; | 1310 | struct pcmcia_device *p_dev; |
1323 | struct pcmcia_device *ret = NULL; | 1311 | struct pcmcia_device *ret = NULL; |
1324 | unsigned long flags; | ||
1325 | 1312 | ||
1326 | p_dev = pcmcia_get_dev(_p_dev); | 1313 | p_dev = pcmcia_get_dev(_p_dev); |
1327 | if (!p_dev) | 1314 | if (!p_dev) |
1328 | return NULL; | 1315 | return NULL; |
1329 | 1316 | ||
1330 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 1317 | mutex_lock(&p_dev->socket->ops_mutex); |
1331 | if (!p_dev->socket->pcmcia_state.present) | 1318 | if (!p_dev->socket->pcmcia_state.present) |
1332 | goto out; | 1319 | goto out; |
1333 | 1320 | ||
@@ -1342,7 +1329,7 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
1342 | 1329 | ||
1343 | ret = p_dev; | 1330 | ret = p_dev; |
1344 | out: | 1331 | out: |
1345 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 1332 | mutex_unlock(&p_dev->socket->ops_mutex); |
1346 | pcmcia_put_dev(p_dev); | 1333 | pcmcia_put_dev(p_dev); |
1347 | return ret; | 1334 | return ret; |
1348 | } | 1335 | } |
@@ -1406,14 +1393,13 @@ static void pcmcia_bus_remove_socket(struct device *dev, | |||
1406 | struct class_interface *class_intf) | 1393 | struct class_interface *class_intf) |
1407 | { | 1394 | { |
1408 | struct pcmcia_socket *socket = dev_get_drvdata(dev); | 1395 | struct pcmcia_socket *socket = dev_get_drvdata(dev); |
1409 | unsigned long flags; | ||
1410 | 1396 | ||
1411 | if (!socket) | 1397 | if (!socket) |
1412 | return; | 1398 | return; |
1413 | 1399 | ||
1414 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 1400 | mutex_lock(&socket->ops_mutex); |
1415 | socket->pcmcia_state.dead = 1; | 1401 | socket->pcmcia_state.dead = 1; |
1416 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 1402 | mutex_unlock(&socket->ops_mutex); |
1417 | 1403 | ||
1418 | pccard_register_pcmcia(socket, NULL); | 1404 | pccard_register_pcmcia(socket, NULL); |
1419 | 1405 | ||
@@ -1455,8 +1441,6 @@ static int __init init_pcmcia_bus(void) | |||
1455 | { | 1441 | { |
1456 | int ret; | 1442 | int ret; |
1457 | 1443 | ||
1458 | spin_lock_init(&pcmcia_dev_list_lock); | ||
1459 | |||
1460 | ret = bus_register(&pcmcia_bus_type); | 1444 | ret = bus_register(&pcmcia_bus_type); |
1461 | if (ret < 0) { | 1445 | if (ret < 0) { |
1462 | printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); | 1446 | printk(KERN_WARNING "pcmcia: bus_register error: %d\n", ret); |