diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-04-08 20:10:21 +0200 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2010-04-11 14:38:31 +0200 |
commit | b1095afe6fd6ea4c0d9e75489b955f898d6617d9 (patch) | |
tree | 65777d0feebe7e5710fdfa4419ce52d493992cf8 | |
parent | 509b0865fbd8ab6c820397706dde980c1c285538 (diff) | |
download | linux-3.10-b1095afe6fd6ea4c0d9e75489b955f898d6617d9.tar.gz linux-3.10-b1095afe6fd6ea4c0d9e75489b955f898d6617d9.tar.bz2 linux-3.10-b1095afe6fd6ea4c0d9e75489b955f898d6617d9.zip |
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>
-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 cb6036d89e5..4014cf8e4a2 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s) new_funcs = mfc.nfn; else new_funcs = 1; - if (old_funcs > new_funcs) { + if (old_funcs != new_funcs) { + /* we need to re-start */ pcmcia_card_remove(s, NULL); pcmcia_card_add(s); - } else if (new_funcs > old_funcs) { - s->functions = new_funcs; - pcmcia_device_add(s, 1); } } @@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) struct pcmcia_socket *s = dev->socket; const struct firmware *fw; int ret = -ENOMEM; + cistpl_longlink_mfc_t mfc; + int old_funcs, new_funcs = 1; if (!filename) return -EINVAL; @@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) goto release; } + /* we need to re-start if the number of functions changed */ + old_funcs = s->functions; + if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC, + &mfc)) + new_funcs = mfc.nfn; + + if (old_funcs != new_funcs) + ret = -EBUSY; /* update information */ pcmcia_device_query(dev); @@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { dev_dbg(&dev->dev, "device needs a fake CIS\n"); if (!dev->socket->fake_cis) - pcmcia_load_firmware(dev, did->cisfile); - - if (!dev->socket->fake_cis) - return 0; + if (pcmcia_load_firmware(dev, did->cisfile)) + return 0; } if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { |