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.c99
1 files changed, 44 insertions, 55 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index d5afd557fe37..3e3c6f12bbe6 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -158,17 +158,15 @@ static const lookup_t service_table[] = {
158}; 158};
159 159
160 160
161static int pcmcia_report_error(client_handle_t handle, error_info_t *err) 161static int pcmcia_report_error(struct pcmcia_device *p_dev, error_info_t *err)
162{ 162{
163 int i; 163 int i;
164 char *serv; 164 char *serv;
165 165
166 if (CHECK_HANDLE(handle)) 166 if (!p_dev)
167 printk(KERN_NOTICE); 167 printk(KERN_NOTICE);
168 else { 168 else
169 struct pcmcia_device *p_dev = handle_to_pdev(handle);
170 printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id); 169 printk(KERN_NOTICE "%s: ", p_dev->dev.bus_id);
171 }
172 170
173 for (i = 0; i < ARRAY_SIZE(service_table); i++) 171 for (i = 0; i < ARRAY_SIZE(service_table); i++)
174 if (service_table[i].key == err->func) 172 if (service_table[i].key == err->func)
@@ -193,10 +191,10 @@ static int pcmcia_report_error(client_handle_t handle, error_info_t *err)
193 191
194/*======================================================================*/ 192/*======================================================================*/
195 193
196void cs_error(client_handle_t handle, int func, int ret) 194void cs_error(struct pcmcia_device *p_dev, int func, int ret)
197{ 195{
198 error_info_t err = { func, ret }; 196 error_info_t err = { func, ret };
199 pcmcia_report_error(handle, &err); 197 pcmcia_report_error(p_dev, &err);
200} 198}
201EXPORT_SYMBOL(cs_error); 199EXPORT_SYMBOL(cs_error);
202 200
@@ -207,6 +205,10 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
207 unsigned int i; 205 unsigned int i;
208 u32 hash; 206 u32 hash;
209 207
208 if (!p_drv->attach || !p_drv->event || !p_drv->detach)
209 printk(KERN_DEBUG "pcmcia: %s does misses a callback function",
210 p_drv->drv.name);
211
210 while (did && did->match_flags) { 212 while (did && did->match_flags) {
211 for (i=0; i<4; i++) { 213 for (i=0; i<4; i++) {
212 if (!did->prod_id[i]) 214 if (!did->prod_id[i])
@@ -376,7 +378,7 @@ static int pcmcia_device_probe(struct device * dev)
376 378
377 if (p_drv->attach) { 379 if (p_drv->attach) {
378 p_dev->instance = p_drv->attach(); 380 p_dev->instance = p_drv->attach();
379 if ((!p_dev->instance) || (p_dev->client.state & CLIENT_UNBOUND)) { 381 if ((!p_dev->instance) || (p_dev->state & CLIENT_UNBOUND)) {
380 printk(KERN_NOTICE "ds: unable to create instance " 382 printk(KERN_NOTICE "ds: unable to create instance "
381 "of '%s'!\n", p_drv->drv.name); 383 "of '%s'!\n", p_drv->drv.name);
382 ret = -EINVAL; 384 ret = -EINVAL;
@@ -516,10 +518,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
516 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); 518 sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
517 519
518 /* compat */ 520 /* compat */
519 p_dev->client.client_magic = CLIENT_MAGIC; 521 p_dev->state = CLIENT_UNBOUND;
520 p_dev->client.Socket = s;
521 p_dev->client.Function = function;
522 p_dev->client.state = CLIENT_UNBOUND;
523 522
524 /* Add to the list in pcmcia_bus_socket */ 523 /* Add to the list in pcmcia_bus_socket */
525 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 524 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
@@ -573,8 +572,6 @@ static int pcmcia_card_add(struct pcmcia_socket *s)
573 else 572 else
574 no_funcs = 1; 573 no_funcs = 1;
575 574
576 /* this doesn't handle multifunction devices on one pcmcia function
577 * yet. */
578 for (i=0; i < no_funcs; i++) 575 for (i=0; i < no_funcs; i++)
579 pcmcia_device_add(s, i); 576 pcmcia_device_add(s, i);
580 577
@@ -914,6 +911,7 @@ struct send_event_data {
914static int send_event_callback(struct device *dev, void * _data) 911static int send_event_callback(struct device *dev, void * _data)
915{ 912{
916 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 913 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
914 struct pcmcia_driver *p_drv;
917 struct send_event_data *data = _data; 915 struct send_event_data *data = _data;
918 916
919 /* we get called for all sockets, but may only pass the event 917 /* we get called for all sockets, but may only pass the event
@@ -921,11 +919,16 @@ static int send_event_callback(struct device *dev, void * _data)
921 if (p_dev->socket != data->skt) 919 if (p_dev->socket != data->skt)
922 return 0; 920 return 0;
923 921
924 if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE)) 922 p_drv = to_pcmcia_drv(p_dev->dev.driver);
923 if (!p_drv)
925 return 0; 924 return 0;
926 925
927 if (p_dev->client.EventMask & data->event) 926 if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE))
928 return EVENT(&p_dev->client, data->event, data->priority); 927 return 0;
928
929 if (p_drv->event)
930 return p_drv->event(data->event, data->priority,
931 &p_dev->event_callback_args);
929 932
930 return 0; 933 return 0;
931} 934}
@@ -987,11 +990,11 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
987 990
988 991
989 992
990int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) 993int pcmcia_register_client(struct pcmcia_device **handle, client_reg_t *req)
991{ 994{
992 client_t *client = NULL;
993 struct pcmcia_socket *s = NULL; 995 struct pcmcia_socket *s = NULL;
994 struct pcmcia_device *p_dev = NULL; 996 struct pcmcia_device *p_dev = NULL;
997 struct pcmcia_driver *p_drv = NULL;
995 998
996 /* Look for unbound client with matching dev_info */ 999 /* Look for unbound client with matching dev_info */
997 down_read(&pcmcia_socket_list_rwsem); 1000 down_read(&pcmcia_socket_list_rwsem);
@@ -1006,18 +1009,16 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1006 continue; 1009 continue;
1007 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 1010 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
1008 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { 1011 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
1009 struct pcmcia_driver *p_drv;
1010 p_dev = pcmcia_get_dev(p_dev); 1012 p_dev = pcmcia_get_dev(p_dev);
1011 if (!p_dev) 1013 if (!p_dev)
1012 continue; 1014 continue;
1013 if (!(p_dev->client.state & CLIENT_UNBOUND) || 1015 if (!(p_dev->state & CLIENT_UNBOUND) ||
1014 (!p_dev->dev.driver)) { 1016 (!p_dev->dev.driver)) {
1015 pcmcia_put_dev(p_dev); 1017 pcmcia_put_dev(p_dev);
1016 continue; 1018 continue;
1017 } 1019 }
1018 p_drv = to_pcmcia_drv(p_dev->dev.driver); 1020 p_drv = to_pcmcia_drv(p_dev->dev.driver);
1019 if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) { 1021 if (!strncmp(p_drv->drv.name, (char *)req->dev_info, DEV_NAME_LEN)) {
1020 client = &p_dev->client;
1021 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 1022 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1022 goto found; 1023 goto found;
1023 } 1024 }
@@ -1028,26 +1029,20 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1028 } 1029 }
1029 found: 1030 found:
1030 up_read(&pcmcia_socket_list_rwsem); 1031 up_read(&pcmcia_socket_list_rwsem);
1031 if (!p_dev || !client) 1032 if (!p_dev)
1032 return -ENODEV; 1033 return -ENODEV;
1033 1034
1034 pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */ 1035 pcmcia_put_socket(s); /* safe, as we already hold a reference from bind_device */
1035 1036
1036 *handle = client; 1037 *handle = p_dev;
1037 client->state &= ~CLIENT_UNBOUND; 1038 p_dev->state &= ~CLIENT_UNBOUND;
1038 client->Socket = s; 1039 p_dev->event_callback_args = req->event_callback_args;
1039 client->EventMask = req->EventMask; 1040 p_dev->event_callback_args.client_handle = p_dev;
1040 client->event_handler = req->event_handler;
1041 client->event_callback_args = req->event_callback_args;
1042 client->event_callback_args.client_handle = client;
1043 1041
1044 if (s->state & SOCKET_CARDBUS)
1045 client->state |= CLIENT_CARDBUS;
1046 1042
1047 if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) && 1043 if (!s->functions) {
1048 (client->Function != BIND_FN_ALL)) {
1049 cistpl_longlink_mfc_t mfc; 1044 cistpl_longlink_mfc_t mfc;
1050 if (pccard_read_tuple(s, client->Function, CISTPL_LONGLINK_MFC, &mfc) 1045 if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC, &mfc)
1051 == CS_SUCCESS) 1046 == CS_SUCCESS)
1052 s->functions = mfc.nfn; 1047 s->functions = mfc.nfn;
1053 else 1048 else
@@ -1060,13 +1055,13 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
1060 } 1055 }
1061 1056
1062 ds_dbg(1, "register_client(): client 0x%p, dev %s\n", 1057 ds_dbg(1, "register_client(): client 0x%p, dev %s\n",
1063 client, p_dev->dev.bus_id); 1058 p_dev, p_dev->dev.bus_id);
1064 if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
1065 EVENT(client, CS_EVENT_REGISTRATION_COMPLETE, CS_EVENT_PRI_LOW);
1066 1059
1067 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { 1060 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) {
1068 if (client->EventMask & CS_EVENT_CARD_INSERTION) 1061 if (p_drv->event)
1069 EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); 1062 p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW,
1063 &p_dev->event_callback_args);
1064
1070 } 1065 }
1071 1066
1072 return CS_SUCCESS; 1067 return CS_SUCCESS;
@@ -1099,7 +1094,7 @@ static int unbind_request(struct pcmcia_socket *s)
1099 } 1094 }
1100 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list); 1095 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
1101 list_del(&p_dev->socket_device_list); 1096 list_del(&p_dev->socket_device_list);
1102 p_dev->client.state |= CLIENT_STALE; 1097 p_dev->state |= CLIENT_STALE;
1103 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 1098 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
1104 1099
1105 device_unregister(&p_dev->dev); 1100 device_unregister(&p_dev->dev);
@@ -1108,31 +1103,25 @@ static int unbind_request(struct pcmcia_socket *s)
1108 return 0; 1103 return 0;
1109} /* unbind_request */ 1104} /* unbind_request */
1110 1105
1111int pcmcia_deregister_client(client_handle_t handle) 1106int pcmcia_deregister_client(struct pcmcia_device *p_dev)
1112{ 1107{
1113 struct pcmcia_socket *s; 1108 struct pcmcia_socket *s;
1114 int i; 1109 int i;
1115 struct pcmcia_device *p_dev = handle_to_pdev(handle);
1116
1117 if (CHECK_HANDLE(handle))
1118 return CS_BAD_HANDLE;
1119 1110
1120 s = SOCKET(handle); 1111 s = p_dev->socket;
1121 ds_dbg(1, "deregister_client(%p)\n", handle); 1112 ds_dbg(1, "deregister_client(%p)\n", p_dev);
1122 1113
1123 if (handle->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) 1114 if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED))
1124 goto warn_out; 1115 goto warn_out;
1125 for (i = 0; i < MAX_WIN; i++) 1116 for (i = 0; i < MAX_WIN; i++)
1126 if (handle->state & CLIENT_WIN_REQ(i)) 1117 if (p_dev->state & CLIENT_WIN_REQ(i))
1127 goto warn_out; 1118 goto warn_out;
1128 1119
1129 if (handle->state & CLIENT_STALE) { 1120 if (p_dev->state & CLIENT_STALE) {
1130 handle->client_magic = 0; 1121 p_dev->state &= ~CLIENT_STALE;
1131 handle->state &= ~CLIENT_STALE;
1132 pcmcia_put_dev(p_dev); 1122 pcmcia_put_dev(p_dev);
1133 } else { 1123 } else {
1134 handle->state = CLIENT_UNBOUND; 1124 p_dev->state = CLIENT_UNBOUND;
1135 handle->event_handler = NULL;
1136 } 1125 }
1137 1126
1138 return CS_SUCCESS; 1127 return CS_SUCCESS;