2 * Generic PCI pccard driver interface.
4 * (C) Copyright 1999 Linus Torvalds
6 * This implements the common parts of PCI pccard drivers,
7 * notably detection and infrastructure conversion (ie change
8 * from socket index to "struct pci_dev" etc)
10 * This does NOT implement the actual low-level driver details,
11 * and this has on purpose been left generic enough that it can
12 * be used to set up a PCI PCMCIA controller (ie non-cardbus),
13 * or to set up a controller.
15 * See for example the "yenta" driver for PCI cardbus controllers
16 * conforming to the yenta cardbus specifications.
18 #include <linux/module.h>
20 #include <linux/init.h>
21 #include <linux/pci.h>
22 #include <linux/sched.h>
23 #include <linux/interrupt.h>
25 #include <pcmcia/ss.h>
29 #include "pci_socket.h"
32 extern struct socket_info_t
*pcmcia_register_socket (int slot
,
33 struct pccard_operations
*vtable
, int use_bus_pm
);
34 extern void pcmcia_unregister_socket (struct socket_info_t
*socket
);
35 extern void pcmcia_suspend_socket (struct socket_info_t
*socket
);
36 extern void pcmcia_resume_socket (struct socket_info_t
*socket
);
40 * Arbitrary define. This is the array of active cardbus
43 #define MAX_SOCKETS (8)
44 static pci_socket_t pci_socket_array
[MAX_SOCKETS
];
46 static int pci_init_socket(unsigned int sock
)
48 pci_socket_t
*socket
= pci_socket_array
+ sock
;
50 if (socket
->op
&& socket
->op
->init
)
51 return socket
->op
->init(socket
);
55 static int pci_suspend_socket(unsigned int sock
)
57 pci_socket_t
*socket
= pci_socket_array
+ sock
;
59 if (socket
->op
&& socket
->op
->suspend
)
60 return socket
->op
->suspend(socket
);
64 static int pci_register_callback(unsigned int sock
, void (*handler
)(void *, unsigned int), void * info
)
66 pci_socket_t
*socket
= pci_socket_array
+ sock
;
68 socket
->handler
= handler
;
77 static int pci_inquire_socket(unsigned int sock
, socket_cap_t
*cap
)
79 pci_socket_t
*socket
= pci_socket_array
+ sock
;
85 static int pci_get_status(unsigned int sock
, unsigned int *value
)
87 pci_socket_t
*socket
= pci_socket_array
+ sock
;
89 if (socket
->op
&& socket
->op
->get_status
)
90 return socket
->op
->get_status(socket
, value
);
95 static int pci_get_socket(unsigned int sock
, socket_state_t
*state
)
97 pci_socket_t
*socket
= pci_socket_array
+ sock
;
99 if (socket
->op
&& socket
->op
->get_socket
)
100 return socket
->op
->get_socket(socket
, state
);
104 static int pci_set_socket(unsigned int sock
, socket_state_t
*state
)
106 pci_socket_t
*socket
= pci_socket_array
+ sock
;
108 if (socket
->op
&& socket
->op
->set_socket
)
109 return socket
->op
->set_socket(socket
, state
);
113 static int pci_get_io_map(unsigned int sock
, struct pccard_io_map
*io
)
115 pci_socket_t
*socket
= pci_socket_array
+ sock
;
117 if (socket
->op
&& socket
->op
->get_io_map
)
118 return socket
->op
->get_io_map(socket
, io
);
122 static int pci_set_io_map(unsigned int sock
, struct pccard_io_map
*io
)
124 pci_socket_t
*socket
= pci_socket_array
+ sock
;
126 if (socket
->op
&& socket
->op
->set_io_map
)
127 return socket
->op
->set_io_map(socket
, io
);
131 static int pci_get_mem_map(unsigned int sock
, struct pccard_mem_map
*mem
)
133 pci_socket_t
*socket
= pci_socket_array
+ sock
;
135 if (socket
->op
&& socket
->op
->get_mem_map
)
136 return socket
->op
->get_mem_map(socket
, mem
);
140 static int pci_set_mem_map(unsigned int sock
, struct pccard_mem_map
*mem
)
142 pci_socket_t
*socket
= pci_socket_array
+ sock
;
144 if (socket
->op
&& socket
->op
->set_mem_map
)
145 return socket
->op
->set_mem_map(socket
, mem
);
149 static void pci_proc_setup(unsigned int sock
, struct proc_dir_entry
*base
)
151 pci_socket_t
*socket
= pci_socket_array
+ sock
;
153 if (socket
->op
&& socket
->op
->proc_setup
)
154 socket
->op
->proc_setup(socket
, base
);
157 static struct pccard_operations pci_socket_operations
= {
160 pci_register_callback
,
172 static int __devinit
add_pci_socket(int nr
, struct pci_dev
*dev
, struct pci_socket_ops
*ops
)
174 pci_socket_t
*socket
= nr
+ pci_socket_array
;
176 memset(socket
, 0, sizeof(*socket
));
179 dev
->driver_data
= socket
;
180 spin_lock_init(&socket
->event_lock
);
181 return socket
->op
->open(socket
);
184 void cardbus_register(pci_socket_t
*socket
)
186 int nr
= socket
- pci_socket_array
;
188 socket
->pcmcia_socket
= pcmcia_register_socket(nr
, &pci_socket_operations
, 1);
192 cardbus_probe (struct pci_dev
*dev
, const struct pci_device_id
*id
)
196 for (s
= 0; s
< MAX_SOCKETS
; s
++) {
197 if (pci_socket_array
[s
].dev
== 0) {
198 add_pci_socket (s
, dev
, ¥ta_operations
);
205 static void __devexit
cardbus_remove (struct pci_dev
*dev
)
207 pci_socket_t
*socket
= (pci_socket_t
*) dev
->driver_data
;
209 pcmcia_unregister_socket (socket
->pcmcia_socket
);
210 if (socket
->op
&& socket
->op
->close
)
211 socket
->op
->close(socket
);
212 dev
->driver_data
= 0;
215 static void cardbus_suspend (struct pci_dev
*dev
)
217 pci_socket_t
*socket
= (pci_socket_t
*) dev
->driver_data
;
218 pcmcia_suspend_socket (socket
->pcmcia_socket
);
221 static void cardbus_resume (struct pci_dev
*dev
)
223 pci_socket_t
*socket
= (pci_socket_t
*) dev
->driver_data
;
224 pcmcia_resume_socket (socket
->pcmcia_socket
);
228 static struct pci_device_id cardbus_table
[] __devinitdata
= { {
229 class: PCI_CLASS_BRIDGE_CARDBUS
<< 8,
234 subvendor
: PCI_ANY_ID
,
235 subdevice
: PCI_ANY_ID
,
236 }, { /* all zeroes */ }
238 MODULE_DEVICE_TABLE(pci
, cardbus_table
);
240 static struct pci_driver pci_cardbus_driver
= {
242 id_table
: cardbus_table
,
243 probe
: cardbus_probe
,
244 remove
: cardbus_remove
,
245 suspend
: cardbus_suspend
,
246 resume
: cardbus_resume
,
249 static int __init
pci_socket_init(void)
251 return pci_module_init (&pci_cardbus_driver
);
254 static void __exit
pci_socket_exit (void)
256 pci_unregister_driver (&pci_cardbus_driver
);
259 module_init(pci_socket_init
);
260 module_exit(pci_socket_exit
);