aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/ds.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r--drivers/pcmcia/ds.c31
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) {