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 <<
36 #include <pcmcia/version.h> <<
37 #include <pcmcia/cs_types.h> 35 #include <pcmcia/cs_types.h>
38 #include <pcmcia/ss.h> 36 #include <pcmcia/ss.h>
39 #include <pcmcia/cs.h> 37 #include <pcmcia/cs.h>
40 #include <pcmcia/bulkmem.h> <<
41 #include <pcmcia/cistpl.h> 38 #include <pcmcia/cistpl.h>
42 #include <pcmcia/cisreg.h> 39 #include <pcmcia/cisreg.h>
43 #include <pcmcia/ds.h> 40 #include <pcmcia/ds.h>
44 #include "cs_internal.h" 41 #include "cs_internal.h"
45 42
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 43
72 /* Module parameters */ 44 /* Module parameters */
73 45
74 MODULE_AUTHOR("David Hinds <dahinds@users.sour 46 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
75 MODULE_DESCRIPTION("Linux Kernel Card Services !! 47 MODULE_DESCRIPTION("Linux Kernel Card Services");
76 MODULE_LICENSE("GPL"); 48 MODULE_LICENSE("GPL");
77 49
78 #define INT_MODULE_PARM(n, v) static int n = v 50 #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444)
79 51
80 INT_MODULE_PARM(setup_delay, 10); 52 INT_MODULE_PARM(setup_delay, 10); /* centiseconds */
81 INT_MODULE_PARM(resume_delay, 20); 53 INT_MODULE_PARM(resume_delay, 20); /* centiseconds */
82 INT_MODULE_PARM(shutdown_delay, 3); 54 INT_MODULE_PARM(shutdown_delay, 3); /* centiseconds */
83 INT_MODULE_PARM(vcc_settle, 40); 55 INT_MODULE_PARM(vcc_settle, 40); /* centiseconds */
84 INT_MODULE_PARM(reset_time, 10); 56 INT_MODULE_PARM(reset_time, 10); /* usecs */
85 INT_MODULE_PARM(unreset_delay, 10); 57 INT_MODULE_PARM(unreset_delay, 10); /* centiseconds */
86 INT_MODULE_PARM(unreset_check, 10); 58 INT_MODULE_PARM(unreset_check, 10); /* centiseconds */
87 INT_MODULE_PARM(unreset_limit, 30); 59 INT_MODULE_PARM(unreset_limit, 30); /* unreset_check's */
88 60
89 /* Access speed for attribute memory windows * 61 /* Access speed for attribute memory windows */
90 INT_MODULE_PARM(cis_speed, 300); 62 INT_MODULE_PARM(cis_speed, 300); /* ns */
91 63
92 /* Access speed for IO windows */ !! 64 #ifdef CONFIG_PCMCIA_DEBUG
93 INT_MODULE_PARM(io_speed, 0); <<
94 <<
95 #ifdef DEBUG <<
96 static int pc_debug; 65 static int pc_debug;
97 66
98 module_param(pc_debug, int, 0644); 67 module_param(pc_debug, int, 0644);
99 68
100 int cs_debug_level(int level) 69 int cs_debug_level(int level)
101 { 70 {
102 return pc_debug > level; 71 return pc_debug > level;
103 } 72 }
104 #endif 73 #endif
105 74
106 /*============================================ <<
107 75
108 socket_state_t dead_socket = { 76 socket_state_t dead_socket = {
109 .csc_mask = SS_DETECT, 77 .csc_mask = SS_DETECT,
110 }; 78 };
>> 79 EXPORT_SYMBOL(dead_socket);
111 80
112 81
113 /* List of all sockets, protected by a rwsem * 82 /* List of all sockets, protected by a rwsem */
114 LIST_HEAD(pcmcia_socket_list); 83 LIST_HEAD(pcmcia_socket_list);
115 DECLARE_RWSEM(pcmcia_socket_list_rwsem); <<
116 EXPORT_SYMBOL(pcmcia_socket_list); 84 EXPORT_SYMBOL(pcmcia_socket_list);
117 EXPORT_SYMBOL(pcmcia_socket_list_rwsem); <<
118 <<
119 85
120 #ifdef CONFIG_PCMCIA_PROBE !! 86 DECLARE_RWSEM(pcmcia_socket_list_rwsem);
121 /* mask ofIRQs already reserved by other cards !! 87 EXPORT_SYMBOL(pcmcia_socket_list_rwsem);
122 static u8 pcmcia_used_irq[NR_IRQS]; <<
123 #endif <<
124 <<
125 /*============================================ <<
126 88
127 Low-level PC Card interface drivers need t <<
128 Services using these calls. <<
129 <<
130 ============================================== <<
131 89
132 /** !! 90 /*
133 * socket drivers are expected to use the foll !! 91 * Low-level PCMCIA socket drivers need to register with the PCCard
>> 92 * core using pcmcia_register_socket.
>> 93 *
>> 94 * socket drivers are expected to use the following callbacks in their
134 * .drv struct: 95 * .drv struct:
135 * - pcmcia_socket_dev_suspend 96 * - pcmcia_socket_dev_suspend
136 * - pcmcia_socket_dev_resume 97 * - pcmcia_socket_dev_resume
137 * These functions check for the appropriate s 98 * These functions check for the appropriate struct pcmcia_soket arrays,
138 * and pass them to the low-level functions pc 99 * and pass them to the low-level functions pcmcia_{suspend,resume}_socket
139 */ 100 */
>> 101 static int socket_early_resume(struct pcmcia_socket *skt);
>> 102 static int socket_late_resume(struct pcmcia_socket *skt);
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 static void pcmcia_socket_dev_run(struct device *dev,
>> 107 int (*cb)(struct pcmcia_socket *))
144 { 108 {
145 struct pcmcia_socket *socket; 109 struct pcmcia_socket *socket;
146 110
147 down_read(&pcmcia_socket_list_rwsem); 111 down_read(&pcmcia_socket_list_rwsem);
148 list_for_each_entry(socket, &pcmcia_so 112 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
149 if (socket->dev.dev != dev) !! 113 if (socket->dev.parent != dev)
150 continue; 114 continue;
151 down(&socket->skt_sem); !! 115 mutex_lock(&socket->skt_mutex);
152 socket_suspend(socket); !! 116 cb(socket);
153 up(&socket->skt_sem); !! 117 mutex_unlock(&socket->skt_mutex);
154 } 118 }
155 up_read(&pcmcia_socket_list_rwsem); 119 up_read(&pcmcia_socket_list_rwsem);
>> 120 }
156 121
>> 122 int pcmcia_socket_dev_suspend(struct device *dev)
>> 123 {
>> 124 pcmcia_socket_dev_run(dev, socket_suspend);
157 return 0; 125 return 0;
158 } 126 }
159 EXPORT_SYMBOL(pcmcia_socket_dev_suspend); 127 EXPORT_SYMBOL(pcmcia_socket_dev_suspend);
160 128
161 int pcmcia_socket_dev_resume(struct device *de !! 129 void pcmcia_socket_dev_early_resume(struct device *dev)
162 { 130 {
163 struct pcmcia_socket *socket; !! 131 pcmcia_socket_dev_run(dev, socket_early_resume);
>> 132 }
>> 133 EXPORT_SYMBOL(pcmcia_socket_dev_early_resume);
164 134
165 down_read(&pcmcia_socket_list_rwsem); !! 135 void pcmcia_socket_dev_late_resume(struct device *dev)
166 list_for_each_entry(socket, &pcmcia_so !! 136 {
167 if (socket->dev.dev != dev) !! 137 pcmcia_socket_dev_run(dev, socket_late_resume);
168 continue; !! 138 }
169 down(&socket->skt_sem); !! 139 EXPORT_SYMBOL(pcmcia_socket_dev_late_resume);
170 socket_resume(socket); <<
171 up(&socket->skt_sem); <<
172 } <<
173 up_read(&pcmcia_socket_list_rwsem); <<
174 140
>> 141 int pcmcia_socket_dev_resume(struct device *dev)
>> 142 {
>> 143 pcmcia_socket_dev_run(dev, socket_resume);
175 return 0; 144 return 0;
176 } 145 }
177 EXPORT_SYMBOL(pcmcia_socket_dev_resume); 146 EXPORT_SYMBOL(pcmcia_socket_dev_resume);
178 147
179 148
180 struct pcmcia_socket * pcmcia_get_socket(struc 149 struct pcmcia_socket * pcmcia_get_socket(struct pcmcia_socket *skt)
181 { 150 {
182 struct class_device *cl_dev = class_de !! 151 struct device *dev = get_device(&skt->dev);
183 if (!cl_dev) !! 152 if (!dev)
184 return NULL; 153 return NULL;
185 skt = class_get_devdata(cl_dev); !! 154 skt = dev_get_drvdata(dev);
186 if (!try_module_get(skt->owner)) { 155 if (!try_module_get(skt->owner)) {
187 class_device_put(&skt->dev); !! 156 put_device(&skt->dev);
188 return NULL; 157 return NULL;
189 } 158 }
190 return (skt); 159 return (skt);
191 } 160 }
192 EXPORT_SYMBOL(pcmcia_get_socket); 161 EXPORT_SYMBOL(pcmcia_get_socket);
193 162
194 163
195 void pcmcia_put_socket(struct pcmcia_socket *s 164 void pcmcia_put_socket(struct pcmcia_socket *skt)
196 { 165 {
197 module_put(skt->owner); 166 module_put(skt->owner);
198 class_device_put(&skt->dev); !! 167 put_device(&skt->dev);
199 } 168 }
200 EXPORT_SYMBOL(pcmcia_put_socket); 169 EXPORT_SYMBOL(pcmcia_put_socket);
201 170
202 171
203 static void pcmcia_release_socket(struct class !! 172 static void pcmcia_release_socket(struct device *dev)
204 { 173 {
205 struct pcmcia_socket *socket = class_g !! 174 struct pcmcia_socket *socket = dev_get_drvdata(dev);
206 175
207 complete(&socket->socket_released); 176 complete(&socket->socket_released);
208 } 177 }
209 178
210 static int pccardd(void *__skt); 179 static int pccardd(void *__skt);
211 180
212 /** 181 /**
213 * pcmcia_register_socket - add a new pcmcia s 182 * pcmcia_register_socket - add a new pcmcia socket device
>> 183 * @socket: the &socket to register
214 */ 184 */
215 int pcmcia_register_socket(struct pcmcia_socke 185 int pcmcia_register_socket(struct pcmcia_socket *socket)
216 { 186 {
>> 187 struct task_struct *tsk;
217 int ret; 188 int ret;
218 189
219 if (!socket || !socket->ops || !socket !! 190 if (!socket || !socket->ops || !socket->dev.parent || !socket->resource_ops)
220 return -EINVAL; 191 return -EINVAL;
221 192
222 cs_dbg(socket, 0, "pcmcia_register_soc 193 cs_dbg(socket, 0, "pcmcia_register_socket(0x%p)\n", socket->ops);
223 194
224 if (socket->resource_ops->init) { !! 195 spin_lock_init(&socket->lock);
225 ret = socket->resource_ops->in <<
226 if (ret) <<
227 return (ret); <<
228 } <<
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 dev_set_name(&socket->dev, "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 mutex_init(&socket->skt_mutex);
269 init_MUTEX(&socket->skt_sem); <<
270 spin_lock_init(&socket->thread_lock); 242 spin_lock_init(&socket->thread_lock);
271 243
272 ret = kernel_thread(pccardd, socket, C !! 244 if (socket->resource_ops->init) {
273 if (ret < 0) !! 245 ret = socket->resource_ops->init(socket);
>> 246 if (ret)
>> 247 goto err;
>> 248 }
>> 249
>> 250 tsk = kthread_run(pccardd, socket, "pccardd");
>> 251 if (IS_ERR(tsk)) {
>> 252 ret = PTR_ERR(tsk);
274 goto err; 253 goto err;
>> 254 }
275 255
276 wait_for_completion(&socket->thread_do 256 wait_for_completion(&socket->thread_done);
277 if(!socket->thread) { !! 257 if (!socket->thread) {
278 printk(KERN_WARNING "PCMCIA: w !! 258 dev_printk(KERN_WARNING, &socket->dev,
>> 259 "PCMCIA: warning: socket thread did not start\n");
279 return -EIO; 260 return -EIO;
280 } 261 }
>> 262
281 pcmcia_parse_events(socket, SS_DETECT) 263 pcmcia_parse_events(socket, SS_DETECT);
282 264
283 return 0; 265 return 0;
284 266
285 err: 267 err:
286 down_write(&pcmcia_socket_list_rwsem); 268 down_write(&pcmcia_socket_list_rwsem);
287 list_del(&socket->socket_list); 269 list_del(&socket->socket_list);
288 up_write(&pcmcia_socket_list_rwsem); 270 up_write(&pcmcia_socket_list_rwsem);
289 return ret; 271 return ret;
290 } /* pcmcia_register_socket */ 272 } /* pcmcia_register_socket */
291 EXPORT_SYMBOL(pcmcia_register_socket); 273 EXPORT_SYMBOL(pcmcia_register_socket);
292 274
293 275
294 /** 276 /**
295 * pcmcia_unregister_socket - remove a pcmcia 277 * pcmcia_unregister_socket - remove a pcmcia socket device
>> 278 * @socket: the &socket to unregister
296 */ 279 */
297 void pcmcia_unregister_socket(struct pcmcia_so 280 void pcmcia_unregister_socket(struct pcmcia_socket *socket)
298 { 281 {
299 if (!socket) 282 if (!socket)
300 return; 283 return;
301 284
302 cs_dbg(socket, 0, "pcmcia_unregister_s 285 cs_dbg(socket, 0, "pcmcia_unregister_socket(0x%p)\n", socket->ops);
303 286
304 if (socket->thread) { !! 287 if (socket->thread)
305 init_completion(&socket->threa !! 288 kthread_stop(socket->thread);
306 socket->thread = NULL; !! 289
307 wake_up(&socket->thread_wait); <<
308 wait_for_completion(&socket->t <<
309 } <<
310 release_cis_mem(socket); 290 release_cis_mem(socket);
311 291
312 /* remove from our own list */ 292 /* remove from our own list */
313 down_write(&pcmcia_socket_list_rwsem); 293 down_write(&pcmcia_socket_list_rwsem);
314 list_del(&socket->socket_list); 294 list_del(&socket->socket_list);
315 up_write(&pcmcia_socket_list_rwsem); 295 up_write(&pcmcia_socket_list_rwsem);
316 296
317 /* wait for sysfs to drop all referenc 297 /* wait for sysfs to drop all references */
318 release_resource_db(socket); 298 release_resource_db(socket);
319 wait_for_completion(&socket->socket_re 299 wait_for_completion(&socket->socket_released);
320 } /* pcmcia_unregister_socket */ 300 } /* pcmcia_unregister_socket */
321 EXPORT_SYMBOL(pcmcia_unregister_socket); 301 EXPORT_SYMBOL(pcmcia_unregister_socket);
322 302
323 303
324 struct pcmcia_socket * pcmcia_get_socket_by_nr 304 struct pcmcia_socket * pcmcia_get_socket_by_nr(unsigned int nr)
325 { 305 {
326 struct pcmcia_socket *s; 306 struct pcmcia_socket *s;
327 307
328 down_read(&pcmcia_socket_list_rwsem); 308 down_read(&pcmcia_socket_list_rwsem);
329 list_for_each_entry(s, &pcmcia_socket_ 309 list_for_each_entry(s, &pcmcia_socket_list, socket_list)
330 if (s->sock == nr) { 310 if (s->sock == nr) {
331 up_read(&pcmcia_socket 311 up_read(&pcmcia_socket_list_rwsem);
332 return s; 312 return s;
333 } 313 }
334 up_read(&pcmcia_socket_list_rwsem); 314 up_read(&pcmcia_socket_list_rwsem);
335 315
336 return NULL; 316 return NULL;
337 317
338 } 318 }
339 EXPORT_SYMBOL(pcmcia_get_socket_by_nr); 319 EXPORT_SYMBOL(pcmcia_get_socket_by_nr);
340 320
341 !! 321 /*
342 /*============================================ !! 322 * The central event handler. Send_event() sends an event to the
343 !! 323 * 16-bit subsystem, which then calls the relevant device drivers.
344 socket_setup() and shutdown_socket() are c !! 324 * Parse_events() interprets the event bits from
345 handler when card insertion and removal ev !! 325 * a card status change report. Do_shutdown() handles the high
346 socket_setup() turns on socket power and r !! 326 * priority stuff associated with a card removal.
347 shutdown_socket() unconfigures a socket an !! 327 */
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 328
391 /* NOTE: send_event needs to be called with sk 329 /* NOTE: send_event needs to be called with skt->sem held. */
392 330
393 static int send_event(struct pcmcia_socket *s, 331 static int send_event(struct pcmcia_socket *s, event_t event, int priority)
394 { 332 {
395 int ret; 333 int ret;
396 334
397 if (s->state & SOCKET_CARDBUS) 335 if (s->state & SOCKET_CARDBUS)
398 return 0; 336 return 0;
399 337
400 cs_dbg(s, 1, "send_event(event %d, pri 338 cs_dbg(s, 1, "send_event(event %d, pri %d, callback 0x%p)\n",
401 event, priority, s->callback); 339 event, priority, s->callback);
402 340
403 if (!s->callback) 341 if (!s->callback)
404 return 0; 342 return 0;
405 if (!try_module_get(s->callback->owner 343 if (!try_module_get(s->callback->owner))
406 return 0; 344 return 0;
407 345
408 ret = s->callback->event(s, event, pri 346 ret = s->callback->event(s, event, priority);
409 347
410 module_put(s->callback->owner); 348 module_put(s->callback->owner);
411 349
412 return ret; 350 return ret;
413 } 351 }
414 352
415 static void socket_remove_drivers(struct pcmci 353 static void socket_remove_drivers(struct pcmcia_socket *skt)
416 { 354 {
417 cs_dbg(skt, 4, "remove_drivers\n"); 355 cs_dbg(skt, 4, "remove_drivers\n");
418 356
419 send_event(skt, CS_EVENT_CARD_REMOVAL, 357 send_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
420 } 358 }
421 359
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 * 360 static int socket_reset(struct pcmcia_socket *skt)
434 { 361 {
435 int status, i; 362 int status, i;
436 363
437 cs_dbg(skt, 4, "reset\n"); 364 cs_dbg(skt, 4, "reset\n");
438 365
439 skt->socket.flags |= SS_OUTPUT_ENA | S 366 skt->socket.flags |= SS_OUTPUT_ENA | SS_RESET;
440 skt->ops->set_socket(skt, &skt->socket 367 skt->ops->set_socket(skt, &skt->socket);
441 udelay((long)reset_time); 368 udelay((long)reset_time);
442 369
443 skt->socket.flags &= ~SS_RESET; 370 skt->socket.flags &= ~SS_RESET;
444 skt->ops->set_socket(skt, &skt->socket 371 skt->ops->set_socket(skt, &skt->socket);
445 372
446 msleep(unreset_delay * 10); 373 msleep(unreset_delay * 10);
447 for (i = 0; i < unreset_limit; i++) { 374 for (i = 0; i < unreset_limit; i++) {
448 skt->ops->get_status(skt, &sta 375 skt->ops->get_status(skt, &status);
449 376
450 if (!(status & SS_DETECT)) 377 if (!(status & SS_DETECT))
451 return CS_NO_CARD; !! 378 return -ENODEV;
452 379
453 if (status & SS_READY) 380 if (status & SS_READY)
454 return CS_SUCCESS; !! 381 return 0;
455 382
456 msleep(unreset_check * 10); 383 msleep(unreset_check * 10);
457 } 384 }
458 385
459 cs_err(skt, "time out after reset.\n") 386 cs_err(skt, "time out after reset.\n");
460 return CS_GENERAL_FAILURE; !! 387 return -ETIMEDOUT;
>> 388 }
>> 389
>> 390 /*
>> 391 * socket_setup() and socket_shutdown() are called by the main event handler
>> 392 * when card insertion and removal events are received.
>> 393 * socket_setup() turns on socket power and resets the socket, in two stages.
>> 394 * socket_shutdown() unconfigures a socket and turns off socket power.
>> 395 */
>> 396 static void socket_shutdown(struct pcmcia_socket *s)
>> 397 {
>> 398 int status;
>> 399
>> 400 cs_dbg(s, 4, "shutdown\n");
>> 401
>> 402 socket_remove_drivers(s);
>> 403 s->state &= SOCKET_INUSE | SOCKET_PRESENT;
>> 404 msleep(shutdown_delay * 10);
>> 405 s->state &= SOCKET_INUSE;
>> 406
>> 407 /* Blank out the socket state */
>> 408 s->socket = dead_socket;
>> 409 s->ops->init(s);
>> 410 s->ops->set_socket(s, &s->socket);
>> 411 s->irq.AssignedIRQ = s->irq.Config = 0;
>> 412 s->lock_count = 0;
>> 413 destroy_cis_cache(s);
>> 414 #ifdef CONFIG_CARDBUS
>> 415 cb_free(s);
>> 416 #endif
>> 417 s->functions = 0;
>> 418
>> 419 /* give socket some time to power down */
>> 420 msleep(100);
>> 421
>> 422 s->ops->get_status(s, &status);
>> 423 if (status & SS_POWERON) {
>> 424 dev_printk(KERN_ERR, &s->dev,
>> 425 "*** DANGER *** unable to remove socket power\n");
>> 426 }
>> 427
>> 428 cs_socket_put(s);
461 } 429 }
462 430
463 static int socket_setup(struct pcmcia_socket * 431 static int socket_setup(struct pcmcia_socket *skt, int initial_delay)
464 { 432 {
465 int status, i; 433 int status, i;
466 434
467 cs_dbg(skt, 4, "setup\n"); 435 cs_dbg(skt, 4, "setup\n");
468 436
469 skt->ops->get_status(skt, &status); 437 skt->ops->get_status(skt, &status);
470 if (!(status & SS_DETECT)) 438 if (!(status & SS_DETECT))
471 return CS_NO_CARD; !! 439 return -ENODEV;
472 440
473 msleep(initial_delay * 10); 441 msleep(initial_delay * 10);
474 442
475 for (i = 0; i < 100; i++) { 443 for (i = 0; i < 100; i++) {
476 skt->ops->get_status(skt, &sta 444 skt->ops->get_status(skt, &status);
477 if (!(status & SS_DETECT)) 445 if (!(status & SS_DETECT))
478 return CS_NO_CARD; !! 446 return -ENODEV;
479 447
480 if (!(status & SS_PENDING)) 448 if (!(status & SS_PENDING))
481 break; 449 break;
482 450
483 msleep(100); 451 msleep(100);
484 } 452 }
485 453
486 if (status & SS_PENDING) { 454 if (status & SS_PENDING) {
487 cs_err(skt, "voltage interroga 455 cs_err(skt, "voltage interrogation timed out.\n");
488 return CS_GENERAL_FAILURE; !! 456 return -ETIMEDOUT;
489 } 457 }
490 458
491 if (status & SS_CARDBUS) { 459 if (status & SS_CARDBUS) {
>> 460 if (!(skt->features & SS_CAP_CARDBUS)) {
>> 461 cs_err(skt, "cardbus cards are not supported.\n");
>> 462 return -EINVAL;
>> 463 }
492 skt->state |= SOCKET_CARDBUS; 464 skt->state |= SOCKET_CARDBUS;
493 #ifndef CONFIG_CARDBUS <<
494 cs_err(skt, "cardbus cards are <<
495 return CS_BAD_TYPE; <<
496 #endif <<
497 } 465 }
498 466
499 /* 467 /*
500 * Decode the card voltage requirement 468 * Decode the card voltage requirements, and apply power to the card.
501 */ 469 */
502 if (status & SS_3VCARD) 470 if (status & SS_3VCARD)
503 skt->socket.Vcc = skt->socket. 471 skt->socket.Vcc = skt->socket.Vpp = 33;
504 else if (!(status & SS_XVCARD)) 472 else if (!(status & SS_XVCARD))
505 skt->socket.Vcc = skt->socket. 473 skt->socket.Vcc = skt->socket.Vpp = 50;
506 else { 474 else {
507 cs_err(skt, "unsupported volta 475 cs_err(skt, "unsupported voltage key.\n");
508 return CS_BAD_TYPE; !! 476 return -EIO;
509 } 477 }
>> 478
>> 479 if (skt->power_hook)
>> 480 skt->power_hook(skt, HOOK_POWER_PRE);
>> 481
510 skt->socket.flags = 0; 482 skt->socket.flags = 0;
511 skt->ops->set_socket(skt, &skt->socket 483 skt->ops->set_socket(skt, &skt->socket);
512 484
513 /* 485 /*
514 * Wait "vcc_settle" for the supply to 486 * Wait "vcc_settle" for the supply to stabilise.
515 */ 487 */
516 msleep(vcc_settle * 10); 488 msleep(vcc_settle * 10);
517 489
518 skt->ops->get_status(skt, &status); 490 skt->ops->get_status(skt, &status);
519 if (!(status & SS_POWERON)) { 491 if (!(status & SS_POWERON)) {
520 cs_err(skt, "unable to apply p 492 cs_err(skt, "unable to apply power.\n");
521 return CS_BAD_TYPE; !! 493 return -EIO;
522 } 494 }
523 495
524 return socket_reset(skt); !! 496 status = socket_reset(skt);
>> 497
>> 498 if (skt->power_hook)
>> 499 skt->power_hook(skt, HOOK_POWER_POST);
>> 500
>> 501 return status;
525 } 502 }
526 503
527 /* 504 /*
528 * Handle card insertion. Setup the socket, r 505 * Handle card insertion. Setup the socket, reset the card,
529 * and then tell the rest of PCMCIA that a car 506 * and then tell the rest of PCMCIA that a card is present.
530 */ 507 */
531 static int socket_insert(struct pcmcia_socket 508 static int socket_insert(struct pcmcia_socket *skt)
532 { 509 {
533 int ret; 510 int ret;
534 511
535 cs_dbg(skt, 4, "insert\n"); 512 cs_dbg(skt, 4, "insert\n");
536 513
537 if (!cs_socket_get(skt)) 514 if (!cs_socket_get(skt))
538 return CS_NO_CARD; !! 515 return -ENODEV;
539 516
540 ret = socket_setup(skt, setup_delay); 517 ret = socket_setup(skt, setup_delay);
541 if (ret == CS_SUCCESS) { !! 518 if (ret == 0) {
542 skt->state |= SOCKET_PRESENT; 519 skt->state |= SOCKET_PRESENT;
>> 520
>> 521 dev_printk(KERN_NOTICE, &skt->dev,
>> 522 "pccard: %s card inserted into slot %d\n",
>> 523 (skt->state & SOCKET_CARDBUS) ? "CardBus" : "PCMCIA",
>> 524 skt->sock);
>> 525
543 #ifdef CONFIG_CARDBUS 526 #ifdef CONFIG_CARDBUS
544 if (skt->state & SOCKET_CARDBU 527 if (skt->state & SOCKET_CARDBUS) {
545 cb_alloc(skt); 528 cb_alloc(skt);
546 skt->state |= SOCKET_C 529 skt->state |= SOCKET_CARDBUS_CONFIG;
547 } 530 }
548 #endif 531 #endif
549 cs_dbg(skt, 4, "insert done\n" 532 cs_dbg(skt, 4, "insert done\n");
550 533
551 send_event(skt, CS_EVENT_CARD_ 534 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
552 } else { 535 } else {
553 socket_shutdown(skt); 536 socket_shutdown(skt);
554 cs_socket_put(skt); <<
555 } 537 }
556 538
557 return ret; 539 return ret;
558 } 540 }
559 541
560 static int socket_suspend(struct pcmcia_socket 542 static int socket_suspend(struct pcmcia_socket *skt)
561 { 543 {
562 if (skt->state & SOCKET_SUSPEND) 544 if (skt->state & SOCKET_SUSPEND)
563 return CS_IN_USE; !! 545 return -EBUSY;
564 546
565 send_event(skt, CS_EVENT_PM_SUSPEND, C 547 send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW);
566 skt->socket = dead_socket; 548 skt->socket = dead_socket;
567 skt->ops->suspend(skt); !! 549 skt->ops->set_socket(skt, &skt->socket);
>> 550 if (skt->ops->suspend)
>> 551 skt->ops->suspend(skt);
568 skt->state |= SOCKET_SUSPEND; 552 skt->state |= SOCKET_SUSPEND;
569 553
570 return CS_SUCCESS; !! 554 return 0;
571 } 555 }
572 556
573 /* !! 557 static int socket_early_resume(struct pcmcia_socket *skt)
574 * Resume a socket. If a card is present, ver <<
575 * our cached copy. If they are different, th <<
576 * replaced, and we need to tell the drivers. <<
577 */ <<
578 static int socket_resume(struct pcmcia_socket <<
579 { 558 {
580 int ret; <<
581 <<
582 if (!(skt->state & SOCKET_SUSPEND)) <<
583 return CS_IN_USE; <<
584 <<
585 skt->socket = dead_socket; 559 skt->socket = dead_socket;
586 skt->ops->init(skt); 560 skt->ops->init(skt);
587 skt->ops->set_socket(skt, &skt->socket 561 skt->ops->set_socket(skt, &skt->socket);
>> 562 if (skt->state & SOCKET_PRESENT)
>> 563 skt->resume_status = socket_setup(skt, resume_delay);
>> 564 return 0;
>> 565 }
588 566
589 ret = socket_setup(skt, resume_delay); !! 567 static int socket_late_resume(struct pcmcia_socket *skt)
590 if (ret == CS_SUCCESS) { !! 568 {
>> 569 if (!(skt->state & SOCKET_PRESENT)) {
>> 570 skt->state &= ~SOCKET_SUSPEND;
>> 571 return socket_insert(skt);
>> 572 }
>> 573
>> 574 if (skt->resume_status == 0) {
591 /* 575 /*
592 * FIXME: need a better check 576 * FIXME: need a better check here for cardbus cards.
593 */ 577 */
594 if (verify_cis_cache(skt) != 0 578 if (verify_cis_cache(skt) != 0) {
595 cs_dbg(skt, 4, "cis mi 579 cs_dbg(skt, 4, "cis mismatch - different card\n");
596 socket_remove_drivers( 580 socket_remove_drivers(skt);
597 destroy_cis_cache(skt) 581 destroy_cis_cache(skt);
598 /* 582 /*
599 * Workaround: give DS 583 * Workaround: give DS time to schedule removal.
600 * Remove me once the 584 * Remove me once the 100ms delay is eliminated
601 * in ds.c 585 * in ds.c
602 */ 586 */
603 msleep(200); 587 msleep(200);
604 send_event(skt, CS_EVE 588 send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
605 } else { 589 } else {
606 cs_dbg(skt, 4, "cis ma 590 cs_dbg(skt, 4, "cis matches cache\n");
607 send_event(skt, CS_EVE 591 send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
608 } 592 }
609 } else { 593 } else {
610 socket_shutdown(skt); 594 socket_shutdown(skt);
611 cs_socket_put(skt); <<
612 } 595 }
613 596
614 skt->state &= ~SOCKET_SUSPEND; 597 skt->state &= ~SOCKET_SUSPEND;
615 598
616 return CS_SUCCESS; !! 599 return 0;
>> 600 }
>> 601
>> 602 /*
>> 603 * Resume a socket. If a card is present, verify its CIS against
>> 604 * our cached copy. If they are different, the card has been
>> 605 * replaced, and we need to tell the drivers.
>> 606 */
>> 607 static int socket_resume(struct pcmcia_socket *skt)
>> 608 {
>> 609 if (!(skt->state & SOCKET_SUSPEND))
>> 610 return -EBUSY;
>> 611
>> 612 socket_early_resume(skt);
>> 613 return socket_late_resume(skt);
617 } 614 }
618 615
619 static void socket_remove(struct pcmcia_socket 616 static void socket_remove(struct pcmcia_socket *skt)
620 { 617 {
>> 618 dev_printk(KERN_NOTICE, &skt->dev,
>> 619 "pccard: card ejected from slot %d\n", skt->sock);
621 socket_shutdown(skt); 620 socket_shutdown(skt);
622 cs_socket_put(skt); <<
623 } 621 }
624 622
625 /* 623 /*
626 * Process a socket card detect status change. 624 * Process a socket card detect status change.
627 * 625 *
628 * If we don't have a card already present, de 626 * If we don't have a card already present, delay the detect event for
629 * about 20ms (to be on the safe side) before 627 * about 20ms (to be on the safe side) before reading the socket status.
630 * 628 *
631 * Some i82365-based systems send multiple SS_ 629 * Some i82365-based systems send multiple SS_DETECT events during card
632 * insertion, and the "card present" status bi 630 * insertion, and the "card present" status bit seems to bounce. This
633 * will probably be true with GPIO-based card 631 * will probably be true with GPIO-based card detection systems after
634 * the product has aged. 632 * the product has aged.
635 */ 633 */
636 static void socket_detect_change(struct pcmcia 634 static void socket_detect_change(struct pcmcia_socket *skt)
637 { 635 {
638 if (!(skt->state & SOCKET_SUSPEND)) { 636 if (!(skt->state & SOCKET_SUSPEND)) {
639 int status; 637 int status;
640 638
641 if (!(skt->state & SOCKET_PRES 639 if (!(skt->state & SOCKET_PRESENT))
642 msleep(20); 640 msleep(20);
643 641
644 skt->ops->get_status(skt, &sta 642 skt->ops->get_status(skt, &status);
645 if ((skt->state & SOCKET_PRESE 643 if ((skt->state & SOCKET_PRESENT) &&
646 !(status & SS_DETECT)) 644 !(status & SS_DETECT))
647 socket_remove(skt); 645 socket_remove(skt);
648 if (!(skt->state & SOCKET_PRES 646 if (!(skt->state & SOCKET_PRESENT) &&
649 (status & SS_DETECT)) 647 (status & SS_DETECT))
650 socket_insert(skt); 648 socket_insert(skt);
651 } 649 }
652 } 650 }
653 651
654 static int pccardd(void *__skt) 652 static int pccardd(void *__skt)
655 { 653 {
656 struct pcmcia_socket *skt = __skt; 654 struct pcmcia_socket *skt = __skt;
657 DECLARE_WAITQUEUE(wait, current); <<
658 int ret; 655 int ret;
659 656
660 daemonize("pccardd"); <<
661 <<
662 skt->thread = current; 657 skt->thread = current;
663 skt->socket = dead_socket; 658 skt->socket = dead_socket;
664 skt->ops->init(skt); 659 skt->ops->init(skt);
665 skt->ops->set_socket(skt, &skt->socket 660 skt->ops->set_socket(skt, &skt->socket);
666 661
667 /* register with the device core */ 662 /* register with the device core */
668 ret = class_device_register(&skt->dev) !! 663 ret = device_register(&skt->dev);
669 if (ret) { 664 if (ret) {
670 printk(KERN_WARNING "PCMCIA: u !! 665 dev_printk(KERN_WARNING, &skt->dev,
671 skt); !! 666 "PCMCIA: unable to register socket\n");
672 skt->thread = NULL; 667 skt->thread = NULL;
673 complete_and_exit(&skt->thread !! 668 complete(&skt->thread_done);
>> 669 return 0;
674 } 670 }
>> 671 ret = pccard_sysfs_add_socket(&skt->dev);
>> 672 if (ret)
>> 673 dev_warn(&skt->dev, "err %d adding socket attributes\n", ret);
>> 674
675 complete(&skt->thread_done); 675 complete(&skt->thread_done);
676 676
677 add_wait_queue(&skt->thread_wait, &wai !! 677 set_freezable();
678 for (;;) { 678 for (;;) {
679 unsigned long flags; 679 unsigned long flags;
680 unsigned int events; 680 unsigned int events;
681 681
682 set_current_state(TASK_INTERRU 682 set_current_state(TASK_INTERRUPTIBLE);
683 683
684 spin_lock_irqsave(&skt->thread 684 spin_lock_irqsave(&skt->thread_lock, flags);
685 events = skt->thread_events; 685 events = skt->thread_events;
686 skt->thread_events = 0; 686 skt->thread_events = 0;
687 spin_unlock_irqrestore(&skt->t 687 spin_unlock_irqrestore(&skt->thread_lock, flags);
688 688
689 if (events) { 689 if (events) {
690 down(&skt->skt_sem); !! 690 mutex_lock(&skt->skt_mutex);
691 if (events & SS_DETECT 691 if (events & SS_DETECT)
692 socket_detect_ 692 socket_detect_change(skt);
693 if (events & SS_BATDEA 693 if (events & SS_BATDEAD)
694 send_event(skt 694 send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW);
695 if (events & SS_BATWAR 695 if (events & SS_BATWARN)
696 send_event(skt 696 send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
697 if (events & SS_READY) 697 if (events & SS_READY)
698 send_event(skt 698 send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
699 up(&skt->skt_sem); !! 699 mutex_unlock(&skt->skt_mutex);
700 continue; 700 continue;
701 } 701 }
702 702
703 schedule(); !! 703 if (kthread_should_stop())
704 try_to_freeze(PF_FREEZE); <<
705 <<
706 if (!skt->thread) <<
707 break; 704 break;
>> 705
>> 706 schedule();
>> 707 try_to_freeze();
708 } 708 }
709 remove_wait_queue(&skt->thread_wait, & !! 709 /* make sure we are running before we exit */
>> 710 set_current_state(TASK_RUNNING);
710 711
711 /* remove from the device core */ 712 /* remove from the device core */
712 class_device_unregister(&skt->dev); !! 713 pccard_sysfs_remove_socket(&skt->dev);
>> 714 device_unregister(&skt->dev);
713 715
714 complete_and_exit(&skt->thread_done, 0 !! 716 return 0;
715 } 717 }
716 718
717 /* 719 /*
718 * Yenta (at least) probes interrupts before r 720 * Yenta (at least) probes interrupts before registering the socket and
719 * starting the handler thread. 721 * starting the handler thread.
720 */ 722 */
721 void pcmcia_parse_events(struct pcmcia_socket 723 void pcmcia_parse_events(struct pcmcia_socket *s, u_int events)
722 { 724 {
>> 725 unsigned long flags;
723 cs_dbg(s, 4, "parse_events: events %08 726 cs_dbg(s, 4, "parse_events: events %08x\n", events);
724 if (s->thread) { 727 if (s->thread) {
725 spin_lock(&s->thread_lock); !! 728 spin_lock_irqsave(&s->thread_lock, flags);
726 s->thread_events |= events; 729 s->thread_events |= events;
727 spin_unlock(&s->thread_lock); !! 730 spin_unlock_irqrestore(&s->thread_lock, flags);
728 731
729 wake_up(&s->thread_wait); !! 732 wake_up_process(s->thread);
730 } 733 }
731 } /* pcmcia_parse_events */ 734 } /* pcmcia_parse_events */
>> 735 EXPORT_SYMBOL(pcmcia_parse_events);
732 736
733 737
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 */ 738 /* register pcmcia_callback */
1147 int pccard_register_pcmcia(struct pcmcia_sock 739 int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
1148 { 740 {
1149 int ret = 0; 741 int ret = 0;
1150 742
1151 /* s->skt_sem also protects s->callba !! 743 /* s->skt_mutex also protects s->callback */
1152 down(&s->skt_sem); !! 744 mutex_lock(&s->skt_mutex);
1153 745
1154 if (c) { 746 if (c) {
1155 /* registration */ 747 /* registration */
1156 if (s->callback) { 748 if (s->callback) {
1157 ret = -EBUSY; 749 ret = -EBUSY;
1158 goto err; 750 goto err;
1159 } 751 }
1160 752
1161 s->callback = c; 753 s->callback = c;
1162 754
1163 if ((s->state & (SOCKET_PRESE 755 if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT)
1164 send_event(s, CS_EVEN 756 send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW);
1165 } else 757 } else
1166 s->callback = NULL; 758 s->callback = NULL;
1167 err: 759 err:
1168 up(&s->skt_sem); !! 760 mutex_unlock(&s->skt_mutex);
1169 761
1170 return ret; 762 return ret;
1171 } 763 }
1172 EXPORT_SYMBOL(pccard_register_pcmcia); 764 EXPORT_SYMBOL(pccard_register_pcmcia);
1173 765
1174 /*=========================================== <<
1175 <<
1176 int pcmcia_release_configuration(client_handl <<
1177 { <<
1178 pccard_io_map io = { 0, 0, 0, 0, 1 }; <<
1179 struct pcmcia_socket *s; <<
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 766
1219 Release_io() releases the I/O ranges allo !! 767 /* I'm not sure which "reset" function this is supposed to use,
1220 may be invoked some time after a card eje !! 768 * but for now, it uses the low-level interface's reset, not the
1221 the actual socket configuration, so if th !! 769 * CIS register.
1222 don't bother checking the port ranges aga !! 770 */
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 771
1707 int pccard_reset_card(struct pcmcia_socket *s !! 772 int pcmcia_reset_card(struct pcmcia_socket *skt)
1708 { 773 {
1709 int ret; 774 int ret;
1710 !! 775
1711 cs_dbg(skt, 1, "resetting socket\n"); 776 cs_dbg(skt, 1, "resetting socket\n");
1712 777
1713 down(&skt->skt_sem); !! 778 mutex_lock(&skt->skt_mutex);
1714 do { 779 do {
1715 if (!(skt->state & SOCKET_PRE 780 if (!(skt->state & SOCKET_PRESENT)) {
1716 ret = CS_NO_CARD; !! 781 ret = -ENODEV;
1717 break; 782 break;
1718 } 783 }
1719 if (skt->state & SOCKET_SUSPE 784 if (skt->state & SOCKET_SUSPEND) {
1720 ret = CS_IN_USE; !! 785 ret = -EBUSY;
1721 break; 786 break;
1722 } 787 }
1723 if (skt->state & SOCKET_CARDB 788 if (skt->state & SOCKET_CARDBUS) {
1724 ret = CS_UNSUPPORTED_ !! 789 ret = -EPERM;
1725 break; 790 break;
1726 } 791 }
1727 792
1728 ret = send_event(skt, CS_EVEN 793 ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW);
1729 if (ret == 0) { 794 if (ret == 0) {
1730 send_event(skt, CS_EV 795 send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW);
1731 if (socket_reset(skt) !! 796 if (skt->callback)
>> 797 skt->callback->suspend(skt);
>> 798 if (socket_reset(skt) == 0) {
1732 send_event(sk 799 send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
>> 800 if (skt->callback)
>> 801 skt->callback->resume(skt);
>> 802 }
1733 } 803 }
1734 804
1735 ret = CS_SUCCESS; !! 805 ret = 0;
1736 } while (0); 806 } while (0);
1737 up(&skt->skt_sem); !! 807 mutex_unlock(&skt->skt_mutex);
1738 808
1739 return ret; 809 return ret;
1740 } /* reset_card */ 810 } /* reset_card */
1741 EXPORT_SYMBOL(pccard_reset_card); !! 811 EXPORT_SYMBOL(pcmcia_reset_card);
1742 812
1743 /*=========================================== <<
1744 <<
1745 These shut down or wake up a socket. The <<
1746 initiated versions of the APM suspend and <<
1747 <<
1748 ============================================= <<
1749 813
>> 814 /* These shut down or wake up a socket. They are sort of user
>> 815 * initiated versions of the APM suspend and resume actions.
>> 816 */
1750 int pcmcia_suspend_card(struct pcmcia_socket 817 int pcmcia_suspend_card(struct pcmcia_socket *skt)
1751 { 818 {
1752 int ret; 819 int ret;
1753 !! 820
1754 cs_dbg(skt, 1, "suspending socket\n") 821 cs_dbg(skt, 1, "suspending socket\n");
1755 822
1756 down(&skt->skt_sem); !! 823 mutex_lock(&skt->skt_mutex);
1757 do { 824 do {
1758 if (!(skt->state & SOCKET_PRE 825 if (!(skt->state & SOCKET_PRESENT)) {
1759 ret = CS_NO_CARD; !! 826 ret = -ENODEV;
1760 break; 827 break;
1761 } 828 }
1762 if (skt->state & SOCKET_CARDB 829 if (skt->state & SOCKET_CARDBUS) {
1763 ret = CS_UNSUPPORTED_ !! 830 ret = -EPERM;
1764 break; 831 break;
1765 } 832 }
>> 833 if (skt->callback) {
>> 834 ret = skt->callback->suspend(skt);
>> 835 if (ret)
>> 836 break;
>> 837 }
1766 ret = socket_suspend(skt); 838 ret = socket_suspend(skt);
1767 } while (0); 839 } while (0);
1768 up(&skt->skt_sem); !! 840 mutex_unlock(&skt->skt_mutex);
1769 841
1770 return ret; 842 return ret;
1771 } /* suspend_card */ 843 } /* suspend_card */
>> 844 EXPORT_SYMBOL(pcmcia_suspend_card);
>> 845
1772 846
1773 int pcmcia_resume_card(struct pcmcia_socket * 847 int pcmcia_resume_card(struct pcmcia_socket *skt)
1774 { 848 {
1775 int ret; 849 int ret;
1776 850
1777 cs_dbg(skt, 1, "waking up socket\n"); 851 cs_dbg(skt, 1, "waking up socket\n");
1778 852
1779 down(&skt->skt_sem); !! 853 mutex_lock(&skt->skt_mutex);
1780 do { 854 do {
1781 if (!(skt->state & SOCKET_PRE 855 if (!(skt->state & SOCKET_PRESENT)) {
1782 ret = CS_NO_CARD; !! 856 ret = -ENODEV;
1783 break; 857 break;
1784 } 858 }
1785 if (skt->state & SOCKET_CARDB 859 if (skt->state & SOCKET_CARDBUS) {
1786 ret = CS_UNSUPPORTED_ !! 860 ret = -EPERM;
1787 break; 861 break;
1788 } 862 }
1789 ret = socket_resume(skt); 863 ret = socket_resume(skt);
>> 864 if (!ret && skt->callback)
>> 865 skt->callback->resume(skt);
1790 } while (0); 866 } while (0);
1791 up(&skt->skt_sem); !! 867 mutex_unlock(&skt->skt_mutex);
1792 868
1793 return ret; 869 return ret;
1794 } /* resume_card */ 870 } /* resume_card */
>> 871 EXPORT_SYMBOL(pcmcia_resume_card);
1795 872
1796 /*=========================================== <<
1797 <<
1798 These handle user requests to eject or in <<
1799 <<
1800 ============================================= <<
1801 873
>> 874 /* These handle user requests to eject or insert a card. */
1802 int pcmcia_eject_card(struct pcmcia_socket *s 875 int pcmcia_eject_card(struct pcmcia_socket *skt)
1803 { 876 {
1804 int ret; 877 int ret;
1805 878
1806 cs_dbg(skt, 1, "user eject request\n" 879 cs_dbg(skt, 1, "user eject request\n");
1807 880
1808 down(&skt->skt_sem); !! 881 mutex_lock(&skt->skt_mutex);
1809 do { 882 do {
1810 if (!(skt->state & SOCKET_PRE 883 if (!(skt->state & SOCKET_PRESENT)) {
1811 ret = -ENODEV; 884 ret = -ENODEV;
1812 break; 885 break;
1813 } 886 }
1814 887
1815 ret = send_event(skt, CS_EVEN 888 ret = send_event(skt, CS_EVENT_EJECTION_REQUEST, CS_EVENT_PRI_LOW);
1816 if (ret != 0) { 889 if (ret != 0) {
1817 ret = -EINVAL; 890 ret = -EINVAL;
1818 break; 891 break;
1819 } 892 }
1820 893
1821 socket_remove(skt); 894 socket_remove(skt);
1822 ret = 0; 895 ret = 0;
1823 } while (0); 896 } while (0);
1824 up(&skt->skt_sem); !! 897 mutex_unlock(&skt->skt_mutex);
1825 898
1826 return ret; 899 return ret;
1827 } /* eject_card */ 900 } /* eject_card */
>> 901 EXPORT_SYMBOL(pcmcia_eject_card);
>> 902
1828 903
1829 int pcmcia_insert_card(struct pcmcia_socket * 904 int pcmcia_insert_card(struct pcmcia_socket *skt)
1830 { 905 {
1831 int ret; 906 int ret;
1832 907
1833 cs_dbg(skt, 1, "user insert request\n 908 cs_dbg(skt, 1, "user insert request\n");
1834 909
1835 down(&skt->skt_sem); !! 910 mutex_lock(&skt->skt_mutex);
1836 do { 911 do {
1837 if (skt->state & SOCKET_PRESE 912 if (skt->state & SOCKET_PRESENT) {
1838 ret = -EBUSY; 913 ret = -EBUSY;
1839 break; 914 break;
1840 } 915 }
1841 if (socket_insert(skt) == CS_ !! 916 if (socket_insert(skt) == -ENODEV) {
1842 ret = -ENODEV; 917 ret = -ENODEV;
1843 break; 918 break;
1844 } 919 }
1845 ret = 0; 920 ret = 0;
1846 } while (0); 921 } while (0);
1847 up(&skt->skt_sem); !! 922 mutex_unlock(&skt->skt_mutex);
1848 923
1849 return ret; 924 return ret;
1850 } /* insert_card */ 925 } /* insert_card */
>> 926 EXPORT_SYMBOL(pcmcia_insert_card);
1851 927
1852 /*=========================================== <<
1853 928
1854 OS-specific module glue goes here !! 929 static int pcmcia_socket_uevent(struct device *dev,
1855 !! 930 struct kobj_uevent_env *env)
1856 ============================================= !! 931 {
1857 /* in alpha order */ !! 932 struct pcmcia_socket *s = container_of(dev, struct pcmcia_socket, dev);
1858 EXPORT_SYMBOL(pcmcia_eject_card); !! 933
1859 EXPORT_SYMBOL(pcmcia_get_card_services_info); !! 934 if (add_uevent_var(env, "SOCKET_NO=%u", s->sock))
1860 EXPORT_SYMBOL(pcmcia_get_mem_page); !! 935 return -ENOMEM;
1861 EXPORT_SYMBOL(pcmcia_insert_card); !! 936
1862 EXPORT_SYMBOL(pcmcia_map_mem_page); !! 937 return 0;
1863 EXPORT_SYMBOL(pcmcia_modify_configuration); !! 938 }
1864 EXPORT_SYMBOL(pcmcia_release_configuration); !! 939
1865 EXPORT_SYMBOL(pcmcia_release_io); !! 940
1866 EXPORT_SYMBOL(pcmcia_release_irq); !! 941 static struct completion pcmcia_unload;
1867 EXPORT_SYMBOL(pcmcia_release_window); !! 942
1868 EXPORT_SYMBOL(pcmcia_replace_cis); !! 943 static void pcmcia_release_socket_class(struct class *data)
1869 EXPORT_SYMBOL(pcmcia_request_configuration); !! 944 {
1870 EXPORT_SYMBOL(pcmcia_request_io); !! 945 complete(&pcmcia_unload);
1871 EXPORT_SYMBOL(pcmcia_request_irq); !! 946 }
1872 EXPORT_SYMBOL(pcmcia_request_window); <<
1873 EXPORT_SYMBOL(pcmcia_resume_card); <<
1874 EXPORT_SYMBOL(pcmcia_suspend_card); <<
1875 947
1876 EXPORT_SYMBOL(dead_socket); <<
1877 EXPORT_SYMBOL(pcmcia_parse_events); <<
1878 948
1879 struct class pcmcia_socket_class = { 949 struct class pcmcia_socket_class = {
1880 .name = "pcmcia_socket", 950 .name = "pcmcia_socket",
1881 .release = pcmcia_release_socket, !! 951 .dev_uevent = pcmcia_socket_uevent,
>> 952 .dev_release = pcmcia_release_socket,
>> 953 .class_release = pcmcia_release_socket_class,
1882 }; 954 };
1883 EXPORT_SYMBOL(pcmcia_socket_class); 955 EXPORT_SYMBOL(pcmcia_socket_class);
1884 956
1885 957
1886 static int __init init_pcmcia_cs(void) 958 static int __init init_pcmcia_cs(void)
1887 { 959 {
1888 int ret; !! 960 init_completion(&pcmcia_unload);
1889 printk(KERN_INFO "%s\n", release); !! 961 return class_register(&pcmcia_socket_class);
1890 printk(KERN_INFO " %s\n", options); <<
1891 <<
1892 ret = class_register(&pcmcia_socket_c <<
1893 if (ret) <<
1894 return (ret); <<
1895 return class_interface_register(&pcca <<
1896 } 962 }
1897 963
1898 static void __exit exit_pcmcia_cs(void) 964 static void __exit exit_pcmcia_cs(void)
1899 { 965 {
1900 printk(KERN_INFO "unloading Kernel Card S !! 966 class_unregister(&pcmcia_socket_class);
1901 class_interface_unregister(&pccard_sysfs_ !! 967 wait_for_completion(&pcmcia_unload);
1902 class_unregister(&pcmcia_socket_class); <<
1903 } 968 }
1904 969
1905 subsys_initcall(init_pcmcia_cs); 970 subsys_initcall(init_pcmcia_cs);
1906 module_exit(exit_pcmcia_cs); 971 module_exit(exit_pcmcia_cs);
1907 972
1908 /*=========================================== <<
1909 <<
1910 973
|
This page was automatically generated by the
LXR engine.
|