aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2010-07-11 03:51:14 -0400
committerDominik Brodowski <linux@dominikbrodowski.net>2010-07-30 15:07:26 -0400
commit5716d415f8c5a17d44f6e1d5a1e4998f7306a93b (patch)
tree81a946cccfd7ddb6f1b01839f68afa27fc42a180
parentb37fa16e78d6f9790462b3181602a26b5af36260 (diff)
pcmcia: remove obsolete ioctl
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
-rw-r--r--Documentation/feature-removal-schedule.txt23
-rw-r--r--drivers/pcmcia/Makefile1
-rw-r--r--drivers/pcmcia/cs_internal.h40
-rw-r--r--drivers/pcmcia/ds.c26
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c1077
-rw-r--r--drivers/pcmcia/rsrc_iodyn.c2
-rw-r--r--drivers/pcmcia/rsrc_mgr.c2
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c2
-rw-r--r--include/pcmcia/ds.h209
-rw-r--r--include/pcmcia/ss.h8
10 files changed, 7 insertions, 1383 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c268783bc4e7..27ed68d95adc 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -116,29 +116,6 @@ Who: Mauro Carvalho Chehab <mchehab@infradead.org>
116 116
117--------------------------- 117---------------------------
118 118
119What: PCMCIA control ioctl (needed for pcmcia-cs [cardmgr, cardctl])
120When: 2.6.35/2.6.36
121Files: drivers/pcmcia/: pcmcia_ioctl.c
122Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a
123 normal hotpluggable bus, and with it using the default kernel
124 infrastructure (hotplug, driver core, sysfs) keeping the PCMCIA
125 control ioctl needed by cardmgr and cardctl from pcmcia-cs is
126 unnecessary and potentially harmful (it does not provide for
127 proper locking), and makes further cleanups and integration of the
128 PCMCIA subsystem into the Linux kernel device driver model more
129 difficult. The features provided by cardmgr and cardctl are either
130 handled by the kernel itself now or are available in the new
131 pcmciautils package available at
132 http://kernel.org/pub/linux/utils/kernel/pcmcia/
133
134 For all architectures except ARM, the associated config symbol
135 has been removed from kernel 2.6.34; for ARM, it will be likely
136 be removed from kernel 2.6.35. The actual code will then likely
137 be removed from kernel 2.6.36.
138Who: Dominik Brodowski <linux@dominikbrodowski.net>
139
140---------------------------
141
142What: sys_sysctl 119What: sys_sysctl
143When: September 2010 120When: September 2010
144Option: CONFIG_SYSCTL_SYSCALL 121Option: CONFIG_SYSCTL_SYSCALL
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index d006e8beab9c..7a2b1604bf1c 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -7,7 +7,6 @@ pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
7obj-$(CONFIG_PCCARD) += pcmcia_core.o 7obj-$(CONFIG_PCCARD) += pcmcia_core.o
8 8
9pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o 9pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o
10pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
11obj-$(CONFIG_PCMCIA) += pcmcia.o 10obj-$(CONFIG_PCMCIA) += pcmcia.o
12 11
13pcmcia_rsrc-y += rsrc_mgr.o 12pcmcia_rsrc-y += rsrc_mgr.o
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 4126a75445ea..a6cc63db8c8e 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -60,14 +60,6 @@ struct pccard_resource_ops {
60 struct resource* (*find_mem) (unsigned long base, unsigned long num, 60 struct resource* (*find_mem) (unsigned long base, unsigned long num,
61 unsigned long align, int low, 61 unsigned long align, int low,
62 struct pcmcia_socket *s); 62 struct pcmcia_socket *s);
63 int (*add_io) (struct pcmcia_socket *s,
64 unsigned int action,
65 unsigned long r_start,
66 unsigned long r_end);
67 int (*add_mem) (struct pcmcia_socket *s,
68 unsigned int action,
69 unsigned long r_start,
70 unsigned long r_end);
71 int (*init) (struct pcmcia_socket *s); 63 int (*init) (struct pcmcia_socket *s);
72 void (*exit) (struct pcmcia_socket *s); 64 void (*exit) (struct pcmcia_socket *s);
73}; 65};
@@ -146,6 +138,8 @@ void pcmcia_put_socket(struct pcmcia_socket *skt);
146/* ds.c */ 138/* ds.c */
147extern struct bus_type pcmcia_bus_type; 139extern struct bus_type pcmcia_bus_type;
148 140
141struct pcmcia_device;
142
149/* pcmcia_resource.c */ 143/* pcmcia_resource.c */
150extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); 144extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
151extern int pcmcia_validate_mem(struct pcmcia_socket *s); 145extern int pcmcia_validate_mem(struct pcmcia_socket *s);
@@ -188,34 +182,4 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function,
188 182
189int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); 183int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple);
190 184
191
192#ifdef CONFIG_PCMCIA_IOCTL
193/* ds.c */
194extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev);
195extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
196
197struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
198 unsigned int function);
199
200/* pcmcia_ioctl.c */
201extern void __init pcmcia_setup_ioctl(void);
202extern void __exit pcmcia_cleanup_ioctl(void);
203extern void handle_event(struct pcmcia_socket *s, event_t event);
204extern int handle_request(struct pcmcia_socket *s, event_t event);
205
206#else /* CONFIG_PCMCIA_IOCTL */
207
208static inline void __init pcmcia_setup_ioctl(void) { return; }
209static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
210static inline void handle_event(struct pcmcia_socket *s, event_t event)
211{
212 return;
213}
214static inline int handle_request(struct pcmcia_socket *s, event_t event)
215{
216 return 0;
217}
218
219#endif /* CONFIG_PCMCIA_IOCTL */
220
221#endif /* _LINUX_CS_INTERNAL_H */ 185#endif /* _LINUX_CS_INTERNAL_H */
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index eac961463be2..d2ec45848413 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -213,7 +213,7 @@ EXPORT_SYMBOL(pcmcia_unregister_driver);
213 213
214/* pcmcia_device handling */ 214/* pcmcia_device handling */
215 215
216struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) 216static struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
217{ 217{
218 struct device *tmp_dev; 218 struct device *tmp_dev;
219 tmp_dev = get_device(&p_dev->dev); 219 tmp_dev = get_device(&p_dev->dev);
@@ -222,7 +222,7 @@ struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev)
222 return to_pcmcia_dev(tmp_dev); 222 return to_pcmcia_dev(tmp_dev);
223} 223}
224 224
225void pcmcia_put_dev(struct pcmcia_device *p_dev) 225static void pcmcia_put_dev(struct pcmcia_device *p_dev)
226{ 226{
227 if (p_dev) 227 if (p_dev)
228 put_device(&p_dev->dev); 228 put_device(&p_dev->dev);
@@ -477,7 +477,8 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
477} 477}
478 478
479 479
480struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) 480static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s,
481 unsigned int function)
481{ 482{
482 struct pcmcia_device *p_dev, *tmp_dev; 483 struct pcmcia_device *p_dev, *tmp_dev;
483 int i; 484 int i;
@@ -885,14 +886,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv)
885 } 886 }
886 mutex_unlock(&p_drv->dynids.lock); 887 mutex_unlock(&p_drv->dynids.lock);
887 888
888#ifdef CONFIG_PCMCIA_IOCTL
889 /* matching by cardmgr */
890 if (p_dev->cardmgr == p_drv) {
891 dev_dbg(dev, "cardmgr matched to %s\n", drv->name);
892 return 1;
893 }
894#endif
895
896 while (did && did->match_flags) { 889 while (did && did->match_flags) {
897 dev_dbg(dev, "trying to match to %s\n", drv->name); 890 dev_dbg(dev, "trying to match to %s\n", drv->name);
898 if (pcmcia_devmatch(p_dev, did)) { 891 if (pcmcia_devmatch(p_dev, did)) {
@@ -1245,7 +1238,6 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1245 case CS_EVENT_CARD_REMOVAL: 1238 case CS_EVENT_CARD_REMOVAL:
1246 atomic_set(&skt->present, 0); 1239 atomic_set(&skt->present, 0);
1247 pcmcia_card_remove(skt, NULL); 1240 pcmcia_card_remove(skt, NULL);
1248 handle_event(skt, event);
1249 mutex_lock(&s->ops_mutex); 1241 mutex_lock(&s->ops_mutex);
1250 destroy_cis_cache(s); 1242 destroy_cis_cache(s);
1251 pcmcia_cleanup_irq(s); 1243 pcmcia_cleanup_irq(s);
@@ -1259,7 +1251,6 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1259 destroy_cis_cache(s); /* to be on the safe side... */ 1251 destroy_cis_cache(s); /* to be on the safe side... */
1260 mutex_unlock(&s->ops_mutex); 1252 mutex_unlock(&s->ops_mutex);
1261 pcmcia_card_add(skt); 1253 pcmcia_card_add(skt);
1262 handle_event(skt, event);
1263 break; 1254 break;
1264 1255
1265 case CS_EVENT_EJECTION_REQUEST: 1256 case CS_EVENT_EJECTION_REQUEST:
@@ -1280,14 +1271,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1280 ds_event(skt, CS_EVENT_CARD_INSERTION, 1271 ds_event(skt, CS_EVENT_CARD_INSERTION,
1281 CS_EVENT_PRI_LOW); 1272 CS_EVENT_PRI_LOW);
1282 } 1273 }
1283 handle_event(skt, event);
1284 break; 1274 break;
1285 1275
1286 case CS_EVENT_PM_SUSPEND: 1276 case CS_EVENT_PM_SUSPEND:
1287 case CS_EVENT_RESET_PHYSICAL: 1277 case CS_EVENT_RESET_PHYSICAL:
1288 case CS_EVENT_CARD_RESET: 1278 case CS_EVENT_CARD_RESET:
1289 default: 1279 default:
1290 handle_event(skt, event);
1291 break; 1280 break;
1292 } 1281 }
1293 1282
@@ -1350,9 +1339,6 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev,
1350 return ret; 1339 return ret;
1351 } 1340 }
1352 1341
1353#ifdef CONFIG_PCMCIA_IOCTL
1354 init_waitqueue_head(&socket->queue);
1355#endif
1356 INIT_LIST_HEAD(&socket->devices_list); 1342 INIT_LIST_HEAD(&socket->devices_list);
1357 memset(&socket->pcmcia_state, 0, sizeof(u8)); 1343 memset(&socket->pcmcia_state, 0, sizeof(u8));
1358 socket->device_count = 0; 1344 socket->device_count = 0;
@@ -1429,8 +1415,6 @@ static int __init init_pcmcia_bus(void)
1429 return ret; 1415 return ret;
1430 } 1416 }
1431 1417
1432 pcmcia_setup_ioctl();
1433
1434 return 0; 1418 return 0;
1435} 1419}
1436fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that 1420fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
@@ -1439,8 +1423,6 @@ fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that
1439 1423
1440static void __exit exit_pcmcia_bus(void) 1424static void __exit exit_pcmcia_bus(void)
1441{ 1425{
1442 pcmcia_cleanup_ioctl();
1443
1444 class_interface_unregister(&pcmcia_bus_interface); 1426 class_interface_unregister(&pcmcia_bus_interface);
1445 1427
1446 bus_unregister(&pcmcia_bus_type); 1428 bus_unregister(&pcmcia_bus_type);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
deleted file mode 100644
index d007a2a03830..000000000000
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ /dev/null
@@ -1,1077 +0,0 @@
1/*
2 * pcmcia_ioctl.c -- ioctl interface for cardmgr and cardctl
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * The initial developer of the original code is David A. Hinds
9 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
10 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
11 *
12 * (C) 1999 David A. Hinds
13 * (C) 2003 - 2004 Dominik Brodowski
14 */
15
16/*
17 * This file will go away soon.
18 */
19
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/init.h>
24#include <linux/major.h>
25#include <linux/errno.h>
26#include <linux/ioctl.h>
27#include <linux/proc_fs.h>
28#include <linux/poll.h>
29#include <linux/pci.h>
30#include <linux/slab.h>
31#include <linux/seq_file.h>
32#include <linux/smp_lock.h>
33#include <linux/workqueue.h>
34
35#include <pcmcia/cs_types.h>
36#include <pcmcia/cs.h>
37#include <pcmcia/cistpl.h>
38#include <pcmcia/cisreg.h>
39#include <pcmcia/ds.h>
40#include <pcmcia/ss.h>
41
42#include "cs_internal.h"
43
44static int major_dev = -1;
45
46
47/* Device user information */
48#define MAX_EVENTS 32
49#define USER_MAGIC 0x7ea4
50#define CHECK_USER(u) \
51 (((u) == NULL) || ((u)->user_magic != USER_MAGIC))
52
53typedef struct user_info_t {
54 u_int user_magic;
55 int event_head, event_tail;
56 event_t event[MAX_EVENTS];
57 struct user_info_t *next;
58 struct pcmcia_socket *socket;
59} user_info_t;
60
61
62static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
63 unsigned int function)
64{
65 struct pcmcia_device *p_dev = NULL;
66
67 mutex_lock(&s->ops_mutex);
68 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
69 if (p_dev->func == function) {
70 mutex_unlock(&s->ops_mutex);
71 return pcmcia_get_dev(p_dev);
72 }
73 }
74 mutex_unlock(&s->ops_mutex);
75 return NULL;
76}
77
78/* backwards-compatible accessing of driver --- by name! */
79
80static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
81{
82 struct device_driver *drv;
83 struct pcmcia_driver *p_drv;
84
85 drv = driver_find((char *) dev_info, &pcmcia_bus_type);
86 if (!drv)
87 return NULL;
88
89 p_drv = container_of(drv, struct pcmcia_driver, drv);
90
91 return p_drv;
92}
93
94
95#ifdef CONFIG_PROC_FS
96static struct proc_dir_entry *proc_pccard;
97
98static int proc_read_drivers_callback(struct device_driver *driver, void *_m)
99{
100 struct seq_file *m = _m;
101 struct pcmcia_driver *p_drv = container_of(driver,
102 struct pcmcia_driver, drv);
103
104 seq_printf(m, "%-24.24s 1 %d\n", p_drv->drv.name,
105#ifdef CONFIG_MODULE_UNLOAD
106 (p_drv->owner) ? module_refcount(p_drv->owner) : 1
107#else
108 1
109#endif
110 );
111 return 0;
112}
113
114static int pccard_drivers_proc_show(struct seq_file *m, void *v)
115{
116 return bus_for_each_drv(&pcmcia_bus_type, NULL,
117 m, proc_read_drivers_callback);
118}
119
120static int pccard_drivers_proc_open(struct inode *inode, struct file *file)
121{
122 return single_open(file, pccard_drivers_proc_show, NULL);
123}
124
125static const struct file_operations pccard_drivers_proc_fops = {
126 .owner = THIS_MODULE,
127 .open = pccard_drivers_proc_open,
128 .read = seq_read,
129 .llseek = seq_lseek,
130 .release = single_release,
131};
132#endif
133
134
135#ifdef CONFIG_PCMCIA_PROBE
136
137static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
138{
139 int irq;
140 u32 mask;
141
142 irq = adj->resource.irq.IRQ;
143 if ((irq < 0) || (irq > 15))
144 return -EINVAL;
145
146 if (adj->Action != REMOVE_MANAGED_RESOURCE)
147 return 0;
148
149 mask = 1 << irq;
150
151 if (!(s->irq_mask & mask))
152 return 0;
153
154 s->irq_mask &= ~mask;
155
156 return 0;
157}
158
159#else
160
161static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
162{
163 return 0;
164}
165
166#endif
167
168static int pcmcia_adjust_resource_info(adjust_t *adj)
169{
170 struct pcmcia_socket *s;
171 int ret = -ENOSYS;
172
173 down_read(&pcmcia_socket_list_rwsem);
174 list_for_each_entry(s, &pcmcia_socket_list, socket_list) {
175
176 if (adj->Resource == RES_IRQ)
177 ret = adjust_irq(s, adj);
178
179 else if (s->resource_ops->add_io) {
180 unsigned long begin, end;
181
182 /* you can't use the old interface if the new
183 * one was used before */
184 mutex_lock(&s->ops_mutex);
185 if ((s->resource_setup_new) &&
186 !(s->resource_setup_old)) {
187 mutex_unlock(&s->ops_mutex);
188 continue;
189 } else if (!(s->resource_setup_old))
190 s->resource_setup_old = 1;
191
192 switch (adj->Resource) {
193 case RES_MEMORY_RANGE:
194 begin = adj->resource.memory.Base;
195 end = adj->resource.memory.Base + adj->resource.memory.Size - 1;
196 if (s->resource_ops->add_mem)
197 ret = s->resource_ops->add_mem(s, adj->Action, begin, end);
198 case RES_IO_RANGE:
199 begin = adj->resource.io.BasePort;
200 end = adj->resource.io.BasePort + adj->resource.io.NumPorts - 1;
201 if (s->resource_ops->add_io)
202 ret = s->resource_ops->add_io(s, adj->Action, begin, end);
203 }
204 if (!ret) {
205 /* as there's no way we know this is the
206 * last call to adjust_resource_info, we
207 * always need to assume this is the latest
208 * one... */
209 s->resource_setup_done = 1;
210 }
211 mutex_unlock(&s->ops_mutex);
212 }
213 }
214 up_read(&pcmcia_socket_list_rwsem);
215
216 return ret;
217}
218
219
220/** pcmcia_get_window
221 */
222static int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *wh_out,
223 window_handle_t wh, win_req_t *req)
224{
225 pccard_mem_map *win;
226 window_handle_t w;
227
228 wh--;
229 if (!s || !(s->state & SOCKET_PRESENT))
230 return -ENODEV;
231 if (wh >= MAX_WIN)
232 return -EINVAL;
233 for (w = wh; w < MAX_WIN; w++)
234 if (s->state & SOCKET_WIN_REQ(w))
235 break;
236 if (w == MAX_WIN)
237 return -EINVAL;
238 win = &s->win[w];
239 req->Base = win->res->start;
240 req->Size = win->res->end - win->res->start + 1;
241 req->AccessSpeed = win->speed;
242 req->Attributes = 0;
243 if (win->flags & MAP_ATTRIB)
244 req->Attributes |= WIN_MEMORY_TYPE_AM;
245 if (win->flags & MAP_ACTIVE)
246 req->Attributes |= WIN_ENABLE;
247 if (win->flags & MAP_16BIT)
248 req->Attributes |= WIN_DATA_WIDTH_16;
249 if (win->flags & MAP_USE_WAIT)
250 req->Attributes |= WIN_USE_WAIT;
251
252 *wh_out = w + 1;
253 return 0;
254} /* pcmcia_get_window */
255
256
257/** pcmcia_get_mem_page
258 *
259 * Change the card address of an already open memory window.
260 */
261static int pcmcia_get_mem_page(struct pcmcia_socket *skt, window_handle_t wh,
262 memreq_t *req)
263{
264 wh--;
265 if (wh >= MAX_WIN)
266 return -EINVAL;
267
268 req->Page = 0;
269 req->CardOffset = skt->win[wh].card_start;
270 return 0;
271} /* pcmcia_get_mem_page */
272
273
274/** pccard_get_status
275 *
276 * Get the current socket state bits. We don't support the latched
277 * SocketState yet: I haven't seen any point for it.
278 */
279
280static int pccard_get_status(struct pcmcia_socket *s,
281 struct pcmcia_device *p_dev,
282 cs_status_t *status)
283{
284 config_t *c;
285 int val;
286
287 s->ops->get_status(s, &val);
288 status->CardState = status->SocketState = 0;
289 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0;
290 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0;
291 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0;
292 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0;
293 if (s->state & SOCKET_SUSPEND)
294 status->CardState |= CS_EVENT_PM_SUSPEND;
295 if (!(s->state & SOCKET_PRESENT))
296 return -ENODEV;
297
298 c = (p_dev) ? p_dev->function_config : NULL;
299
300 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
301 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
302 u_char reg;
303 if (c->CardValues & PRESENT_PIN_REPLACE) {
304 mutex_lock(&s->ops_mutex);
305 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
306 mutex_unlock(&s->ops_mutex);
307 status->CardState |=
308 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
309 status->CardState |=
310 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0;
311 status->CardState |=
312 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0;
313 status->CardState |=
314 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0;
315 } else {
316 /* No PRR? Then assume we're always ready */
317 status->CardState |= CS_EVENT_READY_CHANGE;
318 }
319 if (c->CardValues & PRESENT_EXT_STATUS) {
320 mutex_lock(&s->ops_mutex);
321 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
322 mutex_unlock(&s->ops_mutex);
323 status->CardState |=
324 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
325 }
326 return 0;
327 }
328 status->CardState |=
329 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0;
330 status->CardState |=
331 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0;
332 status->CardState |=
333 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0;
334 status->CardState |=
335 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0;
336 return 0;
337} /* pccard_get_status */
338
339static int pccard_get_configuration_info(struct pcmcia_socket *s,
340 struct pcmcia_device *p_dev,
341 config_info_t *config)
342{
343 config_t *c;
344
345 if (!(s->state & SOCKET_PRESENT))
346 return -ENODEV;
347
348
349#ifdef CONFIG_CARDBUS
350 if (s->state & SOCKET_CARDBUS) {
351 memset(config, 0, sizeof(config_info_t));
352 config->Vcc = s->socket.Vcc;
353 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
354 config->Option = s->cb_dev->subordinate->number;
355 if (s->state & SOCKET_CARDBUS_CONFIG) {
356 config->Attributes = CONF_VALID_CLIENT;
357 config->IntType = INT_CARDBUS;
358 config->AssignedIRQ = s->pcmcia_irq;
359 if (config->AssignedIRQ)
360 config->Attributes |= CONF_ENABLE_IRQ;
361 if (s->io[0].res) {
362 config->BasePort1 = s->io[0].res->start;
363 config->NumPorts1 = s->io[0].res->end -
364 config->BasePort1 + 1;
365 }
366 }
367 return 0;
368 }
369#endif
370
371 if (p_dev) {
372 c = p_dev->function_config;
373 config->Function = p_dev->func;
374 } else {
375 c = NULL;
376 config->Function = 0;
377 }
378
379 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
380 config->Attributes = 0;
381 config->Vcc = s->socket.Vcc;
382 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
383 return 0;
384 }
385
386 config->Attributes = c->Attributes | CONF_VALID_CLIENT;
387 config->Vcc = s->socket.Vcc;
388 config->Vpp1 = config->Vpp2 = s->socket.Vpp;
389 config->IntType = c->IntType;
390 config->ConfigBase = c->ConfigBase;
391 config->Status = c->Status;
392 config->Pin = c->Pin;
393 config->Copy = c->Copy;
394 config->Option = c->Option;
395 config->ExtStatus = c->ExtStatus;
396 config->Present = config->CardValues = c->CardValues;
397 config->IRQAttributes = c->irq.Attributes;
398 config->AssignedIRQ = s->pcmcia_irq;
399 config->BasePort1 = c->io.BasePort1;
400 config->NumPorts1 = c->io.NumPorts1;
401 config->Attributes1 = c->io.Attributes1;
402 config->BasePort2 = c->io.BasePort2;
403 config->NumPorts2 = c->io.NumPorts2;
404 config->Attributes2 = c->io.Attributes2;
405 config->IOAddrLines = c->io.IOAddrLines;
406
407 return 0;
408} /* pccard_get_configuration_info */
409
410
411/*======================================================================
412
413 These manage a ring buffer of events pending for one user process
414
415======================================================================*/
416
417
418static int queue_empty(user_info_t *user)
419{
420 return (user->event_head == user->event_tail);
421}
422
423static event_t get_queued_event(user_info_t *user)
424{
425 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
426 return user->event[user->event_tail];
427}
428
429static void queue_event(user_info_t *user, event_t event)
430{
431 user->event_head = (user->event_head+1) % MAX_EVENTS;
432 if (user->event_head == user->event_tail)
433 user->event_tail = (user->event_tail+1) % MAX_EVENTS;
434 user->event[user->event_head] = event;
435}
436
437void handle_event(struct pcmcia_socket *s, event_t event)
438{
439 user_info_t *user;
440 for (user = s->user; user; user = user->next)
441 queue_event(user, event);
442 wake_up_interruptible(&s->queue);
443}
444
445
446/*======================================================================
447
448 bind_request() and bind_device() are merged by now. Register_client()
449 is called right at the end of bind_request(), during the driver's
450 ->attach() call. Individual descriptions:
451
452 bind_request() connects a socket to a particular client driver.
453 It looks up the specified device ID in the list of registered
454 drivers, binds it to the socket, and tries to create an instance
455 of the device. unbind_request() deletes a driver instance.
456
457 Bind_device() associates a device driver with a particular socket.
458 It is normally called by Driver Services after it has identified
459 a newly inserted card. An instance of that driver will then be
460 eligible to register as a client of this socket.
461
462 Register_client() uses the dev_info_t handle to match the
463 caller with a socket. The driver must have already been bound
464 to a socket with bind_device() -- in fact, bind_device()
465 allocates the client structure that will be used.
466
467======================================================================*/
468
469static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
470{
471 struct pcmcia_driver *p_drv;
472 struct pcmcia_device *p_dev;
473 int ret = 0;
474
475 s = pcmcia_get_socket(s);
476 if (!s)
477 return -EINVAL;
478
479 pr_debug("bind_request(%d, '%s')\n", s->sock,
480 (char *)bind_info->dev_info);
481
482 p_drv = get_pcmcia_driver(&bind_info->dev_info);
483 if (!p_drv) {
484 ret = -EINVAL;
485 goto err_put;
486 }
487
488 if (!try_module_get(p_drv->owner)) {
489 ret = -EINVAL;
490 goto err_put_driver;
491 }
492
493 mutex_lock(&s->ops_mutex);
494 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
495 if (p_dev->func == bind_info->function) {
496 if ((p_dev->dev.driver == &p_drv->drv)) {
497 if (p_dev->cardmgr) {
498 /* if there's already a device
499 * registered, and it was registered
500 * by userspace before, we need to
501 * return the "instance". */
502 mutex_unlock(&s->ops_mutex);
503 bind_info->instance = p_dev;
504 ret = -EBUSY;
505 goto err_put_module;
506 } else {
507 /* the correct driver managed to bind
508 * itself magically to the correct
509 * device. */
510 mutex_unlock(&s->ops_mutex);
511 p_dev->cardmgr = p_drv;
512 ret = 0;
513 goto err_put_module;
514 }
515 } else if (!p_dev->dev.driver) {
516 /* there's already a device available where
517 * no device has been bound to yet. So we don't
518 * need to register a device! */
519 mutex_unlock(&s->ops_mutex);
520 goto rescan;
521 }
522 }
523 }
524 mutex_unlock(&s->ops_mutex);
525
526 p_dev = pcmcia_device_add(s, bind_info->function);
527 if (!p_dev) {
528 ret = -EIO;
529 goto err_put_module;
530 }
531
532rescan:
533 p_dev->cardmgr = p_drv;
534
535 /* if a driver is already running, we can abort */
536 if (p_dev->dev.driver)
537 goto err_put_module;
538
539 /*
540 * Prevent this racing with a card insertion.
541 */
542 mutex_lock(&s->skt_mutex);
543 ret = bus_rescan_devices(&pcmcia_bus_type);
544 mutex_unlock(&s->skt_mutex);
545 if (ret)
546 goto err_put_module;
547
548 /* check whether the driver indeed matched. I don't care if this
549 * is racy or not, because it can only happen on cardmgr access
550 * paths...
551 */
552 if (!(p_dev->dev.driver == &p_drv->drv))
553 p_dev->cardmgr = NULL;
554
555 err_put_module:
556 module_put(p_drv->owner);
557 err_put_driver:
558 put_driver(&p_drv->drv);
559 err_put:
560 pcmcia_put_socket(s);
561
562 return ret;
563} /* bind_request */
564
565#ifdef CONFIG_CARDBUS
566
567static struct pci_bus *pcmcia_lookup_bus(struct pcmcia_socket *s)
568{
569 if (!s || !(s->state & SOCKET_CARDBUS))
570 return NULL;
571
572 return s->cb_dev->subordinate;
573}
574#endif
575
576static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int first)
577{
578 struct pcmcia_device *p_dev;
579 struct pcmcia_driver *p_drv;
580 int ret = 0;
581
582#ifdef CONFIG_CARDBUS
583 /*
584 * Some unbelievably ugly code to associate the PCI cardbus
585 * device and its driver with the PCMCIA "bind" information.
586 */
587 {
588 struct pci_bus *bus;
589
590 bus = pcmcia_lookup_bus(s);
591 if (bus) {
592 struct list_head *list;
593 struct pci_dev *dev = NULL;
594
595 list = bus->devices.next;
596 while (list != &bus->devices) {
597 struct pci_dev *pdev = pci_dev_b(list);
598 list = list->next;
599
600 if (first) {
601 dev = pdev;
602 break;
603 }
604
605 /* Try to handle "next" here some way? */
606 }
607 if (dev && dev->driver) {
608 strlcpy(bind_info->name, dev->driver->name, DEV_NAME_LEN);
609 bind_info->major = 0;
610 bind_info->minor = 0;
611 bind_info->next = NULL;
612 return 0;
613 }
614 }
615 }
616#endif
617
618 mutex_lock(&s->ops_mutex);
619 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
620 if (p_dev->func == bind_info->function) {
621 p_dev = pcmcia_get_dev(p_dev);
622 if (!p_dev)
623 continue;
624 goto found;
625 }
626 }
627 mutex_unlock(&s->ops_mutex);
628 return -ENODEV;
629
630 found:
631 mutex_unlock(&s->ops_mutex);
632
633 p_drv = to_pcmcia_drv(p_dev->dev.driver);
634 if (p_drv && !p_dev->_locked) {
635 ret = -EAGAIN;
636 goto err_put;
637 }
638
639 if (!first) {
640 ret = -ENODEV;
641 goto err_put;
642 }
643
644 strlcpy(bind_info->name, dev_name(&p_dev->dev), DEV_NAME_LEN);
645 bind_info->next = NULL;
646
647 err_put:
648 pcmcia_put_dev(p_dev);
649 return ret;
650} /* get_device_info */
651
652
653static int ds_open(struct inode *inode, struct file *file)
654{
655 socket_t i = iminor(inode);
656 struct pcmcia_socket *s;
657 user_info_t *user;
658 static int warning_printed;
659 int ret = 0;
660
661 pr_debug("ds_open(socket %d)\n", i);
662
663 lock_kernel();
664 s = pcmcia_get_socket_by_nr(i);
665 if (!s) {
666 ret = -ENODEV;
667 goto out;
668 }
669 s = pcmcia_get_socket(s);
670 if (!s) {
671 ret = -ENODEV;
672 goto out;
673 }
674
675 if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
676 if (s->pcmcia_state.busy) {
677 pcmcia_put_socket(s);
678 ret = -EBUSY;
679 goto out;
680 }
681 else
682 s->pcmcia_state.busy = 1;
683 }
684
685 user = kmalloc(sizeof(user_info_t), GFP_KERNEL);
686 if (!user) {
687 pcmcia_put_socket(s);
688 ret = -ENOMEM;
689 goto out;
690 }
691 user->event_tail = user->event_head = 0;
692 user->next = s->user;
693 user->user_magic = USER_MAGIC;
694 user->socket = s;
695 s->user = user;
696 file->private_data = user;
697
698 if (!warning_printed) {
699 printk(KERN_INFO "pcmcia: Detected deprecated PCMCIA ioctl "
700 "usage from process: %s.\n", current->comm);
701 printk(KERN_INFO "pcmcia: This interface will soon be removed from "
702 "the kernel; please expect breakage unless you upgrade "
703 "to new tools.\n");
704 printk(KERN_INFO "pcmcia: see http://www.kernel.org/pub/linux/"
705 "utils/kernel/pcmcia/pcmcia.html for details.\n");
706 warning_printed = 1;
707 }
708
709 if (atomic_read(&s->present))
710 queue_event(user, CS_EVENT_CARD_INSERTION);
711out:
712 unlock_kernel();
713 return ret;
714} /* ds_open */
715
716/*====================================================================*/
717
718static int ds_release(struct inode *inode, struct file *file)
719{
720 struct pcmcia_socket *s;
721 user_info_t *user, **link;
722
723 pr_debug("ds_release(socket %d)\n", iminor(inode));
724
725 user = file->private_data;
726 if (CHECK_USER(user))
727 goto out;
728
729 s = user->socket;
730
731 /* Unlink user data structure */
732 if ((file->f_flags & O_ACCMODE) != O_RDONLY)
733 s->pcmcia_state.busy = 0;
734
735 file->private_data = NULL;
736 for (link = &s->user; *link; link = &(*link)->next)
737 if (*link == user)
738 break;
739 if (link == NULL)
740 goto out;
741 *link = user->next;
742 user->user_magic = 0;
743 kfree(user);
744 pcmcia_put_socket(s);
745out:
746 return 0;
747} /* ds_release */
748
749/*====================================================================*/
750
751static ssize_t ds_read(struct file *file, char __user *buf,
752 size_t count, loff_t *ppos)
753{
754 struct pcmcia_socket *s;
755 user_info_t *user;
756 int ret;
757
758 pr_debug("ds_read(socket %d)\n", iminor(file->f_path.dentry->d_inode));
759
760 if (count < 4)
761 return -EINVAL;
762
763 user = file->private_data;
764 if (CHECK_USER(user))
765 return -EIO;
766
767 s = user->socket;
768 ret = wait_event_interruptible(s->queue, !queue_empty(user));
769 if (ret == 0)
770 ret = put_user(get_queued_event(user), (int __user *)buf) ? -EFAULT : 4;
771
772 return ret;
773} /* ds_read */
774
775/*====================================================================*/
776
777static ssize_t ds_write(struct file *file, const char __user *buf,
778 size_t count, loff_t *ppos)
779{
780 pr_debug("ds_write(socket %d)\n", iminor(file->f_path.dentry->d_inode));
781
782 if (count != 4)
783 return -EINVAL;
784 if ((file->f_flags & O_ACCMODE) == O_RDONLY)
785 return -EBADF;
786
787 return -EIO;
788} /* ds_write */
789
790/*====================================================================*/
791
792/* No kernel lock - fine */
793static u_int ds_poll(struct file *file, poll_table *wait)
794{
795 struct pcmcia_socket *s;
796 user_info_t *user;
797
798 pr_debug("ds_poll(socket %d)\n", iminor(file->f_path.dentry->d_inode));
799
800 user = file->private_data;
801 if (CHECK_USER(user))
802 return POLLERR;
803 s = user->socket;
804 /*
805 * We don't check for a dead socket here since that
806 * will send cardmgr into an endless spin.
807 */
808 poll_wait(file, &s->queue, wait);
809 if (!queue_empty(user))
810 return POLLIN | POLLRDNORM;
811 return 0;
812} /* ds_poll */
813
814/*====================================================================*/
815
816static int ds_ioctl(struct file *file, u_int cmd, u_long arg)
817{
818 struct pcmcia_socket *s;
819 void __user *uarg = (char __user *)arg;
820 u_int size;
821 int ret, err;
822 ds_ioctl_arg_t *buf;
823 user_info_t *user;
824
825 pr_debug("ds_ioctl(socket %d, %#x, %#lx)\n", iminor(inode), cmd, arg);
826
827 user = file->private_data;
828 if (CHECK_USER(user))
829 return -EIO;
830
831 s = user->socket;
832
833 size = (cmd & IOCSIZE_MASK) >> IOCSIZE_SHIFT;
834 if (size > sizeof(ds_ioctl_arg_t))
835 return -EINVAL;
836
837 /* Permission check */
838 if (!(cmd & IOC_OUT) && !capable(CAP_SYS_ADMIN))
839 return -EPERM;
840
841 if (cmd & IOC_IN) {
842 if (!access_ok(VERIFY_READ, uarg, size)) {
843 pr_debug("ds_ioctl(): verify_read = %d\n", -EFAULT);
844 return -EFAULT;
845 }
846 }
847 if (cmd & IOC_OUT) {
848 if (!access_ok(VERIFY_WRITE, uarg, size)) {
849 pr_debug("ds_ioctl(): verify_write = %d\n", -EFAULT);
850 return -EFAULT;
851 }
852 }
853 buf = kmalloc(sizeof(ds_ioctl_arg_t), GFP_KERNEL);
854 if (!buf)
855 return -ENOMEM;
856
857 err = ret = 0;
858
859 if (cmd & IOC_IN) {
860 if (__copy_from_user((char *)buf, uarg, size)) {
861 err = -EFAULT;
862 goto free_out;
863 }
864 }
865
866 switch (cmd) {
867 case DS_ADJUST_RESOURCE_INFO:
868 ret = pcmcia_adjust_resource_info(&buf->adjust);
869 break;
870 case DS_GET_CONFIGURATION_INFO:
871 if (buf->config.Function &&
872 (buf->config.Function >= s->functions))
873 ret = -EINVAL;
874 else {
875 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
876 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
877 pcmcia_put_dev(p_dev);
878 }
879 break;
880 case DS_GET_FIRST_TUPLE:
881 mutex_lock(&s->skt_mutex);
882 pcmcia_validate_mem(s);
883 mutex_unlock(&s->skt_mutex);
884 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
885 break;
886 case DS_GET_NEXT_TUPLE:
887 ret = pccard_get_next_tuple(s, BIND_FN_ALL, &buf->tuple);
888 break;
889 case DS_GET_TUPLE_DATA:
890 buf->tuple.TupleData = buf->tuple_parse.data;
891 buf->tuple.TupleDataMax = sizeof(buf->tuple_parse.data);
892 ret = pccard_get_tuple_data(s, &buf->tuple);
893 break;
894 case DS_PARSE_TUPLE:
895 buf->tuple.TupleData = buf->tuple_parse.data;
896 ret = pcmcia_parse_tuple(&buf->tuple, &buf->tuple_parse.parse);
897 break;
898 case DS_RESET_CARD:
899 ret = pcmcia_reset_card(s);
900 break;
901 case DS_GET_STATUS:
902 if (buf->status.Function &&
903 (buf->status.Function >= s->functions))
904 ret = -EINVAL;
905 else {
906 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
907 ret = pccard_get_status(s, p_dev, &buf->status);
908 pcmcia_put_dev(p_dev);
909 }
910 break;
911 case DS_VALIDATE_CIS:
912 mutex_lock(&s->skt_mutex);
913 pcmcia_validate_mem(s);
914 mutex_unlock(&s->skt_mutex);
915 ret = pccard_validate_cis(s, &buf->cisinfo.Chains);
916 break;
917 case DS_SUSPEND_CARD:
918 pcmcia_parse_uevents(s, PCMCIA_UEVENT_SUSPEND);
919 break;
920 case DS_RESUME_CARD:
921 pcmcia_parse_uevents(s, PCMCIA_UEVENT_RESUME);
922 break;
923 case DS_EJECT_CARD:
924 pcmcia_parse_uevents(s, PCMCIA_UEVENT_EJECT);
925 break;
926 case DS_INSERT_CARD:
927 pcmcia_parse_uevents(s, PCMCIA_UEVENT_INSERT);
928 break;
929 case DS_ACCESS_CONFIGURATION_REGISTER:
930 if ((buf->conf_reg.Action == CS_WRITE) && !capable(CAP_SYS_ADMIN)) {
931 err = -EPERM;
932 goto free_out;
933 }
934
935 ret = -EINVAL;
936
937 if (!(buf->conf_reg.Function &&
938 (buf->conf_reg.Function >= s->functions))) {
939 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
940 if (p_dev) {
941 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
942 pcmcia_put_dev(p_dev);
943 }
944 }
945 break;
946 case DS_GET_FIRST_REGION:
947 case DS_GET_NEXT_REGION:
948 case DS_BIND_MTD:
949 if (!capable(CAP_SYS_ADMIN)) {
950 err = -EPERM;
951 goto free_out;
952 } else {
953 printk_once(KERN_WARNING
954 "2.6. kernels use pcmciamtd instead of memory_cs.c and do not require special\n");
955 printk_once(KERN_WARNING "MTD handling any more.\n");
956 }
957 err = -EINVAL;
958 goto free_out;
959 break;
960 case DS_GET_FIRST_WINDOW:
961 ret = pcmcia_get_window(s, &buf->win_info.handle, 1,
962 &buf->win_info.window);
963 break;
964 case DS_GET_NEXT_WINDOW:
965 ret = pcmcia_get_window(s, &buf->win_info.handle,
966 buf->win_info.handle + 1, &buf->win_info.window);
967 break;
968 case DS_GET_MEM_PAGE:
969 ret = pcmcia_get_mem_page(s, buf->win_info.handle,
970 &buf->win_info.map);
971 break;
972 case DS_REPLACE_CIS:
973 ret = pcmcia_replace_cis(s, buf->cisdump.Data, buf->cisdump.Length);
974 break;
975 case DS_BIND_REQUEST:
976 if (!capable(CAP_SYS_ADMIN)) {
977 err = -EPERM;
978 goto free_out;
979 }
980 err = bind_request(s, &buf->bind_info);
981 break;
982 case DS_GET_DEVICE_INFO:
983 err = get_device_info(s, &buf->bind_info, 1);
984 break;
985 case DS_GET_NEXT_DEVICE:
986 err = get_device_info(s, &buf->bind_info, 0);
987 break;
988 case DS_UNBIND_REQUEST:
989 err = 0;
990 break;
991 default:
992 err = -EINVAL;
993 }
994
995 if ((err == 0) && (ret != 0)) {
996 pr_debug("ds_ioctl: ret = %d\n", ret);
997 switch (ret) {
998 case -ENODEV:
999 case -EINVAL:
1000 case -EBUSY:
1001 case -ENOSYS:
1002 err = ret;
1003 break;
1004 case -ENOMEM:
1005 err = -ENOSPC; break;
1006 case -ENOSPC:
1007 err = -ENODATA; break;
1008 default:
1009 err = -EIO; break;
1010 }
1011 }
1012
1013 if (cmd & IOC_OUT) {
1014 if (__copy_to_user(uarg, (char *)buf, size))
1015 err = -EFAULT;
1016 }
1017
1018free_out:
1019 kfree(buf);
1020 return err;
1021} /* ds_ioctl */
1022
1023static long ds_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1024{
1025 int ret;
1026
1027 lock_kernel();
1028 ret = ds_ioctl(file, cmd, arg);
1029 unlock_kernel();
1030
1031 return ret;
1032}
1033
1034
1035/*====================================================================*/
1036
1037static const struct file_operations ds_fops = {
1038 .owner = THIS_MODULE,
1039 .open = ds_open,
1040 .release = ds_release,
1041 .unlocked_ioctl = ds_unlocked_ioctl,
1042 .read = ds_read,
1043 .write = ds_write,
1044 .poll = ds_poll,
1045};
1046
1047void __init pcmcia_setup_ioctl(void)
1048{
1049 int i;
1050
1051 /* Set up character device for user mode clients */
1052 i = register_chrdev(0, "pcmcia", &ds_fops);
1053 if (i < 0)
1054 printk(KERN_NOTICE "unable to find a free device # for "
1055 "Driver Services (error=%d)\n", i);
1056 else
1057 major_dev = i;
1058
1059#ifdef CONFIG_PROC_FS
1060 proc_pccard = proc_mkdir("bus/pccard", NULL);
1061 if (proc_pccard)
1062 proc_create("drivers", 0, proc_pccard, &pccard_drivers_proc_fops);
1063#endif
1064}
1065
1066
1067void __exit pcmcia_cleanup_ioctl(void)
1068{
1069#ifdef CONFIG_PROC_FS
1070 if (proc_pccard) {
1071 remove_proc_entry("drivers", proc_pccard);
1072 remove_proc_entry("bus/pccard", NULL);
1073 }
1074#endif
1075 if (major_dev != -1)
1076 unregister_chrdev(major_dev, "pcmcia");
1077}
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c
index d0bf35021065..6ed7bf171ca3 100644
--- a/drivers/pcmcia/rsrc_iodyn.c
+++ b/drivers/pcmcia/rsrc_iodyn.c
@@ -164,8 +164,6 @@ struct pccard_resource_ops pccard_iodyn_ops = {
164 .validate_mem = NULL, 164 .validate_mem = NULL,
165 .find_io = iodyn_find_io, 165 .find_io = iodyn_find_io,
166 .find_mem = NULL, 166 .find_mem = NULL,
167 .add_io = NULL,
168 .add_mem = NULL,
169 .init = static_init, 167 .init = static_init,
170 .exit = NULL, 168 .exit = NULL,
171}; 169};
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 142efac3c387..b12ecf7c32bf 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -62,8 +62,6 @@ struct pccard_resource_ops pccard_static_ops = {
62 .validate_mem = NULL, 62 .validate_mem = NULL,
63 .find_io = static_find_io, 63 .find_io = static_find_io,
64 .find_mem = NULL, 64 .find_mem = NULL,
65 .add_io = NULL,
66 .add_mem = NULL,
67 .init = static_init, 65 .init = static_init,
68 .exit = NULL, 66 .exit = NULL,
69}; 67};
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index dcd1a4ad3d63..d217dc1d426b 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -1055,8 +1055,6 @@ struct pccard_resource_ops pccard_nonstatic_ops = {
1055 .validate_mem = pcmcia_nonstatic_validate_mem, 1055 .validate_mem = pcmcia_nonstatic_validate_mem,
1056 .find_io = nonstatic_find_io, 1056 .find_io = nonstatic_find_io,
1057 .find_mem = nonstatic_find_mem_region, 1057 .find_mem = nonstatic_find_mem_region,
1058 .add_io = adjust_io,
1059 .add_mem = adjust_memory,
1060 .init = nonstatic_init, 1058 .init = nonstatic_init,
1061 .exit = nonstatic_release_resource_db, 1059 .exit = nonstatic_release_resource_db,
1062}; 1060};
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index c180165fbd3e..7d7721e86032 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -117,11 +117,6 @@ struct pcmcia_device {
117 u64 dma_mask; 117 u64 dma_mask;
118 struct device dev; 118 struct device dev;
119 119
120#ifdef CONFIG_PCMCIA_IOCTL
121 /* device driver wanted by cardmgr */
122 struct pcmcia_driver *cardmgr;
123#endif
124
125 /* data private to drivers */ 120 /* data private to drivers */
126 void *priv; 121 void *priv;
127}; 122};
@@ -211,208 +206,4 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev);
211 206
212#endif /* __KERNEL__ */ 207#endif /* __KERNEL__ */
213 208
214
215
216/* Below, there are only definitions which are used by
217 * - the PCMCIA ioctl
218 * - deprecated PCMCIA userspace tools only
219 *
220 * here be dragons ... here be dragons ... here be dragons ... here be drag
221 */
222
223#if defined(CONFIG_PCMCIA_IOCTL) || !defined(__KERNEL__)
224
225#if defined(__arm__) || defined(__mips__) || defined(__avr32__) || \
226 defined(__bfin__)
227/* This (ioaddr_t) is exposed to userspace & hence cannot be changed. */
228typedef u_int ioaddr_t;
229#else
230typedef u_short ioaddr_t;
231#endif
232
233/* for AdjustResourceInfo */
234typedef struct adjust_t {
235 u_int Action;
236 u_int Resource;
237 u_int Attributes;
238 union {
239 struct memory {
240 u_long Base;
241 u_long Size;
242 } memory;
243 struct io {
244 ioaddr_t BasePort;
245 ioaddr_t NumPorts;
246 u_int IOAddrLines;
247 } io;
248 struct irq {
249 u_int IRQ;
250 } irq;
251 } resource;
252} adjust_t;
253
254/* Action field */
255#define REMOVE_MANAGED_RESOURCE 1
256#define ADD_MANAGED_RESOURCE 2
257#define GET_FIRST_MANAGED_RESOURCE 3
258#define GET_NEXT_MANAGED_RESOURCE 4
259/* Resource field */
260#define RES_MEMORY_RANGE 1
261#define RES_IO_RANGE 2
262#define RES_IRQ 3
263/* Attribute field */
264#define RES_IRQ_TYPE 0x03
265#define RES_IRQ_TYPE_EXCLUSIVE 0
266#define RES_IRQ_TYPE_TIME 1
267#define RES_IRQ_TYPE_DYNAMIC 2
268#define RES_IRQ_CSC 0x04
269#define RES_SHARED 0x08
270#define RES_RESERVED 0x10
271#define RES_ALLOCATED 0x20
272#define RES_REMOVED 0x40
273
274
275typedef struct tuple_parse_t {
276 tuple_t tuple;
277 cisdata_t data[255];
278 cisparse_t parse;
279} tuple_parse_t;
280
281typedef struct win_info_t {
282 window_handle_t handle;
283 win_req_t window;
284 memreq_t map;
285} win_info_t;
286
287typedef struct bind_info_t {
288 dev_info_t dev_info;
289 u_char function;
290 struct pcmcia_device *instance;
291 char name[DEV_NAME_LEN];
292 u_short major, minor;
293 void *next;
294} bind_info_t;
295
296typedef struct mtd_info_t {
297 dev_info_t dev_info;
298 u_int Attributes;
299 u_int CardOffset;
300} mtd_info_t;
301
302typedef struct region_info_t {
303 u_int Attributes;
304 u_int CardOffset;
305 u_int RegionSize;
306 u_int AccessSpeed;
307 u_int BlockSize;
308 u_int PartMultiple;
309 u_char JedecMfr, JedecInfo;
310 memory_handle_t next;
311} region_info_t;
312
313#define REGION_TYPE 0x0001
314#define REGION_TYPE_CM 0x0000
315#define REGION_TYPE_AM 0x0001
316#define REGION_PREFETCH 0x0008
317#define REGION_CACHEABLE 0x0010
318#define REGION_BAR_MASK 0xe000
319#define REGION_BAR_SHIFT 13
320
321/* For ReplaceCIS */
322typedef struct cisdump_t {
323 u_int Length;
324 cisdata_t Data[CISTPL_MAX_CIS_SIZE];
325} cisdump_t;
326
327/* for GetConfigurationInfo */
328typedef struct config_info_t {
329 u_char Function;
330 u_int Attributes;
331 u_int Vcc, Vpp1, Vpp2;
332 u_int IntType;
333 u_int ConfigBase;
334 u_char Status, Pin, Copy, Option, ExtStatus;
335 u_int Present;
336 u_int CardValues;
337 u_int AssignedIRQ;
338 u_int IRQAttributes;
339 ioaddr_t BasePort1;
340 ioaddr_t NumPorts1;
341 u_int Attributes1;
342 ioaddr_t BasePort2;
343 ioaddr_t NumPorts2;
344 u_int Attributes2;
345 u_int IOAddrLines;
346} config_info_t;
347
348/* For ValidateCIS */
349typedef struct cisinfo_t {
350 u_int Chains;
351} cisinfo_t;
352
353typedef struct cs_status_t {
354 u_char Function;
355 event_t CardState;
356 event_t SocketState;
357} cs_status_t;
358
359typedef union ds_ioctl_arg_t {
360 adjust_t adjust;
361 config_info_t config;
362 tuple_t tuple;
363 tuple_parse_t tuple_parse;
364 client_req_t client_req;
365 cs_status_t status;
366 conf_reg_t conf_reg;
367 cisinfo_t cisinfo;
368 region_info_t region;
369 bind_info_t bind_info;
370 mtd_info_t mtd_info;
371 win_info_t win_info;
372 cisdump_t cisdump;
373} ds_ioctl_arg_t;
374
375#define DS_ADJUST_RESOURCE_INFO _IOWR('d', 2, adjust_t)
376#define DS_GET_CONFIGURATION_INFO _IOWR('d', 3, config_info_t)
377#define DS_GET_FIRST_TUPLE _IOWR('d', 4, tuple_t)
378#define DS_GET_NEXT_TUPLE _IOWR('d', 5, tuple_t)
379#define DS_GET_TUPLE_DATA _IOWR('d', 6, tuple_parse_t)
380#define DS_PARSE_TUPLE _IOWR('d', 7, tuple_parse_t)
381#define DS_RESET_CARD _IO ('d', 8)
382#define DS_GET_STATUS _IOWR('d', 9, cs_status_t)
383#define DS_ACCESS_CONFIGURATION_REGISTER _IOWR('d', 10, conf_reg_t)
384#define DS_VALIDATE_CIS _IOR ('d', 11, cisinfo_t)
385#define DS_SUSPEND_CARD _IO ('d', 12)
386#define DS_RESUME_CARD _IO ('d', 13)
387#define DS_EJECT_CARD _IO ('d', 14)
388#define DS_INSERT_CARD _IO ('d', 15)
389#define DS_GET_FIRST_REGION _IOWR('d', 16, region_info_t)
390#define DS_GET_NEXT_REGION _IOWR('d', 17, region_info_t)
391#define DS_REPLACE_CIS _IOWR('d', 18, cisdump_t)
392#define DS_GET_FIRST_WINDOW _IOR ('d', 19, win_info_t)
393#define DS_GET_NEXT_WINDOW _IOWR('d', 20, win_info_t)
394#define DS_GET_MEM_PAGE _IOWR('d', 21, win_info_t)
395
396#define DS_BIND_REQUEST _IOWR('d', 60, bind_info_t)
397#define DS_GET_DEVICE_INFO _IOWR('d', 61, bind_info_t)
398#define DS_GET_NEXT_DEVICE _IOWR('d', 62, bind_info_t)
399#define DS_UNBIND_REQUEST _IOW ('d', 63, bind_info_t)
400#define DS_BIND_MTD _IOWR('d', 64, mtd_info_t)
401
402
403/* used in userspace only */
404#define CS_IN_USE 0x1e
405
406#define INFO_MASTER_CLIENT 0x01
407#define INFO_IO_CLIENT 0x02
408#define INFO_MTD_CLIENT 0x04
409#define INFO_MEM_CLIENT 0x08
410#define MAX_NUM_CLIENTS 3
411
412#define INFO_CARD_SHARE 0x10
413#define INFO_CARD_EXCL 0x20
414
415
416#endif /* !defined(__KERNEL__) || defined(CONFIG_PCMCIA_IOCTL) */
417
418#endif /* _LINUX_DS_H */ 209#endif /* _LINUX_DS_H */
diff --git a/include/pcmcia/ss.h b/include/pcmcia/ss.h
index 764281b29218..66740b764da7 100644
--- a/include/pcmcia/ss.h
+++ b/include/pcmcia/ss.h
@@ -220,12 +220,10 @@ struct pcmcia_socket {
220 220
221 /* 16-bit state: */ 221 /* 16-bit state: */
222 struct { 222 struct {
223 /* "master" ioctl is used */
224 u8 busy:1;
225 /* the PCMCIA card consists of two pseudo devices */ 223 /* the PCMCIA card consists of two pseudo devices */
226 u8 has_pfc:1; 224 u8 has_pfc:1;
227 225
228 u8 reserved:6; 226 u8 reserved:7;
229 } pcmcia_state; 227 } pcmcia_state;
230 228
231 /* non-zero if PCMCIA card is present */ 229 /* non-zero if PCMCIA card is present */
@@ -234,10 +232,6 @@ struct pcmcia_socket {
234 /* IRQ to be used by PCMCIA devices. May not be IRQ 0. */ 232 /* IRQ to be used by PCMCIA devices. May not be IRQ 0. */
235 unsigned int pcmcia_irq; 233 unsigned int pcmcia_irq;
236 234
237#ifdef CONFIG_PCMCIA_IOCTL
238 struct user_info_t *user;
239 wait_queue_head_t queue;
240#endif /* CONFIG_PCMCIA_IOCTL */
241#endif /* CONFIG_PCMCIA */ 235#endif /* CONFIG_PCMCIA */
242 236
243 /* socket device */ 237 /* socket device */