diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2005-06-27 19:28:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-27 21:03:19 -0400 |
commit | dc109497bd5799770fedfc6503119808497b3677 (patch) | |
tree | 04b2a219ab92511c2fe37220543405fa4ff86d49 /drivers/pcmcia | |
parent | b5e43913cfe95a18ad8929585a0bb58e46cf3390 (diff) |
[PATCH] pcmcia: merge struct pcmcia_bus_socket into struct pcmcia_socket
Merge struct pcmcia_bus_socket into struct pcmcia_socket.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r-- | drivers/pcmcia/ds.c | 123 | ||||
-rw-r--r-- | drivers/pcmcia/ds_internal.h | 45 | ||||
-rw-r--r-- | drivers/pcmcia/pcmcia_ioctl.c | 97 |
3 files changed, 90 insertions, 175 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 85e2cb2b9e91..f796dcd64dcb 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -75,7 +75,7 @@ module_param_named(pc_debug, ds_pc_debug, int, 0644); | |||
75 | 75 | ||
76 | spinlock_t pcmcia_dev_list_lock; | 76 | spinlock_t pcmcia_dev_list_lock; |
77 | 77 | ||
78 | static int unbind_request(struct pcmcia_bus_socket *s); | 78 | static int unbind_request(struct pcmcia_socket *s); |
79 | 79 | ||
80 | /*====================================================================*/ | 80 | /*====================================================================*/ |
81 | 81 | ||
@@ -313,24 +313,6 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam | |||
313 | /*======================================================================*/ | 313 | /*======================================================================*/ |
314 | 314 | ||
315 | 315 | ||
316 | void pcmcia_release_bus_socket(struct kref *refcount) | ||
317 | { | ||
318 | struct pcmcia_bus_socket *s = container_of(refcount, struct pcmcia_bus_socket, refcount); | ||
319 | pcmcia_put_socket(s->parent); | ||
320 | kfree(s); | ||
321 | } | ||
322 | |||
323 | void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s) | ||
324 | { | ||
325 | kref_put(&s->refcount, pcmcia_release_bus_socket); | ||
326 | } | ||
327 | |||
328 | struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s) | ||
329 | { | ||
330 | kref_get(&s->refcount); | ||
331 | return (s); | ||
332 | } | ||
333 | |||
334 | /** | 316 | /** |
335 | * pcmcia_register_driver - register a PCMCIA driver with the bus core | 317 | * pcmcia_register_driver - register a PCMCIA driver with the bus core |
336 | * | 318 | * |
@@ -387,7 +369,7 @@ static void pcmcia_release_dev(struct device *dev) | |||
387 | { | 369 | { |
388 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 370 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
389 | ds_dbg(1, "releasing dev %p\n", p_dev); | 371 | ds_dbg(1, "releasing dev %p\n", p_dev); |
390 | pcmcia_put_bus_socket(p_dev->socket->pcmcia); | 372 | pcmcia_put_socket(p_dev->socket); |
391 | kfree(p_dev); | 373 | kfree(p_dev); |
392 | } | 374 | } |
393 | 375 | ||
@@ -522,12 +504,12 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
522 | */ | 504 | */ |
523 | static DECLARE_MUTEX(device_add_lock); | 505 | static DECLARE_MUTEX(device_add_lock); |
524 | 506 | ||
525 | struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function) | 507 | struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) |
526 | { | 508 | { |
527 | struct pcmcia_device *p_dev; | 509 | struct pcmcia_device *p_dev; |
528 | unsigned long flags; | 510 | unsigned long flags; |
529 | 511 | ||
530 | s = pcmcia_get_bus_socket(s); | 512 | s = pcmcia_get_socket(s); |
531 | if (!s) | 513 | if (!s) |
532 | return NULL; | 514 | return NULL; |
533 | 515 | ||
@@ -542,18 +524,18 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned i | |||
542 | goto err_put; | 524 | goto err_put; |
543 | memset(p_dev, 0, sizeof(struct pcmcia_device)); | 525 | memset(p_dev, 0, sizeof(struct pcmcia_device)); |
544 | 526 | ||
545 | p_dev->socket = s->parent; | 527 | p_dev->socket = s; |
546 | p_dev->device_no = (s->device_count++); | 528 | p_dev->device_no = (s->device_count++); |
547 | p_dev->func = function; | 529 | p_dev->func = function; |
548 | 530 | ||
549 | p_dev->dev.bus = &pcmcia_bus_type; | 531 | p_dev->dev.bus = &pcmcia_bus_type; |
550 | p_dev->dev.parent = s->parent->dev.dev; | 532 | p_dev->dev.parent = s->dev.dev; |
551 | p_dev->dev.release = pcmcia_release_dev; | 533 | p_dev->dev.release = pcmcia_release_dev; |
552 | sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); | 534 | sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); |
553 | 535 | ||
554 | /* compat */ | 536 | /* compat */ |
555 | p_dev->client.client_magic = CLIENT_MAGIC; | 537 | p_dev->client.client_magic = CLIENT_MAGIC; |
556 | p_dev->client.Socket = s->parent; | 538 | p_dev->client.Socket = s; |
557 | p_dev->client.Function = function; | 539 | p_dev->client.Function = function; |
558 | p_dev->client.state = CLIENT_UNBOUND; | 540 | p_dev->client.state = CLIENT_UNBOUND; |
559 | 541 | ||
@@ -581,7 +563,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned i | |||
581 | s->device_count--; | 563 | s->device_count--; |
582 | err_put: | 564 | err_put: |
583 | up(&device_add_lock); | 565 | up(&device_add_lock); |
584 | pcmcia_put_bus_socket(s); | 566 | pcmcia_put_socket(s); |
585 | 567 | ||
586 | return NULL; | 568 | return NULL; |
587 | } | 569 | } |
@@ -612,7 +594,7 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
612 | /* this doesn't handle multifunction devices on one pcmcia function | 594 | /* this doesn't handle multifunction devices on one pcmcia function |
613 | * yet. */ | 595 | * yet. */ |
614 | for (i=0; i < no_funcs; i++) | 596 | for (i=0; i < no_funcs; i++) |
615 | pcmcia_device_add(s->pcmcia, i); | 597 | pcmcia_device_add(s, i); |
616 | 598 | ||
617 | return (ret); | 599 | return (ret); |
618 | } | 600 | } |
@@ -620,12 +602,12 @@ static int pcmcia_card_add(struct pcmcia_socket *s) | |||
620 | 602 | ||
621 | static void pcmcia_delayed_add_pseudo_device(void *data) | 603 | static void pcmcia_delayed_add_pseudo_device(void *data) |
622 | { | 604 | { |
623 | struct pcmcia_bus_socket *s = data; | 605 | struct pcmcia_socket *s = data; |
624 | pcmcia_device_add(s, 0); | 606 | pcmcia_device_add(s, 0); |
625 | s->pcmcia_state.device_add_pending = 0; | 607 | s->pcmcia_state.device_add_pending = 0; |
626 | } | 608 | } |
627 | 609 | ||
628 | static inline void pcmcia_add_pseudo_device(struct pcmcia_bus_socket *s) | 610 | static inline void pcmcia_add_pseudo_device(struct pcmcia_socket *s) |
629 | { | 611 | { |
630 | if (!s->pcmcia_state.device_add_pending) { | 612 | if (!s->pcmcia_state.device_add_pending) { |
631 | schedule_work(&s->device_add); | 613 | schedule_work(&s->device_add); |
@@ -650,7 +632,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt) | |||
650 | 632 | ||
651 | /* must be called with skt_sem held */ | 633 | /* must be called with skt_sem held */ |
652 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 634 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
653 | if (list_empty(&skt->pcmcia->devices_list)) | 635 | if (list_empty(&skt->devices_list)) |
654 | no_devices=1; | 636 | no_devices=1; |
655 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 637 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
656 | 638 | ||
@@ -727,7 +709,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
727 | * pseudo devices, and if not, add the second one. | 709 | * pseudo devices, and if not, add the second one. |
728 | */ | 710 | */ |
729 | if (dev->device_no == 0) | 711 | if (dev->device_no == 0) |
730 | pcmcia_add_pseudo_device(dev->socket->pcmcia); | 712 | pcmcia_add_pseudo_device(dev->socket); |
731 | 713 | ||
732 | if (dev->device_no != did->device_no) | 714 | if (dev->device_no != did->device_no) |
733 | return 0; | 715 | return 0; |
@@ -947,21 +929,13 @@ static int send_event_callback(struct device *dev, void * _data) | |||
947 | 929 | ||
948 | static int send_event(struct pcmcia_socket *s, event_t event, int priority) | 930 | static int send_event(struct pcmcia_socket *s, event_t event, int priority) |
949 | { | 931 | { |
950 | int ret = 0; | ||
951 | struct send_event_data private; | 932 | struct send_event_data private; |
952 | struct pcmcia_bus_socket *skt = pcmcia_get_bus_socket(s->pcmcia); | ||
953 | |||
954 | if (!skt) | ||
955 | return 0; | ||
956 | 933 | ||
957 | private.skt = s; | 934 | private.skt = s; |
958 | private.event = event; | 935 | private.event = event; |
959 | private.priority = priority; | 936 | private.priority = priority; |
960 | 937 | ||
961 | ret = bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); | 938 | return bus_for_each_dev(&pcmcia_bus_type, NULL, &private, send_event_callback); |
962 | |||
963 | pcmcia_put_bus_socket(skt); | ||
964 | return ret; | ||
965 | } /* send_event */ | 939 | } /* send_event */ |
966 | 940 | ||
967 | 941 | ||
@@ -972,25 +946,25 @@ static int send_event(struct pcmcia_socket *s, event_t event, int priority) | |||
972 | 946 | ||
973 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | 947 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) |
974 | { | 948 | { |
975 | struct pcmcia_bus_socket *s = skt->pcmcia; | 949 | struct pcmcia_socket *s = pcmcia_get_socket(skt); |
976 | int ret = 0; | 950 | int ret = 0; |
977 | 951 | ||
978 | ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", | 952 | ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", |
979 | event, priority, s); | 953 | event, priority, skt); |
980 | 954 | ||
981 | switch (event) { | 955 | switch (event) { |
982 | 956 | ||
983 | case CS_EVENT_CARD_REMOVAL: | 957 | case CS_EVENT_CARD_REMOVAL: |
984 | s->pcmcia_state.present = 0; | 958 | s->pcmcia_state.present = 0; |
985 | send_event(skt, event, priority); | 959 | send_event(skt, event, priority); |
986 | unbind_request(s); | 960 | unbind_request(skt); |
987 | handle_event(s, event); | 961 | handle_event(skt, event); |
988 | break; | 962 | break; |
989 | 963 | ||
990 | case CS_EVENT_CARD_INSERTION: | 964 | case CS_EVENT_CARD_INSERTION: |
991 | s->pcmcia_state.present = 1; | 965 | s->pcmcia_state.present = 1; |
992 | pcmcia_card_add(skt); | 966 | pcmcia_card_add(skt); |
993 | handle_event(s, event); | 967 | handle_event(skt, event); |
994 | break; | 968 | break; |
995 | 969 | ||
996 | case CS_EVENT_EJECTION_REQUEST: | 970 | case CS_EVENT_EJECTION_REQUEST: |
@@ -998,11 +972,13 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
998 | break; | 972 | break; |
999 | 973 | ||
1000 | default: | 974 | default: |
1001 | handle_event(s, event); | 975 | handle_event(skt, event); |
1002 | send_event(skt, event, priority); | 976 | send_event(skt, event, priority); |
1003 | break; | 977 | break; |
1004 | } | 978 | } |
1005 | 979 | ||
980 | pcmcia_put_socket(s); | ||
981 | |||
1006 | return 0; | 982 | return 0; |
1007 | } /* ds_event */ | 983 | } /* ds_event */ |
1008 | 984 | ||
@@ -1011,8 +987,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | |||
1011 | int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | 987 | int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) |
1012 | { | 988 | { |
1013 | client_t *client = NULL; | 989 | client_t *client = NULL; |
1014 | struct pcmcia_socket *s; | 990 | struct pcmcia_socket *s = NULL; |
1015 | struct pcmcia_bus_socket *skt = NULL; | ||
1016 | struct pcmcia_device *p_dev = NULL; | 991 | struct pcmcia_device *p_dev = NULL; |
1017 | 992 | ||
1018 | /* Look for unbound client with matching dev_info */ | 993 | /* Look for unbound client with matching dev_info */ |
@@ -1023,14 +998,11 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
1023 | if (s->state & SOCKET_CARDBUS) | 998 | if (s->state & SOCKET_CARDBUS) |
1024 | continue; | 999 | continue; |
1025 | 1000 | ||
1026 | skt = s->pcmcia; | 1001 | s = pcmcia_get_socket(s); |
1027 | if (!skt) | 1002 | if (!s) |
1028 | continue; | ||
1029 | skt = pcmcia_get_bus_socket(skt); | ||
1030 | if (!skt) | ||
1031 | continue; | 1003 | continue; |
1032 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 1004 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
1033 | list_for_each_entry(p_dev, &skt->devices_list, socket_device_list) { | 1005 | list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { |
1034 | struct pcmcia_driver *p_drv; | 1006 | struct pcmcia_driver *p_drv; |
1035 | p_dev = pcmcia_get_dev(p_dev); | 1007 | p_dev = pcmcia_get_dev(p_dev); |
1036 | if (!p_dev) | 1008 | if (!p_dev) |
@@ -1049,14 +1021,14 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
1049 | pcmcia_put_dev(p_dev); | 1021 | pcmcia_put_dev(p_dev); |
1050 | } | 1022 | } |
1051 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 1023 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
1052 | pcmcia_put_bus_socket(skt); | 1024 | pcmcia_put_socket(s); |
1053 | } | 1025 | } |
1054 | found: | 1026 | found: |
1055 | up_read(&pcmcia_socket_list_rwsem); | 1027 | up_read(&pcmcia_socket_list_rwsem); |
1056 | if (!p_dev || !client) | 1028 | if (!p_dev || !client) |
1057 | return -ENODEV; | 1029 | return -ENODEV; |
1058 | 1030 | ||
1059 | pcmcia_put_bus_socket(skt); /* safe, as we already hold a reference from bind_device */ | 1031 | pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */ |
1060 | 1032 | ||
1061 | *handle = client; | 1033 | *handle = client; |
1062 | client->state &= ~CLIENT_UNBOUND; | 1034 | client->state &= ~CLIENT_UNBOUND; |
@@ -1106,12 +1078,12 @@ EXPORT_SYMBOL(pcmcia_register_client); | |||
1106 | /* unbind _all_ devices attached to a given pcmcia_bus_socket. The | 1078 | /* unbind _all_ devices attached to a given pcmcia_bus_socket. The |
1107 | * drivers have been called with EVENT_CARD_REMOVAL before. | 1079 | * drivers have been called with EVENT_CARD_REMOVAL before. |
1108 | */ | 1080 | */ |
1109 | static int unbind_request(struct pcmcia_bus_socket *s) | 1081 | static int unbind_request(struct pcmcia_socket *s) |
1110 | { | 1082 | { |
1111 | struct pcmcia_device *p_dev; | 1083 | struct pcmcia_device *p_dev; |
1112 | unsigned long flags; | 1084 | unsigned long flags; |
1113 | 1085 | ||
1114 | ds_dbg(2, "unbind_request(%d)\n", s->parent->sock); | 1086 | ds_dbg(2, "unbind_request(%d)\n", s->sock); |
1115 | 1087 | ||
1116 | s->device_count = 0; | 1088 | s->device_count = 0; |
1117 | 1089 | ||
@@ -1176,24 +1148,14 @@ static struct pcmcia_callback pcmcia_bus_callback = { | |||
1176 | static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) | 1148 | static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) |
1177 | { | 1149 | { |
1178 | struct pcmcia_socket *socket = class_get_devdata(class_dev); | 1150 | struct pcmcia_socket *socket = class_get_devdata(class_dev); |
1179 | struct pcmcia_bus_socket *s; | ||
1180 | int ret; | 1151 | int ret; |
1181 | 1152 | ||
1182 | s = kmalloc(sizeof(struct pcmcia_bus_socket), GFP_KERNEL); | 1153 | socket = pcmcia_get_socket(socket); |
1183 | if(!s) | 1154 | if (!socket) { |
1184 | return -ENOMEM; | ||
1185 | memset(s, 0, sizeof(struct pcmcia_bus_socket)); | ||
1186 | |||
1187 | /* get reference to parent socket */ | ||
1188 | s->parent = pcmcia_get_socket(socket); | ||
1189 | if (!s->parent) { | ||
1190 | printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); | 1155 | printk(KERN_ERR "PCMCIA obtaining reference to socket %p failed\n", socket); |
1191 | kfree (s); | ||
1192 | return -ENODEV; | 1156 | return -ENODEV; |
1193 | } | 1157 | } |
1194 | 1158 | ||
1195 | kref_init(&s->refcount); | ||
1196 | |||
1197 | /* | 1159 | /* |
1198 | * Ugly. But we want to wait for the socket threads to have started up. | 1160 | * Ugly. But we want to wait for the socket threads to have started up. |
1199 | * We really should let the drivers themselves drive some of this.. | 1161 | * We really should let the drivers themselves drive some of this.. |
@@ -1201,19 +1163,17 @@ static int __devinit pcmcia_bus_add_socket(struct class_device *class_dev) | |||
1201 | msleep(250); | 1163 | msleep(250); |
1202 | 1164 | ||
1203 | #ifdef CONFIG_PCMCIA_IOCTL | 1165 | #ifdef CONFIG_PCMCIA_IOCTL |
1204 | init_waitqueue_head(&s->queue); | 1166 | init_waitqueue_head(&socket->queue); |
1205 | #endif | 1167 | #endif |
1206 | INIT_LIST_HEAD(&s->devices_list); | 1168 | INIT_LIST_HEAD(&socket->devices_list); |
1207 | INIT_WORK(&s->device_add, pcmcia_delayed_add_pseudo_device, s); | 1169 | INIT_WORK(&socket->device_add, pcmcia_delayed_add_pseudo_device, socket); |
1208 | 1170 | memset(&socket->pcmcia_state, 0, sizeof(u8)); | |
1209 | /* Set up hotline to Card Services */ | 1171 | socket->device_count = 0; |
1210 | socket->pcmcia = s; | ||
1211 | 1172 | ||
1212 | ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback); | 1173 | ret = pccard_register_pcmcia(socket, &pcmcia_bus_callback); |
1213 | if (ret) { | 1174 | if (ret) { |
1214 | printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket); | 1175 | printk(KERN_ERR "PCMCIA registration PCCard core failed for socket %p\n", socket); |
1215 | pcmcia_put_bus_socket(s); | 1176 | pcmcia_put_socket(socket); |
1216 | socket->pcmcia = NULL; | ||
1217 | return (ret); | 1177 | return (ret); |
1218 | } | 1178 | } |
1219 | 1179 | ||
@@ -1224,14 +1184,13 @@ static void pcmcia_bus_remove_socket(struct class_device *class_dev) | |||
1224 | { | 1184 | { |
1225 | struct pcmcia_socket *socket = class_get_devdata(class_dev); | 1185 | struct pcmcia_socket *socket = class_get_devdata(class_dev); |
1226 | 1186 | ||
1227 | if (!socket || !socket->pcmcia) | 1187 | if (!socket) |
1228 | return; | 1188 | return; |
1229 | 1189 | ||
1190 | socket->pcmcia_state.dead = 1; | ||
1230 | pccard_register_pcmcia(socket, NULL); | 1191 | pccard_register_pcmcia(socket, NULL); |
1231 | 1192 | ||
1232 | socket->pcmcia->pcmcia_state.dead = 1; | 1193 | pcmcia_put_socket(socket); |
1233 | pcmcia_put_bus_socket(socket->pcmcia); | ||
1234 | socket->pcmcia = NULL; | ||
1235 | 1194 | ||
1236 | return; | 1195 | return; |
1237 | } | 1196 | } |
diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h index 2c3bb189dec6..d359bd25a51c 100644 --- a/drivers/pcmcia/ds_internal.h +++ b/drivers/pcmcia/ds_internal.h | |||
@@ -1,56 +1,21 @@ | |||
1 | /* ds_internal.h - internal header for 16-bit PCMCIA devices management */ | 1 | /* ds_internal.h - internal header for 16-bit PCMCIA devices management */ |
2 | 2 | ||
3 | struct user_info_t; | ||
4 | |||
5 | /* Socket state information */ | ||
6 | struct pcmcia_bus_socket { | ||
7 | struct kref refcount; | ||
8 | struct pcmcia_socket *parent; | ||
9 | |||
10 | /* the PCMCIA devices connected to this socket (normally one, more | ||
11 | * for multifunction devices: */ | ||
12 | struct list_head devices_list; | ||
13 | u8 device_count; /* the number of devices, used | ||
14 | * only internally and subject | ||
15 | * to incorrectness and change */ | ||
16 | |||
17 | struct { | ||
18 | u8 present:1, | ||
19 | busy:1, | ||
20 | dead:1, | ||
21 | device_add_pending:1, | ||
22 | reserved:4; | ||
23 | } pcmcia_state; | ||
24 | |||
25 | struct work_struct device_add; | ||
26 | |||
27 | |||
28 | #ifdef CONFIG_PCMCIA_IOCTL | ||
29 | struct user_info_t *user; | ||
30 | wait_queue_head_t queue; | ||
31 | #endif | ||
32 | }; | ||
33 | extern spinlock_t pcmcia_dev_list_lock; | 3 | extern spinlock_t pcmcia_dev_list_lock; |
34 | |||
35 | extern struct bus_type pcmcia_bus_type; | 4 | extern struct bus_type pcmcia_bus_type; |
36 | 5 | ||
37 | |||
38 | extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev); | 6 | extern struct pcmcia_device * pcmcia_get_dev(struct pcmcia_device *p_dev); |
39 | extern void pcmcia_put_dev(struct pcmcia_device *p_dev); | 7 | extern void pcmcia_put_dev(struct pcmcia_device *p_dev); |
40 | 8 | ||
41 | struct pcmcia_bus_socket *pcmcia_get_bus_socket(struct pcmcia_bus_socket *s); | 9 | struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); |
42 | void pcmcia_put_bus_socket(struct pcmcia_bus_socket *s); | ||
43 | |||
44 | struct pcmcia_device * pcmcia_device_add(struct pcmcia_bus_socket *s, unsigned int function); | ||
45 | 10 | ||
46 | #ifdef CONFIG_PCMCIA_IOCTL | 11 | #ifdef CONFIG_PCMCIA_IOCTL |
47 | extern void __init pcmcia_setup_ioctl(void); | 12 | extern void __init pcmcia_setup_ioctl(void); |
48 | extern void __exit pcmcia_cleanup_ioctl(void); | 13 | extern void __exit pcmcia_cleanup_ioctl(void); |
49 | extern void handle_event(struct pcmcia_bus_socket *s, event_t event); | 14 | extern void handle_event(struct pcmcia_socket *s, event_t event); |
50 | extern int handle_request(struct pcmcia_bus_socket *s, event_t event); | 15 | extern int handle_request(struct pcmcia_socket *s, event_t event); |
51 | #else | 16 | #else |
52 | static inline void __init pcmcia_setup_ioctl(void) { return; } | 17 | static inline void __init pcmcia_setup_ioctl(void) { return; } |
53 | static inline void __init pcmcia_cleanup_ioctl(void) { return; } | 18 | static inline void __init pcmcia_cleanup_ioctl(void) { return; } |
54 | static inline void handle_event(struct pcmcia_bus_socket *s, event_t event) { return; } | 19 | static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } |
55 | static inline int handle_request(struct pcmcia_bus_socket *s, event_t event) { return CS_SUCCESS; } | 20 | static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } |
56 | #endif | 21 | #endif |
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index b223f5235de7..0bebfdbdc27b 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c | |||
@@ -70,7 +70,7 @@ typedef struct user_info_t { | |||
70 | int event_head, event_tail; | 70 | int event_head, event_tail; |
71 | event_t event[MAX_EVENTS]; | 71 | event_t event[MAX_EVENTS]; |
72 | struct user_info_t *next; | 72 | struct user_info_t *next; |
73 | struct pcmcia_bus_socket *socket; | 73 | struct pcmcia_socket *socket; |
74 | } user_info_t; | 74 | } user_info_t; |
75 | 75 | ||
76 | 76 | ||
@@ -87,15 +87,6 @@ extern int ds_pc_debug; | |||
87 | #endif | 87 | #endif |
88 | 88 | ||
89 | 89 | ||
90 | static struct pcmcia_bus_socket * get_socket_info_by_nr(unsigned int nr) | ||
91 | { | ||
92 | struct pcmcia_socket * s = pcmcia_get_socket_by_nr(nr); | ||
93 | if (s && s->pcmcia) | ||
94 | return s->pcmcia; | ||
95 | else | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | /* backwards-compatible accessing of driver --- by name! */ | 90 | /* backwards-compatible accessing of driver --- by name! */ |
100 | 91 | ||
101 | static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) | 92 | static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) |
@@ -172,7 +163,7 @@ static void queue_event(user_info_t *user, event_t event) | |||
172 | user->event[user->event_head] = event; | 163 | user->event[user->event_head] = event; |
173 | } | 164 | } |
174 | 165 | ||
175 | void handle_event(struct pcmcia_bus_socket *s, event_t event) | 166 | void handle_event(struct pcmcia_socket *s, event_t event) |
176 | { | 167 | { |
177 | user_info_t *user; | 168 | user_info_t *user; |
178 | for (user = s->user; user; user = user->next) | 169 | for (user = s->user; user; user = user->next) |
@@ -204,18 +195,18 @@ void handle_event(struct pcmcia_bus_socket *s, event_t event) | |||
204 | 195 | ||
205 | ======================================================================*/ | 196 | ======================================================================*/ |
206 | 197 | ||
207 | static int bind_request(struct pcmcia_bus_socket *s, bind_info_t *bind_info) | 198 | static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info) |
208 | { | 199 | { |
209 | struct pcmcia_driver *p_drv; | 200 | struct pcmcia_driver *p_drv; |
210 | struct pcmcia_device *p_dev; | 201 | struct pcmcia_device *p_dev; |
211 | int ret = 0; | 202 | int ret = 0; |
212 | unsigned long flags; | 203 | unsigned long flags; |
213 | 204 | ||
214 | s = pcmcia_get_bus_socket(s); | 205 | s = pcmcia_get_socket(s); |
215 | if (!s) | 206 | if (!s) |
216 | return -EINVAL; | 207 | return -EINVAL; |
217 | 208 | ||
218 | ds_dbg(2, "bind_request(%d, '%s')\n", s->parent->sock, | 209 | ds_dbg(2, "bind_request(%d, '%s')\n", s->sock, |
219 | (char *)bind_info->dev_info); | 210 | (char *)bind_info->dev_info); |
220 | 211 | ||
221 | p_drv = get_pcmcia_driver(&bind_info->dev_info); | 212 | p_drv = get_pcmcia_driver(&bind_info->dev_info); |
@@ -278,9 +269,9 @@ rescan: | |||
278 | /* | 269 | /* |
279 | * Prevent this racing with a card insertion. | 270 | * Prevent this racing with a card insertion. |
280 | */ | 271 | */ |
281 | down(&s->parent->skt_sem); | 272 | down(&s->skt_sem); |
282 | bus_rescan_devices(&pcmcia_bus_type); | 273 | bus_rescan_devices(&pcmcia_bus_type); |
283 | up(&s->parent->skt_sem); | 274 | up(&s->skt_sem); |
284 | 275 | ||
285 | /* check whether the driver indeed matched. I don't care if this | 276 | /* check whether the driver indeed matched. I don't care if this |
286 | * is racy or not, because it can only happen on cardmgr access | 277 | * is racy or not, because it can only happen on cardmgr access |
@@ -294,7 +285,7 @@ rescan: | |||
294 | err_put_driver: | 285 | err_put_driver: |
295 | put_driver(&p_drv->drv); | 286 | put_driver(&p_drv->drv); |
296 | err_put: | 287 | err_put: |
297 | pcmcia_put_bus_socket(s); | 288 | pcmcia_put_socket(s); |
298 | 289 | ||
299 | return (ret); | 290 | return (ret); |
300 | } /* bind_request */ | 291 | } /* bind_request */ |
@@ -302,7 +293,7 @@ rescan: | |||
302 | 293 | ||
303 | extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s); | 294 | extern struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s); |
304 | 295 | ||
305 | static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, int first) | 296 | static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first) |
306 | { | 297 | { |
307 | dev_node_t *node; | 298 | dev_node_t *node; |
308 | struct pcmcia_device *p_dev; | 299 | struct pcmcia_device *p_dev; |
@@ -317,7 +308,7 @@ static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, | |||
317 | { | 308 | { |
318 | struct pci_bus *bus; | 309 | struct pci_bus *bus; |
319 | 310 | ||
320 | bus = pcmcia_lookup_bus(s->parent); | 311 | bus = pcmcia_lookup_bus(s); |
321 | if (bus) { | 312 | if (bus) { |
322 | struct list_head *list; | 313 | struct list_head *list; |
323 | struct pci_dev *dev = NULL; | 314 | struct pci_dev *dev = NULL; |
@@ -391,21 +382,21 @@ static int get_device_info(struct pcmcia_bus_socket *s, bind_info_t *bind_info, | |||
391 | static int ds_open(struct inode *inode, struct file *file) | 382 | static int ds_open(struct inode *inode, struct file *file) |
392 | { | 383 | { |
393 | socket_t i = iminor(inode); | 384 | socket_t i = iminor(inode); |
394 | struct pcmcia_bus_socket *s; | 385 | struct pcmcia_socket *s; |
395 | user_info_t *user; | 386 | user_info_t *user; |
396 | 387 | ||
397 | ds_dbg(0, "ds_open(socket %d)\n", i); | 388 | ds_dbg(0, "ds_open(socket %d)\n", i); |
398 | 389 | ||
399 | s = get_socket_info_by_nr(i); | 390 | s = pcmcia_get_socket_by_nr(i); |
400 | if (!s) | 391 | if (!s) |
401 | return -ENODEV; | 392 | return -ENODEV; |
402 | s = pcmcia_get_bus_socket(s); | 393 | s = pcmcia_get_socket(s); |
403 | if (!s) | 394 | if (!s) |
404 | return -ENODEV; | 395 | return -ENODEV; |
405 | 396 | ||
406 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { | 397 | if ((file->f_flags & O_ACCMODE) != O_RDONLY) { |
407 | if (s->pcmcia_state.busy) { | 398 | if (s->pcmcia_state.busy) { |
408 | pcmcia_put_bus_socket(s); | 399 | pcmcia_put_socket(s); |
409 | return -EBUSY; | 400 | return -EBUSY; |
410 | } | 401 | } |
411 | else | 402 | else |
@@ -414,7 +405,7 @@ static int ds_open(struct inode *inode, struct file *file) | |||
414 | 405 | ||
415 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); | 406 | user = kmalloc(sizeof(user_info_t), GFP_KERNEL); |
416 | if (!user) { | 407 | if (!user) { |
417 | pcmcia_put_bus_socket(s); | 408 | pcmcia_put_socket(s); |
418 | return -ENOMEM; | 409 | return -ENOMEM; |
419 | } | 410 | } |
420 | user->event_tail = user->event_head = 0; | 411 | user->event_tail = user->event_head = 0; |
@@ -433,7 +424,7 @@ static int ds_open(struct inode *inode, struct file *file) | |||
433 | 424 | ||
434 | static int ds_release(struct inode *inode, struct file *file) | 425 | static int ds_release(struct inode *inode, struct file *file) |
435 | { | 426 | { |
436 | struct pcmcia_bus_socket *s; | 427 | struct pcmcia_socket *s; |
437 | user_info_t *user, **link; | 428 | user_info_t *user, **link; |
438 | 429 | ||
439 | ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); | 430 | ds_dbg(0, "ds_release(socket %d)\n", iminor(inode)); |
@@ -456,7 +447,7 @@ static int ds_release(struct inode *inode, struct file *file) | |||
456 | *link = user->next; | 447 | *link = user->next; |
457 | user->user_magic = 0; | 448 | user->user_magic = 0; |
458 | kfree(user); | 449 | kfree(user); |
459 | pcmcia_put_bus_socket(s); | 450 | pcmcia_put_socket(s); |
460 | out: | 451 | out: |
461 | return 0; | 452 | return 0; |
462 | } /* ds_release */ | 453 | } /* ds_release */ |
@@ -466,7 +457,7 @@ out: | |||
466 | static ssize_t ds_read(struct file *file, char __user *buf, | 457 | static ssize_t ds_read(struct file *file, char __user *buf, |
467 | size_t count, loff_t *ppos) | 458 | size_t count, loff_t *ppos) |
468 | { | 459 | { |
469 | struct pcmcia_bus_socket *s; | 460 | struct pcmcia_socket *s; |
470 | user_info_t *user; | 461 | user_info_t *user; |
471 | int ret; | 462 | int ret; |
472 | 463 | ||
@@ -510,7 +501,7 @@ static ssize_t ds_write(struct file *file, const char __user *buf, | |||
510 | /* No kernel lock - fine */ | 501 | /* No kernel lock - fine */ |
511 | static u_int ds_poll(struct file *file, poll_table *wait) | 502 | static u_int ds_poll(struct file *file, poll_table *wait) |
512 | { | 503 | { |
513 | struct pcmcia_bus_socket *s; | 504 | struct pcmcia_socket *s; |
514 | user_info_t *user; | 505 | user_info_t *user; |
515 | 506 | ||
516 | ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode)); | 507 | ds_dbg(2, "ds_poll(socket %d)\n", iminor(file->f_dentry->d_inode)); |
@@ -536,7 +527,7 @@ extern int pcmcia_adjust_resource_info(adjust_t *adj); | |||
536 | static int ds_ioctl(struct inode * inode, struct file * file, | 527 | static int ds_ioctl(struct inode * inode, struct file * file, |
537 | u_int cmd, u_long arg) | 528 | u_int cmd, u_long arg) |
538 | { | 529 | { |
539 | struct pcmcia_bus_socket *s; | 530 | struct pcmcia_socket *s; |
540 | void __user *uarg = (char __user *)arg; | 531 | void __user *uarg = (char __user *)arg; |
541 | u_int size; | 532 | u_int size; |
542 | int ret, err; | 533 | int ret, err; |
@@ -589,57 +580,57 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
589 | break; | 580 | break; |
590 | case DS_GET_CONFIGURATION_INFO: | 581 | case DS_GET_CONFIGURATION_INFO: |
591 | if (buf->config.Function && | 582 | if (buf->config.Function && |
592 | (buf->config.Function >= s->parent->functions)) | 583 | (buf->config.Function >= s->functions)) |
593 | ret = CS_BAD_ARGS; | 584 | ret = CS_BAD_ARGS; |
594 | else | 585 | else |
595 | ret = pccard_get_configuration_info(s->parent, | 586 | ret = pccard_get_configuration_info(s, |
596 | buf->config.Function, &buf->config); | 587 | buf->config.Function, &buf->config); |
597 | break; | 588 | break; |
598 | case DS_GET_FIRST_TUPLE: | 589 | case DS_GET_FIRST_TUPLE: |
599 | down(&s->parent->skt_sem); | 590 | down(&s->skt_sem); |
600 | pcmcia_validate_mem(s->parent); | 591 | pcmcia_validate_mem(s); |
601 | up(&s->parent->skt_sem); | 592 | up(&s->skt_sem); |
602 | ret = pccard_get_first_tuple(s->parent, BIND_FN_ALL, &buf->tuple); | 593 | ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple); |
603 | break; | 594 | break; |
604 | case DS_GET_NEXT_TUPLE: | 595 | case DS_GET_NEXT_TUPLE: |
605 | ret = pccard_get_next_tuple(s->parent, BIND_FN_ALL, &buf->tuple); | 596 | ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple); |
606 | break; | 597 | break; |
607 | case DS_GET_TUPLE_DATA: | 598 | case DS_GET_TUPLE_DATA: |
608 | buf->tuple.TupleData = buf->tuple_parse.data; | 599 | buf->tuple.TupleData = buf->tuple_parse.data; |
609 | buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data); | 600 | buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data); |
610 | ret = pccard_get_tuple_data(s->parent, &buf->tuple); | 601 | ret = pccard_get_tuple_data(s, &buf->tuple); |
611 | break; | 602 | break; |
612 | case DS_PARSE_TUPLE: | 603 | case DS_PARSE_TUPLE: |
613 | buf->tuple.TupleData = buf->tuple_parse.data; | 604 | buf->tuple.TupleData = buf->tuple_parse.data; |
614 | ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); | 605 | ret = pccard_parse_tuple(&buf->tuple, &buf->tuple_parse.parse); |
615 | break; | 606 | break; |
616 | case DS_RESET_CARD: | 607 | case DS_RESET_CARD: |
617 | ret = pccard_reset_card(s->parent); | 608 | ret = pccard_reset_card(s); |
618 | break; | 609 | break; |
619 | case DS_GET_STATUS: | 610 | case DS_GET_STATUS: |
620 | if (buf->status.Function && | 611 | if (buf->status.Function && |
621 | (buf->status.Function >= s->parent->functions)) | 612 | (buf->status.Function >= s->functions)) |
622 | ret = CS_BAD_ARGS; | 613 | ret = CS_BAD_ARGS; |
623 | else | 614 | else |
624 | ret = pccard_get_status(s->parent, buf->status.Function, &buf->status); | 615 | ret = pccard_get_status(s, buf->status.Function, &buf->status); |
625 | break; | 616 | break; |
626 | case DS_VALIDATE_CIS: | 617 | case DS_VALIDATE_CIS: |
627 | down(&s->parent->skt_sem); | 618 | down(&s->skt_sem); |
628 | pcmcia_validate_mem(s->parent); | 619 | pcmcia_validate_mem(s); |
629 | up(&s->parent->skt_sem); | 620 | up(&s->skt_sem); |
630 | ret = pccard_validate_cis(s->parent, BIND_FN_ALL, &buf->cisinfo); | 621 | ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); |
631 | break; | 622 | break; |
632 | case DS_SUSPEND_CARD: | 623 | case DS_SUSPEND_CARD: |
633 | ret = pcmcia_suspend_card(s->parent); | 624 | ret = pcmcia_suspend_card(s); |
634 | break; | 625 | break; |
635 | case DS_RESUME_CARD: | 626 | case DS_RESUME_CARD: |
636 | ret = pcmcia_resume_card(s->parent); | 627 | ret = pcmcia_resume_card(s); |
637 | break; | 628 | break; |
638 | case DS_EJECT_CARD: | 629 | case DS_EJECT_CARD: |
639 | err = pcmcia_eject_card(s->parent); | 630 | err = pcmcia_eject_card(s); |
640 | break; | 631 | break; |
641 | case DS_INSERT_CARD: | 632 | case DS_INSERT_CARD: |
642 | err = pcmcia_insert_card(s->parent); | 633 | err = pcmcia_insert_card(s); |
643 | break; | 634 | break; |
644 | case DS_ACCESS_CONFIGURATION_REGISTER: | 635 | case DS_ACCESS_CONFIGURATION_REGISTER: |
645 | if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) { | 636 | if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) { |
@@ -647,10 +638,10 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
647 | goto free_out; | 638 | goto free_out; |
648 | } | 639 | } |
649 | if (buf->conf_reg.Function && | 640 | if (buf->conf_reg.Function && |
650 | (buf->conf_reg.Function >= s->parent->functions)) | 641 | (buf->conf_reg.Function >= s->functions)) |
651 | ret = CS_BAD_ARGS; | 642 | ret = CS_BAD_ARGS; |
652 | else | 643 | else |
653 | ret = pccard_access_configuration_register(s->parent, | 644 | ret = pccard_access_configuration_register(s, |
654 | buf->conf_reg.Function, &buf->conf_reg); | 645 | buf->conf_reg.Function, &buf->conf_reg); |
655 | break; | 646 | break; |
656 | case DS_GET_FIRST_REGION: | 647 | case DS_GET_FIRST_REGION: |
@@ -671,11 +662,11 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
671 | goto free_out; | 662 | goto free_out; |
672 | break; | 663 | break; |
673 | case DS_GET_FIRST_WINDOW: | 664 | case DS_GET_FIRST_WINDOW: |
674 | ret = pcmcia_get_window(s->parent, &buf->win_info.handle, 0, | 665 | ret = pcmcia_get_window(s, &buf->win_info.handle, 0, |
675 | &buf->win_info.window); | 666 | &buf->win_info.window); |
676 | break; | 667 | break; |
677 | case DS_GET_NEXT_WINDOW: | 668 | case DS_GET_NEXT_WINDOW: |
678 | ret = pcmcia_get_window(s->parent, &buf->win_info.handle, | 669 | ret = pcmcia_get_window(s, &buf->win_info.handle, |
679 | buf->win_info.handle->index + 1, &buf->win_info.window); | 670 | buf->win_info.handle->index + 1, &buf->win_info.window); |
680 | break; | 671 | break; |
681 | case DS_GET_MEM_PAGE: | 672 | case DS_GET_MEM_PAGE: |
@@ -683,7 +674,7 @@ static int ds_ioctl(struct inode * inode, struct file * file, | |||
683 | &buf->win_info.map); | 674 | &buf->win_info.map); |
684 | break; | 675 | break; |
685 | case DS_REPLACE_CIS: | 676 | case DS_REPLACE_CIS: |
686 | ret = pcmcia_replace_cis(s->parent, &buf->cisdump); | 677 | ret = pcmcia_replace_cis(s, &buf->cisdump); |
687 | break; | 678 | break; |
688 | case DS_BIND_REQUEST: | 679 | case DS_BIND_REQUEST: |
689 | if (!capable(CAP_SYS_ADMIN)) { | 680 | if (!capable(CAP_SYS_ADMIN)) { |