diff options
Diffstat (limited to 'drivers/pcmcia/ds.c')
-rw-r--r-- | drivers/pcmcia/ds.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index d5afd557fe37..367ebf75beeb 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -207,6 +207,10 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
207 | unsigned int i; | 207 | unsigned int i; |
208 | u32 hash; | 208 | u32 hash; |
209 | 209 | ||
210 | if (!p_drv->attach || !p_drv->event || !p_drv->detach) | ||
211 | printk(KERN_DEBUG "pcmcia: %s does misses a callback function", | ||
212 | p_drv->drv.name); | ||
213 | |||
210 | while (did && did->match_flags) { | 214 | while (did && did->match_flags) { |
211 | for (i=0; i<4; i++) { | 215 | for (i=0; i<4; i++) { |
212 | if (!did->prod_id[i]) | 216 | if (!did->prod_id[i]) |
@@ -914,6 +918,7 @@ struct send_event_data { | |||
914 | static int send_event_callback(struct device *dev, void * _data) | 918 | static int send_event_callback(struct device *dev, void * _data) |
915 | { | 919 | { |
916 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | 920 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); |
921 | struct pcmcia_driver *p_drv; | ||
917 | struct send_event_data *data = _data; | 922 | struct send_event_data *data = _data; |
918 | 923 | ||
919 | /* we get called for all sockets, but may only pass the event | 924 | /* we get called for all sockets, but may only pass the event |
@@ -921,11 +926,16 @@ static int send_event_callback(struct device *dev, void * _data) | |||
921 | if (p_dev->socket != data->skt) | 926 | if (p_dev->socket != data->skt) |
922 | return 0; | 927 | return 0; |
923 | 928 | ||
929 | p_drv = to_pcmcia_drv(p_dev->dev.driver); | ||
930 | if (!p_drv) | ||
931 | return 0; | ||
932 | |||
924 | if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE)) | 933 | if (p_dev->client.state & (CLIENT_UNBOUND|CLIENT_STALE)) |
925 | return 0; | 934 | return 0; |
926 | 935 | ||
927 | if (p_dev->client.EventMask & data->event) | 936 | if (p_drv->event) |
928 | return EVENT(&p_dev->client, data->event, data->priority); | 937 | return p_drv->event(data->event, data->priority, |
938 | &p_dev->event_callback_args); | ||
929 | 939 | ||
930 | return 0; | 940 | return 0; |
931 | } | 941 | } |
@@ -992,6 +1002,7 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
992 | client_t *client = NULL; | 1002 | client_t *client = NULL; |
993 | struct pcmcia_socket *s = NULL; | 1003 | struct pcmcia_socket *s = NULL; |
994 | struct pcmcia_device *p_dev = NULL; | 1004 | struct pcmcia_device *p_dev = NULL; |
1005 | struct pcmcia_driver *p_drv = NULL; | ||
995 | 1006 | ||
996 | /* Look for unbound client with matching dev_info */ | 1007 | /* Look for unbound client with matching dev_info */ |
997 | down_read(&pcmcia_socket_list_rwsem); | 1008 | down_read(&pcmcia_socket_list_rwsem); |
@@ -1006,7 +1017,6 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
1006 | continue; | 1017 | continue; |
1007 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); | 1018 | spin_lock_irqsave(&pcmcia_dev_list_lock, flags); |
1008 | list_for_each_entry(p_dev, &s->devices_list, socket_device_list) { | 1019 | 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); | 1020 | p_dev = pcmcia_get_dev(p_dev); |
1011 | if (!p_dev) | 1021 | if (!p_dev) |
1012 | continue; | 1022 | continue; |
@@ -1036,10 +1046,9 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
1036 | *handle = client; | 1046 | *handle = client; |
1037 | client->state &= ~CLIENT_UNBOUND; | 1047 | client->state &= ~CLIENT_UNBOUND; |
1038 | client->Socket = s; | 1048 | client->Socket = s; |
1039 | client->EventMask = req->EventMask; | 1049 | p_dev->event_callback_args = req->event_callback_args; |
1040 | client->event_handler = req->event_handler; | 1050 | p_dev->event_callback_args.client_handle = client; |
1041 | client->event_callback_args = req->event_callback_args; | 1051 | |
1042 | client->event_callback_args.client_handle = client; | ||
1043 | 1052 | ||
1044 | if (s->state & SOCKET_CARDBUS) | 1053 | if (s->state & SOCKET_CARDBUS) |
1045 | client->state |= CLIENT_CARDBUS; | 1054 | client->state |= CLIENT_CARDBUS; |
@@ -1061,12 +1070,12 @@ int pcmcia_register_client(client_handle_t *handle, client_reg_t *req) | |||
1061 | 1070 | ||
1062 | ds_dbg(1, "register_client(): client 0x%p, dev %s\n", | 1071 | ds_dbg(1, "register_client(): client 0x%p, dev %s\n", |
1063 | client, p_dev->dev.bus_id); | 1072 | client, 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 | 1073 | ||
1067 | if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { | 1074 | if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) { |
1068 | if (client->EventMask & CS_EVENT_CARD_INSERTION) | 1075 | if (p_drv->event) |
1069 | EVENT(client, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); | 1076 | p_drv->event(CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW, |
1077 | &p_dev->event_callback_args); | ||
1078 | |||
1070 | } | 1079 | } |
1071 | 1080 | ||
1072 | return CS_SUCCESS; | 1081 | return CS_SUCCESS; |
@@ -1132,7 +1141,6 @@ int pcmcia_deregister_client(client_handle_t handle) | |||
1132 | pcmcia_put_dev(p_dev); | 1141 | pcmcia_put_dev(p_dev); |
1133 | } else { | 1142 | } else { |
1134 | handle->state = CLIENT_UNBOUND; | 1143 | handle->state = CLIENT_UNBOUND; |
1135 | handle->event_handler = NULL; | ||
1136 | } | 1144 | } |
1137 | 1145 | ||
1138 | return CS_SUCCESS; | 1146 | return CS_SUCCESS; |