diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 111 |
1 files changed, 45 insertions, 66 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cb6036d89e59..7ef7adee5e4f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -335,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
335 | 335 | ||
336 | mutex_lock(&s->ops_mutex); | 336 | mutex_lock(&s->ops_mutex); |
337 | list_del(&p_dev->socket_device_list); | 337 | list_del(&p_dev->socket_device_list); |
338 | p_dev->_removed = 1; | ||
339 | mutex_unlock(&s->ops_mutex); | 338 | mutex_unlock(&s->ops_mutex); |
340 | 339 | ||
341 | dev_dbg(&p_dev->dev, "unregistering device\n"); | 340 | dev_dbg(&p_dev->dev, "unregistering device\n"); |
@@ -372,8 +371,6 @@ static int pcmcia_device_remove(struct device *dev) | |||
372 | if (p_drv->remove) | 371 | if (p_drv->remove) |
373 | p_drv->remove(p_dev); | 372 | p_drv->remove(p_dev); |
374 | 373 | ||
375 | p_dev->dev_node = NULL; | ||
376 | |||
377 | /* check for proper unloading */ | 374 | /* check for proper unloading */ |
378 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) | 375 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) |
379 | dev_printk(KERN_INFO, dev, | 376 | dev_printk(KERN_INFO, dev, |
@@ -480,15 +477,6 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
480 | } | 477 | } |
481 | 478 | ||
482 | 479 | ||
483 | /* device_add_lock is needed to avoid double registration by cardmgr and kernel. | ||
484 | * Serializes pcmcia_device_add; will most likely be removed in future. | ||
485 | * | ||
486 | * While it has the caveat that adding new PCMCIA devices inside(!) device_register() | ||
487 | * won't work, this doesn't matter much at the moment: the driver core doesn't | ||
488 | * support it either. | ||
489 | */ | ||
490 | static DEFINE_MUTEX(device_add_lock); | ||
491 | |||
492 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) | 480 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) |
493 | { | 481 | { |
494 | struct pcmcia_device *p_dev, *tmp_dev; | 482 | struct pcmcia_device *p_dev, *tmp_dev; |
@@ -498,8 +486,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
498 | if (!s) | 486 | if (!s) |
499 | return NULL; | 487 | return NULL; |
500 | 488 | ||
501 | mutex_lock(&device_add_lock); | ||
502 | |||
503 | pr_debug("adding device to %d, function %d\n", s->sock, function); | 489 | pr_debug("adding device to %d, function %d\n", s->sock, function); |
504 | 490 | ||
505 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); | 491 | p_dev = kzalloc(sizeof(struct pcmcia_device), GFP_KERNEL); |
@@ -539,8 +525,8 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
539 | 525 | ||
540 | /* | 526 | /* |
541 | * p_dev->function_config must be the same for all card functions. | 527 | * p_dev->function_config must be the same for all card functions. |
542 | * Note that this is serialized by the device_add_lock, so that | 528 | * Note that this is serialized by ops_mutex, so that only one |
543 | * only one such struct will be created. | 529 | * such struct will be created. |
544 | */ | 530 | */ |
545 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) | 531 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) |
546 | if (p_dev->func == tmp_dev->func) { | 532 | if (p_dev->func == tmp_dev->func) { |
@@ -553,28 +539,31 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
553 | /* Add to the list in pcmcia_bus_socket */ | 539 | /* Add to the list in pcmcia_bus_socket */ |
554 | list_add(&p_dev->socket_device_list, &s->devices_list); | 540 | list_add(&p_dev->socket_device_list, &s->devices_list); |
555 | 541 | ||
556 | mutex_unlock(&s->ops_mutex); | 542 | if (pcmcia_setup_irq(p_dev)) |
543 | dev_warn(&p_dev->dev, | ||
544 | "IRQ setup failed -- device might not work\n"); | ||
557 | 545 | ||
558 | if (!p_dev->function_config) { | 546 | if (!p_dev->function_config) { |
559 | dev_dbg(&p_dev->dev, "creating config_t\n"); | 547 | dev_dbg(&p_dev->dev, "creating config_t\n"); |
560 | p_dev->function_config = kzalloc(sizeof(struct config_t), | 548 | p_dev->function_config = kzalloc(sizeof(struct config_t), |
561 | GFP_KERNEL); | 549 | GFP_KERNEL); |
562 | if (!p_dev->function_config) | 550 | if (!p_dev->function_config) { |
551 | mutex_unlock(&s->ops_mutex); | ||
563 | goto err_unreg; | 552 | goto err_unreg; |
553 | } | ||
564 | kref_init(&p_dev->function_config->ref); | 554 | kref_init(&p_dev->function_config->ref); |
565 | } | 555 | } |
556 | mutex_unlock(&s->ops_mutex); | ||
566 | 557 | ||
567 | dev_printk(KERN_NOTICE, &p_dev->dev, | 558 | dev_printk(KERN_NOTICE, &p_dev->dev, |
568 | "pcmcia: registering new device %s\n", | 559 | "pcmcia: registering new device %s (IRQ: %d)\n", |
569 | p_dev->devname); | 560 | p_dev->devname, p_dev->irq); |
570 | 561 | ||
571 | pcmcia_device_query(p_dev); | 562 | pcmcia_device_query(p_dev); |
572 | 563 | ||
573 | if (device_register(&p_dev->dev)) | 564 | if (device_register(&p_dev->dev)) |
574 | goto err_unreg; | 565 | goto err_unreg; |
575 | 566 | ||
576 | mutex_unlock(&device_add_lock); | ||
577 | |||
578 | return p_dev; | 567 | return p_dev; |
579 | 568 | ||
580 | err_unreg: | 569 | err_unreg: |
@@ -592,7 +581,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
592 | kfree(p_dev->devname); | 581 | kfree(p_dev->devname); |
593 | kfree(p_dev); | 582 | kfree(p_dev); |
594 | err_put: | 583 | err_put: |
595 | mutex_unlock(&device_add_lock); | ||
596 | pcmcia_put_socket(s); | 584 | pcmcia_put_socket(s); |
597 | 585 | ||
598 | return NULL; | 586 | return NULL; |
@@ -654,14 +642,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data) | |||
654 | 642 | ||
655 | static void pcmcia_requery(struct pcmcia_socket *s) | 643 | static void pcmcia_requery(struct pcmcia_socket *s) |
656 | { | 644 | { |
657 | int present, has_pfc; | 645 | int has_pfc; |
658 | |||
659 | mutex_lock(&s->ops_mutex); | ||
660 | present = s->pcmcia_state.present; | ||
661 | mutex_unlock(&s->ops_mutex); | ||
662 | |||
663 | if (!present) | ||
664 | return; | ||
665 | 646 | ||
666 | if (s->functions == 0) { | 647 | if (s->functions == 0) { |
667 | pcmcia_card_add(s); | 648 | pcmcia_card_add(s); |
@@ -687,12 +668,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) | |||
687 | new_funcs = mfc.nfn; | 668 | new_funcs = mfc.nfn; |
688 | else | 669 | else |
689 | new_funcs = 1; | 670 | new_funcs = 1; |
690 | if (old_funcs > new_funcs) { | 671 | if (old_funcs != new_funcs) { |
672 | /* we need to re-start */ | ||
691 | pcmcia_card_remove(s, NULL); | 673 | pcmcia_card_remove(s, NULL); |
692 | pcmcia_card_add(s); | 674 | pcmcia_card_add(s); |
693 | } else if (new_funcs > old_funcs) { | ||
694 | s->functions = new_funcs; | ||
695 | pcmcia_device_add(s, 1); | ||
696 | } | 675 | } |
697 | } | 676 | } |
698 | 677 | ||
@@ -728,6 +707,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
728 | struct pcmcia_socket *s = dev->socket; | 707 | struct pcmcia_socket *s = dev->socket; |
729 | const struct firmware *fw; | 708 | const struct firmware *fw; |
730 | int ret = -ENOMEM; | 709 | int ret = -ENOMEM; |
710 | cistpl_longlink_mfc_t mfc; | ||
711 | int old_funcs, new_funcs = 1; | ||
731 | 712 | ||
732 | if (!filename) | 713 | if (!filename) |
733 | return -EINVAL; | 714 | return -EINVAL; |
@@ -750,6 +731,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
750 | goto release; | 731 | goto release; |
751 | } | 732 | } |
752 | 733 | ||
734 | /* we need to re-start if the number of functions changed */ | ||
735 | old_funcs = s->functions; | ||
736 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, | ||
737 | &mfc)) | ||
738 | new_funcs = mfc.nfn; | ||
739 | |||
740 | if (old_funcs != new_funcs) | ||
741 | ret = -EBUSY; | ||
753 | 742 | ||
754 | /* update information */ | 743 | /* update information */ |
755 | pcmcia_device_query(dev); | 744 | pcmcia_device_query(dev); |
@@ -820,11 +809,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
820 | } | 809 | } |
821 | 810 | ||
822 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { | 811 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { |
823 | if (dev->device_no != did->device_no) | 812 | dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n"); |
824 | return 0; | ||
825 | mutex_lock(&dev->socket->ops_mutex); | 813 | mutex_lock(&dev->socket->ops_mutex); |
826 | dev->socket->pcmcia_state.has_pfc = 1; | 814 | dev->socket->pcmcia_state.has_pfc = 1; |
827 | mutex_unlock(&dev->socket->ops_mutex); | 815 | mutex_unlock(&dev->socket->ops_mutex); |
816 | if (dev->device_no != did->device_no) | ||
817 | return 0; | ||
828 | } | 818 | } |
829 | 819 | ||
830 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { | 820 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { |
@@ -835,7 +825,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
835 | 825 | ||
836 | /* if this is a pseudo-multi-function device, | 826 | /* if this is a pseudo-multi-function device, |
837 | * we need explicit matches */ | 827 | * we need explicit matches */ |
838 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) | 828 | if (dev->socket->pcmcia_state.has_pfc) |
839 | return 0; | 829 | return 0; |
840 | if (dev->device_no) | 830 | if (dev->device_no) |
841 | return 0; | 831 | return 0; |
@@ -858,10 +848,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
858 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 848 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
859 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); | 849 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); |
860 | if (!dev->socket->fake_cis) | 850 | if (!dev->socket->fake_cis) |
861 | pcmcia_load_firmware(dev, did->cisfile); | 851 | if (pcmcia_load_firmware(dev, did->cisfile)) |
862 | 852 | return 0; | |
863 | if (!dev->socket->fake_cis) | ||
864 | return 0; | ||
865 | } | 853 | } |
866 | 854 | ||
867 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { | 855 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { |
@@ -1254,20 +1242,19 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1254 | 1242 | ||
1255 | switch (event) { | 1243 | switch (event) { |
1256 | case CS_EVENT_CARD_REMOVAL: | 1244 | case CS_EVENT_CARD_REMOVAL: |
1257 | mutex_lock(&s->ops_mutex); | 1245 | atomic_set(&skt->present, 0); |
1258 | s->pcmcia_state.present = 0; | ||
1259 | mutex_unlock(&s->ops_mutex); | ||
1260 | pcmcia_card_remove(skt, NULL); | 1246 | pcmcia_card_remove(skt, NULL); |
1261 | handle_event(skt, event); | 1247 | handle_event(skt, event); |
1262 | mutex_lock(&s->ops_mutex); | 1248 | mutex_lock(&s->ops_mutex); |
1263 | destroy_cis_cache(s); | 1249 | destroy_cis_cache(s); |
1250 | pcmcia_cleanup_irq(s); | ||
1264 | mutex_unlock(&s->ops_mutex); | 1251 | mutex_unlock(&s->ops_mutex); |
1265 | break; | 1252 | break; |
1266 | 1253 | ||
1267 | case CS_EVENT_CARD_INSERTION: | 1254 | case CS_EVENT_CARD_INSERTION: |
1255 | atomic_set(&skt->present, 1); | ||
1268 | mutex_lock(&s->ops_mutex); | 1256 | mutex_lock(&s->ops_mutex); |
1269 | s->pcmcia_state.has_pfc = 0; | 1257 | s->pcmcia_state.has_pfc = 0; |
1270 | s->pcmcia_state.present = 1; | ||
1271 | destroy_cis_cache(s); /* to be on the safe side... */ | 1258 | destroy_cis_cache(s); /* to be on the safe side... */ |
1272 | mutex_unlock(&s->ops_mutex); | 1259 | mutex_unlock(&s->ops_mutex); |
1273 | pcmcia_card_add(skt); | 1260 | pcmcia_card_add(skt); |
@@ -1286,6 +1273,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1286 | destroy_cis_cache(skt); | 1273 | destroy_cis_cache(skt); |
1287 | kfree(skt->fake_cis); | 1274 | kfree(skt->fake_cis); |
1288 | skt->fake_cis = NULL; | 1275 | skt->fake_cis = NULL; |
1276 | s->functions = 0; | ||
1289 | mutex_unlock(&s->ops_mutex); | 1277 | mutex_unlock(&s->ops_mutex); |
1290 | /* now, add the new card */ | 1278 | /* now, add the new card */ |
1291 | ds_event(skt, CS_EVENT_CARD_INSERTION, | 1279 | ds_event(skt, CS_EVENT_CARD_INSERTION, |
@@ -1307,7 +1295,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1307 | return 0; | 1295 | return 0; |
1308 | } /* ds_event */ | 1296 | } /* ds_event */ |
1309 | 1297 | ||
1310 | 1298 | /* | |
1299 | * NOTE: This is racy. There's no guarantee the card will still be | ||
1300 | * physically present, even if the call to this function returns | ||
1301 | * non-NULL. Furthermore, the device driver most likely is unbound | ||
1302 | * almost immediately, so the timeframe where pcmcia_dev_present | ||
1303 | * returns NULL is probably really really small. | ||
1304 | */ | ||
1311 | struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | 1305 | struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) |
1312 | { | 1306 | { |
1313 | struct pcmcia_device *p_dev; | 1307 | struct pcmcia_device *p_dev; |
@@ -1317,22 +1311,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
1317 | if (!p_dev) | 1311 | if (!p_dev) |
1318 | return NULL; | 1312 | return NULL; |
1319 | 1313 | ||
1320 | mutex_lock(&p_dev->socket->ops_mutex); | 1314 | if (atomic_read(&p_dev->socket->present) != 0) |
1321 | if (!p_dev->socket->pcmcia_state.present) | 1315 | ret = p_dev; |
1322 | goto out; | ||
1323 | 1316 | ||
1324 | if (p_dev->socket->pcmcia_state.dead) | ||
1325 | goto out; | ||
1326 | |||
1327 | if (p_dev->_removed) | ||
1328 | goto out; | ||
1329 | |||
1330 | if (p_dev->suspended) | ||
1331 | goto out; | ||
1332 | |||
1333 | ret = p_dev; | ||
1334 | out: | ||
1335 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
1336 | pcmcia_put_dev(p_dev); | 1317 | pcmcia_put_dev(p_dev); |
1337 | return ret; | 1318 | return ret; |
1338 | } | 1319 | } |
@@ -1382,6 +1363,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, | |||
1382 | return ret; | 1363 | return ret; |
1383 | } | 1364 | } |
1384 | 1365 | ||
1366 | atomic_set(&socket->present, 0); | ||
1367 | |||
1385 | return 0; | 1368 | return 0; |
1386 | } | 1369 | } |
1387 | 1370 | ||
@@ -1393,10 +1376,6 @@ static void pcmcia_bus_remove_socket(struct device *dev, | |||
1393 | if (!socket) | 1376 | if (!socket) |
1394 | return; | 1377 | return; |
1395 | 1378 | ||
1396 | mutex_lock(&socket->ops_mutex); | ||
1397 | socket->pcmcia_state.dead = 1; | ||
1398 | mutex_unlock(&socket->ops_mutex); | ||
1399 | |||
1400 | pccard_register_pcmcia(socket, NULL); | 1379 | pccard_register_pcmcia(socket, NULL); |
1401 | 1380 | ||
1402 | /* unregister any unbound devices */ | 1381 | /* unregister any unbound devices */ |