diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-04-08 14:10:21 -0400 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-04-11 08:38:31 -0400 |
commit | b1095afe6fd6ea4c0d9e75489b955f898d6617d9 (patch) | |
tree | 65777d0feebe7e5710fdfa4419ce52d493992cf8 /drivers/pcmcia/ds.c | |
parent | 509b0865fbd8ab6c820397706dde980c1c285538 (diff) |
pcmcia: re-start on MFC override
If there are changes to the number of socket devices, we need to
start over in all cases: else pcmcia_request_configuration() might
get confused.
Reported-by: Alexander Kurz <linux@kbdbabel.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cb6036d89e59..4014cf8e4a26 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) | |||
687 | new_funcs = mfc.nfn; | 687 | new_funcs = mfc.nfn; |
688 | else | 688 | else |
689 | new_funcs = 1; | 689 | new_funcs = 1; |
690 | if (old_funcs > new_funcs) { | 690 | if (old_funcs != new_funcs) { |
691 | /* we need to re-start */ | ||
691 | pcmcia_card_remove(s, NULL); | 692 | pcmcia_card_remove(s, NULL); |
692 | pcmcia_card_add(s); | 693 | pcmcia_card_add(s); |
693 | } else if (new_funcs > old_funcs) { | ||
694 | s->functions = new_funcs; | ||
695 | pcmcia_device_add(s, 1); | ||
696 | } | 694 | } |
697 | } | 695 | } |
698 | 696 | ||
@@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
728 | struct pcmcia_socket *s = dev->socket; | 726 | struct pcmcia_socket *s = dev->socket; |
729 | const struct firmware *fw; | 727 | const struct firmware *fw; |
730 | int ret = -ENOMEM; | 728 | int ret = -ENOMEM; |
729 | cistpl_longlink_mfc_t mfc; | ||
730 | int old_funcs, new_funcs = 1; | ||
731 | 731 | ||
732 | if (!filename) | 732 | if (!filename) |
733 | return -EINVAL; | 733 | return -EINVAL; |
@@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | |||
750 | goto release; | 750 | goto release; |
751 | } | 751 | } |
752 | 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; | ||
753 | 761 | ||
754 | /* update information */ | 762 | /* update information */ |
755 | pcmcia_device_query(dev); | 763 | pcmcia_device_query(dev); |
@@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
858 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { | 866 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { |
859 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); | 867 | dev_dbg(&dev->dev, "device needs a fake CIS\n"); |
860 | if (!dev->socket->fake_cis) | 868 | if (!dev->socket->fake_cis) |
861 | pcmcia_load_firmware(dev, did->cisfile); | 869 | if (pcmcia_load_firmware(dev, did->cisfile)) |
862 | 870 | return 0; | |
863 | if (!dev->socket->fake_cis) | ||
864 | return 0; | ||
865 | } | 871 | } |
866 | 872 | ||
867 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { | 873 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { |