diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index ad93ebd7b2a2..4014cf8e4a26 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/firmware.h> | 24 | #include <linux/firmware.h> |
25 | #include <linux/kref.h> | 25 | #include <linux/kref.h> |
26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
27 | #include <linux/slab.h> | ||
27 | 28 | ||
28 | #include <pcmcia/cs_types.h> | 29 | #include <pcmcia/cs_types.h> |
29 | #include <pcmcia/cs.h> | 30 | #include <pcmcia/cs.h> |
@@ -509,8 +510,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
509 | p_dev->device_no = (s->device_count++); | 510 | p_dev->device_no = (s->device_count++); |
510 | mutex_unlock(&s->ops_mutex); | 511 | mutex_unlock(&s->ops_mutex); |
511 | 512 | ||
512 | /* max of 2 devices per card */ | 513 | /* max of 2 PFC devices */ |
513 | if (p_dev->device_no >= 2) | 514 | if ((p_dev->device_no >= 2) && (function == 0)) |
515 | goto err_free; | ||
516 | |||
517 | /* max of 4 devices overall */ | ||
518 | if (p_dev->device_no >= 4) | ||
514 | goto err_free; | 519 | goto err_free; |
515 | 520 | ||
516 | p_dev->socket = s; | 521 | p_dev->socket = s; |
@@ -682,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) | |||
682 | new_funcs = mfc.nfn; | 687 | new_funcs = mfc.nfn; |
683 | else | 688 | else |
684 | new_funcs = 1; | 689 | new_funcs = 1; |
685 | if (old_funcs > new_funcs) { | 690 | if (old_funcs != new_funcs) { |
691 | /* we need to re-start */ | ||
686 | pcmcia_card_remove(s, NULL); | 692 | pcmcia_card_remove(s, NULL); |
687 | pcmcia_card_add(s); | 693 | pcmcia_card_add(s); |
688 | } else if (new_funcs > old_funcs) { | ||
689 | s->functions = new_funcs; | ||
690 | pcmcia_device_add(s, 1); | ||
691 | } | 694 | } |
692 | } | 695 | } |
693 | 696 | ||
@@ -723,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
723 | struct pcmcia_socket *s = dev->socket; | 726 | struct pcmcia_socket *s = dev->socket; |
724 | const struct firmware *fw; | 727 | const struct firmware *fw; |
725 | int ret = -ENOMEM; | 728 | int ret = -ENOMEM; |
729 | cistpl_longlink_mfc_t mfc; | ||
730 | int old_funcs, new_funcs = 1; | ||
726 | 731 | ||
727 | if (!filename) | 732 | if (!filename) |
728 | return -EINVAL; | 733 | return -EINVAL; |
@@ -745,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
745 | goto release; | 750 | goto release; |
746 | } | 751 | } |
747 | 752 | ||
753 | /* we need to re-start if the number of functions changed */ | ||
754 | old_funcs = s->functions; | ||
755 | if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, | ||
756 | &mfc)) | ||
757 | new_funcs = mfc.nfn; | ||
758 | |||
759 | if (old_funcs != new_funcs) | ||
760 | ret = -EBUSY; | ||
748 | 761 | ||
749 | /* update information */ | 762 | /* update information */ |
750 | pcmcia_device_query(dev); | 763 | pcmcia_device_query(dev); |
@@ -853,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
853 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 866 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
854 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); | 867 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); |
855 | if (!dev->socket->fake_cis) | 868 | if (!dev->socket->fake_cis) |
856 | pcmcia_load_firmware(dev, did->cisfile); | 869 | if (pcmcia_load_firmware(dev, did->cisfile)) |
857 | 870 | return 0; | |
858 | if (!dev->socket->fake_cis) | ||
859 | return 0; | ||
860 | } | 871 | } |
861 | 872 | ||
862 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { | 873 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { |