1 /*======================================================================
3 PC Card Driver Services
5 ds.c 1.112 2001/10/13 00:08:28
7 The contents of this file are subject to the Mozilla Public
8 License Version 1.1 (the "License"); you may not use this file
9 except in compliance with the License. You may obtain a copy of
10 the License at http://www.mozilla.org/MPL/
12 Software distributed under the License is distributed on an "AS
13 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 implied. See the License for the specific language governing
15 rights and limitations under the License.
17 The initial developer of the original code is David A. Hinds
18 <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
19 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
21 Alternatively, the contents of this file may be used under the
22 terms of the GNU General Public License version 2 (the "GPL"), in
23 which case the provisions of the GPL are applicable instead of the
24 above. If you wish to allow the use of your version of this file
25 only under the terms of the GPL and not to allow others to use
26 your version of this file under the MPL, indicate your decision
27 by deleting the provisions above and replace them with the notice
28 and other provisions required by the GPL. If you do not delete
29 the provisions above, a recipient may use your version of this
30 file under either the MPL or the GPL.
32 ======================================================================*/
34 #include <linux/config.h>
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/init.h>
38 #include <linux/kernel.h>
39 #include <linux/major.h>
40 #include <linux/string.h>
41 #include <linux/errno.h>
42 #include <linux/slab.h>
44 #include <linux/fcntl.h>
45 #include <linux/sched.h>
46 #include <linux/smp_lock.h>
47 #include <linux/timer.h>
48 #include <linux/ioctl.h>
49 #include <linux/proc_fs.h>
50 #include <linux/poll.h>
51 #include <linux/pci.h>
52 #include <linux/list.h>
53 #include <linux/delay.h>
54 #include <linux/workqueue.h>
56 #include <asm/atomic.h>
58 #define IN_CARD_SERVICES
59 #include <pcmcia/version.h>
60 #include <pcmcia/cs_types.h>
61 #include <pcmcia/cs.h>
62 #include <pcmcia/bulkmem.h>
63 #include <pcmcia/cistpl.h>
64 #include <pcmcia/ds.h>
65 #include <pcmcia/ss.h>
67 #include "cs_internal.h"
69 /*====================================================================*/
71 /* Module parameters */
73 MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
74 MODULE_DESCRIPTION("PCMCIA Driver Services");
75 MODULE_LICENSE("Dual MPL/GPL");
80 module_param(pc_debug
, int, 0644);
82 #define ds_dbg(lvl, fmt, arg...) do { \
83 if (pc_debug > (lvl)) \
84 printk(KERN_DEBUG "ds: " fmt , ## arg); \
87 #define ds_dbg(lvl, fmt, arg...) do { } while (0)
90 /*====================================================================*/
92 typedef struct socket_bind_t
{
93 struct pcmcia_driver
*driver
;
96 struct socket_bind_t
*next
;
99 /* Device user information */
100 #define MAX_EVENTS 32
101 #define USER_MAGIC 0x7ea4
102 #define CHECK_USER(u) \
103 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
104 typedef struct user_info_t
{
106 int event_head
, event_tail
;
107 event_t event
[MAX_EVENTS
];
108 struct user_info_t
*next
;
109 struct pcmcia_bus_socket
*socket
;
112 /* Socket state information */
113 struct pcmcia_bus_socket
{
115 client_handle_t handle
;
118 int req_pending
, req_result
;
119 wait_queue_head_t queue
, request
;
120 struct work_struct removal
;
122 struct pcmcia_socket
*parent
;
125 #define DS_SOCKET_PRESENT 0x01
126 #define DS_SOCKET_BUSY 0x02
127 #define DS_SOCKET_REMOVAL_PENDING 0x10
128 #define DS_SOCKET_DEAD 0x80
130 /*====================================================================*/
132 /* Device driver ID passed to Card Services */
133 static dev_info_t dev_info
= "Driver Services";
135 static int major_dev
= -1;
137 static struct proc_dir_entry
*proc_pccard
;
139 /*====================================================================*/
141 /* code which was in cs.c before */
143 /*======================================================================
145 Bind_device() associates a device driver with a particular socket.
146 It is normally called by Driver Services after it has identified
147 a newly inserted card. An instance of that driver will then be
148 eligible to register as a client of this socket.
150 ======================================================================*/
152 static int pcmcia_bind_device(bind_req_t
*req
)
155 struct pcmcia_socket
*s
;
159 return CS_BAD_SOCKET
;
161 client
= (client_t
*) kmalloc(sizeof(client_t
), GFP_KERNEL
);
163 return CS_OUT_OF_RESOURCE
;
164 memset(client
, '\0', sizeof(client_t
));
165 client
->client_magic
= CLIENT_MAGIC
;
166 strlcpy(client
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
168 client
->Function
= req
->Function
;
169 client
->state
= CLIENT_UNBOUND
;
170 client
->erase_busy
.next
= &client
->erase_busy
;
171 client
->erase_busy
.prev
= &client
->erase_busy
;
172 init_waitqueue_head(&client
->mtd_req
);
173 client
->next
= s
->clients
;
175 ds_dbg(1, "%s: bind_device(): client 0x%p, dev %s\n",
176 cs_socket_name(client
->Socket
), client
, client
->dev_info
);
181 /*======================================================================
183 Bind_mtd() associates a device driver with a particular memory
184 region. It is normally called by Driver Services after it has
185 identified a memory device type. An instance of the corresponding
186 driver will then be able to register to control this region.
188 ======================================================================*/
190 static int pcmcia_bind_mtd(mtd_bind_t
*req
)
192 struct pcmcia_socket
*s
;
193 memory_handle_t region
;
197 return CS_BAD_SOCKET
;
199 if (req
->Attributes
& REGION_TYPE_AM
)
200 region
= s
->a_region
;
202 region
= s
->c_region
;
205 if (region
->info
.CardOffset
== req
->CardOffset
)
207 region
= region
->info
.next
;
209 if (!region
|| (region
->mtd
!= NULL
))
210 return CS_BAD_OFFSET
;
211 strlcpy(region
->dev_info
, (char *)req
->dev_info
, DEV_NAME_LEN
);
213 ds_dbg(1, "%s: bind_mtd: attr 0x%x, offset 0x%x, dev %s\n",
214 cs_socket_name(s
), req
->Attributes
, req
->CardOffset
,
215 (char *)req
->dev_info
);
220 /* String tables for error messages */
222 typedef struct lookup_t
{
227 static const lookup_t error_table
[] = {
228 { CS_SUCCESS
, "Operation succeeded" },
229 { CS_BAD_ADAPTER
, "Bad adapter" },
230 { CS_BAD_ATTRIBUTE
, "Bad attribute", },
231 { CS_BAD_BASE
, "Bad base address" },
232 { CS_BAD_EDC
, "Bad EDC" },
233 { CS_BAD_IRQ
, "Bad IRQ" },
234 { CS_BAD_OFFSET
, "Bad offset" },
235 { CS_BAD_PAGE
, "Bad page number" },
236 { CS_READ_FAILURE
, "Read failure" },
237 { CS_BAD_SIZE
, "Bad size" },
238 { CS_BAD_SOCKET
, "Bad socket" },
239 { CS_BAD_TYPE
, "Bad type" },
240 { CS_BAD_VCC
, "Bad Vcc" },
241 { CS_BAD_VPP
, "Bad Vpp" },
242 { CS_BAD_WINDOW
, "Bad window" },
243 { CS_WRITE_FAILURE
, "Write failure" },
244 { CS_NO_CARD
, "No card present" },
245 { CS_UNSUPPORTED_FUNCTION
, "Usupported function" },
246 { CS_UNSUPPORTED_MODE
, "Unsupported mode" },
247 { CS_BAD_SPEED
, "Bad speed" },
248 { CS_BUSY
, "Resource busy" },
249 { CS_GENERAL_FAILURE
, "General failure" },
250 { CS_WRITE_PROTECTED
, "Write protected" },
251 { CS_BAD_ARG_LENGTH
, "Bad argument length" },
252 { CS_BAD_ARGS
, "Bad arguments" },
253 { CS_CONFIGURATION_LOCKED
, "Configuration locked" },
254 { CS_IN_USE
, "Resource in use" },
255 { CS_NO_MORE_ITEMS
, "No more items" },
256 { CS_OUT_OF_RESOURCE
, "Out of resource" },
257 { CS_BAD_HANDLE
, "Bad handle" },
258 { CS_BAD_TUPLE
, "Bad CIS tuple" }
262 static const lookup_t service_table
[] = {
263 { AccessConfigurationRegister
, "AccessConfigurationRegister" },
264 { AddSocketServices
, "AddSocketServices" },
265 { AdjustResourceInfo
, "AdjustResourceInfo" },
266 { CheckEraseQueue
, "CheckEraseQueue" },
267 { CloseMemory
, "CloseMemory" },
268 { DeregisterClient
, "DeregisterClient" },
269 { DeregisterEraseQueue
, "DeregisterEraseQueue" },
270 { GetCardServicesInfo
, "GetCardServicesInfo" },
271 { GetClientInfo
, "GetClientInfo" },
272 { GetConfigurationInfo
, "GetConfigurationInfo" },
273 { GetEventMask
, "GetEventMask" },
274 { GetFirstClient
, "GetFirstClient" },
275 { GetFirstRegion
, "GetFirstRegion" },
276 { GetFirstTuple
, "GetFirstTuple" },
277 { GetNextClient
, "GetNextClient" },
278 { GetNextRegion
, "GetNextRegion" },
279 { GetNextTuple
, "GetNextTuple" },
280 { GetStatus
, "GetStatus" },
281 { GetTupleData
, "GetTupleData" },
282 { MapMemPage
, "MapMemPage" },
283 { ModifyConfiguration
, "ModifyConfiguration" },
284 { ModifyWindow
, "ModifyWindow" },
285 { OpenMemory
, "OpenMemory" },
286 { ParseTuple
, "ParseTuple" },
287 { ReadMemory
, "ReadMemory" },
288 { RegisterClient
, "RegisterClient" },
289 { RegisterEraseQueue
, "RegisterEraseQueue" },
290 { RegisterMTD
, "RegisterMTD" },
291 { ReleaseConfiguration
, "ReleaseConfiguration" },
292 { ReleaseIO
, "ReleaseIO" },
293 { ReleaseIRQ
, "ReleaseIRQ" },
294 { ReleaseWindow
, "ReleaseWindow" },
295 { RequestConfiguration
, "RequestConfiguration" },
296 { RequestIO
, "RequestIO" },
297 { RequestIRQ
, "RequestIRQ" },
298 { RequestSocketMask
, "RequestSocketMask" },
299 { RequestWindow
, "RequestWindow" },
300 { ResetCard
, "ResetCard" },
301 { SetEventMask
, "SetEventMask" },
302 { ValidateCIS
, "ValidateCIS" },
303 { WriteMemory
, "WriteMemory" },
304 { BindDevice
, "BindDevice" },
305 { BindMTD
, "BindMTD" },
306 { ReportError
, "ReportError" },
307 { SuspendCard
, "SuspendCard" },
308 { ResumeCard
, "ResumeCard" },
309 { EjectCard
, "EjectCard" },
310 { InsertCard
, "InsertCard" },
311 { ReplaceCIS
, "ReplaceCIS" }
315 int pcmcia_report_error(client_handle_t handle
, error_info_t
*err
)
320 if (CHECK_HANDLE(handle
))
323 printk(KERN_NOTICE
"%s: ", handle
->dev_info
);
325 for (i
= 0; i
< ARRAY_SIZE(service_table
); i
++)
326 if (service_table
[i
].key
== err
->func
)
328 if (i
< ARRAY_SIZE(service_table
))
329 serv
= service_table
[i
].msg
;
331 serv
= "Unknown service number";
333 for (i
= 0; i
< ARRAY_SIZE(error_table
); i
++)
334 if (error_table
[i
].key
== err
->retcode
)
336 if (i
< ARRAY_SIZE(error_table
))
337 printk("%s: %s\n", serv
, error_table
[i
].msg
);
339 printk("%s: Unknown error code %#x\n", serv
, err
->retcode
);
343 EXPORT_SYMBOL(pcmcia_report_error
);
345 /* end of code which was in cs.c before */
347 /*======================================================================*/
349 void cs_error(client_handle_t handle
, int func
, int ret
)
351 error_info_t err
= { func
, ret
};
352 pcmcia_report_error(handle
, &err
);
354 EXPORT_SYMBOL(cs_error
);
356 /*======================================================================*/
358 static struct pcmcia_driver
* get_pcmcia_driver (dev_info_t
*dev_info
);
359 static struct pcmcia_bus_socket
* get_socket_info_by_nr(unsigned int nr
);
361 static void pcmcia_put_bus_socket(struct pcmcia_bus_socket
*s
)
363 if (atomic_dec_and_test(&s
->refcount
))
367 static struct pcmcia_bus_socket
*pcmcia_get_bus_socket(int nr
)
369 struct pcmcia_bus_socket
*s
;
371 s
= get_socket_info_by_nr(nr
);
373 WARN_ON(atomic_read(&s
->refcount
) == 0);
374 atomic_inc(&s
->refcount
);
380 * pcmcia_register_driver - register a PCMCIA driver with the bus core
382 * Registers a PCMCIA driver with the PCMCIA bus core.
384 int pcmcia_register_driver(struct pcmcia_driver
*driver
)
389 driver
->use_count
= 0;
390 driver
->drv
.bus
= &pcmcia_bus_type
;
392 return driver_register(&driver
->drv
);
394 EXPORT_SYMBOL(pcmcia_register_driver
);
397 * pcmcia_unregister_driver - unregister a PCMCIA driver with the bus core
399 void pcmcia_unregister_driver(struct pcmcia_driver
*driver
)
401 driver_unregister(&driver
->drv
);
403 EXPORT_SYMBOL(pcmcia_unregister_driver
);
405 #ifdef CONFIG_PROC_FS
406 static struct proc_dir_entry
*proc_pccard
= NULL
;
408 static int proc_read_drivers_callback(struct device_driver
*driver
, void *d
)
411 struct pcmcia_driver
*p_dev
= container_of(driver
,
412 struct pcmcia_driver
, drv
);
414 *p
+= sprintf(*p
, "%-24.24s 1 %d\n", driver
->name
, p_dev
->use_count
);
420 static int proc_read_drivers(char *buf
, char **start
, off_t pos
,
421 int count
, int *eof
, void *data
)
425 bus_for_each_drv(&pcmcia_bus_type
, NULL
,
426 (void *) &p
, proc_read_drivers_callback
);
432 /*======================================================================
434 These manage a ring buffer of events pending for one user process
436 ======================================================================*/
438 static int queue_empty(user_info_t
*user
)
440 return (user
->event_head
== user
->event_tail
);
443 static event_t
get_queued_event(user_info_t
*user
)
445 user
->event_tail
= (user
->event_tail
+1) % MAX_EVENTS
;
446 return user
->event
[user
->event_tail
];
449 static void queue_event(user_info_t
*user
, event_t event
)
451 user
->event_head
= (user
->event_head
+1) % MAX_EVENTS
;
452 if (user
->event_head
== user
->event_tail
)
453 user
->event_tail
= (user
->event_tail
+1) % MAX_EVENTS
;
454 user
->event
[user
->event_head
] = event
;
457 static void handle_event(struct pcmcia_bus_socket
*s
, event_t event
)
460 for (user
= s
->user
; user
; user
= user
->next
)
461 queue_event(user
, event
);
462 wake_up_interruptible(&s
->queue
);
465 static int handle_request(struct pcmcia_bus_socket
*s
, event_t event
)
467 if (s
->req_pending
!= 0)
469 if (s
->state
& DS_SOCKET_BUSY
)
471 handle_event(s
, event
);
472 if (wait_event_interruptible(s
->request
, s
->req_pending
<= 0))
474 if (s
->state
& DS_SOCKET_BUSY
)
475 return s
->req_result
;
479 static void handle_removal(void *data
)
481 struct pcmcia_bus_socket
*s
= data
;
482 handle_event(s
, CS_EVENT_CARD_REMOVAL
);
483 s
->state
&= ~DS_SOCKET_REMOVAL_PENDING
;
486 /*======================================================================
488 The card status event handler.
490 ======================================================================*/
492 static int ds_event(event_t event
, int priority
,
493 event_callback_args_t
*args
)
495 struct pcmcia_bus_socket
*s
;
497 ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n",
498 event
, priority
, args
->client_handle
);
499 s
= args
->client_data
;
503 case CS_EVENT_CARD_REMOVAL
:
504 s
->state
&= ~DS_SOCKET_PRESENT
;
505 if (!(s
->state
& DS_SOCKET_REMOVAL_PENDING
)) {
506 s
->state
|= DS_SOCKET_REMOVAL_PENDING
;
507 schedule_delayed_work(&s
->removal
, HZ
/10);
511 case CS_EVENT_CARD_INSERTION
:
512 s
->state
|= DS_SOCKET_PRESENT
;
513 handle_event(s
, event
);
516 case CS_EVENT_EJECTION_REQUEST
:
517 return handle_request(s
, event
);
521 handle_event(s
, event
);
528 /*======================================================================
530 bind_mtd() connects a memory region with an MTD client.
532 ======================================================================*/
534 static int bind_mtd(struct pcmcia_bus_socket
*bus_sock
, mtd_info_t
*mtd_info
)
539 bind_req
.dev_info
= &mtd_info
->dev_info
;
540 bind_req
.Attributes
= mtd_info
->Attributes
;
541 bind_req
.Socket
= bus_sock
->parent
;
542 bind_req
.CardOffset
= mtd_info
->CardOffset
;
543 ret
= pcmcia_bind_mtd(&bind_req
);
544 if (ret
!= CS_SUCCESS
) {
545 cs_error(NULL
, BindMTD
, ret
);
546 printk(KERN_NOTICE
"ds: unable to bind MTD '%s' to socket %d"
548 (char *)bind_req
.dev_info
, bus_sock
->parent
->sock
, bind_req
.CardOffset
);
554 /*======================================================================
556 bind_request() connects a socket to a particular client driver.
557 It looks up the specified device ID in the list of registered
558 drivers, binds it to the socket, and tries to create an instance
559 of the device. unbind_request() deletes a driver instance.
561 ======================================================================*/
563 static int bind_request(struct pcmcia_bus_socket
*s
, bind_info_t
*bind_info
)
565 struct pcmcia_driver
*driver
;
573 ds_dbg(2, "bind_request(%d, '%s')\n", s
->parent
->sock
,
574 (char *)bind_info
->dev_info
);
575 driver
= get_pcmcia_driver(&bind_info
->dev_info
);
579 for (b
= s
->bind
; b
; b
= b
->next
)
580 if ((driver
== b
->driver
) &&
581 (bind_info
->function
== b
->function
))
584 bind_info
->instance
= b
->instance
;
588 if (!try_module_get(driver
->owner
))
591 bind_req
.Socket
= s
->parent
;
592 bind_req
.Function
= bind_info
->function
;
593 bind_req
.dev_info
= (dev_info_t
*) driver
->drv
.name
;
594 ret
= pcmcia_bind_device(&bind_req
);
595 if (ret
!= CS_SUCCESS
) {
596 cs_error(NULL
, BindDevice
, ret
);
597 printk(KERN_NOTICE
"ds: unable to bind '%s' to socket %d\n",
598 (char *)dev_info
, s
->parent
->sock
);
599 module_put(driver
->owner
);
603 /* Add binding to list for this socket */
605 b
= kmalloc(sizeof(socket_bind_t
), GFP_KERNEL
);
609 module_put(driver
->owner
);
613 b
->function
= bind_info
->function
;
618 if (driver
->attach
) {
619 b
->instance
= driver
->attach();
620 if (b
->instance
== NULL
) {
621 printk(KERN_NOTICE
"ds: unable to create instance "
622 "of '%s'!\n", (char *)bind_info
->dev_info
);
623 module_put(driver
->owner
);
631 /*====================================================================*/
633 static int get_device_info(struct pcmcia_bus_socket
*s
, bind_info_t
*bind_info
, int first
)
638 #ifdef CONFIG_CARDBUS
640 * Some unbelievably ugly code to associate the PCI cardbus
641 * device and its driver with the PCMCIA "bind" information.
646 bus
= pcmcia_lookup_bus(s
->handle
);
648 struct list_head
*list
;
649 struct pci_dev
*dev
= NULL
;
651 list
= bus
->devices
.next
;
652 while (list
!= &bus
->devices
) {
653 struct pci_dev
*pdev
= pci_dev_b(list
);
661 /* Try to handle "next" here some way? */
663 if (dev
&& dev
->driver
) {
664 strlcpy(bind_info
->name
, dev
->driver
->name
, DEV_NAME_LEN
);
665 bind_info
->major
= 0;
666 bind_info
->minor
= 0;
667 bind_info
->next
= NULL
;
674 for (b
= s
->bind
; b
; b
= b
->next
)
675 if ((strcmp((char *)b
->driver
->drv
.name
,
676 (char *)bind_info
->dev_info
) == 0) &&
677 (b
->function
== bind_info
->function
))
679 if (b
== NULL
) return -ENODEV
;
680 if ((b
->instance
== NULL
) ||
681 (b
->instance
->state
& DEV_CONFIG_PENDING
))
684 node
= b
->instance
->dev
;
686 for (node
= b
->instance
->dev
; node
; node
= node
->next
)
687 if (node
== bind_info
->next
) break;
688 if (node
== NULL
) return -ENODEV
;
690 strlcpy(bind_info
->name
, node
->dev_name
, DEV_NAME_LEN
);
691 bind_info
->major
= node
->major
;
692 bind_info
->minor
= node
->minor
;
693 bind_info
->next
= node
->next
;
696 } /* get_device_info */
698 /*====================================================================*/
700 static int unbind_request(struct pcmcia_bus_socket
*s
, bind_info_t
*bind_info
)
702 socket_bind_t
**b
, *c
;
704 ds_dbg(2, "unbind_request(%d, '%s')\n", s
->parent
->sock
,
705 (char *)bind_info
->dev_info
);
706 for (b
= &s
->bind
; *b
; b
= &(*b
)->next
)
707 if ((strcmp((char *)(*b
)->driver
->drv
.name
,
708 (char *)bind_info
->dev_info
) == 0) &&
709 ((*b
)->function
== bind_info
->function
))
715 c
->driver
->use_count
--;
716 if (c
->driver
->detach
) {
718 c
->driver
->detach(c
->instance
);
720 module_put(c
->driver
->owner
);
724 } /* unbind_request */
726 /*======================================================================
728 The user-mode PC Card device interface
730 ======================================================================*/
732 static int ds_open(struct inode
*inode
, struct file
*file
)
734 socket_t i
= iminor(inode
);
735 struct pcmcia_bus_socket
*s
;
738 ds_dbg(0, "ds_open(socket %d)\n", i
);
740 s
= pcmcia_get_bus_socket(i
);
744 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
745 if (s
->state
& DS_SOCKET_BUSY
)
748 s
->state
|= DS_SOCKET_BUSY
;
751 user
= kmalloc(sizeof(user_info_t
), GFP_KERNEL
);
752 if (!user
) return -ENOMEM
;
753 user
->event_tail
= user
->event_head
= 0;
754 user
->next
= s
->user
;
755 user
->user_magic
= USER_MAGIC
;
758 file
->private_data
= user
;
760 if (s
->state
& DS_SOCKET_PRESENT
)
761 queue_event(user
, CS_EVENT_CARD_INSERTION
);
765 /*====================================================================*/
767 static int ds_release(struct inode
*inode
, struct file
*file
)
769 struct pcmcia_bus_socket
*s
;
770 user_info_t
*user
, **link
;
772 ds_dbg(0, "ds_release(socket %d)\n", iminor(inode
));
774 user
= file
->private_data
;
775 if (CHECK_USER(user
))
780 /* Unlink user data structure */
781 if ((file
->f_flags
& O_ACCMODE
) != O_RDONLY
) {
782 s
->state
&= ~DS_SOCKET_BUSY
;
784 wake_up_interruptible(&s
->request
);
786 file
->private_data
= NULL
;
787 for (link
= &s
->user
; *link
; link
= &(*link
)->next
)
788 if (*link
== user
) break;
792 user
->user_magic
= 0;
794 pcmcia_put_bus_socket(s
);
799 /*====================================================================*/
801 static ssize_t
ds_read(struct file
*file
, char __user
*buf
,
802 size_t count
, loff_t
*ppos
)
804 struct pcmcia_bus_socket
*s
;
808 ds_dbg(2, "ds_read(socket %d)\n", iminor(file
->f_dentry
->d_inode
));
813 user
= file
->private_data
;
814 if (CHECK_USER(user
))
818 if (s
->state
& DS_SOCKET_DEAD
)
821 ret
= wait_event_interruptible(s
->queue
, !queue_empty(user
));
823 ret
= put_user(get_queued_event(user
), (int __user
*)buf
) ? -EFAULT
: 4;
828 /*====================================================================*/
830 static ssize_t
ds_write(struct file
*file
, const char __user
*buf
,
831 size_t count
, loff_t
*ppos
)
833 struct pcmcia_bus_socket
*s
;
836 ds_dbg(2, "ds_write(socket %d)\n", iminor(file
->f_dentry
->d_inode
));
840 if ((file
->f_flags
& O_ACCMODE
) == O_RDONLY
)
843 user
= file
->private_data
;
844 if (CHECK_USER(user
))
848 if (s
->state
& DS_SOCKET_DEAD
)
851 if (s
->req_pending
) {
853 get_user(s
->req_result
, (int __user
*)buf
);
854 if ((s
->req_result
!= 0) || (s
->req_pending
== 0))
855 wake_up_interruptible(&s
->request
);
862 /*====================================================================*/
864 /* No kernel lock - fine */
865 static u_int
ds_poll(struct file
*file
, poll_table
*wait
)
867 struct pcmcia_bus_socket
*s
;
870 ds_dbg(2, "ds_poll(socket %d)\n", iminor(file
->f_dentry
->d_inode
));
872 user
= file
->private_data
;
873 if (CHECK_USER(user
))
877 * We don't check for a dead socket here since that
878 * will send cardmgr into an endless spin.
880 poll_wait(file
, &s
->queue
, wait
);
881 if (!queue_empty(user
))
882 return POLLIN
| POLLRDNORM
;
886 /*====================================================================*/
888 static int ds_ioctl(struct inode
* inode
, struct file
* file
,
889 u_int cmd
, u_long arg
)
891 struct pcmcia_bus_socket
*s
;
892 void __user
*uarg
= (char __user
*)arg
;
898 ds_dbg(2, "ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode
), cmd
, arg
);
900 user
= file
->private_data
;
901 if (CHECK_USER(user
))
905 if (s
->state
& DS_SOCKET_DEAD
)
908 size
= (cmd
& IOCSIZE_MASK
) >> IOCSIZE_SHIFT
;
909 if (size
> sizeof(ds_ioctl_arg_t
)) return -EINVAL
;
911 /* Permission check */
912 if (!(cmd
& IOC_OUT
) && !capable(CAP_SYS_ADMIN
))
916 err
= verify_area(VERIFY_READ
, uarg
, size
);
918 ds_dbg(3, "ds_ioctl(): verify_read = %d\n", err
);
923 err
= verify_area(VERIFY_WRITE
, uarg
, size
);
925 ds_dbg(3, "ds_ioctl(): verify_write = %d\n", err
);
932 if (cmd
& IOC_IN
) __copy_from_user((char *)&buf
, uarg
, size
);
935 case DS_ADJUST_RESOURCE_INFO
:
936 ret
= pcmcia_adjust_resource_info(s
->handle
, &buf
.adjust
);
938 case DS_GET_CARD_SERVICES_INFO
:
939 ret
= pcmcia_get_card_services_info(&buf
.servinfo
);
941 case DS_GET_CONFIGURATION_INFO
:
942 ret
= pcmcia_get_configuration_info(s
->handle
, &buf
.config
);
944 case DS_GET_FIRST_TUPLE
:
945 pcmcia_validate_mem(s
->parent
);
946 ret
= pcmcia_get_first_tuple(s
->handle
, &buf
.tuple
);
948 case DS_GET_NEXT_TUPLE
:
949 ret
= pcmcia_get_next_tuple(s
->handle
, &buf
.tuple
);
951 case DS_GET_TUPLE_DATA
:
952 buf
.tuple
.TupleData
= buf
.tuple_parse
.data
;
953 buf
.tuple
.TupleDataMax
= sizeof(buf
.tuple_parse
.data
);
954 ret
= pcmcia_get_tuple_data(s
->handle
, &buf
.tuple
);
957 buf
.tuple
.TupleData
= buf
.tuple_parse
.data
;
958 ret
= pcmcia_parse_tuple(s
->handle
, &buf
.tuple
, &buf
.tuple_parse
.parse
);
961 ret
= pcmcia_reset_card(s
->handle
, NULL
);
964 ret
= pcmcia_get_status(s
->handle
, &buf
.status
);
966 case DS_VALIDATE_CIS
:
967 pcmcia_validate_mem(s
->parent
);
968 ret
= pcmcia_validate_cis(s
->handle
, &buf
.cisinfo
);
970 case DS_SUSPEND_CARD
:
971 ret
= pcmcia_suspend_card(s
->parent
);
974 ret
= pcmcia_resume_card(s
->parent
);
977 err
= pcmcia_eject_card(s
->parent
);
980 err
= pcmcia_insert_card(s
->parent
);
982 case DS_ACCESS_CONFIGURATION_REGISTER
:
983 if ((buf
.conf_reg
.Action
== CS_WRITE
) && !capable(CAP_SYS_ADMIN
))
985 ret
= pcmcia_access_configuration_register(s
->handle
, &buf
.conf_reg
);
987 case DS_GET_FIRST_REGION
:
988 ret
= pcmcia_get_first_region(s
->handle
, &buf
.region
);
990 case DS_GET_NEXT_REGION
:
991 ret
= pcmcia_get_next_region(s
->handle
, &buf
.region
);
993 case DS_GET_FIRST_WINDOW
:
994 buf
.win_info
.handle
= (window_handle_t
)s
->handle
;
995 ret
= pcmcia_get_first_window(&buf
.win_info
.handle
, &buf
.win_info
.window
);
997 case DS_GET_NEXT_WINDOW
:
998 ret
= pcmcia_get_next_window(&buf
.win_info
.handle
, &buf
.win_info
.window
);
1000 case DS_GET_MEM_PAGE
:
1001 ret
= pcmcia_get_mem_page(buf
.win_info
.handle
,
1004 case DS_REPLACE_CIS
:
1005 ret
= pcmcia_replace_cis(s
->handle
, &buf
.cisdump
);
1007 case DS_BIND_REQUEST
:
1008 if (!capable(CAP_SYS_ADMIN
)) return -EPERM
;
1009 err
= bind_request(s
, &buf
.bind_info
);
1011 case DS_GET_DEVICE_INFO
:
1012 err
= get_device_info(s
, &buf
.bind_info
, 1);
1014 case DS_GET_NEXT_DEVICE
:
1015 err
= get_device_info(s
, &buf
.bind_info
, 0);
1017 case DS_UNBIND_REQUEST
:
1018 err
= unbind_request(s
, &buf
.bind_info
);
1021 if (!capable(CAP_SYS_ADMIN
)) return -EPERM
;
1022 err
= bind_mtd(s
, &buf
.mtd_info
);
1028 if ((err
== 0) && (ret
!= CS_SUCCESS
)) {
1029 ds_dbg(2, "ds_ioctl: ret = %d\n", ret
);
1031 case CS_BAD_SOCKET
: case CS_NO_CARD
:
1032 err
= -ENODEV
; break;
1033 case CS_BAD_ARGS
: case CS_BAD_ATTRIBUTE
: case CS_BAD_IRQ
:
1035 err
= -EINVAL
; break;
1037 err
= -EBUSY
; break;
1038 case CS_OUT_OF_RESOURCE
:
1039 err
= -ENOSPC
; break;
1040 case CS_NO_MORE_ITEMS
:
1041 err
= -ENODATA
; break;
1042 case CS_UNSUPPORTED_FUNCTION
:
1043 err
= -ENOSYS
; break;
1049 if (cmd
& IOC_OUT
) __copy_to_user(uarg
, (char *)&buf
, size
);
1054 /*====================================================================*/
1056 static struct file_operations ds_fops
= {
1057 .owner
= THIS_MODULE
,
1059 .release
= ds_release
,
1066 static int __devinit
pcmcia_bus_add_socket(struct class_device
*class_dev
)
1068 struct pcmcia_socket
*socket
= class_dev
->class_data
;
1069 client_reg_t client_reg
;
1071 struct pcmcia_bus_socket
*s
;
1074 s
= kmalloc(sizeof(struct pcmcia_bus_socket
), GFP_KERNEL
);
1077 memset(s
, 0, sizeof(struct pcmcia_bus_socket
));
1078 atomic_set(&s
->refcount
, 1);
1081 * Ugly. But we want to wait for the socket threads to have started up.
1082 * We really should let the drivers themselves drive some of this..
1086 init_waitqueue_head(&s
->queue
);
1087 init_waitqueue_head(&s
->request
);
1089 /* initialize data */
1090 INIT_WORK(&s
->removal
, handle_removal
, s
);
1093 /* Set up hotline to Card Services */
1094 client_reg
.dev_info
= bind
.dev_info
= &dev_info
;
1096 bind
.Socket
= socket
;
1097 bind
.Function
= BIND_FN_ALL
;
1098 ret
= pcmcia_bind_device(&bind
);
1099 if (ret
!= CS_SUCCESS
) {
1100 cs_error(NULL
, BindDevice
, ret
);
1105 client_reg
.Attributes
= INFO_MASTER_CLIENT
;
1106 client_reg
.EventMask
=
1107 CS_EVENT_CARD_INSERTION
| CS_EVENT_CARD_REMOVAL
|
1108 CS_EVENT_RESET_PHYSICAL
| CS_EVENT_CARD_RESET
|
1109 CS_EVENT_EJECTION_REQUEST
| CS_EVENT_INSERTION_REQUEST
|
1110 CS_EVENT_PM_SUSPEND
| CS_EVENT_PM_RESUME
;
1111 client_reg
.event_handler
= &ds_event
;
1112 client_reg
.Version
= 0x0210;
1113 client_reg
.event_callback_args
.client_data
= s
;
1114 ret
= pcmcia_register_client(&s
->handle
, &client_reg
);
1115 if (ret
!= CS_SUCCESS
) {
1116 cs_error(NULL
, RegisterClient
, ret
);
1127 static void pcmcia_bus_remove_socket(struct class_device
*class_dev
)
1129 struct pcmcia_socket
*socket
= class_dev
->class_data
;
1131 if (!socket
|| !socket
->pcmcia
)
1134 flush_scheduled_work();
1136 pcmcia_deregister_client(socket
->pcmcia
->handle
);
1138 socket
->pcmcia
->state
|= DS_SOCKET_DEAD
;
1139 pcmcia_put_bus_socket(socket
->pcmcia
);
1140 socket
->pcmcia
= NULL
;
1146 /* the pcmcia_bus_interface is used to handle pcmcia socket devices */
1147 static struct class_interface pcmcia_bus_interface
= {
1148 .class = &pcmcia_socket_class
,
1149 .add
= &pcmcia_bus_add_socket
,
1150 .remove
= &pcmcia_bus_remove_socket
,
1154 struct bus_type pcmcia_bus_type
= {
1157 EXPORT_SYMBOL(pcmcia_bus_type
);
1160 static int __init
init_pcmcia_bus(void)
1164 bus_register(&pcmcia_bus_type
);
1165 class_interface_register(&pcmcia_bus_interface
);
1167 /* Set up character device for user mode clients */
1168 i
= register_chrdev(0, "pcmcia", &ds_fops
);
1170 printk(KERN_NOTICE
"unable to find a free device # for "
1171 "Driver Services\n");
1175 #ifdef CONFIG_PROC_FS
1176 proc_pccard
= proc_mkdir("pccard", proc_bus
);
1178 create_proc_read_entry("drivers",0,proc_pccard
,proc_read_drivers
,NULL
);
1183 fs_initcall(init_pcmcia_bus
); /* one level after subsys_initcall so that
1184 * pcmcia_socket_class is already registered */
1187 static void __exit
exit_pcmcia_bus(void)
1189 class_interface_unregister(&pcmcia_bus_interface
);
1191 #ifdef CONFIG_PROC_FS
1193 remove_proc_entry("drivers", proc_pccard
);
1194 remove_proc_entry("pccard", proc_bus
);
1197 if (major_dev
!= -1)
1198 unregister_chrdev(major_dev
, "pcmcia");
1200 bus_unregister(&pcmcia_bus_type
);
1202 module_exit(exit_pcmcia_bus
);
1206 /* helpers for backwards-compatible functions */
1208 static struct pcmcia_bus_socket
* get_socket_info_by_nr(unsigned int nr
)
1210 struct pcmcia_socket
* s
= pcmcia_get_socket_by_nr(nr
);
1217 /* backwards-compatible accessing of driver --- by name! */
1221 struct pcmcia_driver
*drv
;
1224 static int cmp_drv_callback(struct device_driver
*drv
, void *data
)
1226 struct cmp_data
*cmp
= data
;
1227 if (strncmp((char *)cmp
->dev_info
, (char *)drv
->name
,
1228 DEV_NAME_LEN
) == 0) {
1229 cmp
->drv
= container_of(drv
, struct pcmcia_driver
, drv
);
1235 static struct pcmcia_driver
* get_pcmcia_driver (dev_info_t
*dev_info
)
1238 struct cmp_data cmp
= {
1239 .dev_info
= dev_info
,
1242 ret
= bus_for_each_drv(&pcmcia_bus_type
, NULL
, &cmp
, cmp_drv_callback
);