ds.c (840c2ac5d3c1d50e8a181e3f661da814e89c8cf8) ds.c (1ad275e3e7d253d44f03868e85977c908e334fed)
1/*
2 * ds.c -- 16-bit PCMCIA core support
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds

--- 87 unchanged lines hidden (view full) ---

96 struct pcmcia_socket *parent;
97
98 /* the PCMCIA devices connected to this socket (normally one, more
99 * for multifunction devices: */
100 struct list_head devices_list;
101 u8 device_count; /* the number of devices, used
102 * only internally and subject
103 * to incorrectness and change */
1/*
2 * ds.c -- 16-bit PCMCIA core support
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds

--- 87 unchanged lines hidden (view full) ---

96 struct pcmcia_socket *parent;
97
98 /* the PCMCIA devices connected to this socket (normally one, more
99 * for multifunction devices: */
100 struct list_head devices_list;
101 u8 device_count; /* the number of devices, used
102 * only internally and subject
103 * to incorrectness and change */
104
105 u8 device_add_pending;
106 struct work_struct device_add;
104};
105static spinlock_t pcmcia_dev_list_lock;
106
107#define DS_SOCKET_PRESENT 0x01
108#define DS_SOCKET_BUSY 0x02
109#define DS_SOCKET_REMOVAL_PENDING 0x10
110#define DS_SOCKET_DEAD 0x80
111

--- 395 unchanged lines hidden (view full) ---

507 unsigned long flags;
508
509 s = pcmcia_get_bus_socket(s);
510 if (!s)
511 return NULL;
512
513 down(&device_add_lock);
514
107};
108static spinlock_t pcmcia_dev_list_lock;
109
110#define DS_SOCKET_PRESENT 0x01
111#define DS_SOCKET_BUSY 0x02
112#define DS_SOCKET_REMOVAL_PENDING 0x10
113#define DS_SOCKET_DEAD 0x80
114

--- 395 unchanged lines hidden (view full) ---

510 unsigned long flags;
511
512 s = pcmcia_get_bus_socket(s);
513 if (!s)
514 return NULL;
515
516 down(&device_add_lock);
517
518 /* max of 2 devices per card */
519 if (s->device_count == 2)
520 goto err_put;
521
515 p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
516 if (!p_dev)
517 goto err_put;
518 memset(p_dev, 0, sizeof(struct pcmcia_device));
519
520 p_dev->socket = s->parent;
521 p_dev->device_no = (s->device_count++);
522 p_dev->func = function;

--- 9 unchanged lines hidden (view full) ---

532 p_dev->client.Function = function;
533 p_dev->client.state = CLIENT_UNBOUND;
534
535 /* Add to the list in pcmcia_bus_socket */
536 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
537 list_add_tail(&p_dev->socket_device_list, &s->devices_list);
538 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
539
522 p_dev = kmalloc(sizeof(struct pcmcia_device), GFP_KERNEL);
523 if (!p_dev)
524 goto err_put;
525 memset(p_dev, 0, sizeof(struct pcmcia_device));
526
527 p_dev->socket = s->parent;
528 p_dev->device_no = (s->device_count++);
529 p_dev->func = function;

--- 9 unchanged lines hidden (view full) ---

539 p_dev->client.Function = function;
540 p_dev->client.state = CLIENT_UNBOUND;
541
542 /* Add to the list in pcmcia_bus_socket */
543 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
544 list_add_tail(&p_dev->socket_device_list, &s->devices_list);
545 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
546
547 pcmcia_device_query(p_dev);
548
540 if (device_register(&p_dev->dev)) {
541 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
542 list_del(&p_dev->socket_device_list);
543 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
544
545 goto err_free;
546 }
547

--- 38 unchanged lines hidden (view full) ---

586 * yet. */
587 for (i=0; i < no_funcs; i++)
588 pcmcia_device_add(s->pcmcia, i);
589
590 return (ret);
591}
592
593
549 if (device_register(&p_dev->dev)) {
550 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
551 list_del(&p_dev->socket_device_list);
552 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
553
554 goto err_free;
555 }
556

--- 38 unchanged lines hidden (view full) ---

