Diff markup
1 /* 1 /*
2 * cs.c -- Kernel Card Services - core service 2 * cs.c -- Kernel Card Services - core services
3 * 3 *
4 * This program is free software; you can redi 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Publi 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * The initial developer of the original code 8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions 9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All 10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 * 11 *
12 * (C) 1999 David A. Hinds 12 * (C) 1999 David A. Hinds
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/moduleparam.h> 16 #include <linux/moduleparam.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/kernel.h> 18 #include <linux/kernel.h>
19 #include <linux/config.h> <<
20 #include <linux/string.h> 19 #include <linux/string.h>
21 #include <linux/major.h> 20 #include <linux/major.h>
22 #include <linux/errno.h> 21 #include <linux/errno.h>
23 #include <linux/slab.h> 22 #include <linux/slab.h>
24 #include <linux/mm.h> 23 #include <linux/mm.h>
25 #include <linux/interrupt.h> 24 #include <linux/interrupt.h>
26 #include <linux/timer.h> 25 #include <linux/timer.h>
27 #include <linux/ioport.h> 26 #include <linux/ioport.h>
28 #include <linux/delay.h> 27 #include <linux/delay.h>
29 #include <linux/pm.h> 28 #include <linux/pm.h>
30 #include <linux/pci.h> <<
31 #include <linux/device.h> 29 #include <linux/device.h>
>> 30 #include <linux/kthread.h>
>> 31 #include <linux/freezer.h>
32 #include <asm/system.h> 32 #include <asm/system.h>
33 #include <asm/irq.h> 33 #include <asm/irq.h>
34 34
35 #define IN_CARD_SERVICES 35 #define IN_CARD_SERVICES
36 #include <pcmcia/version.h> <<
37 #include <pcmcia/cs_types.h> 36 #include <pcmcia/cs_types.h>
38 #include <pcmcia/ss.h> 37 #include <pcmcia/ss.h>
39 #include <pcmcia/cs.h> 38 #include <pcmcia/cs.h>
40 #include <pcmcia/bulkmem.h> 39 #include <pcmcia/bulkmem.h>
41 #include <pcmcia/cistpl.h> 40 #include <pcmcia/cistpl.h>
42 #include <pcmcia/cisreg.h> 41 #include <pcmcia/cisreg.h>
43 #include <pcmcia/ds.h> 42 #include <pcmcia/ds.h>
44 #include "cs_internal.h" 43 #include "cs_internal.h"
45 44
46 #ifdef CONFIG_PCI <<
47 #define PCI_OPT " [pci]" <<
48 #else <<
49 #define PCI_OPT "" <<
50 #endif <<
51 #ifdef CONFIG_CARDBUS <<
52 #define CB_OPT " [cardbus]" <<
53 #else <<
54 #define CB_OPT "" <<
55 #endif <<
56 #ifdef CONFIG_PM <<
57 #define PM_OPT " [pm]" <<
58 #else <<
59 #define PM_OPT "" <<
60 #endif <<
61 #if !defined(CONFIG_CARDBUS) && !defined(CONFI <<
62 #define OPTIONS " none" <<
63 #else <<
64 #define OPTIONS PCI_OPT CB_OPT PM_OPT <<
65 #endif <<
66 <<
67 static const char *release = "Linux Kernel Car <<
68 static const char *options = "options: " OPTIO <<
69 <<
70 /*============================================ <<
71 45
72 /* Module parameters */ 46 /* Module parameters */
73 47
74 MODULE_AUTHOR("David Hinds <dahinds@users.sour 48 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
75 MODULE_DESCRIPTION("Linux Kernel Card Services !! 49 MODULE_DESCRIPTION("Linux Kernel Card Services");
76 MODULE_LICENSE("GPL"); 50 MODULE_LICENSE("GPL");
77 51
78 #define INT_MODULE_PARM(n, v) static int n = v 52 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
79 53
80 INT_MODULE_PARM(setup_delay, 10); 54 INT_MODULE_PARM(setup_delay, 10); /* centiseconds */
81 INT_MODULE_PARM(resume_delay, 20); 55 INT_MODULE_PARM(resume_delay, 20); /* centiseconds */
82 INT_MODULE_PARM(shutdown_delay, 3); 56 INT_MODULE_PARM(shutdown_delay, 3); /* centiseconds */
83 INT_MODULE_PARM(vcc_settle, 40); 57 INT_MODULE_PARM(vcc_settle, 40); /* centiseconds */
84 INT_MODULE_PARM(reset_time, 10); 58 INT_MODULE_PARM(reset_time, 10); /* usecs */
85 INT_MODULE_PARM(unreset_delay, 10); 59 INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
86 INT_MODULE_PARM(unreset_check, 10); 60 INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
87 INT_MODULE_PARM(unreset_limit, 30); 61 INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
88 62
89 /* Access speed for attribute memory windows * 63 /* Access speed for attribute memory windows */
90 INT_MODULE_PARM(cis_speed, 300); 64 INT_MODULE_PARM(cis_speed, 300); /* ns */
91 65
92 /* Access speed for IO windows */ <<
93 INT_MODULE_PARM(io_speed, 0); <<
94 <<
95 #ifdef DEBUG 66 #ifdef DEBUG
96 static int pc_debug; 67 static int pc_debug;
97 68
98 module_param(pc_debug, int, 0644); 69 module_param(pc_debug, int, 0644);
99 70
100 int cs_debug_level(int level) 71 int cs_debug_level(int level)
101 { 72 {
102 return pc_debug > level; 73 return pc_debug > level;
103 } 74 }
104 #endif 75 #endif
105 76
106 /*============================================ <<
107 77
108 socket_state_t dead_socket = { 78 socket_state_t dead_socket = {
109 .csc_mask = SS_DETECT, 79 .csc_mask = SS_DETECT,
110 }; 80 };
>> 81 EXPORT_SYMBOL(dead_socket);
111 82
112 83
113 /* List of all sockets, protected by a rwsem * 84 /* List of all sockets, protected by a rwsem */
114 LIST_HEAD(pcmcia_socket_list); 85 LIST_HEAD(pcmcia_socket_list);
115 DECLARE_RWSEM(pcmcia_socket_list_rwsem); <<
116 EXPORT_SYMBOL(pcmcia_socket_list); 86 EXPORT_SYMBOL(pcmcia_socket_list);
117 EXPORT_SYMBOL(pcmcia_socket_list_rwsem); <<
118 <<
119 87
120 #ifdef CONFIG_PCMCIA_PROBE !! 88 DECLARE_RWSEM(pcmcia_socket_list_rwsem);
121 /* mask ofIRQs already reserved by other cards !! 89 EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
122 static u8 pcmcia_used_irq[NR_IRQS]; <<
123 #endif <<
124 <<
125 /*============================================ <<
126 90
127 Low-level PC Card interface drivers need t <<
128 Services using these calls. <<
129 <<
130 ============================================== <<
131 91
132 /** !! 92 /*
133 * socket drivers are expected to use the foll !! 93 * Low-level PCMCIA socket drivers need to register with the PCCard
>> 94 * core using pcmcia_register_socket.
>> 95 *
>> 96 * socket drivers are expected to use the following callbacks in their
134 * .drv struct: 97 * .drv struct:
135 * - pcmcia_socket_dev_suspend 98 * - pcmcia_socket_dev_suspend
136 * - pcmcia_socket_dev_resume 99 * - pcmcia_socket_dev_resume
137 * These functions check for the appropriate s 100 * These functions check for the appropriate struct pcmcia_soket arrays,
138 * and pass them to the low-level functions pc 101 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
139 */ 102 */
140 static int socket_resume(struct pcmcia_socket 103 static int socket_resume(struct pcmcia_socket *skt);
141 static int socket_suspend(struct pcmcia_socket 104 static int socket_suspend(struct pcmcia_socket *skt);
142 105
143 int pcmcia_socket_dev_suspend(struct device *d !! 106 int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
144 { 107 {
145 struct pcmcia_socket *socket; 108 struct pcmcia_socket *socket;
146 109
147 down_read(&pcmcia_socket_list_rwsem); 110 down_read(&pcmcia_socket_list_rwsem);
148 list_for_each_entry(socket, &pcmcia_so 111 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
149 if (socket->dev.dev != dev) !! 112 if (socket->dev.parent != dev)
150 continue; 113 continue;
151 down(&socket->skt_sem); !! 114 mutex_lock(&socket->skt_mutex);
152 socket_suspend(socket); 115 socket_suspend(socket);
153 up(&socket->skt_sem); !! 116 mutex_unlock(&socket->skt_mutex);
154 } 117 }
155 up_read(&pcmcia_socket_list_rwsem); 118 up_read(&pcmcia_socket_list_rwsem);
156 119
157 return 0; 120 return 0;
158 } 121 }
159 EXPORT_SYMBOL(pcmcia_socket_dev_suspend); 122 EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
160 123
161 int pcmcia_socket_dev_resume(struct device *de 124 int pcmcia_socket_dev_resume(struct device *dev)
162 { 125 {
163 struct pcmcia_socket *socket; 126 struct pcmcia_socket *socket;
164 127
165 down_read(&pcmcia_socket_list_rwsem); 128 down_read(&pcmcia_socket_list_rwsem);
166 list_for_each_entry(socket, &pcmcia_so 129 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
167 if (socket->dev.dev != dev) !! 130 if (socket->dev.parent != dev)
168 continue; 131 continue;
169 down(&socket->skt_sem); !! 132 mutex_lock(&socket->skt_mutex);
170 socket_resume(socket); 133 socket_resume(socket);
171 up(&socket->skt_sem); !! 134 mutex_unlock(&socket->skt_mutex);
172 } 135 }
173 up_read(&pcmcia_socket_list_rwsem); 136 up_read(&pcmcia_socket_list_rwsem);
174 137
175 return 0; 138 return 0;
176 } 139 }
177 EXPORT_SYMBOL(pcmcia_socket_dev_resume); 140 EXPORT_SYMBOL(pcmcia_socket_dev_resume);
178 141
179 142
180 struct pcmcia_socket * pcmcia_get_socket(struc 143 struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
181 { 144 {
182 struct class_device *cl_dev = class_de !! 145 struct device *dev = get_device(&skt->dev);
183 if (!cl_dev) !! 146 if (!dev)
184 return NULL; 147 return NULL;
185 skt = class_get_devdata(cl_dev); !! 148 skt = dev_get_drvdata(dev);
186 if (!try_module_get(skt->owner)) { 149 if (!try_module_get(skt->owner)) {
187 class_device_put(&skt->dev); !! 150 put_device(&skt->dev);
188 return NULL; 151 return NULL;
189 } 152 }
190 return (skt); 153 return (skt);
191 } 154 }
192 EXPORT_SYMBOL(pcmcia_get_socket); 155 EXPORT_SYMBOL(pcmcia_get_socket);
193 156
194 157
195 void pcmcia_put_socket(struct pcmcia_socket *s 158 void pcmcia_put_socket(struct pcmcia_socket *skt)
196 { 159 {
197 module_put(skt->owner); 160 module_put(skt->owner);
198 class_device_put(&skt->dev); !! 161 put_device(&skt->dev);
199 } 162 }
200 EXPORT_SYMBOL(pcmcia_put_socket); 163 EXPORT_SYMBOL(pcmcia_put_socket);
201 164
202 165
203 static void pcmcia_release_socket(struct class !! 166 static void pcmcia_release_socket(struct device *dev)
204 { 167 {
205 struct pcmcia_socket *socket = class_g !! 168 struct pcmcia_socket *socket = dev_get_drvdata(dev);
206 169
207 complete(&socket->socket_released); 170 complete(&socket->socket_released);
208 } 171 }
209 172
210 static int pccardd(void *__skt); 173 static int pccardd(void *__skt);
211 174
212 /** 175 /**
213 * pcmcia_register_socket - add a new pcmcia s 176 * pcmcia_register_socket - add a new pcmcia socket device
>> 177 * @socket: the &socket to register
214 */ 178 */
215 int pcmcia_register_socket(struct pcmcia_socke 179 int pcmcia_register_socket(struct pcmcia_socket *socket)
216 { 180 {
>> 181 struct task_struct *tsk;
217 int ret; 182 int ret;
218 183
219 if (!socket || !socket->ops || !socket !! 184 if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
220 return -EINVAL; 185 return -EINVAL;
221 186
222 cs_dbg(socket, 0, "pcmcia_register_soc 187 cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
223 188
>> 189 spin_lock_init(&socket->lock);
>> 190
224 if (socket->resource_ops->init) { 191 if (socket->resource_ops->init) {
225 ret = socket->resource_ops->in 192 ret = socket->resource_ops->init(socket);
226 if (ret) 193 if (ret)
227 return (ret); 194 return (ret);
228 } 195 }
229 196
230 /* try to obtain a socket number [yes, 197 /* try to obtain a socket number [yes, it gets ugly if we
231 * register more than 2^sizeof(unsigne !! 198 * register more than 2^sizeof(unsigned int) pcmcia
232 * sockets... but the socket number is !! 199 * sockets... but the socket number is deprecated
233 * anyways, so I don't care] */ 200 * anyways, so I don't care] */
234 down_write(&pcmcia_socket_list_rwsem); 201 down_write(&pcmcia_socket_list_rwsem);
235 if (list_empty(&pcmcia_socket_list)) 202 if (list_empty(&pcmcia_socket_list))
236 socket->sock = 0; 203 socket->sock = 0;
237 else { 204 else {
238 unsigned int found, i = 1; 205 unsigned int found, i = 1;
239 struct pcmcia_socket *tmp; 206 struct pcmcia_socket *tmp;
240 do { 207 do {
241 found = 1; 208 found = 1;
242 list_for_each_entry(tm 209 list_for_each_entry(tmp, &pcmcia_socket_list, socket_list) {
243 if (tmp->sock 210 if (tmp->sock == i)
244 found 211 found = 0;
245 } 212 }
246 i++; 213 i++;
247 } while (!found); 214 } while (!found);
248 socket->sock = i - 1; 215 socket->sock = i - 1;
249 } 216 }
250 list_add_tail(&socket->socket_list, &p 217 list_add_tail(&socket->socket_list, &pcmcia_socket_list);
251 up_write(&pcmcia_socket_list_rwsem); 218 up_write(&pcmcia_socket_list_rwsem);
252 219
>> 220 #ifndef CONFIG_CARDBUS
>> 221 /*
>> 222 * If we do not support Cardbus, ensure that
>> 223 * the Cardbus socket capability is disabled.
>> 224 */
>> 225 socket->features &= ~SS_CAP_CARDBUS;
>> 226 #endif
253 227
254 /* set proper values in socket->dev */ 228 /* set proper values in socket->dev */
255 socket->dev.class_data = socket; !! 229 dev_set_drvdata(&socket->dev, socket);
256 socket->dev.class = &pcmcia_socket_cla 230 socket->dev.class = &pcmcia_socket_class;
257 snprintf(socket->dev.class_id, BUS_ID_ !! 231 snprintf(socket->dev.bus_id, BUS_ID_SIZE, "pcmcia_socket%u", socket->sock);
258 232
259 /* base address = 0, map = 0 */ 233 /* base address = 0, map = 0 */
260 socket->cis_mem.flags = 0; 234 socket->cis_mem.flags = 0;
261 socket->cis_mem.speed = cis_speed; 235 socket->cis_mem.speed = cis_speed;
262 236
263 INIT_LIST_HEAD(&socket->cis_cache); 237 INIT_LIST_HEAD(&socket->cis_cache);
264 spin_lock_init(&socket->lock); <<
265 238
266 init_completion(&socket->socket_releas 239 init_completion(&socket->socket_released);
267 init_completion(&socket->thread_done); 240 init_completion(&socket->thread_done);
268 init_waitqueue_head(&socket->thread_wa 241 init_waitqueue_head(&socket->thread_wait);
269 init_MUTEX(&socket->skt_sem); !! 242 mutex_init(&socket->skt_mutex);
270 spin_lock_init(&socket->thread_lock); 243 spin_lock_init(&socket->thread_lock);
271 244
272 ret = kernel_thread(pccardd, socket, C !! 245 tsk = kthread_run(pccardd, socket, "pccardd");
273 if (ret < 0) !! 246 if (IS_ERR(tsk)) {
>> 247 ret = PTR_ERR(tsk);
274 goto err; 248 goto err;
>> 249 }
275 250
276 wait_for_completion(&socket->thread_do 251 wait_for_completion(&socket->thread_done);
277 if(!socket->thread) { !! 252 if (!socket->thread) {
278 printk(KERN_WARNING "PCMCIA: w 253 printk(KERN_WARNING "PCMCIA: warning: socket thread for socket %p did not start\n", socket);
279 return -EIO; 254 return -EIO;
280 } 255 }
>> 256
281 pcmcia_parse_events(socket, SS_DETECT) 257 pcmcia_parse_events(socket, SS_DETECT);
282 258
283 return 0; 259 return 0;
284 260
285 err: 261 err:
286 down_write(&pcmcia_socket_list_rwsem); 262 down_write(&pcmcia_socket_list_rwsem);
287 list_del(&socket->socket_list); 263 list_del(&socket->socket_list);
288 up_write(&pcmcia_socket_list_rwsem); 264 up_write(&pcmcia_socket_list_rwsem);
289 return ret; 265 return ret;
290 } /* pcmcia_register_socket */ 266 } /* pcmcia_register_socket */
291 EXPORT_SYMBOL(pcmcia_register_socket); 267 EXPORT_SYMBOL(pcmcia_register_socket);
292 268
293 269
294 /** 270 /**
295 * pcmcia_unregister_socket - remove a pcmcia 271 * pcmcia_unregister_socket - remove a pcmcia socket device
>> 272 * @socket: the &socket to unregister
296 */ 273 */
297 void pcmcia_unregister_socket(struct pcmcia_so 274 void pcmcia_unregister_socket(struct pcmcia_socket *socket)
298 { 275 {
299 if (!socket) 276 if (!socket)
300 return; 277 return;
301 278
302 cs_dbg(socket, 0, "pcmcia_unregister_s 279 cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
303 280
304 if (socket->thread) { 281 if (socket->thread) {
305 init_completion(&socket->threa <<
306 socket->thread = NULL; <<
307 wake_up(&socket->thread_wait); 282 wake_up(&socket->thread_wait);
308 wait_for_completion(&socket->t !! 283 kthread_stop(socket->thread);
309 } 284 }
310 release_cis_mem(socket); 285 release_cis_mem(socket);
311 286
312 /* remove from our own list */ 287 /* remove from our own list */
313 down_write(&pcmcia_socket_list_rwsem); 288 down_write(&pcmcia_socket_list_rwsem);
314 list_del(&socket->socket_list); 289 list_del(&socket->socket_list);
315 up_write(&pcmcia_socket_list_rwsem); 290 up_write(&pcmcia_socket_list_rwsem);
316 291
317 /* wait for sysfs to drop all referenc 292 /* wait for sysfs to drop all references */
318 release_resource_db(socket); 293 release_resource_db(socket);
319 wait_for_completion(&socket->socket_re 294 wait_for_completion(&socket->socket_released);
320 } /* pcmcia_unregister_socket */ 295 } /* pcmcia_unregister_socket */
321 EXPORT_SYMBOL(pcmcia_unregister_socket); 296 EXPORT_SYMBOL(pcmcia_unregister_socket);
322 297
323 298
324 struct pcmcia_socket * pcmcia_get_socket_by_nr 299 struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
325 { 300 {
326 struct pcmcia_socket *s; 301 struct pcmcia_socket *s;
327 302
328 down_read(&pcmcia_socket_list_rwsem); 303 down_read(&pcmcia_socket_list_rwsem);
329 list_for_each_entry(s, &pcmcia_socket_ 304 list_for_each_entry(s, &pcmcia_socket_list, socket_list)
330 if (s->sock == nr) { 305 if (s->sock == nr) {
331 up_read(&pcmcia_socket 306 up_read(&pcmcia_socket_list_rwsem);
332 return s; 307 return s;
333 } 308 }
334 up_read(&pcmcia_socket_list_rwsem); 309 up_read(&pcmcia_socket_list_rwsem);
335 310
336 return NULL; 311 return NULL;
337 312
338 } 313 }
339 EXPORT_SYMBOL(pcmcia_get_socket_by_nr); 314 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
340 315
341 !! 316 /*
342 /*============================================ !! 317 * The central event handler. Send_event() sends an event to the
343 !! 318 * 16-bit subsystem, which then calls the relevant device drivers.
344 socket_setup() and shutdown_socket() are c !! 319 * Parse_events() interprets the event bits from
345 handler when card insertion and removal ev !! 320 * a card status change report. Do_shutdown() handles the high
346 socket_setup() turns on socket power and r !! 321 * priority stuff associated with a card removal.
347 shutdown_socket() unconfigures a socket an !! 322 */
348 <<
349 ============================================== <<
350 <<
351 static void shutdown_socket(struct pcmcia_sock <<
352 { <<
353 cs_dbg(s, 1, "shutdown_socket\n"); <<
354 <<
355 /* Blank out the socket state */ <<
356 s->socket = dead_socket; <<
357 s->ops->init(s); <<
358 s->ops->set_socket(s, &s->socket); <<
359 s->irq.AssignedIRQ = s->irq.Config = 0; <<
360 s->lock_count = 0; <<
361 destroy_cis_cache(s); <<
362 #ifdef CONFIG_CARDBUS <<
363 cb_free(s); <<
364 #endif <<
365 s->functions = 0; <<
366 if (s->config) { <<
367 kfree(s->config); <<
368 s->config = NULL; <<
369 } <<
370 <<
371 { <<
372 int status; <<
373 s->ops->get_status(s, &status); <<
374 if (status & SS_POWERON) { <<
375 printk(KERN_ERR "PCMCIA: socke <<
376 } <<
377 } <<
378 } /* shutdown_socket */ <<
379 <<
380 /*============================================ <<
381 <<
382 The central event handler. Send_event() s <<
383 16-bit subsystem, which then calls the rel <<
384 Parse_events() interprets the event bits f <<
385 a card status change report. Do_shutdown( <<
386 priority stuff associated with a card remo <<
387 <<
388 ============================================== <<
389 <<
390 323
391 /* NOTE: send_event needs to be called with sk 324 /* NOTE: send_event needs to be called with skt->sem held. */
392 325
393 static int send_event(struct pcmcia_socket *s, 326 static int send_event(struct pcmcia_socket *s, event_t event, int priority)
394 { 327 {
395 int ret; 328 int ret;
396 329
397 if (s->state & SOCKET_CARDBUS) 330 if (s->state & SOCKET_CARDBUS)
398 return 0; 331 return 0;
399 332
400 cs_dbg(s, 1, "send_event(event %d, pri 333 cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
401 event, priority, s->callback); 334 event, priority, s->callback);
402 335
403 if (!s->callback) 336 if (!s->callback)
404 return 0; 337 return 0;
405 if (!try_module_get(s->callback->owner 338 if (!try_module_get(s->callback->owner))
406 return 0; 339 return 0;
407 340
408 ret = s->callback->event(s, event, pri 341 ret = s->callback->event(s, event, priority);
409 342
410 module_put(s->callback->owner); 343 module_put(s->callback->owner);
411 344
412 return ret; 345 return ret;
413 } 346 }
414 347
415 static void socket_remove_drivers(struct pcmci 348 static void socket_remove_drivers(struct pcmcia_socket *skt)
416 { 349 {
417 cs_dbg(skt, 4, "remove_drivers\n"); 350 cs_dbg(skt, 4, "remove_drivers\n");
418 351
419 send_event(skt, CS_EVENT_CARD_REMOVAL, 352 send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
420 } 353 }
421 354
422 static void socket_shutdown(struct pcmcia_sock <<
423 { <<
424 cs_dbg(skt, 4, "shutdown\n"); <<
425 <<
426 socket_remove_drivers(skt); <<
427 skt->state &= SOCKET_INUSE|SOCKET_PRES <<
428 msleep(shutdown_delay * 10); <<
429 skt->state &= SOCKET_INUSE; <<
430 shutdown_socket(skt); <<
431 } <<
432 <<
433 static int socket_reset(struct pcmcia_socket * 355 static int socket_reset(struct pcmcia_socket *skt)
434 { 356 {
435 int status, i; 357 int status, i;
436 358
437 cs_dbg(skt, 4, "reset\n"); 359 cs_dbg(skt, 4, "reset\n");
438 360
439 skt->socket.flags |= SS_OUTPUT_ENA | S 361 skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
440 skt->ops->set_socket(skt, &skt->socket 362 skt->ops->set_socket(skt, &skt->socket);
441 udelay((long)reset_time); 363 udelay((long)reset_time);
442 364
443 skt->socket.flags &= ~SS_RESET; 365 skt->socket.flags &= ~SS_RESET;
444 skt->ops->set_socket(skt, &skt->socket 366 skt->ops->set_socket(skt, &skt->socket);
445 367
446 msleep(unreset_delay * 10); 368 msleep(unreset_delay * 10);
447 for (i = 0; i < unreset_limit; i++) { 369 for (i = 0; i < unreset_limit; i++) {
448 skt->ops->get_status(skt, &sta 370 skt->ops->get_status(skt, &status);
449 371
450 if (!(status & SS_DETECT)) 372 if (!(status & SS_DETECT))
451 return CS_NO_CARD; 373 return CS_NO_CARD;
452 374
453 if (status & SS_READY) 375 if (status & SS_READY)
454 return CS_SUCCESS; 376 return CS_SUCCESS;
455 377
456 msleep(unreset_check * 10); 378 msleep(unreset_check * 10);
457 } 379 }
458 380
459 cs_err(skt, "time out after reset.\n") 381 cs_err(skt, "time out after reset.\n");
460 return CS_GENERAL_FAILURE; 382 return CS_GENERAL_FAILURE;
461 } 383 }
462 384
>> 385 /*
>> 386 * socket_setup() and socket_shutdown() are called by the main event handler
>> 387 * when card insertion and removal events are received.
>> 388 * socket_setup() turns on socket power and resets the socket, in two stages.
>> 389 * socket_shutdown() unconfigures a socket and turns off socket power.
>> 390 */
>> 391 static void socket_shutdown(struct pcmcia_socket *s)
>> 392 {
>> 393 int status;
>> 394
>> 395 cs_dbg(s, 4, "shutdown\n");
>> 396
>> 397 socket_remove_drivers(s);
>> 398 s->state &= SOCKET_INUSE | SOCKET_PRESENT;
>> 399 msleep(shutdown_delay * 10);
>> 400 s->state &= SOCKET_INUSE;
>> 401
>> 402 /* Blank out the socket state */
>> 403 s->socket = dead_socket;
>> 404 s->ops->init(s);
>> 405 s->ops->set_socket(s, &s->socket);
>> 406 s->irq.AssignedIRQ = s->irq.Config = 0;
>> 407 s->lock_count = 0;
>> 408 destroy_cis_cache(s);
>> 409 #ifdef CONFIG_CARDBUS
>> 410 cb_free(s);
>> 411 #endif
>> 412 s->functions = 0;
>> 413
>> 414 /* give socket some time to power down */
>> 415 msleep(100);
>> 416
>> 417 s->ops->get_status(s, &status);
>> 418 if (status & SS_POWERON) {
>> 419 printk(KERN_ERR "PCMCIA: socket %p: *** DANGER *** unable to remove socket power\n", s);
>> 420 }
>> 421
>> 422 cs_socket_put(s);
>> 423 }
>> 424
463 static int socket_setup(struct pcmcia_socket * 425 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
464 { 426 {
465 int status, i; 427 int status, i;
466 428
467 cs_dbg(skt, 4, "setup\n"); 429 cs_dbg(skt, 4, "setup\n");
468 430
469 skt->ops->get_status(skt, &status); 431 skt->ops->get_status(skt, &status);
470 if (!(status & SS_DETECT)) 432 if (!(status & SS_DETECT))
471 return CS_NO_CARD; 433 return CS_NO_CARD;
472 434
473 msleep(initial_delay * 10); 435 msleep(initial_delay * 10);
474 436
475 for (i = 0; i < 100; i++) { 437 for (i = 0; i < 100; i++) {
476 skt->ops->get_status(skt, &sta 438 skt->ops->get_status(skt, &status);
477 if (!(status & SS_DETECT)) 439 if (!(status & SS_DETECT))
478 return CS_NO_CARD; 440 return CS_NO_CARD;
479 441
480 if (!(status & SS_PENDING)) 442 if (!(status & SS_PENDING))
481 break; 443 break;
482 444
483 msleep(100); 445 msleep(100);
484 } 446 }
485 447
486 if (status & SS_PENDING) { 448 if (status & SS_PENDING) {
487 cs_err(skt, "voltage interroga 449 cs_err(skt, "voltage interrogation timed out.\n");
488 return CS_GENERAL_FAILURE; 450 return CS_GENERAL_FAILURE;
489 } 451 }
490 452
491 if (status & SS_CARDBUS) { 453 if (status & SS_CARDBUS) {
>> 454 if (!(skt->features & SS_CAP_CARDBUS)) {
>> 455 cs_err(skt, "cardbus cards are not supported.\n");
>> 456 return CS_BAD_TYPE;
>> 457 }
492 skt->state |= SOCKET_CARDBUS; 458 skt->state |= SOCKET_CARDBUS;
493 #ifndef CONFIG_CARDBUS <<
494 cs_err(skt, "cardbus cards are <<
495 return CS_BAD_TYPE; <<
496 #endif <<
497 } 459 }
498 460
499 /* 461 /*
500 * Decode the card voltage requirement 462 * Decode the card voltage requirements, and apply power to the card.
501 */ 463 */
502 if (status & SS_3VCARD) 464 if (status & SS_3VCARD)
503 skt->socket.Vcc = skt->socket. 465 skt->socket.Vcc = skt->socket.Vpp = 33;
504 else if (!(status & SS_XVCARD)) 466 else if (!(status & SS_XVCARD))
505 skt->socket.Vcc = skt->socket. 467 skt->socket.Vcc = skt->socket.Vpp = 50;
506 else { 468 else {
507 cs_err(skt, "unsupported volta 469 cs_err(skt, "unsupported voltage key.\n");
508 return CS_BAD_TYPE; 470 return CS_BAD_TYPE;
509 } 471 }
>> 472
>> 473 if (skt->power_hook)
>> 474 skt->power_hook(skt, HOOK_POWER_PRE);
>> 475
510 skt->socket.flags = 0; 476 skt->socket.flags = 0;
511 skt->ops->set_socket(skt, &skt->socket 477 skt->ops->set_socket(skt, &skt->socket);
512 478
513 /* 479 /*
514 * Wait "vcc_settle" for the supply to 480 * Wait "vcc_settle" for the supply to stabilise.
515 */ 481 */
516 msleep(vcc_settle * 10); 482 msleep(vcc_settle * 10);
517 483
518 skt->ops->get_status(skt, &status); 484 skt->ops->get_status(skt, &status);
519 if (!(status & SS_POWERON)) { 485 if (!(status & SS_POWERON)) {
520 cs_err(skt, "unable to apply p 486 cs_err(skt, "unable to apply power.\n");
521 return CS_BAD_TYPE; 487 return CS_BAD_TYPE;
522 } 488 }
523 489
524 return socket_reset(skt); !! 490 status = socket_reset(skt);
>> 491
>> 492 if (skt->power_hook)
>> 493 skt->power_hook(skt, HOOK_POWER_POST);
>> 494
>> 495 return status;
525 } 496 }
526 497
527 /* 498 /*
528 * Handle card insertion. Setup the socket, r 499 * Handle card insertion. Setup the socket, reset the card,
529 * and then tell the rest of PCMCIA that a car 500 * and then tell the rest of PCMCIA that a card is present.
530 */ 501 */
531 static int socket_insert(struct pcmcia_socket 502 static int socket_insert(struct pcmcia_socket *skt)
532 { 503 {
533 int ret; 504 int ret;
534 505
535 cs_dbg(skt, 4, "insert\n"); 506 cs_dbg(skt, 4, "insert\n");
536 507
537 if (!cs_socket_get(skt)) 508 if (!cs_socket_get(skt))
538 return CS_NO_CARD; 509 return CS_NO_CARD;
539 510
540 ret = socket_setup(skt, setup_delay); 511 ret = socket_setup(skt, setup_delay);
541 if (ret == CS_SUCCESS) { 512 if (ret == CS_SUCCESS) {
542 skt->state |= SOCKET_PRESENT; 513 skt->state |= SOCKET_PRESENT;
>> 514
>> 515 printk(KERN_NOTICE "pccard: %s card inserted into slot %d\n",
>> 516 (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
>> 517 skt->sock);
>> 518
543 #ifdef CONFIG_CARDBUS 519 #ifdef CONFIG_CARDBUS
544 if (skt->state & SOCKET_CARDBU 520 if (skt->state & SOCKET_CARDBUS) {
545 cb_alloc(skt); 521 cb_alloc(skt);
546 skt->state |= SOCKET_C 522 skt->state |= SOCKET_CARDBUS_CONFIG;
547 } 523 }
548 #endif 524 #endif
549 cs_dbg(skt, 4, "insert done\n" 525 cs_dbg(skt, 4, "insert done\n");
550 526
551 send_event(skt, CS_EVENT_CARD_ 527 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
552 } else { 528 } else {
553 socket_shutdown(skt); 529 socket_shutdown(skt);
554 cs_socket_put(skt); <<
555 } 530 }
556 531
557 return ret; 532 return ret;
558 } 533 }
559 534
560 static int socket_suspend(struct pcmcia_socket 535 static int socket_suspend(struct pcmcia_socket *skt)
561 { 536 {
562 if (skt->state & SOCKET_SUSPEND) 537 if (skt->state & SOCKET_SUSPEND)
563 return CS_IN_USE; 538 return CS_IN_USE;
564 539
565 send_event(skt, CS_EVENT_PM_SUSPEND, C 540 send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
566 skt->socket = dead_socket; 541 skt->socket = dead_socket;
567 skt->ops->suspend(skt); !! 542 skt->ops->set_socket(skt, &skt->socket);
>> 543 if (skt->ops->suspend)
>> 544 skt->ops->suspend(skt);
568 skt->state |= SOCKET_SUSPEND; 545 skt->state |= SOCKET_SUSPEND;
569 546
570 return CS_SUCCESS; 547 return CS_SUCCESS;
571 } 548 }
572 549
573 /* 550 /*
574 * Resume a socket. If a card is present, ver 551 * Resume a socket. If a card is present, verify its CIS against
575 * our cached copy. If they are different, th 552 * our cached copy. If they are different, the card has been
576 * replaced, and we need to tell the drivers. 553 * replaced, and we need to tell the drivers.
577 */ 554 */
578 static int socket_resume(struct pcmcia_socket 555 static int socket_resume(struct pcmcia_socket *skt)
579 { 556 {
580 int ret; 557 int ret;
581 558
582 if (!(skt->state & SOCKET_SUSPEND)) 559 if (!(skt->state & SOCKET_SUSPEND))
583 return CS_IN_USE; 560 return CS_IN_USE;
584 561
585 skt->socket = dead_socket; 562 skt->socket = dead_socket;
586 skt->ops->init(skt); 563 skt->ops->init(skt);
587 skt->ops->set_socket(skt, &skt->socket 564 skt->ops->set_socket(skt, &skt->socket);
588 565
>> 566 if (!(skt->state & SOCKET_PRESENT)) {
>> 567 skt->state &= ~SOCKET_SUSPEND;
>> 568 return socket_insert(skt);
>> 569 }
>> 570
589 ret = socket_setup(skt, resume_delay); 571 ret = socket_setup(skt, resume_delay);
590 if (ret == CS_SUCCESS) { 572 if (ret == CS_SUCCESS) {
591 /* 573 /*
592 * FIXME: need a better check 574 * FIXME: need a better check here for cardbus cards.
593 */ 575 */
594 if (verify_cis_cache(skt) != 0 576 if (verify_cis_cache(skt) != 0) {
595 cs_dbg(skt, 4, "cis mi 577 cs_dbg(skt, 4, "cis mismatch - different card\n");
596 socket_remove_drivers( 578 socket_remove_drivers(skt);
597 destroy_cis_cache(skt) 579 destroy_cis_cache(skt);
598 /* 580 /*
599 * Workaround: give DS 581 * Workaround: give DS time to schedule removal.
600 * Remove me once the 582 * Remove me once the 100ms delay is eliminated
601 * in ds.c 583 * in ds.c
602 */ 584 */
603 msleep(200); 585 msleep(200);
604 send_event(skt, CS_EVE 586 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
605 } else { 587 } else {
606 cs_dbg(skt, 4, "cis ma 588 cs_dbg(skt, 4, "cis matches cache\n");
607 send_event(skt, CS_EVE 589 send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
608 } 590 }
609 } else { 591 } else {
610 socket_shutdown(skt); 592 socket_shutdown(skt);
611 cs_socket_put(skt); <<
612 } 593 }
613 594
614 skt->state &= ~SOCKET_SUSPEND; 595 skt->state &= ~SOCKET_SUSPEND;
615 596
616 return CS_SUCCESS; 597 return CS_SUCCESS;
617 } 598 }
618 599
619 static void socket_remove(struct pcmcia_socket 600 static void socket_remove(struct pcmcia_socket *skt)
620 { 601 {
>> 602 printk(KERN_NOTICE "pccard: card ejected from slot %d\n", skt->sock);
621 socket_shutdown(skt); 603 socket_shutdown(skt);
622 cs_socket_put(skt); <<
623 } 604 }
624 605
625 /* 606 /*
626 * Process a socket card detect status change. 607 * Process a socket card detect status change.
627 * 608 *
628 * If we don't have a card already present, de 609 * If we don't have a card already present, delay the detect event for
629 * about 20ms (to be on the safe side) before 610 * about 20ms (to be on the safe side) before reading the socket status.
630 * 611 *
631 * Some i82365-based systems send multiple SS_ 612 * Some i82365-based systems send multiple SS_DETECT events during card
632 * insertion, and the "card present" status bi 613 * insertion, and the "card present" status bit seems to bounce. This
633 * will probably be true with GPIO-based card 614 * will probably be true with GPIO-based card detection systems after
634 * the product has aged. 615 * the product has aged.
635 */ 616 */
636 static void socket_detect_change(struct pcmcia 617 static void socket_detect_change(struct pcmcia_socket *skt)
637 { 618 {
638 if (!(skt->state & SOCKET_SUSPEND)) { 619 if (!(skt->state & SOCKET_SUSPEND)) {
639 int status; 620 int status;
640 621
641 if (!(skt->state & SOCKET_PRES 622 if (!(skt->state & SOCKET_PRESENT))
642 msleep(20); 623 msleep(20);
643 624
644 skt->ops->get_status(skt, &sta 625 skt->ops->get_status(skt, &status);
645 if ((skt->state & SOCKET_PRESE 626 if ((skt->state & SOCKET_PRESENT) &&
646 !(status & SS_DETECT)) 627 !(status & SS_DETECT))
647 socket_remove(skt); 628 socket_remove(skt);
648 if (!(skt->state & SOCKET_PRES 629 if (!(skt->state & SOCKET_PRESENT) &&
649 (status & SS_DETECT)) 630 (status & SS_DETECT))
650 socket_insert(skt); 631 socket_insert(skt);
651 } 632 }
652 } 633 }
653 634
654 static int pccardd(void *__skt) 635 static int pccardd(void *__skt)
655 { 636 {
656 struct pcmcia_socket *skt = __skt; 637 struct pcmcia_socket *skt = __skt;
657 DECLARE_WAITQUEUE(wait, current); 638 DECLARE_WAITQUEUE(wait, current);
658 int ret; 639 int ret;
659 640
660 daemonize("pccardd"); <<
661 <<
662 skt->thread = current; 641 skt->thread = current;
663 skt->socket = dead_socket; 642 skt->socket = dead_socket;
664 skt->ops->init(skt); 643 skt->ops->init(skt);
665 skt->ops->set_socket(skt, &skt->socket 644 skt->ops->set_socket(skt, &skt->socket);
666 645
667 /* register with the device core */ 646 /* register with the device core */
668 ret = class_device_register(&skt->dev) !! 647 ret = device_register(&skt->dev);
669 if (ret) { 648 if (ret) {
670 printk(KERN_WARNING "PCMCIA: u 649 printk(KERN_WARNING "PCMCIA: unable to register socket 0x%p\n",
671 skt); 650 skt);
672 skt->thread = NULL; 651 skt->thread = NULL;
673 complete_and_exit(&skt->thread !! 652 complete(&skt->thread_done);
>> 653 return 0;
674 } 654 }
675 complete(&skt->thread_done); <<
676 655
677 add_wait_queue(&skt->thread_wait, &wai 656 add_wait_queue(&skt->thread_wait, &wait);
>> 657 complete(&skt->thread_done);
>> 658
>> 659 set_freezable();
678 for (;;) { 660 for (;;) {
679 unsigned long flags; 661 unsigned long flags;
680 unsigned int events; 662 unsigned int events;
681 663
682 set_current_state(TASK_INTERRU 664 set_current_state(TASK_INTERRUPTIBLE);
683 665
684 spin_lock_irqsave(&skt->thread 666 spin_lock_irqsave(&skt->thread_lock, flags);
685 events = skt->thread_events; 667 events = skt->thread_events;
686 skt->thread_events = 0; 668 skt->thread_events = 0;
687 spin_unlock_irqrestore(&skt->t 669 spin_unlock_irqrestore(&skt->thread_lock, flags);
688 670
689 if (events) { 671 if (events) {
690 down(&skt->skt_sem); !! 672 mutex_lock(&skt->skt_mutex);
691 if (events & SS_DETECT 673 if (events & SS_DETECT)
692 socket_detect_ 674 socket_detect_change(skt);
693 if (events & SS_BATDEA 675 if (events & SS_BATDEAD)
694 send_event(skt 676 send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
695 if (events & SS_BATWAR 677 if (events & SS_BATWARN)
696 send_event(skt 678 send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
697 if (events & SS_READY) 679 if (events & SS_READY)
698 send_event(skt 680 send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
699 up(&skt->skt_sem); !! 681 mutex_unlock(&skt->skt_mutex);
700 continue; 682 continue;
701 } 683 }
702 684
703 schedule(); !! 685 if (kthread_should_stop())
704 try_to_freeze(PF_FREEZE); <<
705 <<
706 if (!skt->thread) <<
707 break; 686 break;
>> 687
>> 688 schedule();
>> 689 try_to_freeze();
708 } 690 }
>> 691 /* make sure we are running before we exit */
>> 692 set_current_state(TASK_RUNNING);
>> 693
709 remove_wait_queue(&skt->thread_wait, & 694 remove_wait_queue(&skt->thread_wait, &wait);
710 695
711 /* remove from the device core */ 696 /* remove from the device core */
712 class_device_unregister(&skt->dev); !! 697 device_unregister(&skt->dev);
713 698
714 complete_and_exit(&skt->thread_done, 0 !! 699 return 0;
715 } 700 }
716 701
717 /* 702 /*
718 * Yenta (at least) probes interrupts before r 703 * Yenta (at least) probes interrupts before registering the socket and
719 * starting the handler thread. 704 * starting the handler thread.
720 */ 705 */
721 void pcmcia_parse_events(struct pcmcia_socket 706 void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
722 { 707 {
>> 708 unsigned long flags;
723 cs_dbg(s, 4, "parse_events: events %08 709 cs_dbg(s, 4, "parse_events: events %08x\n", events);
724 if (s->thread) { 710 if (s->thread) {
725 spin_lock(&s->thread_lock); !! 711 spin_lock_irqsave(&s->thread_lock, flags);
726 s->thread_events |= events; 712 s->thread_events |= events;
727 spin_unlock(&s->thread_lock); !! 713 spin_unlock_irqrestore(&s->thread_lock, flags);
728 714
729 wake_up(&s->thread_wait); 715 wake_up(&s->thread_wait);
730 } 716 }
731 } /* pcmcia_parse_events */ 717 } /* pcmcia_parse_events */
>> 718 EXPORT_SYMBOL(pcmcia_parse_events);
732 719
733 720
734 /*============================================ <<
735 <<
736 Special stuff for managing IO windows, bec <<
737 <<
738 ============================================== <<
739 <<
740 static int alloc_io_space(struct pcmcia_socket <<
741 ioaddr_t num, u_int <<
742 { <<
743 int i; <<
744 kio_addr_t try, align; <<
745 <<
746 align = (*base) ? (lines ? 1<<lines : 0) : <<
747 if (align && (align < num)) { <<
748 if (*base) { <<
749 cs_dbg(s, 0, "odd IO request: num <<
750 num, align); <<
751 align = 0; <<
752 } else <<
753 while (align && (align < num)) ali <<
754 } <<
755 if (*base & ~(align-1)) { <<
756 cs_dbg(s, 0, "odd IO request: base %#x <<
757 *base, align); <<
758 align = 0; <<
759 } <<
760 if ((s->features & SS_CAP_STATIC_MAP) && s <<
761 *base = s->io_offset | (*base & 0x0fff <<
762 return 0; <<
763 } <<
764 /* Check for an already-allocated window t <<
765 what was asked for. It is a hack becau <<
766 potential conflicts, just the most obvi <<
767 for (i = 0; i < MAX_IO_WIN; i++) <<
768 if ((s->io[i].NumPorts != 0) && <<
769 ((s->io[i].BasePort & (align-1)) = <<
770 return 1; <<
771 for (i = 0; i < MAX_IO_WIN; i++) { <<
772 if (s->io[i].NumPorts == 0) { <<
773 s->io[i].res = find_io_region(*bas <<
774 if (s->io[i].res) { <<
775 s->io[i].Attributes = attr; <<
776 s->io[i].BasePort = *base = s- <<
777 s->io[i].NumPorts = s->io[i].I <<
778 break; <<
779 } else <<
780 return 1; <<
781 } else if (s->io[i].Attributes != attr <<
782 continue; <<
783 /* Try to extend top of window */ <<
784 try = s->io[i].BasePort + s->io[i].Num <<
785 if ((*base == 0) || (*base == try)) <<
786 if (adjust_io_region(s->io[i].res, <<
787 s->io[i].res- <<
788 *base = try; <<
789 s->io[i].NumPorts += num; <<
790 s->io[i].InUse += num; <<
791 break; <<
792 } <<
793 /* Try to extend bottom of window */ <<
794 try = s->io[i].BasePort - num; <<
795 if ((*base == 0) || (*base == try)) <<
796 if (adjust_io_region(s->io[i].res, <<
797 s->io[i].res- <<
798 s->io[i].BasePort = *base = tr <<
799 s->io[i].NumPorts += num; <<
800 s->io[i].InUse += num; <<
801 break; <<
802 } <<
803 } <<
804 return (i == MAX_IO_WIN); <<
805 } /* alloc_io_space */ <<
806 <<
807 static void release_io_space(struct pcmcia_soc <<
808 ioaddr_t num) <<
809 { <<
810 int i; <<
811 <<
812 for (i = 0; i < MAX_IO_WIN; i++) { <<
813 if ((s->io[i].BasePort <= base) && <<
814 (s->io[i].BasePort+s->io[i].NumPor <<
815 s->io[i].InUse -= num; <<
816 /* Free the window if no one else <<
817 if (s->io[i].InUse == 0) { <<
818 s->io[i].NumPorts = 0; <<
819 release_resource(s->io[i].res) <<
820 kfree(s->io[i].res); <<
821 s->io[i].res = NULL; <<
822 } <<
823 } <<
824 } <<
825 } <<
826 <<
827 /*============================================ <<
828 <<
829 Access_configuration_register() reads and <<
830 registers in attribute memory. Memory win <<
831 this and the tuple reading services. <<
832 <<
833 ============================================== <<
834 <<
835 int pccard_access_configuration_register(struc <<
836 unsig <<
837 conf_ <<
838 { <<
839 config_t *c; <<
840 int addr; <<
841 u_char val; <<
842 <<
843 if (!s || !s->config) <<
844 return CS_NO_CARD; <<
845 <<
846 c = &s->config[function]; <<
847 <<
848 if (c == NULL) <<
849 return CS_NO_CARD; <<
850 <<
851 if (!(c->state & CONFIG_LOCKED)) <<
852 return CS_CONFIGURATION_LOCKED; <<
853 <<
854 addr = (c->ConfigBase + reg->Offset) >> 1; <<
855 <<
856 switch (reg->Action) { <<
857 case CS_READ: <<
858 read_cis_mem(s, 1, addr, 1, &val); <<
859 reg->Value = val; <<
860 break; <<
861 case CS_WRITE: <<
862 val = reg->Value; <<
863 write_cis_mem(s, 1, addr, 1, &val); <<
864 break; <<
865 default: <<
866 return CS_BAD_ARGS; <<
867 break; <<
868 } <<
869 return CS_SUCCESS; <<
870 } /* access_configuration_register */ <<
871 EXPORT_SYMBOL(pccard_access_configuration_regi <<
872 <<
873 <<
874 /*============================================ <<
875 <<
876 int pccard_get_configuration_info(struct pcmci <<
877 unsigned int <<
878 config_info_ <<
879 { <<
880 config_t *c; <<
881 <<
882 if (!(s->state & SOCKET_PRESENT)) <<
883 return CS_NO_CARD; <<
884 <<
885 config->Function = function; <<
886 <<
887 #ifdef CONFIG_CARDBUS <<
888 if (s->state & SOCKET_CARDBUS) { <<
889 memset(config, 0, sizeof(config_info_t <<
890 config->Vcc = s->socket.Vcc; <<
891 config->Vpp1 = config->Vpp2 = s->socke <<
892 config->Option = s->cb_dev->subordinat <<
893 if (s->state & SOCKET_CARDBUS_CONFIG) <<
894 config->Attributes = CONF_VALID_CL <<
895 config->IntType = INT_CARDBUS; <<
896 config->AssignedIRQ = s->irq.Assig <<
897 if (config->AssignedIRQ) <<
898 config->Attributes |= CONF_ENA <<
899 config->BasePort1 = s->io[0].BaseP <<
900 config->NumPorts1 = s->io[0].NumPo <<
901 } <<
902 return CS_SUCCESS; <<
903 } <<
904 #endif <<
905 <<
906 c = (s->config != NULL) ? &s->config[funct <<
907 <<
908 if ((c == NULL) || !(c->state & CONFIG_LOC <<
909 config->Attributes = 0; <<
910 config->Vcc = s->socket.Vcc; <<
911 config->Vpp1 = config->Vpp2 = s->socke <<
912 return CS_SUCCESS; <<
913 } <<
914 <<
915 /* !!! This is a hack !!! */ <<
916 memcpy(&config->Attributes, &c->Attributes <<
917 config->Attributes |= CONF_VALID_CLIENT; <<
918 config->CardValues = c->CardValues; <<
919 config->IRQAttributes = c->irq.Attributes; <<
920 config->AssignedIRQ = s->irq.AssignedIRQ; <<
921 config->BasePort1 = c->io.BasePort1; <<
922 config->NumPorts1 = c->io.NumPorts1; <<
923 config->Attributes1 = c->io.Attributes1; <<
924 config->BasePort2 = c->io.BasePort2; <<
925 config->NumPorts2 = c->io.NumPorts2; <<
926 config->Attributes2 = c->io.Attributes2; <<
927 config->IOAddrLines = c->io.IOAddrLines; <<
928 <<
929 return CS_SUCCESS; <<
930 } /* get_configuration_info */ <<
931 EXPORT_SYMBOL(pccard_get_configuration_info); <<
932 <<
933 /*============================================ <<
934 <<
935 Return information about this version of C <<
936 <<
937 ============================================== <<
938 <<
939 int pcmcia_get_card_services_info(servinfo_t * <<
940 { <<
941 unsigned int socket_count = 0; <<
942 struct list_head *tmp; <<
943 info->Signature[0] = 'C'; <<
944 info->Signature[1] = 'S'; <<
945 down_read(&pcmcia_socket_list_rwsem); <<
946 list_for_each(tmp, &pcmcia_socket_list) <<
947 socket_count++; <<
948 up_read(&pcmcia_socket_list_rwsem); <<
949 info->Count = socket_count; <<
950 info->Revision = CS_RELEASE_CODE; <<
951 info->CSLevel = 0x0210; <<
952 info->VendorString = (char *)release; <<
953 return CS_SUCCESS; <<
954 } /* get_card_services_info */ <<
955 <<
956 <<
957 /*============================================ <<
958 <<
959 int pcmcia_get_window(struct pcmcia_socket *s, <<
960 { <<
961 window_t *win; <<
962 int w; <<
963 <<
964 if (!s || !(s->state & SOCKET_PRESENT)) <<
965 return CS_NO_CARD; <<
966 for (w = idx; w < MAX_WIN; w++) <<
967 if (s->state & SOCKET_WIN_REQ(w)) brea <<
968 if (w == MAX_WIN) <<
969 return CS_NO_MORE_ITEMS; <<
970 win = &s->win[w]; <<
971 req->Base = win->ctl.res->start; <<
972 req->Size = win->ctl.res->end - win->ctl.r <<
973 req->AccessSpeed = win->ctl.speed; <<
974 req->Attributes = 0; <<
975 if (win->ctl.flags & MAP_ATTRIB) <<
976 req->Attributes |= WIN_MEMORY_TYPE_AM; <<
977 if (win->ctl.flags & MAP_ACTIVE) <<
978 req->Attributes |= WIN_ENABLE; <<
979 if (win->ctl.flags & MAP_16BIT) <<
980 req->Attributes |= WIN_DATA_WIDTH_16; <<
981 if (win->ctl.flags & MAP_USE_WAIT) <<
982 req->Attributes |= WIN_USE_WAIT; <<
983 *handle = win; <<
984 return CS_SUCCESS; <<
985 } /* get_window */ <<
986 EXPORT_SYMBOL(pcmcia_get_window); <<
987 <<
988 /*============================================ <<
989 <<
990 Return the PCI device associated with a ca <<
991 <<
992 ============================================== <<
993 <<
994 #ifdef CONFIG_CARDBUS <<
995 <<
996 struct pci_bus *pcmcia_lookup_bus(struct pcmci <<
997 { <<
998 if (!s || !(s->state & SOCKET_CARDBUS) <<
999 return NULL; <<
1000 <<
1001 return s->cb_dev->subordinate; <<
1002 } <<
1003 <<
1004 EXPORT_SYMBOL(pcmcia_lookup_bus); <<
1005 <<
1006 #endif <<
1007 <<
1008 /*=========================================== <<
1009 <<
1010 Get the current socket state bits. We do <<
1011 SocketState yet: I haven't seen any point <<
1012 <<
1013 ============================================= <<
1014 <<
1015 int pccard_get_status(struct pcmcia_socket *s <<
1016 { <<
1017 config_t *c; <<
1018 int val; <<
1019 <<
1020 s->ops->get_status(s, &val); <<
1021 status->CardState = status->SocketState = <<
1022 status->CardState |= (val & SS_DETECT) ? <<
1023 status->CardState |= (val & SS_CARDBUS) ? <<
1024 status->CardState |= (val & SS_3VCARD) ? <<
1025 status->CardState |= (val & SS_XVCARD) ? <<
1026 if (s->state & SOCKET_SUSPEND) <<
1027 status->CardState |= CS_EVENT_PM_SUSP <<
1028 if (!(s->state & SOCKET_PRESENT)) <<
1029 return CS_NO_CARD; <<
1030 <<
1031 c = (s->config != NULL) ? &s->config[func <<
1032 if ((c != NULL) && (c->state & CONFIG_LOC <<
1033 (c->IntType & (INT_MEMORY_AND_IO | IN <<
1034 u_char reg; <<
1035 if (c->Present & PRESENT_PIN_REPLACE) <<
1036 read_cis_mem(s, 1, (c->ConfigBase <<
1037 status->CardState |= <<
1038 (reg & PRR_WP_STATUS) ? CS_EV <<
1039 status->CardState |= <<
1040 (reg & PRR_READY_STATUS) ? CS <<
1041 status->CardState |= <<
1042 (reg & PRR_BVD2_STATUS) ? CS_ <<
1043 status->CardState |= <<
1044 (reg & PRR_BVD1_STATUS) ? CS_ <<
1045 } else { <<
1046 /* No PRR? Then assume we're alw <<
1047 status->CardState |= CS_EVENT_REA <<
1048 } <<
1049 if (c->Present & PRESENT_EXT_STATUS) <<
1050 read_cis_mem(s, 1, (c->ConfigBase <<
1051 status->CardState |= <<
1052 (reg & ESR_REQ_ATTN) ? CS_EVE <<
1053 } <<
1054 return CS_SUCCESS; <<
1055 } <<
1056 status->CardState |= <<
1057 (val & SS_WRPROT) ? CS_EVENT_WRITE_PR <<
1058 status->CardState |= <<
1059 (val & SS_BATDEAD) ? CS_EVENT_BATTERY <<
1060 status->CardState |= <<
1061 (val & SS_BATWARN) ? CS_EVENT_BATTERY <<
1062 status->CardState |= <<
1063 (val & SS_READY) ? CS_EVENT_READY_CHA <<
1064 return CS_SUCCESS; <<
1065 } /* get_status */ <<
1066 EXPORT_SYMBOL(pccard_get_status); <<
1067 <<
1068 /*=========================================== <<
1069 <<
1070 Change the card address of an already ope <<
1071 <<
1072 ============================================= <<
1073 <<
1074 int pcmcia_get_mem_page(window_handle_t win, <<
1075 { <<
1076 if ((win == NULL) || (win->magic != WINDO <<
1077 return CS_BAD_HANDLE; <<
1078 req->Page = 0; <<
1079 req->CardOffset = win->ctl.card_start; <<
1080 return CS_SUCCESS; <<
1081 } /* get_mem_page */ <<
1082 <<
1083 int pcmcia_map_mem_page(window_handle_t win, <<
1084 { <<
1085 struct pcmcia_socket *s; <<
1086 if ((win == NULL) || (win->magic != WINDO <<
1087 return CS_BAD_HANDLE; <<
1088 if (req->Page != 0) <<
1089 return CS_BAD_PAGE; <<
1090 s = win->sock; <<
1091 win->ctl.card_start = req->CardOffset; <<
1092 if (s->ops->set_mem_map(s, &win->ctl) != <<
1093 return CS_BAD_OFFSET; <<
1094 return CS_SUCCESS; <<
1095 } /* map_mem_page */ <<
1096 <<
1097 /*=========================================== <<
1098 <<
1099 Modify a locked socket configuration <<
1100 <<
1101 ============================================= <<
1102 <<
1103 int pcmcia_modify_configuration(client_handle <<
1104 modconf_t *mo <<
1105 { <<
1106 struct pcmcia_socket *s; <<
1107 config_t *c; <<
1108 <<
1109 if (CHECK_HANDLE(handle)) <<
1110 return CS_BAD_HANDLE; <<
1111 s = SOCKET(handle); c = CONFIG(handle); <<
1112 if (!(s->state & SOCKET_PRESENT)) <<
1113 return CS_NO_CARD; <<
1114 if (!(c->state & CONFIG_LOCKED)) <<
1115 return CS_CONFIGURATION_LOCKED; <<
1116 <<
1117 if (mod->Attributes & CONF_IRQ_CHANGE_VAL <<
1118 if (mod->Attributes & CONF_ENABLE_IRQ <<
1119 c->Attributes |= CONF_ENABLE_IRQ; <<
1120 s->socket.io_irq = s->irq.Assigne <<
1121 } else { <<
1122 c->Attributes &= ~CONF_ENABLE_IRQ <<
1123 s->socket.io_irq = 0; <<
1124 } <<
1125 s->ops->set_socket(s, &s->socket); <<
1126 } <<
1127 <<
1128 if (mod->Attributes & CONF_VCC_CHANGE_VAL <<
1129 return CS_BAD_VCC; <<
1130 <<
1131 /* We only allow changing Vpp1 and Vpp2 t <<
1132 if ((mod->Attributes & CONF_VPP1_CHANGE_V <<
1133 (mod->Attributes & CONF_VPP2_CHANGE_V <<
1134 if (mod->Vpp1 != mod->Vpp2) <<
1135 return CS_BAD_VPP; <<
1136 c->Vpp1 = c->Vpp2 = s->socket.Vpp = m <<
1137 if (s->ops->set_socket(s, &s->socket) <<
1138 return CS_BAD_VPP; <<
1139 } else if ((mod->Attributes & CONF_VPP1_C <<
1140 (mod->Attributes & CONF_VPP2_C <<
1141 return CS_BAD_VPP; <<
1142 <<
1143 return CS_SUCCESS; <<
1144 } /* modify_configuration */ <<
1145 <<
1146 /* register pcmcia_callback */ 721 /* register pcmcia_callback */
1147 int pccard_register_pcmcia(struct pcmcia_sock 722 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
1148 { 723 {
1149 int ret = 0; 724 int ret = 0;
1150 725
1151 /* s->skt_sem also protects s->callba !! 726 /* s->skt_mutex also protects s->callback */
1152 down(&s->skt_sem); !! 727 mutex_lock(&s->skt_mutex);
1153 728
1154 if (c) { 729 if (c) {
1155 /* registration */ 730 /* registration */
1156 if (s->callback) { 731 if (s->callback) {
1157 ret = -EBUSY; 732 ret = -EBUSY;
1158 goto err; 733 goto err;
1159 } 734 }
1160 735
1161 s->callback = c; 736 s->callback = c;
1162 737
1163 if ((s->state & (SOCKET_PRESE 738 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
1164 send_event(s, CS_EVEN 739 send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
1165 } else 740 } else
1166 s->callback = NULL; 741 s->callback = NULL;
1167 err: 742 err:
1168 up(&s->skt_sem); !! 743 mutex_unlock(&s->skt_mutex);
1169 744
1170 return ret; 745 return ret;
1171 } 746 }
1172 EXPORT_SYMBOL(pccard_register_pcmcia); 747 EXPORT_SYMBOL(pccard_register_pcmcia);
1173 748
1174 /*=========================================== <<
1175 749
1176 int pcmcia_release_configuration(client_handl !! 750 /* I'm not sure which "reset" function this is supposed to use,
1177 { !! 751 * but for now, it uses the low-level interface's reset, not the
1178 pccard_io_map io = { 0, 0, 0, 0, 1 }; !! 752 * CIS register.
1179 struct pcmcia_socket *s; !! 753 */
1180 int i; <<
1181 <<
1182 if (CHECK_HANDLE(handle) || <<
1183 !(handle->state & CLIENT_CONFIG_LOCKE <<
1184 return CS_BAD_HANDLE; <<
1185 handle->state &= ~CLIENT_CONFIG_LOCKED; <<
1186 s = SOCKET(handle); <<
1187 <<
1188 #ifdef CONFIG_CARDBUS <<
1189 if (handle->state & CLIENT_CARDBUS) <<
1190 return CS_SUCCESS; <<
1191 #endif <<
1192 <<
1193 if (!(handle->state & CLIENT_STALE)) { <<
1194 config_t *c = CONFIG(handle); <<
1195 if (--(s->lock_count) == 0) { <<
1196 s->socket.flags = SS_OUTPUT_ENA; <<
1197 s->socket.Vpp = 0; <<
1198 s->socket.io_irq = 0; <<
1199 s->ops->set_socket(s, &s->socket) <<
1200 } <<
1201 if (c->state & CONFIG_IO_REQ) <<
1202 for (i = 0; i < MAX_IO_WIN; i++) <<
1203 if (s->io[i].NumPorts == 0) <<
1204 continue; <<
1205 s->io[i].Config--; <<
1206 if (s->io[i].Config != 0) <<
1207 continue; <<
1208 io.map = i; <<
1209 s->ops->set_io_map(s, &io); <<
1210 } <<
1211 c->state &= ~CONFIG_LOCKED; <<
1212 } <<
1213 <<
1214 return CS_SUCCESS; <<
1215 } /* release_configuration */ <<
1216 <<
1217 /*=========================================== <<
1218 <<
1219 Release_io() releases the I/O ranges allo <<
1220 may be invoked some time after a card eje <<
1221 the actual socket configuration, so if th <<
1222 don't bother checking the port ranges aga <<
1223 values. <<
1224 <<
1225 ============================================= <<
1226 <<
1227 int pcmcia_release_io(client_handle_t handle, <<
1228 { <<
1229 struct pcmcia_socket *s; <<
1230 <<
1231 if (CHECK_HANDLE(handle) || !(handle->sta <<
1232 return CS_BAD_HANDLE; <<
1233 handle->state &= ~CLIENT_IO_REQ; <<
1234 s = SOCKET(handle); <<
1235 <<
1236 #ifdef CONFIG_CARDBUS <<
1237 if (handle->state & CLIENT_CARDBUS) <<
1238 return CS_SUCCESS; <<
1239 #endif <<
1240 <<
1241 if (!(handle->state & CLIENT_STALE)) { <<
1242 config_t *c = CONFIG(handle); <<
1243 if (c->state & CONFIG_LOCKED) <<
1244 return CS_CONFIGURATION_LOCKED; <<
1245 if ((c->io.BasePort1 != req->BasePort <<
1246 (c->io.NumPorts1 != req->NumPorts <<
1247 (c->io.BasePort2 != req->BasePort <<
1248 (c->io.NumPorts2 != req->NumPorts <<
1249 return CS_BAD_ARGS; <<
1250 c->state &= ~CONFIG_IO_REQ; <<
1251 } <<
1252 <<
1253 release_io_space(s, req->BasePort1, req-> <<
1254 if (req->NumPorts2) <<
1255 release_io_space(s, req->BasePort2, r <<
1256 <<
1257 return CS_SUCCESS; <<
1258 } /* release_io */ <<
1259 <<
1260 /*=========================================== <<
1261 <<
1262 int pcmcia_release_irq(client_handle_t handle <<
1263 { <<
1264 struct pcmcia_socket *s; <<
1265 if (CHECK_HANDLE(handle) || !(handle->sta <<
1266 return CS_BAD_HANDLE; <<
1267 handle->state &= ~CLIENT_IRQ_REQ; <<
1268 s = SOCKET(handle); <<
1269 <<
1270 if (!(handle->state & CLIENT_STALE)) { <<
1271 config_t *c = CONFIG(handle); <<
1272 if (c->state & CONFIG_LOCKED) <<
1273 return CS_CONFIGURATION_LOCKED; <<
1274 if (c->irq.Attributes != req->Attribu <<
1275 return CS_BAD_ATTRIBUTE; <<
1276 if (s->irq.AssignedIRQ != req->Assign <<
1277 return CS_BAD_IRQ; <<
1278 if (--s->irq.Config == 0) { <<
1279 c->state &= ~CONFIG_IRQ_REQ; <<
1280 s->irq.AssignedIRQ = 0; <<
1281 } <<
1282 } <<
1283 <<
1284 if (req->Attributes & IRQ_HANDLE_PRESENT) <<
1285 free_irq(req->AssignedIRQ, req->Insta <<
1286 } <<
1287 <<
1288 #ifdef CONFIG_PCMCIA_PROBE <<
1289 pcmcia_used_irq[req->AssignedIRQ]--; <<
1290 #endif <<
1291 <<
1292 return CS_SUCCESS; <<
1293 } /* cs_release_irq */ <<
1294 <<
1295 /*=========================================== <<
1296 <<
1297 int pcmcia_release_window(window_handle_t win <<
1298 { <<
1299 struct pcmcia_socket *s; <<
1300 <<
1301 if ((win == NULL) || (win->magic != WINDO <<
1302 return CS_BAD_HANDLE; <<
1303 s = win->sock; <<
1304 if (!(win->handle->state & CLIENT_WIN_REQ <<
1305 return CS_BAD_HANDLE; <<
1306 <<
1307 /* Shut down memory window */ <<
1308 win->ctl.flags &= ~MAP_ACTIVE; <<
1309 s->ops->set_mem_map(s, &win->ctl); <<
1310 s->state &= ~SOCKET_WIN_REQ(win->index); <<
1311 <<
1312 /* Release system memory */ <<
1313 if (win->ctl.res) { <<
1314 release_resource(win->ctl.res); <<
1315 kfree(win->ctl.res); <<
1316 win->ctl.res = NULL; <<
1317 } <<
1318 win->handle->state &= ~CLIENT_WIN_REQ(win <<
1319 <<
1320 win->magic = 0; <<
1321 <<
1322 return CS_SUCCESS; <<
1323 } /* release_window */ <<
1324 <<
1325 /*=========================================== <<
1326 <<
1327 int pcmcia_request_configuration(client_handl <<
1328 config_req_t <<
1329 { <<
1330 int i; <<
1331 u_int base; <<
1332 struct pcmcia_socket *s; <<
1333 config_t *c; <<
1334 pccard_io_map iomap; <<
1335 <<
1336 if (CHECK_HANDLE(handle)) <<
1337 return CS_BAD_HANDLE; <<
1338 s = SOCKET(handle); <<
1339 if (!(s->state & SOCKET_PRESENT)) <<
1340 return CS_NO_CARD; <<
1341 <<
1342 #ifdef CONFIG_CARDBUS <<
1343 if (handle->state & CLIENT_CARDBUS) <<
1344 return CS_UNSUPPORTED_MODE; <<
1345 #endif <<
1346 <<
1347 if (req->IntType & INT_CARDBUS) <<
1348 return CS_UNSUPPORTED_MODE; <<
1349 c = CONFIG(handle); <<
1350 if (c->state & CONFIG_LOCKED) <<
1351 return CS_CONFIGURATION_LOCKED; <<
1352 <<
1353 /* Do power control. We don't allow chan <<
1354 if (s->socket.Vcc != req->Vcc) <<
1355 return CS_BAD_VCC; <<
1356 if (req->Vpp1 != req->Vpp2) <<
1357 return CS_BAD_VPP; <<
1358 s->socket.Vpp = req->Vpp1; <<
1359 if (s->ops->set_socket(s, &s->socket)) <<
1360 return CS_BAD_VPP; <<
1361 <<
1362 c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = re <<
1363 <<
1364 /* Pick memory or I/O card, DMA mode, int <<
1365 c->IntType = req->IntType; <<
1366 c->Attributes = req->Attributes; <<
1367 if (req->IntType & INT_MEMORY_AND_IO) <<
1368 s->socket.flags |= SS_IOCARD; <<
1369 if (req->IntType & INT_ZOOMED_VIDEO) <<
1370 s->socket.flags |= SS_ZVCARD | SS_IOC <<
1371 if (req->Attributes & CONF_ENABLE_DMA) <<
1372 s->socket.flags |= SS_DMA_MODE; <<
1373 if (req->Attributes & CONF_ENABLE_SPKR) <<
1374 s->socket.flags |= SS_SPKR_ENA; <<
1375 if (req->Attributes & CONF_ENABLE_IRQ) <<
1376 s->socket.io_irq = s->irq.AssignedIRQ <<
1377 else <<
1378 s->socket.io_irq = 0; <<
1379 s->ops->set_socket(s, &s->socket); <<
1380 s->lock_count++; <<
1381 <<
1382 /* Set up CIS configuration registers */ <<
1383 base = c->ConfigBase = req->ConfigBase; <<
1384 c->Present = c->CardValues = req->Present <<
1385 if (req->Present & PRESENT_COPY) { <<
1386 c->Copy = req->Copy; <<
1387 write_cis_mem(s, 1, (base + CISREG_SC <<
1388 } <<
1389 if (req->Present & PRESENT_OPTION) { <<
1390 if (s->functions == 1) { <<
1391 c->Option = req->ConfigIndex & CO <<
1392 } else { <<
1393 c->Option = req->ConfigIndex & CO <<
1394 c->Option |= COR_FUNC_ENA|COR_IRE <<
1395 if (req->Present & PRESENT_IOBASE <<
1396 c->Option |= COR_ADDR_DECODE; <<
1397 } <<
1398 if (c->state & CONFIG_IRQ_REQ) <<
1399 if (!(c->irq.Attributes & IRQ_FOR <<
1400 c->Option |= COR_LEVEL_REQ; <<
1401 write_cis_mem(s, 1, (base + CISREG_CO <<
1402 mdelay(40); <<
1403 } <<
1404 if (req->Present & PRESENT_STATUS) { <<
1405 c->Status = req->Status; <<
1406 write_cis_mem(s, 1, (base + CISREG_CC <<
1407 } <<
1408 if (req->Present & PRESENT_PIN_REPLACE) { <<
1409 c->Pin = req->Pin; <<
1410 write_cis_mem(s, 1, (base + CISREG_PR <<
1411 } <<
1412 if (req->Present & PRESENT_EXT_STATUS) { <<
1413 c->ExtStatus = req->ExtStatus; <<
1414 write_cis_mem(s, 1, (base + CISREG_ES <<
1415 } <<
1416 if (req->Present & PRESENT_IOBASE_0) { <<
1417 u_char b = c->io.BasePort1 & 0xff; <<
1418 write_cis_mem(s, 1, (base + CISREG_IO <<
1419 b = (c->io.BasePort1 >> 8) & 0xff; <<
1420 write_cis_mem(s, 1, (base + CISREG_IO <<
1421 } <<
1422 if (req->Present & PRESENT_IOSIZE) { <<
1423 u_char b = c->io.NumPorts1 + c->io.Nu <<
1424 write_cis_mem(s, 1, (base + CISREG_IO <<
1425 } <<
1426 <<
1427 /* Configure I/O windows */ <<
1428 if (c->state & CONFIG_IO_REQ) { <<
1429 iomap.speed = io_speed; <<
1430 for (i = 0; i < MAX_IO_WIN; i++) <<
1431 if (s->io[i].NumPorts != 0) { <<
1432 iomap.map = i; <<
1433 iomap.flags = MAP_ACTIVE; <<
1434 switch (s->io[i].Attributes & <<
1435 case IO_DATA_PATH_WIDTH_16: <<
1436 iomap.flags |= MAP_16BIT; <<
1437 case IO_DATA_PATH_WIDTH_AUTO: <<
1438 iomap.flags |= MAP_AUTOSZ <<
1439 default: <<
1440 break; <<
1441 } <<
1442 iomap.start = s->io[i].BasePo <<
1443 iomap.stop = iomap.start + s- <<
1444 s->ops->set_io_map(s, &iomap) <<
1445 s->io[i].Config++; <<
1446 } <<
1447 } <<
1448 <<
1449 c->state |= CONFIG_LOCKED; <<
1450 handle->state |= CLIENT_CONFIG_LOCKED; <<
1451 return CS_SUCCESS; <<
1452 } /* request_configuration */ <<
1453 <<
1454 /*=========================================== <<
1455 <<
1456 Request_io() reserves ranges of port addr <<
1457 I have not implemented range sharing or a <<
1458 <<
1459 ============================================= <<
1460 <<
1461 int pcmcia_request_io(client_handle_t handle, <<
1462 { <<
1463 struct pcmcia_socket *s; <<
1464 config_t *c; <<
1465 <<
1466 if (CHECK_HANDLE(handle)) <<
1467 return CS_BAD_HANDLE; <<
1468 s = SOCKET(handle); <<
1469 if (!(s->state & SOCKET_PRESENT)) <<
1470 return CS_NO_CARD; <<
1471 <<
1472 if (handle->state & CLIENT_CARDBUS) { <<
1473 #ifdef CONFIG_CARDBUS <<
1474 handle->state |= CLIENT_IO_REQ; <<
1475 return CS_SUCCESS; <<
1476 #else <<
1477 return CS_UNSUPPORTED_FUNCTION; <<
1478 #endif <<
1479 } <<
1480 <<
1481 if (!req) <<
1482 return CS_UNSUPPORTED_MODE; <<
1483 c = CONFIG(handle); <<
1484 if (c->state & CONFIG_LOCKED) <<
1485 return CS_CONFIGURATION_LOCKED; <<
1486 if (c->state & CONFIG_IO_REQ) <<
1487 return CS_IN_USE; <<
1488 if (req->Attributes1 & (IO_SHARED | IO_FO <<
1489 return CS_BAD_ATTRIBUTE; <<
1490 if ((req->NumPorts2 > 0) && <<
1491 (req->Attributes2 & (IO_SHARED | IO_F <<
1492 return CS_BAD_ATTRIBUTE; <<
1493 <<
1494 if (alloc_io_space(s, req->Attributes1, & <<
1495 req->NumPorts1, req->I <<
1496 return CS_IN_USE; <<
1497 <<
1498 if (req->NumPorts2) { <<
1499 if (alloc_io_space(s, req->Attributes <<
1500 req->NumPorts2, re <<
1501 release_io_space(s, req->BasePort <<
1502 return CS_IN_USE; <<
1503 } <<
1504 } <<
1505 <<
1506 c->io = *req; <<
1507 c->state |= CONFIG_IO_REQ; <<
1508 handle->state |= CLIENT_IO_REQ; <<
1509 return CS_SUCCESS; <<
1510 } /* request_io */ <<
1511 <<
1512 /*=========================================== <<
1513 <<
1514 Request_irq() reserves an irq for this cl <<
1515 <<
1516 Also, since Linux only reserves irq's whe <<
1517 hooked, we don't guarantee that an irq wi <<
1518 when the configuration is locked. Now th <<
1519 there might be a way to fix this using a <<
1520 <<
1521 ============================================= <<
1522 <<
1523 #ifdef CONFIG_PCMCIA_PROBE <<
1524 static irqreturn_t test_action(int cpl, void <<
1525 { <<
1526 return IRQ_NONE; <<
1527 } <<
1528 #endif <<
1529 <<
1530 int pcmcia_request_irq(client_handle_t handle <<
1531 { <<
1532 struct pcmcia_socket *s; <<
1533 config_t *c; <<
1534 int ret = CS_IN_USE, irq = 0; <<
1535 struct pcmcia_device *p_dev = handle_ <<
1536 <<
1537 if (CHECK_HANDLE(handle)) <<
1538 return CS_BAD_HANDLE; <<
1539 s = SOCKET(handle); <<
1540 if (!(s->state & SOCKET_PRESENT)) <<
1541 return CS_NO_CARD; <<
1542 c = CONFIG(handle); <<
1543 if (c->state & CONFIG_LOCKED) <<
1544 return CS_CONFIGURATION_LOCKE <<
1545 if (c->state & CONFIG_IRQ_REQ) <<
1546 return CS_IN_USE; <<
1547 <<
1548 #ifdef CONFIG_PCMCIA_PROBE <<
1549 if (s->irq.AssignedIRQ != 0) { <<
1550 /* If the interrupt is alread <<
1551 irq = s->irq.AssignedIRQ; <<
1552 } else { <<
1553 int try; <<
1554 u32 mask = s->irq_mask; <<
1555 void *data = NULL; <<
1556 <<
1557 for (try = 0; try < 64; try++ <<
1558 irq = try % 32; <<
1559 <<
1560 /* marked as availabl <<
1561 if (!((mask >> irq) & <<
1562 continue; <<
1563 <<
1564 /* avoid an IRQ which <<
1565 if ((try < 32) && pcm <<
1566 continue; <<
1567 <<
1568 /* register the corre <<
1569 * registering a dumm <<
1570 * marked as used by <<
1571 ret = request_irq(irq <<
1572 (re <<
1573 ((r <<
1574 (s <<
1575 (i <<
1576 p_d <<
1577 (re <<
1578 if (!ret) { <<
1579 if (!(req->At <<
1580 free_ <<
1581 break; <<
1582 } <<
1583 } <<
1584 } <<
1585 #endif <<
1586 if (ret) { <<
1587 if (!s->pci_irq) <<
1588 return ret; <<
1589 irq = s->pci_irq; <<
1590 } <<
1591 <<
1592 if (ret && req->Attributes & IRQ_HAND <<
1593 if (request_irq(irq, req->Han <<
1594 ((req->Attrib <<
1595 (s->function <<
1596 (irq == s->p <<
1597 p_dev->dev.bu <<
1598 return CS_IN_USE; <<
1599 } <<
1600 <<
1601 c->irq.Attributes = req->Attributes; <<
1602 s->irq.AssignedIRQ = req->AssignedIRQ <<
1603 s->irq.Config++; <<
1604 <<
1605 c->state |= CONFIG_IRQ_REQ; <<
1606 handle->state |= CLIENT_IRQ_REQ; <<
1607 <<
1608 #ifdef CONFIG_PCMCIA_PROBE <<
1609 pcmcia_used_irq[irq]++; <<
1610 #endif <<
1611 <<
1612 return CS_SUCCESS; <<
1613 } /* pcmcia_request_irq */ <<
1614 <<
1615 /*=========================================== <<
1616 <<
1617 Request_window() establishes a mapping be <<
1618 and system memory space. <<
1619 <<
1620 ============================================= <<
1621 <<
1622 int pcmcia_request_window(client_handle_t *ha <<
1623 { <<
1624 struct pcmcia_socket *s; <<
1625 window_t *win; <<
1626 u_long align; <<
1627 int w; <<
1628 <<
1629 if (CHECK_HANDLE(*handle)) <<
1630 return CS_BAD_HANDLE; <<
1631 s = (*handle)->Socket; <<
1632 if (!(s->state & SOCKET_PRESENT)) <<
1633 return CS_NO_CARD; <<
1634 if (req->Attributes & (WIN_PAGED | WIN_SH <<
1635 return CS_BAD_ATTRIBUTE; <<
1636 <<
1637 /* Window size defaults to smallest avail <<
1638 if (req->Size == 0) <<
1639 req->Size = s->map_size; <<
1640 align = (((s->features & SS_CAP_MEM_ALIGN <<
1641 (req->Attributes & WIN_STRICT_A <<
1642 req->Size : s->map_size); <<
1643 if (req->Size & (s->map_size-1)) <<
1644 return CS_BAD_SIZE; <<
1645 if ((req->Base && (s->features & SS_CAP_S <<
1646 (req->Base & (align-1))) <<
1647 return CS_BAD_BASE; <<
1648 if (req->Base) <<
1649 align = 0; <<
1650 <<
1651 /* Allocate system memory window */ <<
1652 for (w = 0; w < MAX_WIN; w++) <<
1653 if (!(s->state & SOCKET_WIN_REQ(w))) <<
1654 if (w == MAX_WIN) <<
1655 return CS_OUT_OF_RESOURCE; <<
1656 <<
1657 win = &s->win[w]; <<
1658 win->magic = WINDOW_MAGIC; <<
1659 win->index = w; <<
1660 win->handle = *handle; <<
1661 win->sock = s; <<
1662 <<
1663 if (!(s->features & SS_CAP_STATIC_MAP)) { <<
1664 win->ctl.res = find_mem_region(req->B <<
1665 (req-> <<
1666 if (!win->ctl.res) <<
1667 return CS_IN_USE; <<
1668 } <<
1669 (*handle)->state |= CLIENT_WIN_REQ(w); <<
1670 <<
1671 /* Configure the socket controller */ <<
1672 win->ctl.map = w+1; <<
1673 win->ctl.flags = 0; <<
1674 win->ctl.speed = req->AccessSpeed; <<
1675 if (req->Attributes & WIN_MEMORY_TYPE) <<
1676 win->ctl.flags |= MAP_ATTRIB; <<
1677 if (req->Attributes & WIN_ENABLE) <<
1678 win->ctl.flags |= MAP_ACTIVE; <<
1679 if (req->Attributes & WIN_DATA_WIDTH_16) <<
1680 win->ctl.flags |= MAP_16BIT; <<
1681 if (req->Attributes & WIN_USE_WAIT) <<
1682 win->ctl.flags |= MAP_USE_WAIT; <<
1683 win->ctl.card_start = 0; <<
1684 if (s->ops->set_mem_map(s, &win->ctl) != <<
1685 return CS_BAD_ARGS; <<
1686 s->state |= SOCKET_WIN_REQ(w); <<
1687 <<
1688 /* Return window handle */ <<
1689 if (s->features & SS_CAP_STATIC_MAP) { <<
1690 req->Base = win->ctl.static_start; <<
1691 } else { <<
1692 req->Base = win->ctl.res->start; <<
1693 } <<
1694 *wh = win; <<
1695 <<
1696 return CS_SUCCESS; <<
1697 } /* request_window */ <<
1698 <<
1699 /*=========================================== <<
1700 <<
1701 I'm not sure which "reset" function this <<
1702 but for now, it uses the low-level interf <<
1703 CIS register. <<
1704 <<
1705 ============================================= <<
1706 754
1707 int pccard_reset_card(struct pcmcia_socket *s 755 int pccard_reset_card(struct pcmcia_socket *skt)
1708 { 756 {
1709 int ret; 757 int ret;
1710 !! 758
1711 cs_dbg(skt, 1, "resetting socket\n"); 759 cs_dbg(skt, 1, "resetting socket\n");
1712 760
1713 down(&skt->skt_sem); !! 761 mutex_lock(&skt->skt_mutex);
1714 do { 762 do {
1715 if (!(skt->state & SOCKET_PRE 763 if (!(skt->state & SOCKET_PRESENT)) {
1716 ret = CS_NO_CARD; 764 ret = CS_NO_CARD;
1717 break; 765 break;
1718 } 766 }
1719 if (skt->state & SOCKET_SUSPE 767 if (skt->state & SOCKET_SUSPEND) {
1720 ret = CS_IN_USE; 768 ret = CS_IN_USE;
1721 break; 769 break;
1722 } 770 }
1723 if (skt->state & SOCKET_CARDB 771 if (skt->state & SOCKET_CARDBUS) {
1724 ret = CS_UNSUPPORTED_ 772 ret = CS_UNSUPPORTED_FUNCTION;
1725 break; 773 break;
1726 } 774 }
1727 775
1728 ret = send_event(skt, CS_EVEN 776 ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
1729 if (ret == 0) { 777 if (ret == 0) {
1730 send_event(skt, CS_EV 778 send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
1731 if (socket_reset(skt) !! 779 if (skt->callback)
>> 780 skt->callback->suspend(skt);
>> 781 if (socket_reset(skt) == CS_SUCCESS) {
1732 send_event(sk 782 send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
>> 783 if (skt->callback)
>> 784 skt->callback->resume(skt);
>> 785 }
1733 } 786 }
1734 787
1735 ret = CS_SUCCESS; 788 ret = CS_SUCCESS;
1736 } while (0); 789 } while (0);
1737 up(&skt->skt_sem); !! 790 mutex_unlock(&skt->skt_mutex);
1738 791
1739 return ret; 792 return ret;
1740 } /* reset_card */ 793 } /* reset_card */
1741 EXPORT_SYMBOL(pccard_reset_card); 794 EXPORT_SYMBOL(pccard_reset_card);
1742 795
1743 /*=========================================== <<
1744 <<
1745 These shut down or wake up a socket. The <<
1746 initiated versions of the APM suspend and <<
1747 <<
1748 ============================================= <<
1749 796
>> 797 /* These shut down or wake up a socket. They are sort of user
>> 798 * initiated versions of the APM suspend and resume actions.
>> 799 */
1750 int pcmcia_suspend_card(struct pcmcia_socket 800 int pcmcia_suspend_card(struct pcmcia_socket *skt)
1751 { 801 {
1752 int ret; 802 int ret;
1753 !! 803
1754 cs_dbg(skt, 1, "suspending socket\n") 804 cs_dbg(skt, 1, "suspending socket\n");
1755 805
1756 down(&skt->skt_sem); !! 806 mutex_lock(&skt->skt_mutex);
1757 do { 807 do {
1758 if (!(skt->state & SOCKET_PRE 808 if (!(skt->state & SOCKET_PRESENT)) {
1759 ret = CS_NO_CARD; 809 ret = CS_NO_CARD;
1760 break; 810 break;
1761 } 811 }
1762 if (skt->state & SOCKET_CARDB 812 if (skt->state & SOCKET_CARDBUS) {
1763 ret = CS_UNSUPPORTED_ 813 ret = CS_UNSUPPORTED_FUNCTION;
1764 break; 814 break;
1765 } 815 }
>> 816 if (skt->callback) {
>> 817 ret = skt->callback->suspend(skt);
>> 818 if (ret)
>> 819 break;
>> 820 }
1766 ret = socket_suspend(skt); 821 ret = socket_suspend(skt);
1767 } while (0); 822 } while (0);
1768 up(&skt->skt_sem); !! 823 mutex_unlock(&skt->skt_mutex);
1769 824
1770 return ret; 825 return ret;
1771 } /* suspend_card */ 826 } /* suspend_card */
>> 827 EXPORT_SYMBOL(pcmcia_suspend_card);
>> 828
1772 829
1773 int pcmcia_resume_card(struct pcmcia_socket * 830 int pcmcia_resume_card(struct pcmcia_socket *skt)
1774 { 831 {
1775 int ret; 832 int ret;
1776 833
1777 cs_dbg(skt, 1, "waking up socket\n"); 834 cs_dbg(skt, 1, "waking up socket\n");
1778 835
1779 down(&skt->skt_sem); !! 836 mutex_lock(&skt->skt_mutex);
1780 do { 837 do {
1781 if (!(skt->state & SOCKET_PRE 838 if (!(skt->state & SOCKET_PRESENT)) {
1782 ret = CS_NO_CARD; 839 ret = CS_NO_CARD;
1783 break; 840 break;
1784 } 841 }
1785 if (skt->state & SOCKET_CARDB 842 if (skt->state & SOCKET_CARDBUS) {
1786 ret = CS_UNSUPPORTED_ 843 ret = CS_UNSUPPORTED_FUNCTION;
1787 break; 844 break;
1788 } 845 }
1789 ret = socket_resume(skt); 846 ret = socket_resume(skt);
>> 847 if (!ret && skt->callback)
>> 848 skt->callback->resume(skt);
1790 } while (0); 849 } while (0);
1791 up(&skt->skt_sem); !! 850 mutex_unlock(&skt->skt_mutex);
1792 851
1793 return ret; 852 return ret;
1794 } /* resume_card */ 853 } /* resume_card */
>> 854 EXPORT_SYMBOL(pcmcia_resume_card);
1795 855
1796 /*=========================================== <<
1797 <<
1798 These handle user requests to eject or in <<
1799 <<
1800 ============================================= <<
1801 856
>> 857 /* These handle user requests to eject or insert a card. */
1802 int pcmcia_eject_card(struct pcmcia_socket *s 858 int pcmcia_eject_card(struct pcmcia_socket *skt)
1803 { 859 {
1804 int ret; 860 int ret;
1805 861
1806 cs_dbg(skt, 1, "user eject request\n" 862 cs_dbg(skt, 1, "user eject request\n");
1807 863
1808 down(&skt->skt_sem); !! 864 mutex_lock(&skt->skt_mutex);
1809 do { 865 do {
1810 if (!(skt->state & SOCKET_PRE 866 if (!(skt->state & SOCKET_PRESENT)) {
1811 ret = -ENODEV; 867 ret = -ENODEV;
1812 break; 868 break;
1813 } 869 }
1814 870
1815 ret = send_event(skt, CS_EVEN 871 ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
1816 if (ret != 0) { 872 if (ret != 0) {
1817 ret = -EINVAL; 873 ret = -EINVAL;
1818 break; 874 break;
1819 } 875 }
1820 876
1821 socket_remove(skt); 877 socket_remove(skt);
1822 ret = 0; 878 ret = 0;
1823 } while (0); 879 } while (0);
1824 up(&skt->skt_sem); !! 880 mutex_unlock(&skt->skt_mutex);
1825 881
1826 return ret; 882 return ret;
1827 } /* eject_card */ 883 } /* eject_card */
>> 884 EXPORT_SYMBOL(pcmcia_eject_card);
>> 885
1828 886
1829 int pcmcia_insert_card(struct pcmcia_socket * 887 int pcmcia_insert_card(struct pcmcia_socket *skt)
1830 { 888 {
1831 int ret; 889 int ret;
1832 890
1833 cs_dbg(skt, 1, "user insert request\n 891 cs_dbg(skt, 1, "user insert request\n");
1834 892
1835 down(&skt->skt_sem); !! 893 mutex_lock(&skt->skt_mutex);
1836 do { 894 do {
1837 if (skt->state & SOCKET_PRESE 895 if (skt->state & SOCKET_PRESENT) {
1838 ret = -EBUSY; 896 ret = -EBUSY;
1839 break; 897 break;
1840 } 898 }
1841 if (socket_insert(skt) == CS_ 899 if (socket_insert(skt) == CS_NO_CARD) {
1842 ret = -ENODEV; 900 ret = -ENODEV;
1843 break; 901 break;
1844 } 902 }
1845 ret = 0; 903 ret = 0;
1846 } while (0); 904 } while (0);
1847 up(&skt->skt_sem); !! 905 mutex_unlock(&skt->skt_mutex);
1848 906
1849 return ret; 907 return ret;
1850 } /* insert_card */ 908 } /* insert_card */
>> 909 EXPORT_SYMBOL(pcmcia_insert_card);
1851 910
1852 /*=========================================== <<
1853 911
1854 OS-specific module glue goes here !! 912 static int pcmcia_socket_uevent(struct device *dev,
1855 !! 913 struct kobj_uevent_env *env)
1856 ============================================= !! 914 {
1857 /* in alpha order */ !! 915 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
1858 EXPORT_SYMBOL(pcmcia_eject_card); !! 916
1859 EXPORT_SYMBOL(pcmcia_get_card_services_info); !! 917 if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
1860 EXPORT_SYMBOL(pcmcia_get_mem_page); !! 918 return -ENOMEM;
1861 EXPORT_SYMBOL(pcmcia_insert_card); !! 919
1862 EXPORT_SYMBOL(pcmcia_map_mem_page); !! 920 return 0;
1863 EXPORT_SYMBOL(pcmcia_modify_configuration); !! 921 }
1864 EXPORT_SYMBOL(pcmcia_release_configuration); !! 922
1865 EXPORT_SYMBOL(pcmcia_release_io); !! 923
1866 EXPORT_SYMBOL(pcmcia_release_irq); !! 924 static struct completion pcmcia_unload;
1867 EXPORT_SYMBOL(pcmcia_release_window); !! 925
1868 EXPORT_SYMBOL(pcmcia_replace_cis); !! 926 static void pcmcia_release_socket_class(struct class *data)
1869 EXPORT_SYMBOL(pcmcia_request_configuration); !! 927 {
1870 EXPORT_SYMBOL(pcmcia_request_io); !! 928 complete(&pcmcia_unload);
1871 EXPORT_SYMBOL(pcmcia_request_irq); !! 929 }
1872 EXPORT_SYMBOL(pcmcia_request_window); <<
1873 EXPORT_SYMBOL(pcmcia_resume_card); <<
1874 EXPORT_SYMBOL(pcmcia_suspend_card); <<
1875 930
1876 EXPORT_SYMBOL(dead_socket); <<
1877 EXPORT_SYMBOL(pcmcia_parse_events); <<
1878 931
1879 struct class pcmcia_socket_class = { 932 struct class pcmcia_socket_class = {
1880 .name = "pcmcia_socket", 933 .name = "pcmcia_socket",
1881 .release = pcmcia_release_socket, !! 934 .dev_uevent = pcmcia_socket_uevent,
>> 935 .dev_release = pcmcia_release_socket,
>> 936 .class_release = pcmcia_release_socket_class,
1882 }; 937 };
1883 EXPORT_SYMBOL(pcmcia_socket_class); 938 EXPORT_SYMBOL(pcmcia_socket_class);
1884 939
1885 940
1886 static int __init init_pcmcia_cs(void) 941 static int __init init_pcmcia_cs(void)
1887 { 942 {
1888 int ret; 943 int ret;
1889 printk(KERN_INFO "%s\n", release); <<
1890 printk(KERN_INFO " %s\n", options); <<
1891 944
>> 945 init_completion(&pcmcia_unload);
1892 ret = class_register(&pcmcia_socket_c 946 ret = class_register(&pcmcia_socket_class);
1893 if (ret) 947 if (ret)
1894 return (ret); 948 return (ret);
1895 return class_interface_register(&pcca 949 return class_interface_register(&pccard_sysfs_interface);
1896 } 950 }
1897 951
1898 static void __exit exit_pcmcia_cs(void) 952 static void __exit exit_pcmcia_cs(void)
1899 { 953 {
1900 printk(KERN_INFO "unloading Kernel Card S !! 954 class_interface_unregister(&pccard_sysfs_interface);
1901 class_interface_unregister(&pccard_sysfs_ !! 955 class_unregister(&pcmcia_socket_class);
1902 class_unregister(&pcmcia_socket_class); !! 956
>> 957 wait_for_completion(&pcmcia_unload);
1903 } 958 }
1904 959
1905 subsys_initcall(init_pcmcia_cs); 960 subsys_initcall(init_pcmcia_cs);
1906 module_exit(exit_pcmcia_cs); 961 module_exit(exit_pcmcia_cs);
1907 962
1908 /*=========================================== <<
1909 <<
1910 963
|
This page was automatically generated by the
LXR engine.
|