Linux-2.4.0-test2
[davej-history.git] / drivers / pcmcia / pci_socket.c
blob3f4463e75a9656a83299830b2ab3e282529fd04f
1 /*
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>
27 #include <asm/io.h>
29 #include "pci_socket.h"
32 * Arbitrary define. This is the array of active cardbus
33 * entries.
35 #define MAX_SOCKETS (8)
36 static pci_socket_t pci_socket_array[MAX_SOCKETS];
38 static int pci_init_socket(unsigned int sock)
40 pci_socket_t *socket = pci_socket_array + sock;
42 if (socket->op && socket->op->init)
43 return socket->op->init(socket);
44 return -EINVAL;
47 static int pci_suspend_socket(unsigned int sock)
49 pci_socket_t *socket = pci_socket_array + sock;
51 if (socket->op && socket->op->suspend)
52 return socket->op->suspend(socket);
53 return -EINVAL;
56 static int pci_register_callback(unsigned int sock, void (*handler)(void *, unsigned int), void * info)
58 pci_socket_t *socket = pci_socket_array + sock;
60 socket->handler = handler;
61 socket->info = info;
62 if (handler)
63 MOD_INC_USE_COUNT;
64 else
65 MOD_DEC_USE_COUNT;
66 return 0;
69 static int pci_inquire_socket(unsigned int sock, socket_cap_t *cap)
71 pci_socket_t *socket = pci_socket_array + sock;
73 *cap = socket->cap;
74 return 0;
77 static int pci_get_status(unsigned int sock, unsigned int *value)
79 pci_socket_t *socket = pci_socket_array + sock;
81 if (socket->op && socket->op->get_status)
82 return socket->op->get_status(socket, value);
83 *value = 0;
84 return -EINVAL;
87 static int pci_get_socket(unsigned int sock, socket_state_t *state)
89 pci_socket_t *socket = pci_socket_array + sock;
91 if (socket->op && socket->op->get_socket)
92 return socket->op->get_socket(socket, state);
93 return -EINVAL;
96 static int pci_set_socket(unsigned int sock, socket_state_t *state)
98 pci_socket_t *socket = pci_socket_array + sock;
100 if (socket->op && socket->op->set_socket)
101 return socket->op->set_socket(socket, state);
102 return -EINVAL;
105 static int pci_get_io_map(unsigned int sock, struct pccard_io_map *io)
107 pci_socket_t *socket = pci_socket_array + sock;
109 if (socket->op && socket->op->get_io_map)
110 return socket->op->get_io_map(socket, io);
111 return -EINVAL;
114 static int pci_set_io_map(unsigned int sock, struct pccard_io_map *io)
116 pci_socket_t *socket = pci_socket_array + sock;
118 if (socket->op && socket->op->set_io_map)
119 return socket->op->set_io_map(socket, io);
120 return -EINVAL;
123 static int pci_get_mem_map(unsigned int sock, struct pccard_mem_map *mem)
125 pci_socket_t *socket = pci_socket_array + sock;
127 if (socket->op && socket->op->get_mem_map)
128 return socket->op->get_mem_map(socket, mem);
129 return -EINVAL;
132 static int pci_set_mem_map(unsigned int sock, struct pccard_mem_map *mem)
134 pci_socket_t *socket = pci_socket_array + sock;
136 if (socket->op && socket->op->set_mem_map)
137 return socket->op->set_mem_map(socket, mem);
138 return -EINVAL;
141 static void pci_proc_setup(unsigned int sock, struct proc_dir_entry *base)
143 pci_socket_t *socket = pci_socket_array + sock;
145 if (socket->op && socket->op->proc_setup)
146 socket->op->proc_setup(socket, base);
149 static struct pccard_operations pci_socket_operations = {
150 pci_init_socket,
151 pci_suspend_socket,
152 pci_register_callback,
153 pci_inquire_socket,
154 pci_get_status,
155 pci_get_socket,
156 pci_set_socket,
157 pci_get_io_map,
158 pci_set_io_map,
159 pci_get_mem_map,
160 pci_set_mem_map,
161 pci_proc_setup
164 static int __init add_pci_socket(int nr, struct pci_dev *dev, struct pci_socket_ops *ops)
166 pci_socket_t *socket = nr + pci_socket_array;
168 memset(socket, 0, sizeof(*socket));
169 socket->dev = dev;
170 socket->op = ops;
171 init_waitqueue_head(&socket->wait);
172 return socket->op->open(socket);
175 static int __init pci_socket_init(void)
177 struct pci_dev *dev = NULL;
178 int nr = 0;
180 while ((dev = pci_find_class(PCI_CLASS_BRIDGE_CARDBUS << 8, dev)) != NULL) {
181 printk("Adding cardbus controller %d: %s\n", nr, dev->name);
182 add_pci_socket(nr, dev, &yenta_operations);
183 nr++;
186 if (nr <= 0)
187 return -1;
188 register_ss_entry(nr, &pci_socket_operations);
189 return 0;
192 static void __exit pci_socket_exit(void)
194 int i;
196 unregister_ss_entry(&pci_socket_operations);
197 for (i = 0; i < MAX_SOCKETS; i++) {
198 pci_socket_t *socket = pci_socket_array + i;
200 if (socket->op && socket->op->close)
201 socket->op->close(socket);
205 module_init(pci_socket_init);
206 module_exit(pci_socket_exit);