595 * yet. */
596 for (i=0; i < no_funcs; i++)
597 pcmcia_device_add(s->pcmcia, i);
598
599 return (ret);
600}
601
602
603static void pcmcia_delayed_add_pseudo_device(void *data)
604{
605 struct pcmcia_bus_socket *s = data;
606 pcmcia_device_add(s, 0);
607 s->device_add_pending = 0;
608}
609
610static inline void pcmcia_add_pseudo_device(struct pcmcia_bus_socket *s)
611{
612 if (!s->device_add_pending) {
613 schedule_work(&s->device_add);
614 s->device_add_pending = 1;
615 }
616 return;
617}
618
619
620static inline int pcmcia_devmatch(struct pcmcia_device *dev,
621 struct pcmcia_device_id *did)
622{
623 if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {
624 if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))
625 return 0;
626 }
627
628 if (did->match_flags & PCMCIA_DEV_ID_MATCH_CARD_ID) {
629 if ((!dev->has_card_id) || (dev->card_id != did->card_id))
630 return 0;
631 }
632
633 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNCTION) {
634 if (dev->func != did->function)
635 return 0;
636 }
637
638 if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID1) {
639 if (!dev->prod_id[0])
640 return 0;
641 if (strcmp(did->prod_id[0], dev->prod_id[0]))
642 return 0;
643 }
644
645 if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID2) {
646 if (!dev->prod_id[1])
647 return 0;
648 if (strcmp(did->prod_id[1], dev->prod_id[1]))
649 return 0;
650 }
651
652 if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID3) {
653 if (!dev->prod_id[2])
654 return 0;
655 if (strcmp(did->prod_id[2], dev->prod_id[2]))
656 return 0;
657 }
658
659 if (did->match_flags & PCMCIA_DEV_ID_MATCH_PROD_ID4) {
660 if (!dev->prod_id[3])
661 return 0;
662 if (strcmp(did->prod_id[3], dev->prod_id[3]))
663 return 0;
664 }
665
666 if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
667 /* handle pseudo multifunction devices:
668 * there are at most two pseudo multifunction devices.
669 * if we're matching against the first, schedule a
670 * call which will then check whether there are two
671 * pseudo devices, and if not, add the second one.
672 */
673 if (dev->device_no == 0)
674 pcmcia_add_pseudo_device(dev->socket->pcmcia);
675
676 if (dev->device_no != did->device_no)
677 return 0;
678 }
679
680 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
681 if ((!dev->has_func_id) || (dev->func_id != did->func_id))
682 return 0;
683
684 /* if this is a pseudo-multi-function device,
685 * we need explicit matches */
686 if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO)
687 return 0;
688 if (dev->device_no)
689 return 0;
690
691 /* also, FUNC_ID matching needs to be activated by userspace
692 * after it has re-checked that there is no possible module
693 * with a prod_id/manf_id/card_id match.
694 */
695 if (!dev->allow_func_id_match)
696 return 0;
697 }
698
699 dev->dev.driver_data = (void *) did;
700
701 return 1;
702}
703
704
594static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
595 struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
596 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
705static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
706 struct pcmcia_device * p_dev = to_pcmcia_dev(dev);
707 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
708 struct pcmcia_device_id *did = p_drv->id_table;
597
598 /* matching by cardmgr */
599 if (p_dev->cardmgr == p_drv)
600 return 1;
601
709
710 /* matching by cardmgr */
711 if (p_dev->cardmgr == p_drv)
712 return 1;
713
714 while (did && did->match_flags) {
715 if (pcmcia_devmatch(p_dev, did))
716 return 1;
717 did++;
718 }
719
602 return 0;
603}
604
605#ifdef CONFIG_HOTPLUG
606
607static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
608 char *buffer, int buffer_size)
609{

--- 307 unchanged lines hidden (view full) ---

917 if (!p_dev) {
918 ret = -EIO;
919 goto err_put_module;
920 }
921
922rescan:
923 p_dev->cardmgr = p_drv;
924
720 return 0;
721}
722
723#ifdef CONFIG_HOTPLUG
724
725static int pcmcia_bus_hotplug(struct device *dev, char **envp, int num_envp,
726 char *buffer, int buffer_size)
727{

--- 307 unchanged lines hidden (view full) ---

1035 if (!p_dev) {
1036 ret = -EIO;
1037 goto err_put_module;
1038 }
1039
1040rescan:
1041 p_dev->cardmgr = p_drv;
1042
925 pcmcia_device_query(p_dev);
1043 /* if a driver is already running, we can abort */
1044 if (p_dev->dev.driver)
1045 goto err_put_module;
926
927 /*
928 * Prevent this racing with a card insertion.
929 */
930 down(&s->parent->skt_sem);
931 bus_rescan_devices(&pcmcia_bus_type);
932 up(&s->parent->skt_sem);
933

--- 656 unchanged lines hidden (view full) ---

1590 /*
1591 * Ugly. But we want to wait for the socket threads to have started up.
1592 * We really should let the drivers themselves drive some of this..
1593 */
1594 msleep(250);
1595
1596 init_waitqueue_head(&s->queue);
1597 INIT_LIST_HEAD(&s->devices_list);
1046
1047 /*
1048 * Prevent this racing with a card insertion.
1049 */
1050 down(&s->parent->skt_sem);
1051 bus_rescan_devices(&pcmcia_bus_type);
1052 up(&s->parent->skt_sem);
1053

--- 656 unchanged lines hidden (view full) ---

1710 /*
1711 * Ugly. But we want to wait for the socket threads to have started up.
1712 * We really should let the drivers themselves drive some of this..
1713 */
1714 msleep(250);
1715
1716 init_waitqueue_head(&s->queue);
1717 INIT_LIST_HEAD(&s->devices_list);
1718 INIT_WORK(&s->device_add, pcmcia_delayed_add_pseudo_device, s);
1598
1599 /* Set up hotline to Card Services */
1600 s->callback.owner = THIS_MODULE;
1601 s->callback.event = &ds_event;
1602 s->callback.resources_done = &pcmcia_card_add;
1603 socket->pcmcia = s;
1604
1605 ret = pccard_register_pcmcia(socket, &s->callback);

--- 121 unchanged lines hidden ---
1719
1720 /* Set up hotline to Card Services */
1721 s->callback.owner = THIS_MODULE;
1722 s->callback.event = &ds_event;
1723 s->callback.resources_done = &pcmcia_card_add;
1724 socket->pcmcia = s;
1725
1726 ret = pccard_register_pcmcia(socket, &s->callback);

--- 121 unchanged lines hidden ---