diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 15:25:06 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-06 15:25:06 -0400 |
commit | 1685e633b396b0f3dabbc9fa5d65dfefe6435250 (patch) | |
tree | ee83e26e2468ca1518a1b065c690159e12c8def9 /drivers/pcmcia | |
parent | 1cfd2bda8c486ae0e7a8005354758ebb68172bca (diff) | |
parent | 127c03cdbad9bd5af5d7f33bd31a1015a90cb77f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6:
pcmcia: avoid buffer overflow in pcmcia_setup_isa_irq
pcmcia: do not request windows if you don't need to
pcmcia: insert PCMCIA device resources into resource tree
pcmcia: export resource information to sysfs
pcmcia: use struct resource for PCMCIA devices, part 2
pcmcia: remove memreq_t
pcmcia: move local definitions out of include/pcmcia/cs.h
pcmcia: do not use io_req_t when calling pcmcia_request_io()
pcmcia: do not use io_req_t after call to pcmcia_request_io()
pcmcia: use struct resource for PCMCIA devices
pcmcia: clean up cs.h
pcmcia: use pcmica_{read,write}_config_byte
pcmcia: remove cs_types.h
pcmcia: remove unused flag, simplify headers
pcmcia: remove obsolete CS_EVENT_ definitions
pcmcia: split up central event handler
pcmcia: simplify event callback
pcmcia: remove obsolete ioctl
Conflicts in:
- drivers/staging/comedi/drivers/*
- drivers/staging/wlags49_h2/wl_cs.c
due to dev_info_t and whitespace changes
Diffstat (limited to 'drivers/pcmcia')
27 files changed, 320 insertions, 1472 deletions
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 | |||
7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o | 7 | obj-$(CONFIG_PCCARD) += pcmcia_core.o |
8 | 8 | ||
9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o | 9 | pcmcia-y += ds.o pcmcia_resource.o cistpl.o pcmcia_cis.o |
10 | pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o | ||
11 | obj-$(CONFIG_PCMCIA) += pcmcia.o | 10 | obj-$(CONFIG_PCMCIA) += pcmcia.o |
12 | 11 | ||
13 | pcmcia_rsrc-y += rsrc_mgr.o | 12 | pcmcia_rsrc-y += rsrc_mgr.o |
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h index a324d329dea6..67530cefcf3c 100644 --- a/drivers/pcmcia/au1000_generic.h +++ b/drivers/pcmcia/au1000_generic.h | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | /* include the world */ | 24 | /* include the world */ |
25 | 25 | ||
26 | #include <pcmcia/cs_types.h> | ||
27 | #include <pcmcia/cs.h> | 26 | #include <pcmcia/cs.h> |
28 | #include <pcmcia/ss.h> | 27 | #include <pcmcia/ss.h> |
29 | #include <pcmcia/cistpl.h> | 28 | #include <pcmcia/cistpl.h> |
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c index 5a979cb8f3e6..807f2d75dad3 100644 --- a/drivers/pcmcia/au1000_pb1x00.c +++ b/drivers/pcmcia/au1000_pb1x00.c | |||
@@ -31,11 +31,9 @@ | |||
31 | #include <linux/proc_fs.h> | 31 | #include <linux/proc_fs.h> |
32 | #include <linux/types.h> | 32 | #include <linux/types.h> |
33 | 33 | ||
34 | #include <pcmcia/cs_types.h> | ||
35 | #include <pcmcia/cs.h> | 34 | #include <pcmcia/cs.h> |
36 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
37 | #include <pcmcia/cistpl.h> | 36 | #include <pcmcia/cistpl.h> |
38 | #include <pcmcia/bus_ops.h> | ||
39 | 37 | ||
40 | #include <asm/io.h> | 38 | #include <asm/io.h> |
41 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c index 8844bc3e3118..91414a0ddc44 100644 --- a/drivers/pcmcia/cistpl.c +++ b/drivers/pcmcia/cistpl.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/byteorder.h> | 27 | #include <asm/byteorder.h> |
28 | #include <asm/unaligned.h> | 28 | #include <asm/unaligned.h> |
29 | 29 | ||
30 | #include <pcmcia/cs_types.h> | ||
31 | #include <pcmcia/ss.h> | 30 | #include <pcmcia/ss.h> |
32 | #include <pcmcia/cs.h> | 31 | #include <pcmcia/cs.h> |
33 | #include <pcmcia/cisreg.h> | 32 | #include <pcmcia/cisreg.h> |
@@ -54,6 +53,9 @@ static const u_int exponent[] = { | |||
54 | /* Upper limit on reasonable # of tuples */ | 53 | /* Upper limit on reasonable # of tuples */ |
55 | #define MAX_TUPLES 200 | 54 | #define MAX_TUPLES 200 |
56 | 55 | ||
56 | /* Bits in IRQInfo1 field */ | ||
57 | #define IRQ_INFO2_VALID 0x10 | ||
58 | |||
57 | /* 16-bit CIS? */ | 59 | /* 16-bit CIS? */ |
58 | static int cis_width; | 60 | static int cis_width; |
59 | module_param(cis_width, int, 0444); | 61 | module_param(cis_width, int, 0444); |
@@ -210,7 +212,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
210 | * Probably only useful for writing one-byte registers. Must be called | 212 | * Probably only useful for writing one-byte registers. Must be called |
211 | * with ops_mutex held. | 213 | * with ops_mutex held. |
212 | */ | 214 | */ |
213 | void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | 215 | int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, |
214 | u_int len, void *ptr) | 216 | u_int len, void *ptr) |
215 | { | 217 | { |
216 | void __iomem *sys, *end; | 218 | void __iomem *sys, *end; |
@@ -232,7 +234,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
232 | ((cis_width) ? MAP_16BIT : 0)); | 234 | ((cis_width) ? MAP_16BIT : 0)); |
233 | if (!sys) { | 235 | if (!sys) { |
234 | dev_dbg(&s->dev, "could not map memory\n"); | 236 | dev_dbg(&s->dev, "could not map memory\n"); |
235 | return; /* FIXME: Error */ | 237 | return -EINVAL; |
236 | } | 238 | } |
237 | 239 | ||
238 | writeb(flags, sys+CISREG_ICTRL0); | 240 | writeb(flags, sys+CISREG_ICTRL0); |
@@ -257,7 +259,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
257 | sys = set_cis_map(s, card_offset, flags); | 259 | sys = set_cis_map(s, card_offset, flags); |
258 | if (!sys) { | 260 | if (!sys) { |
259 | dev_dbg(&s->dev, "could not map memory\n"); | 261 | dev_dbg(&s->dev, "could not map memory\n"); |
260 | return; /* FIXME: error */ | 262 | return -EINVAL; |
261 | } | 263 | } |
262 | 264 | ||
263 | end = sys + s->map_size; | 265 | end = sys + s->map_size; |
@@ -271,6 +273,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr, | |||
271 | addr = 0; | 273 | addr = 0; |
272 | } | 274 | } |
273 | } | 275 | } |
276 | return 0; | ||
274 | } | 277 | } |
275 | 278 | ||
276 | 279 | ||
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index 976d80706eae..2ec8ac97445c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <asm/system.h> | 32 | #include <asm/system.h> |
33 | #include <asm/irq.h> | 33 | #include <asm/irq.h> |
34 | 34 | ||
35 | #include <pcmcia/cs_types.h> | ||
36 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
37 | #include <pcmcia/cs.h> | 36 | #include <pcmcia/cs.h> |
38 | #include <pcmcia/cistpl.h> | 37 | #include <pcmcia/cistpl.h> |
@@ -252,38 +251,6 @@ struct pcmcia_socket *pcmcia_get_socket_by_nr(unsigned int nr) | |||
252 | } | 251 | } |
253 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); | 252 | EXPORT_SYMBOL(pcmcia_get_socket_by_nr); |
254 | 253 | ||
255 | /* | ||
256 | * The central event handler. Send_event() sends an event to the | ||
257 | * 16-bit subsystem, which then calls the relevant device drivers. | ||
258 | * Parse_events() interprets the event bits from | ||
259 | * a card status change report. Do_shutdown() handles the high | ||
260 | * priority stuff associated with a card removal. | ||
261 | */ | ||
262 | |||
263 | /* NOTE: send_event needs to be called with skt->sem held. */ | ||
264 | |||
265 | static int send_event(struct pcmcia_socket *s, event_t event, int priority) | ||
266 | { | ||
267 | int ret; | ||
268 | |||
269 | if ((s->state & SOCKET_CARDBUS) && (event != CS_EVENT_CARD_REMOVAL)) | ||
270 | return 0; | ||
271 | |||
272 | dev_dbg(&s->dev, "send_event(event %d, pri %d, callback 0x%p)\n", | ||
273 | event, priority, s->callback); | ||
274 | |||
275 | if (!s->callback) | ||
276 | return 0; | ||
277 | if (!try_module_get(s->callback->owner)) | ||
278 | return 0; | ||
279 | |||
280 | ret = s->callback->event(s, event, priority); | ||
281 | |||
282 | module_put(s->callback->owner); | ||
283 | |||
284 | return ret; | ||
285 | } | ||
286 | |||
287 | static int socket_reset(struct pcmcia_socket *skt) | 254 | static int socket_reset(struct pcmcia_socket *skt) |
288 | { | 255 | { |
289 | int status, i; | 256 | int status, i; |
@@ -326,7 +293,8 @@ static void socket_shutdown(struct pcmcia_socket *s) | |||
326 | 293 | ||
327 | dev_dbg(&s->dev, "shutdown\n"); | 294 | dev_dbg(&s->dev, "shutdown\n"); |
328 | 295 | ||
329 | send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); | 296 | if (s->callback) |
297 | s->callback->remove(s); | ||
330 | 298 | ||
331 | mutex_lock(&s->ops_mutex); | 299 | mutex_lock(&s->ops_mutex); |
332 | s->state &= SOCKET_INUSE | SOCKET_PRESENT; | 300 | s->state &= SOCKET_INUSE | SOCKET_PRESENT; |
@@ -477,7 +445,8 @@ static int socket_insert(struct pcmcia_socket *skt) | |||
477 | dev_dbg(&skt->dev, "insert done\n"); | 445 | dev_dbg(&skt->dev, "insert done\n"); |
478 | mutex_unlock(&skt->ops_mutex); | 446 | mutex_unlock(&skt->ops_mutex); |
479 | 447 | ||
480 | send_event(skt, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); | 448 | if (!(skt->state & SOCKET_CARDBUS) && (skt->callback)) |
449 | skt->callback->add(skt); | ||
481 | } else { | 450 | } else { |
482 | mutex_unlock(&skt->ops_mutex); | 451 | mutex_unlock(&skt->ops_mutex); |
483 | socket_shutdown(skt); | 452 | socket_shutdown(skt); |
@@ -494,7 +463,6 @@ static int socket_suspend(struct pcmcia_socket *skt) | |||
494 | mutex_lock(&skt->ops_mutex); | 463 | mutex_lock(&skt->ops_mutex); |
495 | skt->suspended_state = skt->state; | 464 | skt->suspended_state = skt->state; |
496 | 465 | ||
497 | send_event(skt, CS_EVENT_PM_SUSPEND, CS_EVENT_PRI_LOW); | ||
498 | skt->socket = dead_socket; | 466 | skt->socket = dead_socket; |
499 | skt->ops->set_socket(skt, &skt->socket); | 467 | skt->ops->set_socket(skt, &skt->socket); |
500 | if (skt->ops->suspend) | 468 | if (skt->ops->suspend) |
@@ -555,8 +523,8 @@ static int socket_late_resume(struct pcmcia_socket *skt) | |||
555 | return 0; | 523 | return 0; |
556 | } | 524 | } |
557 | #endif | 525 | #endif |
558 | 526 | if (!(skt->state & SOCKET_CARDBUS) && (skt->callback)) | |
559 | send_event(skt, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW); | 527 | skt->callback->early_resume(skt); |
560 | return 0; | 528 | return 0; |
561 | } | 529 | } |
562 | 530 | ||
@@ -654,16 +622,8 @@ static int pccardd(void *__skt) | |||
654 | spin_unlock_irqrestore(&skt->thread_lock, flags); | 622 | spin_unlock_irqrestore(&skt->thread_lock, flags); |
655 | 623 | ||
656 | mutex_lock(&skt->skt_mutex); | 624 | mutex_lock(&skt->skt_mutex); |
657 | if (events) { | 625 | if (events & SS_DETECT) |
658 | if (events & SS_DETECT) | 626 | socket_detect_change(skt); |
659 | socket_detect_change(skt); | ||
660 | if (events & SS_BATDEAD) | ||
661 | send_event(skt, CS_EVENT_BATTERY_DEAD, CS_EVENT_PRI_LOW); | ||
662 | if (events & SS_BATWARN) | ||
663 | send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW); | ||
664 | if (events & SS_READY) | ||
665 | send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW); | ||
666 | } | ||
667 | 627 | ||
668 | if (sysfs_events) { | 628 | if (sysfs_events) { |
669 | if (sysfs_events & PCMCIA_UEVENT_EJECT) | 629 | if (sysfs_events & PCMCIA_UEVENT_EJECT) |
@@ -783,7 +743,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c) | |||
783 | s->callback = c; | 743 | s->callback = c; |
784 | 744 | ||
785 | if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) | 745 | if ((s->state & (SOCKET_PRESENT|SOCKET_CARDBUS)) == SOCKET_PRESENT) |
786 | send_event(s, CS_EVENT_CARD_INSERTION, CS_EVENT_PRI_LOW); | 746 | s->callback->add(s); |
787 | } else | 747 | } else |
788 | s->callback = NULL; | 748 | s->callback = NULL; |
789 | err: | 749 | err: |
@@ -823,20 +783,13 @@ int pcmcia_reset_card(struct pcmcia_socket *skt) | |||
823 | break; | 783 | break; |
824 | } | 784 | } |
825 | 785 | ||
826 | ret = send_event(skt, CS_EVENT_RESET_REQUEST, CS_EVENT_PRI_LOW); | 786 | if (skt->callback) |
827 | if (ret == 0) { | 787 | skt->callback->suspend(skt); |
828 | send_event(skt, CS_EVENT_RESET_PHYSICAL, CS_EVENT_PRI_LOW); | 788 | mutex_lock(&skt->ops_mutex); |
829 | if (skt->callback) | 789 | ret = socket_reset(skt); |
830 | skt->callback->suspend(skt); | 790 | mutex_unlock(&skt->ops_mutex); |
831 | mutex_lock(&skt->ops_mutex); | 791 | if ((ret == 0) && (skt->callback)) |
832 | ret = socket_reset(skt); | 792 | skt->callback->resume(skt); |
833 | mutex_unlock(&skt->ops_mutex); | ||
834 | if (ret == 0) { | ||
835 | send_event(skt, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW); | ||
836 | if (skt->callback) | ||
837 | skt->callback->resume(skt); | ||
838 | } | ||
839 | } | ||
840 | 793 | ||
841 | ret = 0; | 794 | ret = 0; |
842 | } while (0); | 795 | } while (0); |
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 4126a75445ea..da055dc14d98 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h | |||
@@ -10,7 +10,7 @@ | |||
10 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | 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 | * (C) 2003 - 2008 Dominik Brodowski | 13 | * (C) 2003 - 2010 Dominik Brodowski |
14 | * | 14 | * |
15 | * | 15 | * |
16 | * This file contains definitions _only_ needed by the PCMCIA core modules. | 16 | * This file contains definitions _only_ needed by the PCMCIA core modules. |
@@ -26,6 +26,9 @@ | |||
26 | /* Flags in client state */ | 26 | /* Flags in client state */ |
27 | #define CLIENT_WIN_REQ(i) (0x1<<(i)) | 27 | #define CLIENT_WIN_REQ(i) (0x1<<(i)) |
28 | 28 | ||
29 | /* Flag to access all functions */ | ||
30 | #define BIND_FN_ALL 0xff | ||
31 | |||
29 | /* Each card function gets one of these guys */ | 32 | /* Each card function gets one of these guys */ |
30 | typedef struct config_t { | 33 | typedef struct config_t { |
31 | struct kref ref; | 34 | struct kref ref; |
@@ -35,7 +38,10 @@ typedef struct config_t { | |||
35 | unsigned int ConfigBase; | 38 | unsigned int ConfigBase; |
36 | unsigned char Status, Pin, Copy, Option, ExtStatus; | 39 | unsigned char Status, Pin, Copy, Option, ExtStatus; |
37 | unsigned int CardValues; | 40 | unsigned int CardValues; |
38 | io_req_t io; | 41 | |
42 | struct resource io[MAX_IO_WIN]; /* io ports */ | ||
43 | struct resource mem[MAX_WIN]; /* mem areas */ | ||
44 | |||
39 | struct { | 45 | struct { |
40 | u_int Attributes; | 46 | u_int Attributes; |
41 | } irq; | 47 | } irq; |
@@ -56,18 +62,11 @@ struct pccard_resource_ops { | |||
56 | unsigned int attr, | 62 | unsigned int attr, |
57 | unsigned int *base, | 63 | unsigned int *base, |
58 | unsigned int num, | 64 | unsigned int num, |
59 | unsigned int align); | 65 | unsigned int align, |
66 | struct resource **parent); | ||
60 | struct resource* (*find_mem) (unsigned long base, unsigned long num, | 67 | struct resource* (*find_mem) (unsigned long base, unsigned long num, |
61 | unsigned long align, int low, | 68 | unsigned long align, int low, |
62 | struct pcmcia_socket *s); | 69 | 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); | 70 | int (*init) (struct pcmcia_socket *s); |
72 | void (*exit) (struct pcmcia_socket *s); | 71 | void (*exit) (struct pcmcia_socket *s); |
73 | }; | 72 | }; |
@@ -114,11 +113,12 @@ void cb_free(struct pcmcia_socket *s); | |||
114 | 113 | ||
115 | struct pcmcia_callback{ | 114 | struct pcmcia_callback{ |
116 | struct module *owner; | 115 | struct module *owner; |
117 | int (*event) (struct pcmcia_socket *s, | 116 | int (*add) (struct pcmcia_socket *s); |
118 | event_t event, int priority); | 117 | int (*remove) (struct pcmcia_socket *s); |
119 | void (*requery) (struct pcmcia_socket *s); | 118 | void (*requery) (struct pcmcia_socket *s); |
120 | int (*validate) (struct pcmcia_socket *s, unsigned int *i); | 119 | int (*validate) (struct pcmcia_socket *s, unsigned int *i); |
121 | int (*suspend) (struct pcmcia_socket *s); | 120 | int (*suspend) (struct pcmcia_socket *s); |
121 | int (*early_resume) (struct pcmcia_socket *s); | ||
122 | int (*resume) (struct pcmcia_socket *s); | 122 | int (*resume) (struct pcmcia_socket *s); |
123 | }; | 123 | }; |
124 | 124 | ||
@@ -146,6 +146,8 @@ void pcmcia_put_socket(struct pcmcia_socket *skt); | |||
146 | /* ds.c */ | 146 | /* ds.c */ |
147 | extern struct bus_type pcmcia_bus_type; | 147 | extern struct bus_type pcmcia_bus_type; |
148 | 148 | ||
149 | struct pcmcia_device; | ||
150 | |||
149 | /* pcmcia_resource.c */ | 151 | /* pcmcia_resource.c */ |
150 | extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); | 152 | extern int pcmcia_release_configuration(struct pcmcia_device *p_dev); |
151 | extern int pcmcia_validate_mem(struct pcmcia_socket *s); | 153 | extern int pcmcia_validate_mem(struct pcmcia_socket *s); |
@@ -163,8 +165,8 @@ extern struct bin_attribute pccard_cis_attr; | |||
163 | 165 | ||
164 | int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, | 166 | int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, |
165 | u_int addr, u_int len, void *ptr); | 167 | u_int addr, u_int len, void *ptr); |
166 | void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, | 168 | int pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, |
167 | u_int addr, u_int len, void *ptr); | 169 | u_int addr, u_int len, void *ptr); |
168 | void release_cis_mem(struct pcmcia_socket *s); | 170 | void release_cis_mem(struct pcmcia_socket *s); |
169 | void destroy_cis_cache(struct pcmcia_socket *s); | 171 | void destroy_cis_cache(struct pcmcia_socket *s); |
170 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, | 172 | int pccard_read_tuple(struct pcmcia_socket *s, unsigned int function, |
@@ -188,34 +190,4 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, | |||
188 | 190 | ||
189 | int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); | 191 | int pccard_get_tuple_data(struct pcmcia_socket *s, tuple_t *tuple); |
190 | 192 | ||
191 | |||
192 | #ifdef CONFIG_PCMCIA_IOCTL | ||
193 | /* ds.c */ | ||
194 | extern struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev); | ||
195 | extern void pcmcia_put_dev(struct pcmcia_device *p_dev); | ||
196 | |||
197 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, | ||
198 | unsigned int function); | ||
199 | |||
200 | /* pcmcia_ioctl.c */ | ||
201 | extern void __init pcmcia_setup_ioctl(void); | ||
202 | extern void __exit pcmcia_cleanup_ioctl(void); | ||
203 | extern void handle_event(struct pcmcia_socket *s, event_t event); | ||
204 | extern int handle_request(struct pcmcia_socket *s, event_t event); | ||
205 | |||
206 | #else /* CONFIG_PCMCIA_IOCTL */ | ||
207 | |||
208 | static inline void __init pcmcia_setup_ioctl(void) { return; } | ||
209 | static inline void __exit pcmcia_cleanup_ioctl(void) { return; } | ||
210 | static inline void handle_event(struct pcmcia_socket *s, event_t event) | ||
211 | { | ||
212 | return; | ||
213 | } | ||
214 | static 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 */ | 193 | #endif /* _LINUX_CS_INTERNAL_H */ |
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c index 0f4cc3f00028..27575e6378a1 100644 --- a/drivers/pcmcia/db1xxx_ss.c +++ b/drivers/pcmcia/db1xxx_ss.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
31 | 31 | ||
32 | #include <pcmcia/cs_types.h> | ||
33 | #include <pcmcia/ss.h> | 32 | #include <pcmcia/ss.h> |
34 | 33 | ||
35 | #include <asm/mach-au1x00/au1000.h> | 34 | #include <asm/mach-au1x00/au1000.h> |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index eac961463be2..55570d9e1e4c 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | 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 | * (C) 2003 - 2006 Dominik Brodowski | 13 | * (C) 2003 - 2010 Dominik Brodowski |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <pcmcia/cs_types.h> | ||
30 | #include <pcmcia/cs.h> | 29 | #include <pcmcia/cs.h> |
31 | #include <pcmcia/cistpl.h> | 30 | #include <pcmcia/cistpl.h> |
32 | #include <pcmcia/ds.h> | 31 | #include <pcmcia/ds.h> |
@@ -213,7 +212,7 @@ EXPORT_SYMBOL(pcmcia_unregister_driver); | |||
213 | 212 | ||
214 | /* pcmcia_device handling */ | 213 | /* pcmcia_device handling */ |
215 | 214 | ||
216 | struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) | 215 | static struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) |
217 | { | 216 | { |
218 | struct device *tmp_dev; | 217 | struct device *tmp_dev; |
219 | tmp_dev = get_device(&p_dev->dev); | 218 | tmp_dev = get_device(&p_dev->dev); |
@@ -222,7 +221,7 @@ struct pcmcia_device *pcmcia_get_dev(struct pcmcia_device *p_dev) | |||
222 | return to_pcmcia_dev(tmp_dev); | 221 | return to_pcmcia_dev(tmp_dev); |
223 | } | 222 | } |
224 | 223 | ||
225 | void pcmcia_put_dev(struct pcmcia_device *p_dev) | 224 | static void pcmcia_put_dev(struct pcmcia_device *p_dev) |
226 | { | 225 | { |
227 | if (p_dev) | 226 | if (p_dev) |
228 | put_device(&p_dev->dev); | 227 | put_device(&p_dev->dev); |
@@ -294,7 +293,7 @@ static int pcmcia_device_probe(struct device *dev) | |||
294 | } | 293 | } |
295 | 294 | ||
296 | mutex_lock(&s->ops_mutex); | 295 | mutex_lock(&s->ops_mutex); |
297 | if ((s->pcmcia_state.has_pfc) && | 296 | if ((s->pcmcia_pfc) && |
298 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | 297 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) |
299 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY); | 298 | pcmcia_parse_uevents(s, PCMCIA_UEVENT_REQUERY); |
300 | mutex_unlock(&s->ops_mutex); | 299 | mutex_unlock(&s->ops_mutex); |
@@ -359,7 +358,7 @@ static int pcmcia_device_remove(struct device *dev) | |||
359 | * pseudo multi-function card, we need to unbind | 358 | * pseudo multi-function card, we need to unbind |
360 | * all devices | 359 | * all devices |
361 | */ | 360 | */ |
362 | if ((p_dev->socket->pcmcia_state.has_pfc) && | 361 | if ((p_dev->socket->pcmcia_pfc) && |
363 | (p_dev->socket->device_count > 0) && | 362 | (p_dev->socket->device_count > 0) && |
364 | (p_dev->device_no == 0)) | 363 | (p_dev->device_no == 0)) |
365 | pcmcia_card_remove(p_dev->socket, p_dev); | 364 | pcmcia_card_remove(p_dev->socket, p_dev); |
@@ -477,7 +476,8 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev) | |||
477 | } | 476 | } |
478 | 477 | ||
479 | 478 | ||
480 | struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) | 479 | static struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, |
480 | unsigned int function) | ||
481 | { | 481 | { |
482 | struct pcmcia_device *p_dev, *tmp_dev; | 482 | struct pcmcia_device *p_dev, *tmp_dev; |
483 | int i; | 483 | int i; |
@@ -531,7 +531,6 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
531 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) | 531 | list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list) |
532 | if (p_dev->func == tmp_dev->func) { | 532 | if (p_dev->func == tmp_dev->func) { |
533 | p_dev->function_config = tmp_dev->function_config; | 533 | p_dev->function_config = tmp_dev->function_config; |
534 | p_dev->io = tmp_dev->io; | ||
535 | p_dev->irq = tmp_dev->irq; | 534 | p_dev->irq = tmp_dev->irq; |
536 | kref_get(&p_dev->function_config->ref); | 535 | kref_get(&p_dev->function_config->ref); |
537 | } | 536 | } |
@@ -544,15 +543,29 @@ struct pcmcia_device *pcmcia_device_add(struct pcmcia_socket *s, unsigned int fu | |||
544 | "IRQ setup failed -- device might not work\n"); | 543 | "IRQ setup failed -- device might not work\n"); |
545 | 544 | ||
546 | if (!p_dev->function_config) { | 545 | if (!p_dev->function_config) { |
546 | config_t *c; | ||
547 | dev_dbg(&p_dev->dev, "creating config_t\n"); | 547 | dev_dbg(&p_dev->dev, "creating config_t\n"); |
548 | p_dev->function_config = kzalloc(sizeof(struct config_t), | 548 | c = kzalloc(sizeof(struct config_t), GFP_KERNEL); |
549 | GFP_KERNEL); | 549 | if (!c) { |
550 | if (!p_dev->function_config) { | ||
551 | mutex_unlock(&s->ops_mutex); | 550 | mutex_unlock(&s->ops_mutex); |
552 | goto err_unreg; | 551 | goto err_unreg; |
553 | } | 552 | } |
554 | kref_init(&p_dev->function_config->ref); | 553 | p_dev->function_config = c; |
554 | kref_init(&c->ref); | ||
555 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
556 | c->io[i].name = p_dev->devname; | ||
557 | c->io[i].flags = IORESOURCE_IO; | ||
558 | } | ||
559 | for (i = 0; i< MAX_WIN; i++) { | ||
560 | c->mem[i].name = p_dev->devname; | ||
561 | c->mem[i].flags = IORESOURCE_MEM; | ||
562 | } | ||
555 | } | 563 | } |
564 | for (i = 0; i < MAX_IO_WIN; i++) | ||
565 | p_dev->resource[i] = &p_dev->function_config->io[i]; | ||
566 | for (; i < (MAX_IO_WIN + MAX_WIN); i++) | ||
567 | p_dev->resource[i] = &p_dev->function_config->mem[i-MAX_IO_WIN]; | ||
568 | |||
556 | mutex_unlock(&s->ops_mutex); | 569 | mutex_unlock(&s->ops_mutex); |
557 | 570 | ||
558 | dev_printk(KERN_NOTICE, &p_dev->dev, | 571 | dev_printk(KERN_NOTICE, &p_dev->dev, |
@@ -680,7 +693,7 @@ static void pcmcia_requery(struct pcmcia_socket *s) | |||
680 | * call pcmcia_device_add() -- which will fail if both | 693 | * call pcmcia_device_add() -- which will fail if both |
681 | * devices are already registered. */ | 694 | * devices are already registered. */ |
682 | mutex_lock(&s->ops_mutex); | 695 | mutex_lock(&s->ops_mutex); |
683 | has_pfc = s->pcmcia_state.has_pfc; | 696 | has_pfc = s->pcmcia_pfc; |
684 | mutex_unlock(&s->ops_mutex); | 697 | mutex_unlock(&s->ops_mutex); |
685 | if (has_pfc) | 698 | if (has_pfc) |
686 | pcmcia_device_add(s, 0); | 699 | pcmcia_device_add(s, 0); |
@@ -812,7 +825,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
812 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { | 825 | if (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) { |
813 | dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n"); | 826 | dev_dbg(&dev->dev, "this is a pseudo-multi-function device\n"); |
814 | mutex_lock(&dev->socket->ops_mutex); | 827 | mutex_lock(&dev->socket->ops_mutex); |
815 | dev->socket->pcmcia_state.has_pfc = 1; | 828 | dev->socket->pcmcia_pfc = 1; |
816 | mutex_unlock(&dev->socket->ops_mutex); | 829 | mutex_unlock(&dev->socket->ops_mutex); |
817 | if (dev->device_no != did->device_no) | 830 | if (dev->device_no != did->device_no) |
818 | return 0; | 831 | return 0; |
@@ -826,7 +839,7 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev, | |||
826 | 839 | ||
827 | /* if this is a pseudo-multi-function device, | 840 | /* if this is a pseudo-multi-function device, |
828 | * we need explicit matches */ | 841 | * we need explicit matches */ |
829 | if (dev->socket->pcmcia_state.has_pfc) | 842 | if (dev->socket->pcmcia_pfc) |
830 | return 0; | 843 | return 0; |
831 | if (dev->device_no) | 844 | if (dev->device_no) |
832 | return 0; | 845 | return 0; |
@@ -885,14 +898,6 @@ static int pcmcia_bus_match(struct device *dev, struct device_driver *drv) | |||
885 | } | 898 | } |
886 | mutex_unlock(&p_drv->dynids.lock); | 899 | mutex_unlock(&p_drv->dynids.lock); |
887 | 900 | ||
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) { | 901 | while (did && did->match_flags) { |
897 | dev_dbg(dev, "trying to match to %s\n", drv->name); | 902 | dev_dbg(dev, "trying to match to %s\n", drv->name); |
898 | if (pcmcia_devmatch(p_dev, did)) { | 903 | if (pcmcia_devmatch(p_dev, did)) { |
@@ -1006,6 +1011,18 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); | |||
1006 | pcmcia_device_stringattr(prod_id3, prod_id[2]); | 1011 | pcmcia_device_stringattr(prod_id3, prod_id[2]); |
1007 | pcmcia_device_stringattr(prod_id4, prod_id[3]); | 1012 | pcmcia_device_stringattr(prod_id4, prod_id[3]); |
1008 | 1013 | ||
1014 | static ssize_t pcmcia_show_resources(struct device *dev, | ||
1015 | struct device_attribute *attr, char *buf) | ||
1016 | { | ||
1017 | struct pcmcia_device *p_dev = to_pcmcia_dev(dev); | ||
1018 | char *str = buf; | ||
1019 | int i; | ||
1020 | |||
1021 | for (i = 0; i < PCMCIA_NUM_RESOURCES; i++) | ||
1022 | str += sprintf(str, "%pr\n", p_dev->resource[i]); | ||
1023 | |||
1024 | return str - buf; | ||
1025 | } | ||
1009 | 1026 | ||
1010 | static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf) | 1027 | static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute *attr, char *buf) |
1011 | { | 1028 | { |
@@ -1076,6 +1093,7 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev, | |||
1076 | static struct device_attribute pcmcia_dev_attrs[] = { | 1093 | static struct device_attribute pcmcia_dev_attrs[] = { |
1077 | __ATTR(function, 0444, func_show, NULL), | 1094 | __ATTR(function, 0444, func_show, NULL), |
1078 | __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state), | 1095 | __ATTR(pm_state, 0644, pcmcia_show_pm_state, pcmcia_store_pm_state), |
1096 | __ATTR(resources, 0444, pcmcia_show_resources, NULL), | ||
1079 | __ATTR_RO(func_id), | 1097 | __ATTR_RO(func_id), |
1080 | __ATTR_RO(manf_id), | 1098 | __ATTR_RO(manf_id), |
1081 | __ATTR_RO(card_id), | 1099 | __ATTR_RO(card_id), |
@@ -1215,86 +1233,57 @@ static int pcmcia_bus_suspend(struct pcmcia_socket *skt) | |||
1215 | return 0; | 1233 | return 0; |
1216 | } | 1234 | } |
1217 | 1235 | ||
1236 | static int pcmcia_bus_remove(struct pcmcia_socket *skt) | ||
1237 | { | ||
1238 | atomic_set(&skt->present, 0); | ||
1239 | pcmcia_card_remove(skt, NULL); | ||
1218 | 1240 | ||
1219 | /*====================================================================== | 1241 | mutex_lock(&skt->ops_mutex); |
1242 | destroy_cis_cache(skt); | ||
1243 | pcmcia_cleanup_irq(skt); | ||
1244 | mutex_unlock(&skt->ops_mutex); | ||
1220 | 1245 | ||
1221 | The card status event handler. | 1246 | return 0; |
1247 | } | ||
1222 | 1248 | ||
1223 | ======================================================================*/ | 1249 | static int pcmcia_bus_add(struct pcmcia_socket *skt) |
1250 | { | ||
1251 | atomic_set(&skt->present, 1); | ||
1224 | 1252 | ||
1225 | /* Normally, the event is passed to individual drivers after | 1253 | mutex_lock(&skt->ops_mutex); |
1226 | * informing userspace. Only for CS_EVENT_CARD_REMOVAL this | 1254 | skt->pcmcia_pfc = 0; |
1227 | * is inversed to maintain historic compatibility. | 1255 | destroy_cis_cache(skt); /* to be on the safe side... */ |
1228 | */ | 1256 | mutex_unlock(&skt->ops_mutex); |
1229 | 1257 | ||
1230 | static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) | 1258 | pcmcia_card_add(skt); |
1231 | { | ||
1232 | struct pcmcia_socket *s = pcmcia_get_socket(skt); | ||
1233 | 1259 | ||
1234 | if (!s) { | 1260 | return 0; |
1235 | dev_printk(KERN_ERR, &skt->dev, | 1261 | } |
1236 | "PCMCIA obtaining reference to socket " \ | ||
1237 | "failed, event 0x%x lost!\n", event); | ||
1238 | return -ENODEV; | ||
1239 | } | ||
1240 | 1262 | ||
1241 | dev_dbg(&skt->dev, "ds_event(0x%06x, %d, 0x%p)\n", | 1263 | static int pcmcia_bus_early_resume(struct pcmcia_socket *skt) |
1242 | event, priority, skt); | 1264 | { |
1265 | if (!verify_cis_cache(skt)) { | ||
1266 | pcmcia_put_socket(skt); | ||
1267 | return 0; | ||
1268 | } | ||
1243 | 1269 | ||
1244 | switch (event) { | 1270 | dev_dbg(&skt->dev, "cis mismatch - different card\n"); |
1245 | case CS_EVENT_CARD_REMOVAL: | ||
1246 | atomic_set(&skt->present, 0); | ||
1247 | pcmcia_card_remove(skt, NULL); | ||
1248 | handle_event(skt, event); | ||
1249 | mutex_lock(&s->ops_mutex); | ||
1250 | destroy_cis_cache(s); | ||
1251 | pcmcia_cleanup_irq(s); | ||
1252 | mutex_unlock(&s->ops_mutex); | ||
1253 | break; | ||
1254 | 1271 | ||
1255 | case CS_EVENT_CARD_INSERTION: | 1272 | /* first, remove the card */ |
1256 | atomic_set(&skt->present, 1); | 1273 | pcmcia_bus_remove(skt); |
1257 | mutex_lock(&s->ops_mutex); | ||
1258 | s->pcmcia_state.has_pfc = 0; | ||
1259 | destroy_cis_cache(s); /* to be on the safe side... */ | ||
1260 | mutex_unlock(&s->ops_mutex); | ||
1261 | pcmcia_card_add(skt); | ||
1262 | handle_event(skt, event); | ||
1263 | break; | ||
1264 | |||
1265 | case CS_EVENT_EJECTION_REQUEST: | ||
1266 | break; | ||
1267 | |||
1268 | case CS_EVENT_PM_RESUME: | ||
1269 | if (verify_cis_cache(skt) != 0) { | ||
1270 | dev_dbg(&skt->dev, "cis mismatch - different card\n"); | ||
1271 | /* first, remove the card */ | ||
1272 | ds_event(skt, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH); | ||
1273 | mutex_lock(&s->ops_mutex); | ||
1274 | destroy_cis_cache(skt); | ||
1275 | kfree(skt->fake_cis); | ||
1276 | skt->fake_cis = NULL; | ||
1277 | s->functions = 0; | ||
1278 | mutex_unlock(&s->ops_mutex); | ||
1279 | /* now, add the new card */ | ||
1280 | ds_event(skt, CS_EVENT_CARD_INSERTION, | ||
1281 | CS_EVENT_PRI_LOW); | ||
1282 | } | ||
1283 | handle_event(skt, event); | ||
1284 | break; | ||
1285 | 1274 | ||
1286 | case CS_EVENT_PM_SUSPEND: | 1275 | mutex_lock(&skt->ops_mutex); |
1287 | case CS_EVENT_RESET_PHYSICAL: | 1276 | destroy_cis_cache(skt); |
1288 | case CS_EVENT_CARD_RESET: | 1277 | kfree(skt->fake_cis); |
1289 | default: | 1278 | skt->fake_cis = NULL; |
1290 | handle_event(skt, event); | 1279 | skt->functions = 0; |
1291 | break; | 1280 | mutex_unlock(&skt->ops_mutex); |
1292 | } | ||
1293 | 1281 | ||
1294 | pcmcia_put_socket(s); | 1282 | /* now, add the new card */ |
1283 | pcmcia_bus_add(skt); | ||
1284 | return 0; | ||
1285 | } | ||
1295 | 1286 | ||
1296 | return 0; | ||
1297 | } /* ds_event */ | ||
1298 | 1287 | ||
1299 | /* | 1288 | /* |
1300 | * NOTE: This is racy. There's no guarantee the card will still be | 1289 | * NOTE: This is racy. There's no guarantee the card will still be |
@@ -1323,10 +1312,12 @@ EXPORT_SYMBOL(pcmcia_dev_present); | |||
1323 | 1312 | ||
1324 | static struct pcmcia_callback pcmcia_bus_callback = { | 1313 | static struct pcmcia_callback pcmcia_bus_callback = { |
1325 | .owner = THIS_MODULE, | 1314 | .owner = THIS_MODULE, |
1326 | .event = ds_event, | 1315 | .add = pcmcia_bus_add, |
1316 | .remove = pcmcia_bus_remove, | ||
1327 | .requery = pcmcia_requery, | 1317 | .requery = pcmcia_requery, |
1328 | .validate = pccard_validate_cis, | 1318 | .validate = pccard_validate_cis, |
1329 | .suspend = pcmcia_bus_suspend, | 1319 | .suspend = pcmcia_bus_suspend, |
1320 | .early_resume = pcmcia_bus_early_resume, | ||
1330 | .resume = pcmcia_bus_resume, | 1321 | .resume = pcmcia_bus_resume, |
1331 | }; | 1322 | }; |
1332 | 1323 | ||
@@ -1350,11 +1341,8 @@ static int __devinit pcmcia_bus_add_socket(struct device *dev, | |||
1350 | return ret; | 1341 | return ret; |
1351 | } | 1342 | } |
1352 | 1343 | ||
1353 | #ifdef CONFIG_PCMCIA_IOCTL | ||
1354 | init_waitqueue_head(&socket->queue); | ||
1355 | #endif | ||
1356 | INIT_LIST_HEAD(&socket->devices_list); | 1344 | INIT_LIST_HEAD(&socket->devices_list); |
1357 | memset(&socket->pcmcia_state, 0, sizeof(u8)); | 1345 | socket->pcmcia_pfc = 0; |
1358 | socket->device_count = 0; | 1346 | socket->device_count = 0; |
1359 | atomic_set(&socket->present, 0); | 1347 | atomic_set(&socket->present, 0); |
1360 | 1348 | ||
@@ -1429,8 +1417,6 @@ static int __init init_pcmcia_bus(void) | |||
1429 | return ret; | 1417 | return ret; |
1430 | } | 1418 | } |
1431 | 1419 | ||
1432 | pcmcia_setup_ioctl(); | ||
1433 | |||
1434 | return 0; | 1420 | return 0; |
1435 | } | 1421 | } |
1436 | fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that | 1422 | fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that |
@@ -1439,8 +1425,6 @@ fs_initcall(init_pcmcia_bus); /* one level after subsys_initcall so that | |||
1439 | 1425 | ||
1440 | static void __exit exit_pcmcia_bus(void) | 1426 | static void __exit exit_pcmcia_bus(void) |
1441 | { | 1427 | { |
1442 | pcmcia_cleanup_ioctl(); | ||
1443 | |||
1444 | class_interface_unregister(&pcmcia_bus_interface); | 1428 | class_interface_unregister(&pcmcia_bus_interface); |
1445 | 1429 | ||
1446 | bus_unregister(&pcmcia_bus_type); | 1430 | bus_unregister(&pcmcia_bus_type); |
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c index 3003bb3dfcc0..05d0879ce935 100644 --- a/drivers/pcmcia/i82092.c +++ b/drivers/pcmcia/i82092.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | 17 | ||
18 | #include <pcmcia/cs_types.h> | ||
19 | #include <pcmcia/ss.h> | 18 | #include <pcmcia/ss.h> |
20 | #include <pcmcia/cs.h> | 19 | #include <pcmcia/cs.h> |
21 | 20 | ||
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c index 9e2a15628de5..61746bd598b3 100644 --- a/drivers/pcmcia/i82365.c +++ b/drivers/pcmcia/i82365.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <asm/io.h> | 50 | #include <asm/io.h> |
51 | #include <asm/system.h> | 51 | #include <asm/system.h> |
52 | 52 | ||
53 | #include <pcmcia/cs_types.h> | ||
54 | #include <pcmcia/ss.h> | 53 | #include <pcmcia/ss.h> |
55 | #include <pcmcia/cs.h> | 54 | #include <pcmcia/cs.h> |
56 | 55 | ||
diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 7e16ed8eb0a4..24de49925863 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/system.h> | 27 | #include <asm/system.h> |
28 | 28 | ||
29 | #include <pcmcia/cs_types.h> | ||
30 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
31 | #include <pcmcia/cs.h> | 30 | #include <pcmcia/cs.h> |
32 | 31 | ||
diff --git a/drivers/pcmcia/m32r_pcc.c b/drivers/pcmcia/m32r_pcc.c index 6c5c3f910d71..8e4723844ad3 100644 --- a/drivers/pcmcia/m32r_pcc.c +++ b/drivers/pcmcia/m32r_pcc.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <asm/system.h> | 27 | #include <asm/system.h> |
28 | #include <asm/addrspace.h> | 28 | #include <asm/addrspace.h> |
29 | 29 | ||
30 | #include <pcmcia/cs_types.h> | ||
31 | #include <pcmcia/ss.h> | 30 | #include <pcmcia/ss.h> |
32 | #include <pcmcia/cs.h> | 31 | #include <pcmcia/cs.h> |
33 | 32 | ||
diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 25e5e30a18af..f2f90a7d3e12 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #include <asm/irq.h> | 59 | #include <asm/irq.h> |
60 | #include <asm/fs_pd.h> | 60 | #include <asm/fs_pd.h> |
61 | 61 | ||
62 | #include <pcmcia/cs_types.h> | ||
63 | #include <pcmcia/cs.h> | 62 | #include <pcmcia/cs.h> |
64 | #include <pcmcia/ss.h> | 63 | #include <pcmcia/ss.h> |
65 | 64 | ||
diff --git a/drivers/pcmcia/pcmcia_cis.c b/drivers/pcmcia/pcmcia_cis.c index 4a65eaf96b0a..0ac54da15885 100644 --- a/drivers/pcmcia/pcmcia_cis.c +++ b/drivers/pcmcia/pcmcia_cis.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
21 | 21 | ||
22 | #include <pcmcia/cs_types.h> | ||
23 | #include <pcmcia/cisreg.h> | 22 | #include <pcmcia/cisreg.h> |
24 | #include <pcmcia/cistpl.h> | 23 | #include <pcmcia/cistpl.h> |
25 | #include <pcmcia/ss.h> | 24 | #include <pcmcia/ss.h> |
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 | |||
44 | static 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 | |||
53 | typedef 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 | |||
62 | static 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 | |||
80 | static 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 | ||
96 | static struct proc_dir_entry *proc_pccard; | ||
97 | |||
98 | static 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 | |||
114 | static 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 | |||
120 | static int pccard_drivers_proc_open(struct inode *inode, struct file *file) | ||
121 | { | ||
122 | return single_open(file, pccard_drivers_proc_show, NULL); | ||
123 | } | ||
124 | |||
125 | static 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 | |||
137 | static 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 | |||
161 | static inline int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) | ||
162 | { | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | #endif | ||
167 | |||
168 | static 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 | */ | ||
222 | static 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 | */ | ||
261 | static 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 | |||
280 | static 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, ®); | ||
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, ®); | ||
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 | |||
339 | static 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 | |||
418 | static int queue_empty(user_info_t *user) | ||
419 | { | ||
420 | return (user->event_head == user->event_tail); | ||
421 | } | ||
422 | |||
423 | static 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 | |||
429 | static 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 | |||
437 | void 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 | |||
469 | static 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 | |||
532 | rescan: | ||
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 | |||
567 | static 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 | |||
576 | static 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 | |||
653 | static 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); | ||
711 | out: | ||
712 | unlock_kernel(); | ||
713 | return ret; | ||
714 | } /* ds_open */ | ||
715 | |||
716 | /*====================================================================*/ | ||
717 | |||
718 | static 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); | ||
745 | out: | ||
746 | return 0; | ||
747 | } /* ds_release */ | ||
748 | |||
749 | /*====================================================================*/ | ||
750 | |||
751 | static 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 | |||
777 | static 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 */ | ||
793 | static 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 | |||
816 | static 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 | |||
1018 | free_out: | ||
1019 | kfree(buf); | ||
1020 | return err; | ||
1021 | } /* ds_ioctl */ | ||
1022 | |||
1023 | static 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 | |||
1037 | static 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 | |||
1047 | void __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 | |||
1067 | void __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/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index a4cd9adfcbc0..54aa1c238cb3 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | 27 | ||
28 | #include <pcmcia/cs_types.h> | ||
29 | #include <pcmcia/ss.h> | 28 | #include <pcmcia/ss.h> |
30 | #include <pcmcia/cs.h> | 29 | #include <pcmcia/cs.h> |
31 | #include <pcmcia/cistpl.h> | 30 | #include <pcmcia/cistpl.h> |
@@ -57,77 +56,107 @@ struct resource *pcmcia_find_mem_region(u_long base, u_long num, u_long align, | |||
57 | } | 56 | } |
58 | 57 | ||
59 | 58 | ||
59 | static void release_io_space(struct pcmcia_socket *s, struct resource *res) | ||
60 | { | ||
61 | resource_size_t num = resource_size(res); | ||
62 | int i; | ||
63 | |||
64 | dev_dbg(&s->dev, "release_io_space for %pR\n", res); | ||
65 | |||
66 | for (i = 0; i < MAX_IO_WIN; i++) { | ||
67 | if (!s->io[i].res) | ||
68 | continue; | ||
69 | if ((s->io[i].res->start <= res->start) && | ||
70 | (s->io[i].res->end >= res->end)) { | ||
71 | s->io[i].InUse -= num; | ||
72 | if (res->parent) | ||
73 | release_resource(res); | ||
74 | res->start = res->end = 0; | ||
75 | res->flags = IORESOURCE_IO; | ||
76 | /* Free the window if no one else is using it */ | ||
77 | if (s->io[i].InUse == 0) { | ||
78 | release_resource(s->io[i].res); | ||
79 | kfree(s->io[i].res); | ||
80 | s->io[i].res = NULL; | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | } /* release_io_space */ | ||
85 | |||
60 | /** alloc_io_space | 86 | /** alloc_io_space |
61 | * | 87 | * |
62 | * Special stuff for managing IO windows, because they are scarce | 88 | * Special stuff for managing IO windows, because they are scarce |
63 | */ | 89 | */ |
64 | 90 | static int alloc_io_space(struct pcmcia_socket *s, struct resource *res, | |
65 | static int alloc_io_space(struct pcmcia_socket *s, u_int attr, | 91 | unsigned int lines) |
66 | unsigned int *base, unsigned int num, u_int lines) | ||
67 | { | 92 | { |
68 | unsigned int align; | 93 | unsigned int align; |
94 | unsigned int base = res->start; | ||
95 | unsigned int num = res->end; | ||
96 | int ret; | ||
69 | 97 | ||
70 | align = (*base) ? (lines ? 1<<lines : 0) : 1; | 98 | res->flags |= IORESOURCE_IO; |
99 | |||
100 | dev_dbg(&s->dev, "alloc_io_space request for %pR, %d lines\n", | ||
101 | res, lines); | ||
102 | |||
103 | align = base ? (lines ? 1<<lines : 0) : 1; | ||
71 | if (align && (align < num)) { | 104 | if (align && (align < num)) { |
72 | if (*base) { | 105 | if (base) { |
73 | dev_dbg(&s->dev, "odd IO request: num %#x align %#x\n", | 106 | dev_dbg(&s->dev, "odd IO request\n"); |
74 | num, align); | ||
75 | align = 0; | 107 | align = 0; |
76 | } else | 108 | } else |
77 | while (align && (align < num)) | 109 | while (align && (align < num)) |
78 | align <<= 1; | 110 | align <<= 1; |
79 | } | 111 | } |
80 | if (*base & ~(align-1)) { | 112 | if (base & ~(align-1)) { |
81 | dev_dbg(&s->dev, "odd IO request: base %#x align %#x\n", | 113 | dev_dbg(&s->dev, "odd IO request\n"); |
82 | *base, align); | ||
83 | align = 0; | 114 | align = 0; |
84 | } | 115 | } |
85 | 116 | ||
86 | return s->resource_ops->find_io(s, attr, base, num, align); | 117 | ret = s->resource_ops->find_io(s, res->flags, &base, num, align, |
87 | } /* alloc_io_space */ | 118 | &res->parent); |
88 | 119 | if (ret) { | |
120 | dev_dbg(&s->dev, "alloc_io_space request failed (%d)\n", ret); | ||
121 | return -EINVAL; | ||
122 | } | ||
89 | 123 | ||
90 | static void release_io_space(struct pcmcia_socket *s, unsigned int base, | 124 | res->start = base; |
91 | unsigned int num) | 125 | res->end = res->start + num - 1; |
92 | { | ||
93 | int i; | ||
94 | 126 | ||
95 | for (i = 0; i < MAX_IO_WIN; i++) { | 127 | if (res->parent) { |
96 | if (!s->io[i].res) | 128 | ret = request_resource(res->parent, res); |
97 | continue; | 129 | if (ret) { |
98 | if ((s->io[i].res->start <= base) && | 130 | dev_warn(&s->dev, |
99 | (s->io[i].res->end >= base+num-1)) { | 131 | "request_resource %pR failed: %d\n", res, ret); |
100 | s->io[i].InUse -= num; | 132 | res->parent = NULL; |
101 | /* Free the window if no one else is using it */ | 133 | release_io_space(s, res); |
102 | if (s->io[i].InUse == 0) { | ||
103 | release_resource(s->io[i].res); | ||
104 | kfree(s->io[i].res); | ||
105 | s->io[i].res = NULL; | ||
106 | } | ||
107 | } | 134 | } |
108 | } | 135 | } |
109 | } /* release_io_space */ | 136 | dev_dbg(&s->dev, "alloc_io_space request result %d: %pR\n", ret, res); |
137 | return ret; | ||
138 | } /* alloc_io_space */ | ||
110 | 139 | ||
111 | 140 | ||
112 | /** pccard_access_configuration_register | 141 | /** |
142 | * pcmcia_access_config() - read or write card configuration registers | ||
113 | * | 143 | * |
114 | * Access_configuration_register() reads and writes configuration | 144 | * pcmcia_access_config() reads and writes configuration registers in |
115 | * registers in attribute memory. Memory window 0 is reserved for | 145 | * attribute memory. Memory window 0 is reserved for this and the tuple |
116 | * this and the tuple reading services. | 146 | * reading services. Drivers must use pcmcia_read_config_byte() or |
147 | * pcmcia_write_config_byte(). | ||
117 | */ | 148 | */ |
118 | 149 | static int pcmcia_access_config(struct pcmcia_device *p_dev, | |
119 | int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | 150 | off_t where, u8 *val, |
120 | conf_reg_t *reg) | 151 | int (*accessf) (struct pcmcia_socket *s, |
152 | int attr, unsigned int addr, | ||
153 | unsigned int len, void *ptr)) | ||
121 | { | 154 | { |
122 | struct pcmcia_socket *s; | 155 | struct pcmcia_socket *s; |
123 | config_t *c; | 156 | config_t *c; |
124 | int addr; | 157 | int addr; |
125 | u_char val; | ||
126 | int ret = 0; | 158 | int ret = 0; |
127 | 159 | ||
128 | if (!p_dev || !p_dev->function_config) | ||
129 | return -EINVAL; | ||
130 | |||
131 | s = p_dev->socket; | 160 | s = p_dev->socket; |
132 | 161 | ||
133 | mutex_lock(&s->ops_mutex); | 162 | mutex_lock(&s->ops_mutex); |
@@ -139,44 +168,57 @@ int pcmcia_access_configuration_register(struct pcmcia_device *p_dev, | |||
139 | return -EACCES; | 168 | return -EACCES; |
140 | } | 169 | } |
141 | 170 | ||
142 | addr = (c->ConfigBase + reg->Offset) >> 1; | 171 | addr = (c->ConfigBase + where) >> 1; |
172 | |||
173 | ret = accessf(s, 1, addr, 1, val); | ||
143 | 174 | ||
144 | switch (reg->Action) { | ||
145 | case CS_READ: | ||
146 | ret = pcmcia_read_cis_mem(s, 1, addr, 1, &val); | ||
147 | reg->Value = val; | ||
148 | break; | ||
149 | case CS_WRITE: | ||
150 | val = reg->Value; | ||
151 | pcmcia_write_cis_mem(s, 1, addr, 1, &val); | ||
152 | break; | ||
153 | default: | ||
154 | dev_dbg(&s->dev, "Invalid conf register request\n"); | ||
155 | ret = -EINVAL; | ||
156 | break; | ||
157 | } | ||
158 | mutex_unlock(&s->ops_mutex); | 175 | mutex_unlock(&s->ops_mutex); |
176 | |||
159 | return ret; | 177 | return ret; |
160 | } /* pcmcia_access_configuration_register */ | 178 | } /* pcmcia_access_config */ |
161 | EXPORT_SYMBOL(pcmcia_access_configuration_register); | 179 | |
180 | |||
181 | /** | ||
182 | * pcmcia_read_config_byte() - read a byte from a card configuration register | ||
183 | * | ||
184 | * pcmcia_read_config_byte() reads a byte from a configuration register in | ||
185 | * attribute memory. | ||
186 | */ | ||
187 | int pcmcia_read_config_byte(struct pcmcia_device *p_dev, off_t where, u8 *val) | ||
188 | { | ||
189 | return pcmcia_access_config(p_dev, where, val, pcmcia_read_cis_mem); | ||
190 | } | ||
191 | EXPORT_SYMBOL(pcmcia_read_config_byte); | ||
192 | |||
193 | |||
194 | /** | ||
195 | * pcmcia_write_config_byte() - write a byte to a card configuration register | ||
196 | * | ||
197 | * pcmcia_write_config_byte() writes a byte to a configuration register in | ||
198 | * attribute memory. | ||
199 | */ | ||
200 | int pcmcia_write_config_byte(struct pcmcia_device *p_dev, off_t where, u8 val) | ||
201 | { | ||
202 | return pcmcia_access_config(p_dev, where, &val, pcmcia_write_cis_mem); | ||
203 | } | ||
204 | EXPORT_SYMBOL(pcmcia_write_config_byte); | ||
162 | 205 | ||
163 | 206 | ||
164 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, | 207 | int pcmcia_map_mem_page(struct pcmcia_device *p_dev, window_handle_t wh, |
165 | memreq_t *req) | 208 | unsigned int offset) |
166 | { | 209 | { |
167 | struct pcmcia_socket *s = p_dev->socket; | 210 | struct pcmcia_socket *s = p_dev->socket; |
211 | struct resource *res = wh; | ||
212 | unsigned int w; | ||
168 | int ret; | 213 | int ret; |
169 | 214 | ||
170 | wh--; | 215 | w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; |
171 | if (wh >= MAX_WIN) | 216 | if (w >= MAX_WIN) |
172 | return -EINVAL; | 217 | return -EINVAL; |
173 | if (req->Page != 0) { | 218 | |
174 | dev_dbg(&s->dev, "failure: requested page is zero\n"); | ||
175 | return -EINVAL; | ||
176 | } | ||
177 | mutex_lock(&s->ops_mutex); | 219 | mutex_lock(&s->ops_mutex); |
178 | s->win[wh].card_start = req->CardOffset; | 220 | s->win[w].card_start = offset; |
179 | ret = s->ops->set_mem_map(s, &s->win[wh]); | 221 | ret = s->ops->set_mem_map(s, &s->win[w]); |
180 | if (ret) | 222 | if (ret) |
181 | dev_warn(&s->dev, "failed to set_mem_map\n"); | 223 | dev_warn(&s->dev, "failed to set_mem_map\n"); |
182 | mutex_unlock(&s->ops_mutex); | 224 | mutex_unlock(&s->ops_mutex); |
@@ -316,31 +358,25 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev) | |||
316 | * don't bother checking the port ranges against the current socket | 358 | * don't bother checking the port ranges against the current socket |
317 | * values. | 359 | * values. |
318 | */ | 360 | */ |
319 | static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) | 361 | static int pcmcia_release_io(struct pcmcia_device *p_dev) |
320 | { | 362 | { |
321 | struct pcmcia_socket *s = p_dev->socket; | 363 | struct pcmcia_socket *s = p_dev->socket; |
322 | int ret = -EINVAL; | 364 | int ret = -EINVAL; |
323 | config_t *c; | 365 | config_t *c; |
324 | 366 | ||
325 | mutex_lock(&s->ops_mutex); | 367 | mutex_lock(&s->ops_mutex); |
326 | c = p_dev->function_config; | ||
327 | |||
328 | if (!p_dev->_io) | 368 | if (!p_dev->_io) |
329 | goto out; | 369 | goto out; |
330 | 370 | ||
331 | p_dev->_io = 0; | 371 | c = p_dev->function_config; |
332 | 372 | ||
333 | if ((c->io.BasePort1 != req->BasePort1) || | 373 | release_io_space(s, &c->io[0]); |
334 | (c->io.NumPorts1 != req->NumPorts1) || | ||
335 | (c->io.BasePort2 != req->BasePort2) || | ||
336 | (c->io.NumPorts2 != req->NumPorts2)) | ||
337 | goto out; | ||
338 | 374 | ||
339 | c->state &= ~CONFIG_IO_REQ; | 375 | if (c->io[1].end) |
376 | release_io_space(s, &c->io[1]); | ||
340 | 377 | ||
341 | release_io_space(s, req->BasePort1, req->NumPorts1); | 378 | p_dev->_io = 0; |
342 | if (req->NumPorts2) | 379 | c->state &= ~CONFIG_IO_REQ; |
343 | release_io_space(s, req->BasePort2, req->NumPorts2); | ||
344 | 380 | ||
345 | out: | 381 | out: |
346 | mutex_unlock(&s->ops_mutex); | 382 | mutex_unlock(&s->ops_mutex); |
@@ -349,19 +385,22 @@ out: | |||
349 | } /* pcmcia_release_io */ | 385 | } /* pcmcia_release_io */ |
350 | 386 | ||
351 | 387 | ||
352 | int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | 388 | int pcmcia_release_window(struct pcmcia_device *p_dev, struct resource *res) |
353 | { | 389 | { |
354 | struct pcmcia_socket *s = p_dev->socket; | 390 | struct pcmcia_socket *s = p_dev->socket; |
355 | pccard_mem_map *win; | 391 | pccard_mem_map *win; |
392 | unsigned int w; | ||
393 | |||
394 | dev_dbg(&p_dev->dev, "releasing window %pR\n", res); | ||
356 | 395 | ||
357 | wh--; | 396 | w = ((res->flags & IORESOURCE_BITS & WIN_FLAGS_REQ) >> 2) - 1; |
358 | if (wh >= MAX_WIN) | 397 | if (w >= MAX_WIN) |
359 | return -EINVAL; | 398 | return -EINVAL; |
360 | 399 | ||
361 | mutex_lock(&s->ops_mutex); | 400 | mutex_lock(&s->ops_mutex); |
362 | win = &s->win[wh]; | 401 | win = &s->win[w]; |
363 | 402 | ||
364 | if (!(p_dev->_win & CLIENT_WIN_REQ(wh))) { | 403 | if (!(p_dev->_win & CLIENT_WIN_REQ(w))) { |
365 | dev_dbg(&s->dev, "not releasing unknown window\n"); | 404 | dev_dbg(&s->dev, "not releasing unknown window\n"); |
366 | mutex_unlock(&s->ops_mutex); | 405 | mutex_unlock(&s->ops_mutex); |
367 | return -EINVAL; | 406 | return -EINVAL; |
@@ -370,15 +409,16 @@ int pcmcia_release_window(struct pcmcia_device *p_dev, window_handle_t wh) | |||
370 | /* Shut down memory window */ | 409 | /* Shut down memory window */ |
371 | win->flags &= ~MAP_ACTIVE; | 410 | win->flags &= ~MAP_ACTIVE; |
372 | s->ops->set_mem_map(s, win); | 411 | s->ops->set_mem_map(s, win); |
373 | s->state &= ~SOCKET_WIN_REQ(wh); | 412 | s->state &= ~SOCKET_WIN_REQ(w); |
374 | 413 | ||
375 | /* Release system memory */ | 414 | /* Release system memory */ |
376 | if (win->res) { | 415 | if (win->res) { |
416 | release_resource(res); | ||
377 | release_resource(win->res); | 417 | release_resource(win->res); |
378 | kfree(win->res); | 418 | kfree(win->res); |
379 | win->res = NULL; | 419 | win->res = NULL; |
380 | } | 420 | } |
381 | p_dev->_win &= ~CLIENT_WIN_REQ(wh); | 421 | p_dev->_win &= ~CLIENT_WIN_REQ(w); |
382 | mutex_unlock(&s->ops_mutex); | 422 | mutex_unlock(&s->ops_mutex); |
383 | 423 | ||
384 | return 0; | 424 | return 0; |
@@ -473,13 +513,13 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
473 | pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus); | 513 | pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus); |
474 | } | 514 | } |
475 | if (req->Present & PRESENT_IOBASE_0) { | 515 | if (req->Present & PRESENT_IOBASE_0) { |
476 | u_char b = c->io.BasePort1 & 0xff; | 516 | u8 b = c->io[0].start & 0xff; |
477 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); | 517 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); |
478 | b = (c->io.BasePort1 >> 8) & 0xff; | 518 | b = (c->io[0].start >> 8) & 0xff; |
479 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); | 519 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); |
480 | } | 520 | } |
481 | if (req->Present & PRESENT_IOSIZE) { | 521 | if (req->Present & PRESENT_IOSIZE) { |
482 | u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1; | 522 | u8 b = resource_size(&c->io[0]) + resource_size(&c->io[1]) - 1; |
483 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); | 523 | pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); |
484 | } | 524 | } |
485 | 525 | ||
@@ -513,28 +553,29 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev, | |||
513 | EXPORT_SYMBOL(pcmcia_request_configuration); | 553 | EXPORT_SYMBOL(pcmcia_request_configuration); |
514 | 554 | ||
515 | 555 | ||
516 | /** pcmcia_request_io | 556 | /** |
557 | * pcmcia_request_io() - attempt to reserve port ranges for PCMCIA devices | ||
517 | * | 558 | * |
518 | * Request_io() reserves ranges of port addresses for a socket. | 559 | * pcmcia_request_io() attepts to reserve the IO port ranges specified in |
519 | * I have not implemented range sharing or alias addressing. | 560 | * &struct pcmcia_device @p_dev->resource[0] and @p_dev->resource[1]. The |
561 | * "start" value is the requested start of the IO port resource; "end" | ||
562 | * reflects the number of ports requested. The number of IO lines requested | ||
563 | * is specified in &struct pcmcia_device @p_dev->io_lines. | ||
520 | */ | 564 | */ |
521 | int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) | 565 | int pcmcia_request_io(struct pcmcia_device *p_dev) |
522 | { | 566 | { |
523 | struct pcmcia_socket *s = p_dev->socket; | 567 | struct pcmcia_socket *s = p_dev->socket; |
524 | config_t *c; | 568 | config_t *c = p_dev->function_config; |
525 | int ret = -EINVAL; | 569 | int ret = -EINVAL; |
526 | 570 | ||
527 | mutex_lock(&s->ops_mutex); | 571 | mutex_lock(&s->ops_mutex); |
572 | dev_dbg(&s->dev, "pcmcia_request_io: %pR , %pR", &c->io[0], &c->io[1]); | ||
528 | 573 | ||
529 | if (!(s->state & SOCKET_PRESENT)) { | 574 | if (!(s->state & SOCKET_PRESENT)) { |
530 | dev_dbg(&s->dev, "No card present\n"); | 575 | dev_dbg(&s->dev, "pcmcia_request_io: No card present\n"); |
531 | goto out; | 576 | goto out; |
532 | } | 577 | } |
533 | 578 | ||
534 | if (!req) | ||
535 | goto out; | ||
536 | |||
537 | c = p_dev->function_config; | ||
538 | if (c->state & CONFIG_LOCKED) { | 579 | if (c->state & CONFIG_LOCKED) { |
539 | dev_dbg(&s->dev, "Configuration is locked\n"); | 580 | dev_dbg(&s->dev, "Configuration is locked\n"); |
540 | goto out; | 581 | goto out; |
@@ -543,40 +584,25 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) | |||
543 | dev_dbg(&s->dev, "IO already configured\n"); | 584 | dev_dbg(&s->dev, "IO already configured\n"); |
544 | goto out; | 585 | goto out; |
545 | } | 586 | } |
546 | if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) { | ||
547 | dev_dbg(&s->dev, "bad attribute setting for IO region 1\n"); | ||
548 | goto out; | ||
549 | } | ||
550 | if ((req->NumPorts2 > 0) && | ||
551 | (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) { | ||
552 | dev_dbg(&s->dev, "bad attribute setting for IO region 2\n"); | ||
553 | goto out; | ||
554 | } | ||
555 | 587 | ||
556 | dev_dbg(&s->dev, "trying to allocate resource 1\n"); | 588 | ret = alloc_io_space(s, &c->io[0], p_dev->io_lines); |
557 | ret = alloc_io_space(s, req->Attributes1, &req->BasePort1, | 589 | if (ret) |
558 | req->NumPorts1, req->IOAddrLines); | ||
559 | if (ret) { | ||
560 | dev_dbg(&s->dev, "allocation of resource 1 failed\n"); | ||
561 | goto out; | 590 | goto out; |
562 | } | ||
563 | 591 | ||
564 | if (req->NumPorts2) { | 592 | if (c->io[1].end) { |
565 | dev_dbg(&s->dev, "trying to allocate resource 2\n"); | 593 | ret = alloc_io_space(s, &c->io[1], p_dev->io_lines); |
566 | ret = alloc_io_space(s, req->Attributes2, &req->BasePort2, | ||
567 | req->NumPorts2, req->IOAddrLines); | ||
568 | if (ret) { | 594 | if (ret) { |
569 | dev_dbg(&s->dev, "allocation of resource 2 failed\n"); | 595 | release_io_space(s, &c->io[0]); |
570 | release_io_space(s, req->BasePort1, req->NumPorts1); | ||
571 | goto out; | 596 | goto out; |
572 | } | 597 | } |
573 | } | 598 | } else |
599 | c->io[1].start = 0; | ||
574 | 600 | ||
575 | c->io = *req; | ||
576 | c->state |= CONFIG_IO_REQ; | 601 | c->state |= CONFIG_IO_REQ; |
577 | p_dev->_io = 1; | 602 | p_dev->_io = 1; |
578 | dev_dbg(&s->dev, "allocating resources succeeded: %d\n", ret); | ||
579 | 603 | ||
604 | dev_dbg(&s->dev, "pcmcia_request_io succeeded: %pR , %pR", | ||
605 | &c->io[0], &c->io[1]); | ||
580 | out: | 606 | out: |
581 | mutex_unlock(&s->ops_mutex); | 607 | mutex_unlock(&s->ops_mutex); |
582 | 608 | ||
@@ -651,7 +677,7 @@ EXPORT_SYMBOL(__pcmcia_request_exclusive_irq); | |||
651 | #ifdef CONFIG_PCMCIA_PROBE | 677 | #ifdef CONFIG_PCMCIA_PROBE |
652 | 678 | ||
653 | /* mask of IRQs already reserved by other cards, we should avoid using them */ | 679 | /* mask of IRQs already reserved by other cards, we should avoid using them */ |
654 | static u8 pcmcia_used_irq[NR_IRQS]; | 680 | static u8 pcmcia_used_irq[32]; |
655 | 681 | ||
656 | static irqreturn_t test_action(int cpl, void *dev_id) | 682 | static irqreturn_t test_action(int cpl, void *dev_id) |
657 | { | 683 | { |
@@ -674,6 +700,9 @@ static int pcmcia_setup_isa_irq(struct pcmcia_device *p_dev, int type) | |||
674 | for (try = 0; try < 64; try++) { | 700 | for (try = 0; try < 64; try++) { |
675 | irq = try % 32; | 701 | irq = try % 32; |
676 | 702 | ||
703 | if (irq > NR_IRQS) | ||
704 | continue; | ||
705 | |||
677 | /* marked as available by driver, not blocked by userspace? */ | 706 | /* marked as available by driver, not blocked by userspace? */ |
678 | if (!((mask >> irq) & 1)) | 707 | if (!((mask >> irq) & 1)) |
679 | continue; | 708 | continue; |
@@ -767,23 +796,18 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
767 | struct pcmcia_socket *s = p_dev->socket; | 796 | struct pcmcia_socket *s = p_dev->socket; |
768 | pccard_mem_map *win; | 797 | pccard_mem_map *win; |
769 | u_long align; | 798 | u_long align; |
799 | struct resource *res; | ||
770 | int w; | 800 | int w; |
771 | 801 | ||
772 | if (!(s->state & SOCKET_PRESENT)) { | 802 | if (!(s->state & SOCKET_PRESENT)) { |
773 | dev_dbg(&s->dev, "No card present\n"); | 803 | dev_dbg(&s->dev, "No card present\n"); |
774 | return -ENODEV; | 804 | return -ENODEV; |
775 | } | 805 | } |
776 | if (req->Attributes & (WIN_PAGED | WIN_SHARED)) { | ||
777 | dev_dbg(&s->dev, "bad attribute setting for iomem region\n"); | ||
778 | return -EINVAL; | ||
779 | } | ||
780 | 806 | ||
781 | /* Window size defaults to smallest available */ | 807 | /* Window size defaults to smallest available */ |
782 | if (req->Size == 0) | 808 | if (req->Size == 0) |
783 | req->Size = s->map_size; | 809 | req->Size = s->map_size; |
784 | align = (((s->features & SS_CAP_MEM_ALIGN) || | 810 | align = (s->features & SS_CAP_MEM_ALIGN) ? req->Size : s->map_size; |
785 | (req->Attributes & WIN_STRICT_ALIGN)) ? | ||
786 | req->Size : s->map_size); | ||
787 | if (req->Size & (s->map_size-1)) { | 811 | if (req->Size & (s->map_size-1)) { |
788 | dev_dbg(&s->dev, "invalid map size\n"); | 812 | dev_dbg(&s->dev, "invalid map size\n"); |
789 | return -EINVAL; | 813 | return -EINVAL; |
@@ -797,20 +821,21 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
797 | align = 0; | 821 | align = 0; |
798 | 822 | ||
799 | /* Allocate system memory window */ | 823 | /* Allocate system memory window */ |
824 | mutex_lock(&s->ops_mutex); | ||
800 | for (w = 0; w < MAX_WIN; w++) | 825 | for (w = 0; w < MAX_WIN; w++) |
801 | if (!(s->state & SOCKET_WIN_REQ(w))) | 826 | if (!(s->state & SOCKET_WIN_REQ(w))) |
802 | break; | 827 | break; |
803 | if (w == MAX_WIN) { | 828 | if (w == MAX_WIN) { |
804 | dev_dbg(&s->dev, "all windows are used already\n"); | 829 | dev_dbg(&s->dev, "all windows are used already\n"); |
830 | mutex_unlock(&s->ops_mutex); | ||
805 | return -EINVAL; | 831 | return -EINVAL; |
806 | } | 832 | } |
807 | 833 | ||
808 | mutex_lock(&s->ops_mutex); | ||
809 | win = &s->win[w]; | 834 | win = &s->win[w]; |
810 | 835 | ||
811 | if (!(s->features & SS_CAP_STATIC_MAP)) { | 836 | if (!(s->features & SS_CAP_STATIC_MAP)) { |
812 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, | 837 | win->res = pcmcia_find_mem_region(req->Base, req->Size, align, |
813 | (req->Attributes & WIN_MAP_BELOW_1MB), s); | 838 | 0, s); |
814 | if (!win->res) { | 839 | if (!win->res) { |
815 | dev_dbg(&s->dev, "allocating mem region failed\n"); | 840 | dev_dbg(&s->dev, "allocating mem region failed\n"); |
816 | mutex_unlock(&s->ops_mutex); | 841 | mutex_unlock(&s->ops_mutex); |
@@ -821,16 +846,8 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
821 | 846 | ||
822 | /* Configure the socket controller */ | 847 | /* Configure the socket controller */ |
823 | win->map = w+1; | 848 | win->map = w+1; |
824 | win->flags = 0; | 849 | win->flags = req->Attributes; |
825 | win->speed = req->AccessSpeed; | 850 | win->speed = req->AccessSpeed; |
826 | if (req->Attributes & WIN_MEMORY_TYPE) | ||
827 | win->flags |= MAP_ATTRIB; | ||
828 | if (req->Attributes & WIN_ENABLE) | ||
829 | win->flags |= MAP_ACTIVE; | ||
830 | if (req->Attributes & WIN_DATA_WIDTH_16) | ||
831 | win->flags |= MAP_16BIT; | ||
832 | if (req->Attributes & WIN_USE_WAIT) | ||
833 | win->flags |= MAP_USE_WAIT; | ||
834 | win->card_start = 0; | 851 | win->card_start = 0; |
835 | 852 | ||
836 | if (s->ops->set_mem_map(s, win) != 0) { | 853 | if (s->ops->set_mem_map(s, win) != 0) { |
@@ -846,8 +863,21 @@ int pcmcia_request_window(struct pcmcia_device *p_dev, win_req_t *req, window_ha | |||
846 | else | 863 | else |
847 | req->Base = win->res->start; | 864 | req->Base = win->res->start; |
848 | 865 | ||
866 | /* convert to new-style resources */ | ||
867 | res = p_dev->resource[w + MAX_IO_WIN]; | ||
868 | res->start = req->Base; | ||
869 | res->end = req->Base + req->Size - 1; | ||
870 | res->flags &= ~IORESOURCE_BITS; | ||
871 | res->flags |= (req->Attributes & WIN_FLAGS_MAP) | (win->map << 2); | ||
872 | res->flags |= IORESOURCE_MEM; | ||
873 | res->parent = win->res; | ||
874 | if (win->res) | ||
875 | request_resource(&iomem_resource, res); | ||
876 | |||
877 | dev_dbg(&s->dev, "request_window results in %pR\n", res); | ||
878 | |||
849 | mutex_unlock(&s->ops_mutex); | 879 | mutex_unlock(&s->ops_mutex); |
850 | *wh = w + 1; | 880 | *wh = res; |
851 | 881 | ||
852 | return 0; | 882 | return 0; |
853 | } /* pcmcia_request_window */ | 883 | } /* pcmcia_request_window */ |
@@ -855,13 +885,18 @@ EXPORT_SYMBOL(pcmcia_request_window); | |||
855 | 885 | ||
856 | void pcmcia_disable_device(struct pcmcia_device *p_dev) | 886 | void pcmcia_disable_device(struct pcmcia_device *p_dev) |
857 | { | 887 | { |
888 | int i; | ||
889 | for (i = 0; i < MAX_WIN; i++) { | ||
890 | struct resource *res = p_dev->resource[MAX_IO_WIN + i]; | ||
891 | if (res->flags & WIN_FLAGS_REQ) | ||
892 | pcmcia_release_window(p_dev, res); | ||
893 | } | ||
894 | |||
858 | pcmcia_release_configuration(p_dev); | 895 | pcmcia_release_configuration(p_dev); |
859 | pcmcia_release_io(p_dev, &p_dev->io); | 896 | pcmcia_release_io(p_dev); |
860 | if (p_dev->_irq) { | 897 | if (p_dev->_irq) { |
861 | free_irq(p_dev->irq, p_dev->priv); | 898 | free_irq(p_dev->irq, p_dev->priv); |
862 | p_dev->_irq = 0; | 899 | p_dev->_irq = 0; |
863 | } | 900 | } |
864 | if (p_dev->win) | ||
865 | pcmcia_release_window(p_dev, p_dev->win); | ||
866 | } | 901 | } |
867 | EXPORT_SYMBOL(pcmcia_disable_device); | 902 | EXPORT_SYMBOL(pcmcia_disable_device); |
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index b61a13663a0a..b8a869af0f44 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | 19 | ||
20 | #include <pcmcia/cs_types.h> | ||
21 | #include <pcmcia/ss.h> | 20 | #include <pcmcia/ss.h> |
22 | #include <pcmcia/cs.h> | 21 | #include <pcmcia/cs.h> |
23 | 22 | ||
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index f370476d5417..ae07b4db8a6e 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <mach/pxa2xx-regs.h> | 32 | #include <mach/pxa2xx-regs.h> |
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | 34 | ||
35 | #include <pcmcia/cs_types.h> | ||
36 | #include <pcmcia/ss.h> | 35 | #include <pcmcia/ss.h> |
37 | #include <pcmcia/cistpl.h> | 36 | #include <pcmcia/cistpl.h> |
38 | 37 | ||
diff --git a/drivers/pcmcia/rsrc_iodyn.c b/drivers/pcmcia/rsrc_iodyn.c index d0bf35021065..8510c35d2952 100644 --- a/drivers/pcmcia/rsrc_iodyn.c +++ b/drivers/pcmcia/rsrc_iodyn.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | 18 | ||
19 | #include <pcmcia/cs_types.h> | ||
20 | #include <pcmcia/ss.h> | 19 | #include <pcmcia/ss.h> |
21 | #include <pcmcia/cs.h> | 20 | #include <pcmcia/cs.h> |
22 | #include <pcmcia/cistpl.h> | 21 | #include <pcmcia/cistpl.h> |
@@ -88,7 +87,7 @@ static struct resource *__iodyn_find_io_region(struct pcmcia_socket *s, | |||
88 | 87 | ||
89 | static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, | 88 | static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, |
90 | unsigned int *base, unsigned int num, | 89 | unsigned int *base, unsigned int num, |
91 | unsigned int align) | 90 | unsigned int align, struct resource **parent) |
92 | { | 91 | { |
93 | int i, ret = 0; | 92 | int i, ret = 0; |
94 | 93 | ||
@@ -129,6 +128,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
129 | ((res->flags & ~IORESOURCE_BITS) | | 128 | ((res->flags & ~IORESOURCE_BITS) | |
130 | (attr & IORESOURCE_BITS)); | 129 | (attr & IORESOURCE_BITS)); |
131 | s->io[i].InUse = num; | 130 | s->io[i].InUse = num; |
131 | *parent = res; | ||
132 | return 0; | 132 | return 0; |
133 | } | 133 | } |
134 | 134 | ||
@@ -140,6 +140,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
140 | continue; | 140 | continue; |
141 | *base = try; | 141 | *base = try; |
142 | s->io[i].InUse += num; | 142 | s->io[i].InUse += num; |
143 | *parent = res; | ||
143 | return 0; | 144 | return 0; |
144 | } | 145 | } |
145 | 146 | ||
@@ -152,6 +153,7 @@ static int iodyn_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
152 | continue; | 153 | continue; |
153 | *base = try; | 154 | *base = try; |
154 | s->io[i].InUse += num; | 155 | s->io[i].InUse += num; |
156 | *parent = res; | ||
155 | return 0; | 157 | return 0; |
156 | } | 158 | } |
157 | } | 159 | } |
@@ -164,8 +166,6 @@ struct pccard_resource_ops pccard_iodyn_ops = { | |||
164 | .validate_mem = NULL, | 166 | .validate_mem = NULL, |
165 | .find_io = iodyn_find_io, | 167 | .find_io = iodyn_find_io, |
166 | .find_mem = NULL, | 168 | .find_mem = NULL, |
167 | .add_io = NULL, | ||
168 | .add_mem = NULL, | ||
169 | .init = static_init, | 169 | .init = static_init, |
170 | .exit = NULL, | 170 | .exit = NULL, |
171 | }; | 171 | }; |
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c index 142efac3c387..4e80421fd908 100644 --- a/drivers/pcmcia/rsrc_mgr.c +++ b/drivers/pcmcia/rsrc_mgr.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | 18 | ||
19 | #include <pcmcia/cs_types.h> | ||
20 | #include <pcmcia/ss.h> | 19 | #include <pcmcia/ss.h> |
21 | #include <pcmcia/cs.h> | 20 | #include <pcmcia/cs.h> |
22 | #include <pcmcia/cistpl.h> | 21 | #include <pcmcia/cistpl.h> |
@@ -48,11 +47,12 @@ struct resource *pcmcia_make_resource(unsigned long start, unsigned long end, | |||
48 | 47 | ||
49 | static int static_find_io(struct pcmcia_socket *s, unsigned int attr, | 48 | static int static_find_io(struct pcmcia_socket *s, unsigned int attr, |
50 | unsigned int *base, unsigned int num, | 49 | unsigned int *base, unsigned int num, |
51 | unsigned int align) | 50 | unsigned int align, struct resource **parent) |
52 | { | 51 | { |
53 | if (!s->io_offset) | 52 | if (!s->io_offset) |
54 | return -EINVAL; | 53 | return -EINVAL; |
55 | *base = s->io_offset | (*base & 0x0fff); | 54 | *base = s->io_offset | (*base & 0x0fff); |
55 | *parent = NULL; | ||
56 | 56 | ||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
@@ -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..96f348b35fde 100644 --- a/drivers/pcmcia/rsrc_nonstatic.c +++ b/drivers/pcmcia/rsrc_nonstatic.c | |||
@@ -28,7 +28,6 @@ | |||
28 | 28 | ||
29 | #include <asm/irq.h> | 29 | #include <asm/irq.h> |
30 | 30 | ||
31 | #include <pcmcia/cs_types.h> | ||
32 | #include <pcmcia/ss.h> | 31 | #include <pcmcia/ss.h> |
33 | #include <pcmcia/cs.h> | 32 | #include <pcmcia/cs.h> |
34 | #include <pcmcia/cistpl.h> | 33 | #include <pcmcia/cistpl.h> |
@@ -64,6 +63,9 @@ struct socket_data { | |||
64 | #define MEM_PROBE_LOW (1 << 0) | 63 | #define MEM_PROBE_LOW (1 << 0) |
65 | #define MEM_PROBE_HIGH (1 << 1) | 64 | #define MEM_PROBE_HIGH (1 << 1) |
66 | 65 | ||
66 | /* Action field */ | ||
67 | #define REMOVE_MANAGED_RESOURCE 1 | ||
68 | #define ADD_MANAGED_RESOURCE 2 | ||
67 | 69 | ||
68 | /*====================================================================== | 70 | /*====================================================================== |
69 | 71 | ||
@@ -716,7 +718,7 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s, | |||
716 | 718 | ||
717 | static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, | 719 | static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, |
718 | unsigned int *base, unsigned int num, | 720 | unsigned int *base, unsigned int num, |
719 | unsigned int align) | 721 | unsigned int align, struct resource **parent) |
720 | { | 722 | { |
721 | int i, ret = 0; | 723 | int i, ret = 0; |
722 | 724 | ||
@@ -758,6 +760,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
758 | ((res->flags & ~IORESOURCE_BITS) | | 760 | ((res->flags & ~IORESOURCE_BITS) | |
759 | (attr & IORESOURCE_BITS)); | 761 | (attr & IORESOURCE_BITS)); |
760 | s->io[i].InUse = num; | 762 | s->io[i].InUse = num; |
763 | *parent = res; | ||
761 | return 0; | 764 | return 0; |
762 | } | 765 | } |
763 | 766 | ||
@@ -773,6 +776,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
773 | continue; | 776 | continue; |
774 | *base = try; | 777 | *base = try; |
775 | s->io[i].InUse += num; | 778 | s->io[i].InUse += num; |
779 | *parent = res; | ||
776 | return 0; | 780 | return 0; |
777 | } | 781 | } |
778 | } | 782 | } |
@@ -791,6 +795,7 @@ static int nonstatic_find_io(struct pcmcia_socket *s, unsigned int attr, | |||
791 | continue; | 795 | continue; |
792 | *base = try; | 796 | *base = try; |
793 | s->io[i].InUse += num; | 797 | s->io[i].InUse += num; |
798 | *parent = res; | ||
794 | return 0; | 799 | return 0; |
795 | } | 800 | } |
796 | } | 801 | } |
@@ -1055,8 +1060,6 @@ struct pccard_resource_ops pccard_nonstatic_ops = { | |||
1055 | .validate_mem = pcmcia_nonstatic_validate_mem, | 1060 | .validate_mem = pcmcia_nonstatic_validate_mem, |
1056 | .find_io = nonstatic_find_io, | 1061 | .find_io = nonstatic_find_io, |
1057 | .find_mem = nonstatic_find_mem_region, | 1062 | .find_mem = nonstatic_find_mem_region, |
1058 | .add_io = adjust_io, | ||
1059 | .add_mem = adjust_memory, | ||
1060 | .init = nonstatic_init, | 1063 | .init = nonstatic_init, |
1061 | .exit = nonstatic_release_resource_db, | 1064 | .exit = nonstatic_release_resource_db, |
1062 | }; | 1065 | }; |
@@ -1115,8 +1118,6 @@ static ssize_t store_io_db(struct device *dev, | |||
1115 | 1118 | ||
1116 | mutex_lock(&s->ops_mutex); | 1119 | mutex_lock(&s->ops_mutex); |
1117 | ret = adjust_io(s, add, start_addr, end_addr); | 1120 | ret = adjust_io(s, add, start_addr, end_addr); |
1118 | if (!ret) | ||
1119 | s->resource_setup_new = 1; | ||
1120 | mutex_unlock(&s->ops_mutex); | 1121 | mutex_unlock(&s->ops_mutex); |
1121 | 1122 | ||
1122 | return ret ? ret : count; | 1123 | return ret ? ret : count; |
@@ -1183,8 +1184,6 @@ static ssize_t store_mem_db(struct device *dev, | |||
1183 | 1184 | ||
1184 | mutex_lock(&s->ops_mutex); | 1185 | mutex_lock(&s->ops_mutex); |
1185 | ret = adjust_memory(s, add, start_addr, end_addr); | 1186 | ret = adjust_memory(s, add, start_addr, end_addr); |
1186 | if (!ret) | ||
1187 | s->resource_setup_new = 1; | ||
1188 | mutex_unlock(&s->ops_mutex); | 1187 | mutex_unlock(&s->ops_mutex); |
1189 | 1188 | ||
1190 | return ret ? ret : count; | 1189 | return ret ? ret : count; |
diff --git a/drivers/pcmcia/sa1100_generic.c b/drivers/pcmcia/sa1100_generic.c index edbd8c472628..e09851480295 100644 --- a/drivers/pcmcia/sa1100_generic.c +++ b/drivers/pcmcia/sa1100_generic.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | 37 | ||
38 | #include <pcmcia/cs_types.h> | ||
39 | #include <pcmcia/cs.h> | 38 | #include <pcmcia/cs.h> |
40 | #include <pcmcia/ss.h> | 39 | #include <pcmcia/ss.h> |
41 | 40 | ||
diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index e40824ce6b0b..3fba3a679128 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h | |||
@@ -11,7 +11,6 @@ | |||
11 | 11 | ||
12 | /* include the world */ | 12 | /* include the world */ |
13 | #include <linux/cpufreq.h> | 13 | #include <linux/cpufreq.h> |
14 | #include <pcmcia/cs_types.h> | ||
15 | #include <pcmcia/cs.h> | 14 | #include <pcmcia/cs.h> |
16 | #include <pcmcia/ss.h> | 15 | #include <pcmcia/ss.h> |
17 | #include <pcmcia/cistpl.h> | 16 | #include <pcmcia/cistpl.h> |
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index 80e36bc407da..cb0d3ace18bd 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/system.h> | 26 | #include <asm/system.h> |
27 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
28 | 28 | ||
29 | #include <pcmcia/cs_types.h> | ||
30 | #include <pcmcia/ss.h> | 29 | #include <pcmcia/ss.h> |
31 | #include <pcmcia/cs.h> | 30 | #include <pcmcia/cs.h> |
32 | #include <pcmcia/cistpl.h> | 31 | #include <pcmcia/cistpl.h> |
diff --git a/drivers/pcmcia/tcic.c b/drivers/pcmcia/tcic.c index 56004a1b5bba..be0d841c7ebd 100644 --- a/drivers/pcmcia/tcic.c +++ b/drivers/pcmcia/tcic.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <asm/io.h> | 49 | #include <asm/io.h> |
50 | #include <asm/system.h> | 50 | #include <asm/system.h> |
51 | 51 | ||
52 | #include <pcmcia/cs_types.h> | ||
53 | #include <pcmcia/cs.h> | 52 | #include <pcmcia/cs.h> |
54 | #include <pcmcia/ss.h> | 53 | #include <pcmcia/ss.h> |
55 | #include "tcic.h" | 54 | #include "tcic.h" |
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c index 201ccfa1e97b..fa88c360c37a 100644 --- a/drivers/pcmcia/xxs1500_ss.c +++ b/drivers/pcmcia/xxs1500_ss.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | 19 | ||
20 | #include <pcmcia/cs_types.h> | ||
21 | #include <pcmcia/cs.h> | 20 | #include <pcmcia/cs.h> |
22 | #include <pcmcia/ss.h> | 21 | #include <pcmcia/ss.h> |
23 | #include <pcmcia/cistpl.h> | 22 | #include <pcmcia/cistpl.h> |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index f1d41374eea7..414d9a6f9a32 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | 21 | ||
22 | #include <pcmcia/cs_types.h> | ||
23 | #include <pcmcia/ss.h> | 22 | #include <pcmcia/ss.h> |
24 | #include <pcmcia/cs.h> | 23 | #include <pcmcia/cs.h> |
25 | 24 | ||