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.c86
1 files changed, 40 insertions, 46 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index ad93ebd7b2a2..041eee43fd8d 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>
@@ -334,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le
334 335
335 mutex_lock(&s->ops_mutex); 336 mutex_lock(&s->ops_mutex);
336 list_del(&p_dev->socket_device_list); 337 list_del(&p_dev->socket_device_list);
337 p_dev->_removed = 1;
338 mutex_unlock(&s->ops_mutex); 338 mutex_unlock(&s->ops_mutex);
339 339
340 dev_dbg(&p_dev->dev, "unregistering device\n"); 340 dev_dbg(&p_dev->dev, "unregistering device\n");
@@ -509,8 +509,12 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu
509 p_dev->device_no = (s->device_count++); 509 p_dev->device_no = (s->device_count++);
510 mutex_unlock(&s->ops_mutex); 510 mutex_unlock(&s->ops_mutex);
511 511
512 /* max of 2 devices per card */ 512 /* max of 2 PFC devices */
513 if (p_dev->device_no >= 2) 513 if ((p_dev->device_no >= 2) && (function == 0))
514 goto err_free;
515
516 /* max of 4 devices overall */
517 if (p_dev->device_no >= 4)
514 goto err_free; 518 goto err_free;
515 519
516 p_dev->socket = s; 520 p_dev->socket = s;
@@ -649,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data)
649 653
650static void pcmcia_requery(struct pcmcia_socket *s) 654static void pcmcia_requery(struct pcmcia_socket *s)
651{ 655{
652 int present, has_pfc; 656 int has_pfc;
653
654 mutex_lock(&s->ops_mutex);
655 present = s->pcmcia_state.present;
656 mutex_unlock(&s->ops_mutex);
657
658 if (!present)
659 return;
660 657
661 if (s->functions == 0) { 658 if (s->functions == 0) {
662 pcmcia_card_add(s); 659 pcmcia_card_add(s);
@@ -682,12 +679,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
682 new_funcs = mfc.nfn; 679 new_funcs = mfc.nfn;
683 else 680 else
684 new_funcs = 1; 681 new_funcs = 1;
685 if (old_funcs > new_funcs) { 682 if (old_funcs != new_funcs) {
683 /* we need to re-start */
686 pcmcia_card_remove(s, NULL); 684 pcmcia_card_remove(s, NULL);
687 pcmcia_card_add(s); 685 pcmcia_card_add(s);
688 } else if (new_funcs > old_funcs) {
689 s->functions = new_funcs;
690 pcmcia_device_add(s, 1);
691 } 686 }
692 } 687 }
693 688
@@ -723,6 +718,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
723 struct pcmcia_socket *s = dev->socket; 718 struct pcmcia_socket *s = dev->socket;
724 const struct firmware *fw; 719 const struct firmware *fw;
725 int ret = -ENOMEM; 720 int ret = -ENOMEM;
721 cistpl_longlink_mfc_t mfc;
722 int old_funcs, new_funcs = 1;
726 723
727 if (!filename) 724 if (!filename)
728 return -EINVAL; 725 return -EINVAL;
@@ -745,6 +742,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
745 goto release; 742 goto release;
746 } 743 }
747 744
745 /* we need to re-start if the number of functions changed */
746 old_funcs = s->functions;
747 if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
748 &mfc))
749 new_funcs = mfc.nfn;
750
751 if (old_funcs != new_funcs)
752 ret = -EBUSY;
748 753
749 /* update information */ 754 /* update information */
750 pcmcia_device_query(dev); 755 pcmcia_device_query(dev);
@@ -815,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
815 } 820 }
816 821
817 if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { 822 if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) {
818 if (dev->device_no != did->device_no) 823 dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n");
819 return 0;
820 mutex_lock(&dev->socket->ops_mutex); 824 mutex_lock(&dev->socket->ops_mutex);
821 dev->socket->pcmcia_state.has_pfc = 1; 825 dev->socket->pcmcia_state.has_pfc = 1;
822 mutex_unlock(&dev->socket->ops_mutex); 826 mutex_unlock(&dev->socket->ops_mutex);
827 if (dev->device_no != did->device_no)
828 return 0;
823 } 829 }
824 830
825 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { 831 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) {
@@ -830,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
830 836
831 /* if this is a pseudo-multi-function device, 837 /* if this is a pseudo-multi-function device,
832 * we need explicit matches */ 838 * we need explicit matches */
833 if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) 839 if (dev->socket->pcmcia_state.has_pfc)
834 return 0; 840 return 0;
835 if (dev->device_no) 841 if (dev->device_no)
836 return 0; 842 return 0;
@@ -853,10 +859,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
853 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { 859 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
854 dev_dbg(&dev->dev, "device needs a fake CIS\n"); 860 dev_dbg(&dev->dev, "device needs a fake CIS\n");
855 if (!dev->socket->fake_cis) 861 if (!dev->socket->fake_cis)
856 pcmcia_load_firmware(dev, did->cisfile); 862 if (pcmcia_load_firmware(dev, did->cisfile))
857 863 return 0;
858 if (!dev->socket->fake_cis)
859 return 0;
860 } 864 }
861 865
862 if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { 866 if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
@@ -1249,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1249 1253
1250 switch (event) { 1254 switch (event) {
1251 case CS_EVENT_CARD_REMOVAL: 1255 case CS_EVENT_CARD_REMOVAL:
1252 mutex_lock(&s->ops_mutex); 1256 atomic_set(&skt->present, 0);
1253 s->pcmcia_state.present = 0;
1254 mutex_unlock(&s->ops_mutex);
1255 pcmcia_card_remove(skt, NULL); 1257 pcmcia_card_remove(skt, NULL);
1256 handle_event(skt, event); 1258 handle_event(skt, event);
1257 mutex_lock(&s->ops_mutex); 1259 mutex_lock(&s->ops_mutex);
@@ -1260,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1260 break; 1262 break;
1261 1263
1262 case CS_EVENT_CARD_INSERTION: 1264 case CS_EVENT_CARD_INSERTION:
1265 atomic_set(&skt->present, 1);
1263 mutex_lock(&s->ops_mutex); 1266 mutex_lock(&s->ops_mutex);
1264 s->pcmcia_state.has_pfc = 0; 1267 s->pcmcia_state.has_pfc = 0;
1265 s->pcmcia_state.present = 1;
1266 destroy_cis_cache(s); /* to be on the safe side... */ 1268 destroy_cis_cache(s); /* to be on the safe side... */
1267 mutex_unlock(&s->ops_mutex); 1269 mutex_unlock(&s->ops_mutex);
1268 pcmcia_card_add(skt); 1270 pcmcia_card_add(skt);
@@ -1281,6 +1283,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1281 destroy_cis_cache(skt); 1283 destroy_cis_cache(skt);
1282 kfree(skt->fake_cis); 1284 kfree(skt->fake_cis);
1283 skt->fake_cis = NULL; 1285 skt->fake_cis = NULL;
1286 s->functions = 0;
1284 mutex_unlock(&s->ops_mutex); 1287 mutex_unlock(&s->ops_mutex);
1285 /* now, add the new card */ 1288 /* now, add the new card */
1286 ds_event(skt, CS_EVENT_CARD_INSERTION, 1289 ds_event(skt, CS_EVENT_CARD_INSERTION,
@@ -1302,7 +1305,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1302 return 0; 1305 return 0;
1303} /* ds_event */ 1306} /* ds_event */
1304 1307
1305 1308/*
1309 * NOTE: This is racy. There's no guarantee the card will still be
1310 * physically present, even if the call to this function returns
1311 * non-NULL. Furthermore, the device driver most likely is unbound
1312 * almost immediately, so the timeframe where pcmcia_dev_present
1313 * returns NULL is probably really really small.
1314 */
1306struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) 1315struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
1307{ 1316{
1308 struct pcmcia_device *p_dev; 1317 struct pcmcia_device *p_dev;
@@ -1312,22 +1321,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev)
1312 if (!p_dev) 1321 if (!p_dev)
1313 return NULL; 1322 return NULL;
1314 1323
1315 mutex_lock(&p_dev->socket->ops_mutex); 1324 if (atomic_read(&p_dev->socket->present) != 0)
1316 if (!p_dev->socket->pcmcia_state.present) 1325 ret = p_dev;
1317 goto out;
1318
1319 if (p_dev->socket->pcmcia_state.dead)
1320 goto out;
1321 1326
1322 if (p_dev->_removed)
1323 goto out;
1324
1325 if (p_dev->suspended)
1326 goto out;
1327
1328 ret = p_dev;
1329 out:
1330 mutex_unlock(&p_dev->socket->ops_mutex);
1331 pcmcia_put_dev(p_dev); 1327 pcmcia_put_dev(p_dev);
1332 return ret; 1328 return ret;
1333} 1329}
@@ -1377,6 +1373,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
1377 return ret; 1373 return ret;
1378 } 1374 }
1379 1375
1376 atomic_set(&socket->present, 0);
1377
1380 return 0; 1378 return 0;
1381} 1379}
1382 1380
@@ -1388,10 +1386,6 @@ static void pcmcia_bus_remove_socket(struct device *dev,
1388 if (!socket) 1386 if (!socket)
1389 return; 1387 return;
1390 1388
1391 mutex_lock(&socket->ops_mutex);
1392 socket->pcmcia_state.dead = 1;
1393 mutex_unlock(&socket->ops_mutex);
1394
1395 pccard_register_pcmcia(socket, NULL); 1389 pccard_register_pcmcia(socket, NULL);
1396 1390
1397 /* unregister any unbound devices */ 1391 /* unregister any unbound devices */