diff options
| -rw-r--r-- | drivers/pcmcia/ds.c | 54 | ||||
| -rw-r--r-- | include/pcmcia/ds.h | 7 | ||||
| -rw-r--r-- | include/pcmcia/ss.h | 8 |
3 files changed, 24 insertions, 45 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 4014cf8e4a26..508f94a2a78d 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
| @@ -335,7 +335,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
| 335 | 335 | ||
| 336 | mutex_lock(&s->ops_mutex); | 336 | mutex_lock(&s->ops_mutex); |
| 337 | list_del(&p_dev->socket_device_list); | 337 | list_del(&p_dev->socket_device_list); |
| 338 | p_dev->_removed = 1; | ||
| 339 | mutex_unlock(&s->ops_mutex); | 338 | mutex_unlock(&s->ops_mutex); |
| 340 | 339 | ||
| 341 | dev_dbg(&p_dev->dev, "unregistering device\n"); | 340 | dev_dbg(&p_dev->dev, "unregistering device\n"); |
| @@ -654,14 +653,7 @@ static int pcmcia_requery_callback(struct device *dev, void * _data) | |||
| 654 | 653 | ||
| 655 | static void pcmcia_requery(struct pcmcia_socket *s) | 654 | static void pcmcia_requery(struct pcmcia_socket *s) |
| 656 | { | 655 | { |
| 657 | int present, has_pfc; | 656 | int has_pfc; |
| 658 | |||
| 659 | mutex_lock(&s->ops_mutex); | ||
| 660 | present = s->pcmcia_state.present; | ||
| 661 | mutex_unlock(&s->ops_mutex); | ||
| 662 | |||
| 663 | if (!present) | ||
| 664 | return; | ||
| 665 | 657 | ||
| 666 | if (s->functions == 0) { | 658 | if (s->functions == 0) { |
| 667 | pcmcia_card_add(s); | 659 | pcmcia_card_add(s); |
| @@ -828,11 +820,12 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
| 828 | } | 820 | } |
| 829 | 821 | ||
| 830 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { | 822 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { |
| 831 | if (dev->device_no != did->device_no) | 823 | dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n"); |
| 832 | return 0; | ||
| 833 | mutex_lock(&dev->socket->ops_mutex); | 824 | mutex_lock(&dev->socket->ops_mutex); |
| 834 | dev->socket->pcmcia_state.has_pfc = 1; | 825 | dev->socket->pcmcia_state.has_pfc = 1; |
| 835 | mutex_unlock(&dev->socket->ops_mutex); | 826 | mutex_unlock(&dev->socket->ops_mutex); |
| 827 | if (dev->device_no != did->device_no) | ||
| 828 | return 0; | ||
| 836 | } | 829 | } |
| 837 | 830 | ||
| 838 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { | 831 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_FUNC_ID) { |
| @@ -843,7 +836,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
| 843 | 836 | ||
| 844 | /* if this is a pseudo-multi-function device, | 837 | /* if this is a pseudo-multi-function device, |
| 845 | * we need explicit matches */ | 838 | * we need explicit matches */ |
| 846 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) | 839 | if (dev->socket->pcmcia_state.has_pfc) |
| 847 | return 0; | 840 | return 0; |
| 848 | if (dev->device_no) | 841 | if (dev->device_no) |
| 849 | return 0; | 842 | return 0; |
| @@ -1260,9 +1253,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
| 1260 | 1253 | ||
| 1261 | switch (event) { | 1254 | switch (event) { |
| 1262 | case CS_EVENT_CARD_REMOVAL: | 1255 | case CS_EVENT_CARD_REMOVAL: |
| 1263 | mutex_lock(&s->ops_mutex); | 1256 | atomic_set(&skt->present, 0); |
| 1264 | s->pcmcia_state.present = 0; | ||
| 1265 | mutex_unlock(&s->ops_mutex); | ||
| 1266 | pcmcia_card_remove(skt, NULL); | 1257 | pcmcia_card_remove(skt, NULL); |
| 1267 | handle_event(skt, event); | 1258 | handle_event(skt, event); |
| 1268 | mutex_lock(&s->ops_mutex); | 1259 | mutex_lock(&s->ops_mutex); |
| @@ -1271,9 +1262,9 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
| 1271 | break; | 1262 | break; |
| 1272 | 1263 | ||
| 1273 | case CS_EVENT_CARD_INSERTION: | 1264 | case CS_EVENT_CARD_INSERTION: |
| 1265 | atomic_set(&skt->present, 1); | ||
| 1274 | mutex_lock(&s->ops_mutex); | 1266 | mutex_lock(&s->ops_mutex); |
| 1275 | s->pcmcia_state.has_pfc = 0; | 1267 | s->pcmcia_state.has_pfc = 0; |
| 1276 | s->pcmcia_state.present = 1; | ||
| 1277 | destroy_cis_cache(s); /* to be on the safe side... */ | 1268 | destroy_cis_cache(s); /* to be on the safe side... */ |
| 1278 | mutex_unlock(&s->ops_mutex); | 1269 | mutex_unlock(&s->ops_mutex); |
| 1279 | pcmcia_card_add(skt); | 1270 | pcmcia_card_add(skt); |
| @@ -1313,7 +1304,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
| 1313 | return 0; | 1304 | return 0; |
| 1314 | } /* ds_event */ | 1305 | } /* ds_event */ |
| 1315 | 1306 | ||
| 1316 | 1307 | /* | |
| 1308 | * NOTE: This is racy. There's no guarantee the card will still be | ||
| 1309 | * physically present, even if the call to this function returns | ||
| 1310 | * non-NULL. Furthermore, the device driver most likely is unbound | ||
| 1311 | * almost immediately, so the timeframe where pcmcia_dev_present | ||
| 1312 | * returns NULL is probably really really small. | ||
| 1313 | */ | ||
| 1317 | struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | 1314 | struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) |
| 1318 | { | 1315 | { |
| 1319 | struct pcmcia_device *p_dev; | 1316 | struct pcmcia_device *p_dev; |
| @@ -1323,22 +1320,9 @@ struct pcmcia_device *pcmcia_dev_present(struct pcmcia_device *_p_dev) | |||
| 1323 | if (!p_dev) | 1320 | if (!p_dev) |
| 1324 | return NULL; | 1321 | return NULL; |
| 1325 | 1322 | ||
| 1326 | mutex_lock(&p_dev->socket->ops_mutex); | 1323 | if (atomic_read(&p_dev->socket->present) != 0) |
| 1327 | if (!p_dev->socket->pcmcia_state.present) | 1324 | ret = p_dev; |
| 1328 | goto out; | ||
| 1329 | |||
| 1330 | if (p_dev->socket->pcmcia_state.dead) | ||
| 1331 | goto out; | ||
| 1332 | 1325 | ||
| 1333 | if (p_dev->_removed) | ||
| 1334 | goto out; | ||
| 1335 | |||
| 1336 | if (p_dev->suspended) | ||
| 1337 | goto out; | ||
| 1338 | |||
| 1339 | ret = p_dev; | ||
| 1340 | out: | ||
| 1341 | mutex_unlock(&p_dev->socket->ops_mutex); | ||
| 1342 | pcmcia_put_dev(p_dev); | 1326 | pcmcia_put_dev(p_dev); |
| 1343 | return ret; | 1327 | return ret; |
| 1344 | } | 1328 | } |
| @@ -1388,6 +1372,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, | |||
| 1388 | return ret; | 1372 | return ret; |
| 1389 | } | 1373 | } |
| 1390 | 1374 | ||
| 1375 | atomic_set(&socket->present, 0); | ||
| 1376 | |||
| 1391 | return 0; | 1377 | return 0; |
| 1392 | } | 1378 | } |
| 1393 | 1379 | ||
| @@ -1399,10 +1385,6 @@ static void pcmcia_bus_remove_socket(struct device *dev, | |||
| 1399 | if (!socket) | 1385 | if (!socket) |
| 1400 | return; | 1386 | return; |
| 1401 | 1387 | ||
| 1402 | mutex_lock(&socket->ops_mutex); | ||
| 1403 | socket->pcmcia_state.dead = 1; | ||
| 1404 | mutex_unlock(&socket->ops_mutex); | ||
| 1405 | |||
| 1406 | pccard_register_pcmcia(socket, NULL); | 1388 | pccard_register_pcmcia(socket, NULL); |
| 1407 | 1389 | ||
| 1408 | /* unregister any unbound devices */ | 1390 | /* unregister any unbound devices */ |
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h index d57847f2f6c1..aab3c13dc310 100644 --- a/include/pcmcia/ds.h +++ b/include/pcmcia/ds.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #ifdef __KERNEL__ | 26 | #ifdef __KERNEL__ |
| 27 | #include <linux/device.h> | 27 | #include <linux/device.h> |
| 28 | #include <pcmcia/ss.h> | 28 | #include <pcmcia/ss.h> |
| 29 | #include <asm/atomic.h> | ||
| 29 | 30 | ||
| 30 | /* | 31 | /* |
| 31 | * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus | 32 | * PCMCIA device drivers (16-bit cards only; 32-bit cards require CardBus |
| @@ -94,10 +95,8 @@ struct pcmcia_device { | |||
| 94 | config_req_t conf; | 95 | config_req_t conf; |
| 95 | window_handle_t win; | 96 | window_handle_t win; |
| 96 | 97 | ||
| 97 | /* Is the device suspended, or in the process of | 98 | /* Is the device suspended? */ |
| 98 | * being removed? */ | ||
| 99 | u16 suspended:1; | 99 | u16 suspended:1; |
| 100 | u16 _removed:1; | ||
| 101 | 100 | ||
| 102 | /* Flags whether io, irq, win configurations were | 101 | /* Flags whether io, irq, win configurations were |
| 103 | * requested, and whether the configuration is "locked" */ | 102 | * requested, and whether the configuration is "locked" */ |
| @@ -115,7 +114,7 @@ struct pcmcia_device { | |||
| 115 | u16 has_card_id:1; | 114 | u16 has_card_id:1; |
| 116 | u16 has_func_id:1; | 115 | u16 has_func_id:1; |
| 117 | 116 | ||
| 118 | u16 reserved:3; | 117 | u16 reserved:4; |
| 119 | 118 | ||
| 120 | u8 func_id; | 119 | u8 func_id; |
| 121 | u16 manf_id; | 120 | u16 manf_id; |
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h index 2e488b60bc76..344705cb42f4 100644 --- a/include/pcmcia/ss.h +++ b/include/pcmcia/ss.h | |||
| @@ -224,18 +224,16 @@ struct pcmcia_socket { | |||
| 224 | 224 | ||
| 225 | /* 16-bit state: */ | 225 | /* 16-bit state: */ |
| 226 | struct { | 226 | struct { |
| 227 | /* PCMCIA card is present in socket */ | ||
| 228 | u8 present:1; | ||
| 229 | /* "master" ioctl is used */ | 227 | /* "master" ioctl is used */ |
| 230 | u8 busy:1; | 228 | u8 busy:1; |
| 231 | /* pcmcia module is being unloaded */ | ||
| 232 | u8 dead:1; | ||
| 233 | /* the PCMCIA card consists of two pseudo devices */ | 229 | /* the PCMCIA card consists of two pseudo devices */ |
| 234 | u8 has_pfc:1; | 230 | u8 has_pfc:1; |
| 235 | 231 | ||
| 236 | u8 reserved:4; | 232 | u8 reserved:6; |
| 237 | } pcmcia_state; | 233 | } pcmcia_state; |
| 238 | 234 | ||
| 235 | /* non-zero if PCMCIA card is present */ | ||
| 236 | atomic_t present; | ||
| 239 | 237 | ||
| 240 | #ifdef CONFIG_PCMCIA_IOCTL | 238 | #ifdef CONFIG_PCMCIA_IOCTL |
| 241 | struct user_info_t *user; | 239 | struct user_info_t *user; |
