Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/pcmcia/cs.c (Version 2.6.11.8) and /linux/drivers/pcmcia/cs.c (Version 2.6.25.8)


  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.