aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia')
-rw-r--r--drivers/pcmcia/Kconfig7
-rw-r--r--drivers/pcmcia/Makefile3
-rw-r--r--drivers/pcmcia/at91_cf.c365
-rw-r--r--drivers/pcmcia/cistpl.c1
-rw-r--r--drivers/pcmcia/cs.c43
-rw-r--r--drivers/pcmcia/cs_internal.h19
-rw-r--r--drivers/pcmcia/ds.c249
-rw-r--r--drivers/pcmcia/ds_internal.h4
-rw-r--r--drivers/pcmcia/i82092.c1
-rw-r--r--drivers/pcmcia/i82365.c1
-rw-r--r--drivers/pcmcia/pcmcia_compat.c65
-rw-r--r--drivers/pcmcia/pcmcia_ioctl.c81
-rw-r--r--drivers/pcmcia/pcmcia_resource.c228
-rw-r--r--drivers/pcmcia/pd6729.c1
-rw-r--r--drivers/pcmcia/rsrc_mgr.c5
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c41
-rw-r--r--drivers/pcmcia/sa1100_cerf.c1
-rw-r--r--drivers/pcmcia/socket_sysfs.c10
-rw-r--r--drivers/pcmcia/ti113x.h1
19 files changed, 767 insertions, 359 deletions
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 1f4ad0e7836e..cba6c9eef28e 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -263,6 +263,13 @@ config OMAP_CF
263 Say Y here to support the CompactFlash controller on OMAP. 263 Say Y here to support the CompactFlash controller on OMAP.
264 Note that this doesn't support "True IDE" mode. 264 Note that this doesn't support "True IDE" mode.
265 265
266config AT91_CF
267 tristate "AT91 CompactFlash Controller"
268 depends on PCMCIA && ARCH_AT91RM9200
269 help
270 Say Y here to support the CompactFlash controller on AT91 chips.
271 Or choose M to compile the driver as a module named "at91_cf".
272
266config PCCARD_NONSTATIC 273config PCCARD_NONSTATIC
267 tristate 274 tristate
268 275
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index bcecf5133b7e..4276965517f2 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -10,7 +10,7 @@ pcmcia_core-y += cs.o cistpl.o rsrc_mgr.o socket_sysfs.o
10pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o 10pcmcia_core-$(CONFIG_CARDBUS) += cardbus.o
11obj-$(CONFIG_PCCARD) += pcmcia_core.o 11obj-$(CONFIG_PCCARD) += pcmcia_core.o
12 12
13pcmcia-y += ds.o pcmcia_compat.o pcmcia_resource.o 13pcmcia-y += ds.o pcmcia_resource.o
14pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o 14pcmcia-$(CONFIG_PCMCIA_IOCTL) += pcmcia_ioctl.o
15obj-$(CONFIG_PCMCIA) += pcmcia.o 15obj-$(CONFIG_PCMCIA) += pcmcia.o
16 16
@@ -36,6 +36,7 @@ obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
36obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o 36obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
37obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o 37obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
38obj-$(CONFIG_OMAP_CF) += omap_cf.o 38obj-$(CONFIG_OMAP_CF) += omap_cf.o
39obj-$(CONFIG_AT91_CF) += at91_cf.o
39 40
40sa11xx_core-y += soc_common.o sa11xx_base.o 41sa11xx_core-y += soc_common.o sa11xx_base.o
41pxa2xx_core-y += soc_common.o pxa2xx_base.o 42pxa2xx_core-y += soc_common.o pxa2xx_base.o
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
new file mode 100644
index 000000000000..67cc5f7d0c90
--- /dev/null
+++ b/drivers/pcmcia/at91_cf.c
@@ -0,0 +1,365 @@
1/*
2 * at91_cf.c -- AT91 CompactFlash controller driver
3 *
4 * Copyright (C) 2005 David Brownell
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>
14#include <linux/sched.h>
15#include <linux/platform_device.h>
16#include <linux/errno.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19
20#include <pcmcia/ss.h>
21
22#include <asm/hardware.h>
23#include <asm/io.h>
24#include <asm/sizes.h>
25
26#include <asm/arch/at91rm9200.h>
27#include <asm/arch/board.h>
28#include <asm/arch/gpio.h>
29
30
31#define CF_SIZE 0x30000000 /* CS5+CS6: unavailable */
32
33/*
34 * A0..A10 work in each range; A23 indicates I/O space; A25 is CFRNW;
35 * some other bit in {A24,A22..A11} is nREG to flag memory access
36 * (vs attributes). So more than 2KB/region would just be waste.
37 */
38#define CF_ATTR_PHYS (AT91_CF_BASE)
39#define CF_IO_PHYS (AT91_CF_BASE + (1 << 23))
40#define CF_MEM_PHYS (AT91_CF_BASE + 0x017ff800)
41
42/*--------------------------------------------------------------------------*/
43
44static const char driver_name[] = "at91_cf";
45
46struct at91_cf_socket {
47 struct pcmcia_socket socket;
48
49 unsigned present:1;
50
51 struct platform_device *pdev;
52 struct at91_cf_data *board;
53};
54
55#define SZ_2K (2 * SZ_1K)
56
57static inline int at91_cf_present(struct at91_cf_socket *cf)
58{
59 return !at91_get_gpio_value(cf->board->det_pin);
60}
61
62/*--------------------------------------------------------------------------*/
63
64static int at91_cf_ss_init(struct pcmcia_socket *s)
65{
66 return 0;
67}
68
69static irqreturn_t at91_cf_irq(int irq, void *_cf, struct pt_regs *r)
70{
71 struct at91_cf_socket *cf = (struct at91_cf_socket *) _cf;
72
73 if (irq == cf->board->det_pin) {
74 unsigned present = at91_cf_present(cf);
75
76 /* kick pccard as needed */
77 if (present != cf->present) {
78 cf->present = present;
79 pr_debug("%s: card %s\n", driver_name, present ? "present" : "gone");
80 pcmcia_parse_events(&cf->socket, SS_DETECT);
81 }
82 }
83
84 return IRQ_HANDLED;
85}
86
87static int at91_cf_get_status(struct pcmcia_socket *s, u_int *sp)
88{
89 struct at91_cf_socket *cf;
90
91 if (!sp)
92 return -EINVAL;
93
94 cf = container_of(s, struct at91_cf_socket, socket);
95
96 /* NOTE: we assume 3VCARD, not XVCARD... */
97 if (at91_cf_present(cf)) {
98 int rdy = cf->board->irq_pin; /* RDY/nIRQ */
99 int vcc = cf->board->vcc_pin;
100
101 *sp = SS_DETECT | SS_3VCARD;
102 if (!rdy || at91_get_gpio_value(rdy))
103 *sp |= SS_READY;
104 if (!vcc || at91_get_gpio_value(vcc))
105 *sp |= SS_POWERON;
106 } else
107 *sp = 0;
108
109 return 0;
110}
111
112static int at91_cf_set_socket(struct pcmcia_socket *sock, struct socket_state_t *s)
113{
114 struct at91_cf_socket *cf;
115
116 cf = container_of(sock, struct at91_cf_socket, socket);
117
118 /* switch Vcc if needed and possible */
119 if (cf->board->vcc_pin) {
120 switch (s->Vcc) {
121 case 0:
122 at91_set_gpio_value(cf->board->vcc_pin, 0);
123 break;
124 case 33:
125 at91_set_gpio_value(cf->board->vcc_pin, 1);
126 break;
127 default:
128 return -EINVAL;
129 }
130 }
131
132 /* toggle reset if needed */
133 at91_set_gpio_value(cf->board->rst_pin, s->flags & SS_RESET);
134
135 pr_debug("%s: Vcc %d, io_irq %d, flags %04x csc %04x\n",
136 driver_name, s->Vcc, s->io_irq, s->flags, s->csc_mask);
137
138 return 0;
139}
140
141static int at91_cf_ss_suspend(struct pcmcia_socket *s)
142{
143 return at91_cf_set_socket(s, &dead_socket);
144}
145
146/* we already mapped the I/O region */
147static int at91_cf_set_io_map(struct pcmcia_socket *s, struct pccard_io_map *io)
148{
149 struct at91_cf_socket *cf;
150 u32 csr;
151
152 cf = container_of(s, struct at91_cf_socket, socket);
153 io->flags &= (MAP_ACTIVE | MAP_16BIT | MAP_AUTOSZ);
154
155 /*
156 * Use 16 bit accesses unless/until we need 8-bit i/o space.
157 * Always set CSR4 ... PCMCIA won't always unmap things.
158 */
159 csr = at91_sys_read(AT91_SMC_CSR(4)) & ~AT91_SMC_DBW;
160
161 /*
162 * NOTE: this CF controller ignores IOIS16, so we can't really do
163 * MAP_AUTOSZ. The 16bit mode allows single byte access on either
164 * D0-D7 (even addr) or D8-D15 (odd), so it's close enough for many
165 * purposes (and handles ide-cs).
166 *
167 * The 8bit mode is needed for odd byte access on D0-D7. It seems
168 * some cards only like that way to get at the odd byte, despite
169 * CF 3.0 spec table 35 also giving the D8-D15 option.
170 */
171 if (!(io->flags & (MAP_16BIT|MAP_AUTOSZ))) {
172 csr |= AT91_SMC_DBW_8;
173 pr_debug("%s: 8bit i/o bus\n", driver_name);
174 } else {
175 csr |= AT91_SMC_DBW_16;
176 pr_debug("%s: 16bit i/o bus\n", driver_name);
177 }
178 at91_sys_write(AT91_SMC_CSR(4), csr);
179
180 io->start = cf->socket.io_offset;
181 io->stop = io->start + SZ_2K - 1;
182
183 return 0;
184}
185
186/* pcmcia layer maps/unmaps mem regions */
187static int at91_cf_set_mem_map(struct pcmcia_socket *s, struct pccard_mem_map *map)
188{
189 struct at91_cf_socket *cf;
190
191 if (map->card_start)
192 return -EINVAL;
193
194 cf = container_of(s, struct at91_cf_socket, socket);
195
196 map->flags &= MAP_ACTIVE|MAP_ATTRIB|MAP_16BIT;
197 if (map->flags & MAP_ATTRIB)
198 map->static_start = CF_ATTR_PHYS;
199 else
200 map->static_start = CF_MEM_PHYS;
201
202 return 0;
203}
204
205static struct pccard_operations at91_cf_ops = {
206 .init = at91_cf_ss_init,
207 .suspend = at91_cf_ss_suspend,
208 .get_status = at91_cf_get_status,
209 .set_socket = at91_cf_set_socket,
210 .set_io_map = at91_cf_set_io_map,
211 .set_mem_map = at91_cf_set_mem_map,
212};
213
214/*--------------------------------------------------------------------------*/
215
216static int __init at91_cf_probe(struct device *dev)
217{
218 struct at91_cf_socket *cf;
219 struct at91_cf_data *board = dev->platform_data;
220 struct platform_device *pdev = to_platform_device(dev);
221 unsigned int csa;
222 int status;
223
224 if (!board || !board->det_pin || !board->rst_pin)
225 return -ENODEV;
226
227 cf = kcalloc(1, sizeof *cf, GFP_KERNEL);
228 if (!cf)
229 return -ENOMEM;
230
231 cf->board = board;
232 cf->pdev = pdev;
233 dev_set_drvdata(dev, cf);
234
235 /* CF takes over CS4, CS5, CS6 */
236 csa = at91_sys_read(AT91_EBI_CSA);
237 at91_sys_write(AT91_EBI_CSA, csa | AT91_EBI_CS4A_SMC_COMPACTFLASH);
238
239 /* force poweron defaults for these pins ... */
240 (void) at91_set_A_periph(AT91_PIN_PC9, 0); /* A25/CFRNW */
241 (void) at91_set_A_periph(AT91_PIN_PC10, 0); /* NCS4/CFCS */
242 (void) at91_set_A_periph(AT91_PIN_PC11, 0); /* NCS5/CFCE1 */
243 (void) at91_set_A_periph(AT91_PIN_PC12, 0); /* NCS6/CFCE2 */
244
245 /* nWAIT is _not_ a default setting */
246 (void) at91_set_A_periph(AT91_PIN_PC6, 1); /* nWAIT */
247
248 /*
249 * Static memory controller timing adjustments.
250 * REVISIT: these timings are in terms of MCK cycles, so
251 * when MCK changes (cpufreq etc) so must these values...
252 */
253 at91_sys_write(AT91_SMC_CSR(4), AT91_SMC_ACSS_STD | AT91_SMC_DBW_16 | AT91_SMC_BAT | AT91_SMC_WSEN
254 | AT91_SMC_NWS_(32) /* wait states */
255 | AT91_SMC_RWSETUP_(6) /* setup time */
256 | AT91_SMC_RWHOLD_(4) /* hold time */
257 );
258
259 /* must be a GPIO; ergo must trigger on both edges */
260 status = request_irq(board->det_pin, at91_cf_irq,
261 SA_SAMPLE_RANDOM, driver_name, cf);
262 if (status < 0)
263 goto fail0;
264
265 /*
266 * The card driver will request this irq later as needed.
267 * but it causes lots of "irqNN: nobody cared" messages
268 * unless we report that we handle everything (sigh).
269 * (Note: DK board doesn't wire the IRQ pin...)
270 */
271 if (board->irq_pin) {
272 status = request_irq(board->irq_pin, at91_cf_irq,
273 SA_SHIRQ, driver_name, cf);
274 if (status < 0)
275 goto fail0a;
276 cf->socket.pci_irq = board->irq_pin;
277 }
278 else
279 cf->socket.pci_irq = NR_IRQS + 1;
280
281 /* pcmcia layer only remaps "real" memory not iospace */
282 cf->socket.io_offset = (unsigned long) ioremap(CF_IO_PHYS, SZ_2K);
283 if (!cf->socket.io_offset)
284 goto fail1;
285
286 /* reserve CS4, CS5, and CS6 regions; but use just CS4 */
287 if (!request_mem_region(AT91_CF_BASE, CF_SIZE, driver_name))
288 goto fail1;
289
290 pr_info("%s: irqs det #%d, io #%d\n", driver_name,
291 board->det_pin, board->irq_pin);
292
293 cf->socket.owner = THIS_MODULE;
294 cf->socket.dev.dev = dev;
295 cf->socket.ops = &at91_cf_ops;
296 cf->socket.resource_ops = &pccard_static_ops;
297 cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
298 | SS_CAP_MEM_ALIGN;
299 cf->socket.map_size = SZ_2K;
300 cf->socket.io[0].NumPorts = SZ_2K;
301
302 status = pcmcia_register_socket(&cf->socket);
303 if (status < 0)
304 goto fail2;
305
306 return 0;
307
308fail2:
309 iounmap((void __iomem *) cf->socket.io_offset);
310 release_mem_region(AT91_CF_BASE, CF_SIZE);
311fail1:
312 if (board->irq_pin)
313 free_irq(board->irq_pin, cf);
314fail0a:
315 free_irq(board->det_pin, cf);
316fail0:
317 at91_sys_write(AT91_EBI_CSA, csa);
318 kfree(cf);
319 return status;
320}
321
322static int __exit at91_cf_remove(struct device *dev)
323{
324 struct at91_cf_socket *cf = dev_get_drvdata(dev);
325 unsigned int csa;
326
327 pcmcia_unregister_socket(&cf->socket);
328 free_irq(cf->board->irq_pin, cf);
329 free_irq(cf->board->det_pin, cf);
330 iounmap((void __iomem *) cf->socket.io_offset);
331 release_mem_region(AT91_CF_BASE, CF_SIZE);
332
333 csa = at91_sys_read(AT91_EBI_CSA);
334 at91_sys_write(AT91_EBI_CSA, csa & ~AT91_EBI_CS4A);
335
336 kfree(cf);
337 return 0;
338}
339
340static struct device_driver at91_cf_driver = {
341 .name = (char *) driver_name,
342 .bus = &platform_bus_type,
343 .probe = at91_cf_probe,
344 .remove = __exit_p(at91_cf_remove),
345 .suspend = pcmcia_socket_dev_suspend,
346 .resume = pcmcia_socket_dev_resume,
347};
348
349/*--------------------------------------------------------------------------*/
350
351static int __init at91_cf_init(void)
352{
353 return driver_register(&at91_cf_driver);
354}
355module_init(at91_cf_init);
356
357static void __exit at91_cf_exit(void)
358{
359 driver_unregister(&at91_cf_driver);
360}
361module_exit(at91_cf_exit);
362
363MODULE_DESCRIPTION("AT91 Compact Flash Driver");
364MODULE_AUTHOR("David Brownell");
365MODULE_LICENSE("GPL");
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index 120fa8da6392..912c03e5eb0a 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -12,7 +12,6 @@
12 * (C) 1999 David A. Hinds 12 * (C) 1999 David A. Hinds
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
index 613f2f1fbfdd..3162998579c1 100644
--- a/drivers/pcmcia/cs.c
+++ b/drivers/pcmcia/cs.c
@@ -16,7 +16,6 @@
16#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19#include <linux/config.h>
20#include <linux/string.h> 19#include <linux/string.h>
21#include <linux/major.h> 20#include <linux/major.h>
22#include <linux/errno.h> 21#include <linux/errno.h>
@@ -111,9 +110,9 @@ int pcmcia_socket_dev_suspend(struct device *dev, pm_message_t state)
111 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { 110 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
112 if (socket->dev.dev != dev) 111 if (socket->dev.dev != dev)
113 continue; 112 continue;
114 down(&socket->skt_sem); 113 mutex_lock(&socket->skt_mutex);
115 socket_suspend(socket); 114 socket_suspend(socket);
116 up(&socket->skt_sem); 115 mutex_unlock(&socket->skt_mutex);
117 } 116 }
118 up_read(&pcmcia_socket_list_rwsem); 117 up_read(&pcmcia_socket_list_rwsem);
119 118
@@ -129,9 +128,9 @@ int pcmcia_socket_dev_resume(struct device *dev)
129 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) { 128 list_for_each_entry(socket, &pcmcia_socket_list, socket_list) {
130 if (socket->dev.dev != dev) 129 if (socket->dev.dev != dev)
131 continue; 130 continue;
132 down(&socket->skt_sem); 131 mutex_lock(&socket->skt_mutex);
133 socket_resume(socket); 132 socket_resume(socket);
134 up(&socket->skt_sem); 133 mutex_unlock(&socket->skt_mutex);
135 } 134 }
136 up_read(&pcmcia_socket_list_rwsem); 135 up_read(&pcmcia_socket_list_rwsem);
137 136
@@ -237,7 +236,7 @@ int pcmcia_register_socket(struct pcmcia_socket *socket)
237 init_completion(&socket->socket_released); 236 init_completion(&socket->socket_released);
238 init_completion(&socket->thread_done); 237 init_completion(&socket->thread_done);
239 init_waitqueue_head(&socket->thread_wait); 238 init_waitqueue_head(&socket->thread_wait);
240 init_MUTEX(&socket->skt_sem); 239 mutex_init(&socket->skt_mutex);
241 spin_lock_init(&socket->thread_lock); 240 spin_lock_init(&socket->thread_lock);
242 241
243 ret = kernel_thread(pccardd, socket, CLONE_KERNEL); 242 ret = kernel_thread(pccardd, socket, CLONE_KERNEL);
@@ -406,8 +405,6 @@ static void socket_shutdown(struct pcmcia_socket *s)
406 cb_free(s); 405 cb_free(s);
407#endif 406#endif
408 s->functions = 0; 407 s->functions = 0;
409 kfree(s->config);
410 s->config = NULL;
411 408
412 s->ops->get_status(s, &status); 409 s->ops->get_status(s, &status);
413 if (status & SS_POWERON) { 410 if (status & SS_POWERON) {
@@ -664,7 +661,7 @@ static int pccardd(void *__skt)
664 spin_unlock_irqrestore(&skt->thread_lock, flags); 661 spin_unlock_irqrestore(&skt->thread_lock, flags);
665 662
666 if (events) { 663 if (events) {
667 down(&skt->skt_sem); 664 mutex_lock(&skt->skt_mutex);
668 if (events & SS_DETECT) 665 if (events & SS_DETECT)
669 socket_detect_change(skt); 666 socket_detect_change(skt);
670 if (events & SS_BATDEAD) 667 if (events & SS_BATDEAD)
@@ -673,7 +670,7 @@ static int pccardd(void *__skt)
673 send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW); 670 send_event(skt, CS_EVENT_BATTERY_LOW, CS_EVENT_PRI_LOW);
674 if (events & SS_READY) 671 if (events & SS_READY)
675 send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW); 672 send_event(skt, CS_EVENT_READY_CHANGE, CS_EVENT_PRI_LOW);
676 up(&skt->skt_sem); 673 mutex_unlock(&skt->skt_mutex);
677 continue; 674 continue;
678 } 675 }
679 676
@@ -717,8 +714,8 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
717{ 714{
718 int ret = 0; 715 int ret = 0;
719 716
720 /* s->skt_sem also protects s->callback */ 717 /* s->skt_mutex also protects s->callback */
721 down(&s->skt_sem); 718 mutex_lock(&s->skt_mutex);
722 719
723 if (c) { 720 if (c) {
724 /* registration */ 721 /* registration */
@@ -734,7 +731,7 @@ int pccard_register_pcmcia(struct pcmcia_socket *s, struct pcmcia_callback *c)
734 } else 731 } else
735 s->callback = NULL; 732 s->callback = NULL;
736 err: 733 err:
737 up(&s->skt_sem); 734 mutex_unlock(&s->skt_mutex);
738 735
739 return ret; 736 return ret;
740} 737}
@@ -752,7 +749,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
752 749
753 cs_dbg(skt, 1, "resetting socket\n"); 750 cs_dbg(skt, 1, "resetting socket\n");
754 751
755 down(&skt->skt_sem); 752 mutex_lock(&skt->skt_mutex);
756 do { 753 do {
757 if (!(skt->state & SOCKET_PRESENT)) { 754 if (!(skt->state & SOCKET_PRESENT)) {
758 ret = CS_NO_CARD; 755 ret = CS_NO_CARD;
@@ -781,7 +778,7 @@ int pccard_reset_card(struct pcmcia_socket *skt)
781 778
782 ret = CS_SUCCESS; 779 ret = CS_SUCCESS;
783 } while (0); 780 } while (0);
784 up(&skt->skt_sem); 781 mutex_unlock(&skt->skt_mutex);
785 782
786 return ret; 783 return ret;
787} /* reset_card */ 784} /* reset_card */
@@ -797,7 +794,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
797 794
798 cs_dbg(skt, 1, "suspending socket\n"); 795 cs_dbg(skt, 1, "suspending socket\n");
799 796
800 down(&skt->skt_sem); 797 mutex_lock(&skt->skt_mutex);
801 do { 798 do {
802 if (!(skt->state & SOCKET_PRESENT)) { 799 if (!(skt->state & SOCKET_PRESENT)) {
803 ret = CS_NO_CARD; 800 ret = CS_NO_CARD;
@@ -814,7 +811,7 @@ int pcmcia_suspend_card(struct pcmcia_socket *skt)
814 } 811 }
815 ret = socket_suspend(skt); 812 ret = socket_suspend(skt);
816 } while (0); 813 } while (0);
817 up(&skt->skt_sem); 814 mutex_unlock(&skt->skt_mutex);
818 815
819 return ret; 816 return ret;
820} /* suspend_card */ 817} /* suspend_card */
@@ -827,7 +824,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
827 824
828 cs_dbg(skt, 1, "waking up socket\n"); 825 cs_dbg(skt, 1, "waking up socket\n");
829 826
830 down(&skt->skt_sem); 827 mutex_lock(&skt->skt_mutex);
831 do { 828 do {
832 if (!(skt->state & SOCKET_PRESENT)) { 829 if (!(skt->state & SOCKET_PRESENT)) {
833 ret = CS_NO_CARD; 830 ret = CS_NO_CARD;
@@ -841,7 +838,7 @@ int pcmcia_resume_card(struct pcmcia_socket *skt)
841 if (!ret && skt->callback) 838 if (!ret && skt->callback)
842 skt->callback->resume(skt); 839 skt->callback->resume(skt);
843 } while (0); 840 } while (0);
844 up(&skt->skt_sem); 841 mutex_unlock(&skt->skt_mutex);
845 842
846 return ret; 843 return ret;
847} /* resume_card */ 844} /* resume_card */
@@ -855,7 +852,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
855 852
856 cs_dbg(skt, 1, "user eject request\n"); 853 cs_dbg(skt, 1, "user eject request\n");
857 854
858 down(&skt->skt_sem); 855 mutex_lock(&skt->skt_mutex);
859 do { 856 do {
860 if (!(skt->state & SOCKET_PRESENT)) { 857 if (!(skt->state & SOCKET_PRESENT)) {
861 ret = -ENODEV; 858 ret = -ENODEV;
@@ -871,7 +868,7 @@ int pcmcia_eject_card(struct pcmcia_socket *skt)
871 socket_remove(skt); 868 socket_remove(skt);
872 ret = 0; 869 ret = 0;
873 } while (0); 870 } while (0);
874 up(&skt->skt_sem); 871 mutex_unlock(&skt->skt_mutex);
875 872
876 return ret; 873 return ret;
877} /* eject_card */ 874} /* eject_card */
@@ -884,7 +881,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
884 881
885 cs_dbg(skt, 1, "user insert request\n"); 882 cs_dbg(skt, 1, "user insert request\n");
886 883
887 down(&skt->skt_sem); 884 mutex_lock(&skt->skt_mutex);
888 do { 885 do {
889 if (skt->state & SOCKET_PRESENT) { 886 if (skt->state & SOCKET_PRESENT) {
890 ret = -EBUSY; 887 ret = -EBUSY;
@@ -896,7 +893,7 @@ int pcmcia_insert_card(struct pcmcia_socket *skt)
896 } 893 }
897 ret = 0; 894 ret = 0;
898 } while (0); 895 } while (0);
899 up(&skt->skt_sem); 896 mutex_unlock(&skt->skt_mutex);
900 897
901 return ret; 898 return ret;
902} /* insert_card */ 899} /* insert_card */
diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
index 7b37eba35bf1..d6164cd583fd 100644
--- a/drivers/pcmcia/cs_internal.h
+++ b/drivers/pcmcia/cs_internal.h
@@ -15,7 +15,7 @@
15#ifndef _LINUX_CS_INTERNAL_H 15#ifndef _LINUX_CS_INTERNAL_H
16#define _LINUX_CS_INTERNAL_H 16#define _LINUX_CS_INTERNAL_H
17 17
18#include <linux/config.h> 18#include <linux/kref.h>
19 19
20/* Flags in client state */ 20/* Flags in client state */
21#define CLIENT_CONFIG_LOCKED 0x0001 21#define CLIENT_CONFIG_LOCKED 0x0001
@@ -23,7 +23,7 @@
23#define CLIENT_IO_REQ 0x0004 23#define CLIENT_IO_REQ 0x0004
24#define CLIENT_UNBOUND 0x0008 24#define CLIENT_UNBOUND 0x0008
25#define CLIENT_STALE 0x0010 25#define CLIENT_STALE 0x0010
26#define CLIENT_WIN_REQ(i) (0x20<<(i)) 26#define CLIENT_WIN_REQ(i) (0x1<<(i))
27#define CLIENT_CARDBUS 0x8000 27#define CLIENT_CARDBUS 0x8000
28 28
29#define REGION_MAGIC 0xE3C9 29#define REGION_MAGIC 0xE3C9
@@ -31,7 +31,7 @@ typedef struct region_t {
31 u_short region_magic; 31 u_short region_magic;
32 u_short state; 32 u_short state;
33 dev_info_t dev_info; 33 dev_info_t dev_info;
34 client_handle_t mtd; 34 struct pcmcia_device *mtd;
35 u_int MediaID; 35 u_int MediaID;
36 region_info_t info; 36 region_info_t info;
37} region_t; 37} region_t;
@@ -40,12 +40,12 @@ typedef struct region_t {
40 40
41/* Each card function gets one of these guys */ 41/* Each card function gets one of these guys */
42typedef struct config_t { 42typedef struct config_t {
43 struct kref ref;
43 u_int state; 44 u_int state;
44 u_int Attributes; 45 u_int Attributes;
45 u_int IntType; 46 u_int IntType;
46 u_int ConfigBase; 47 u_int ConfigBase;
47 u_char Status, Pin, Copy, Option, ExtStatus; 48 u_char Status, Pin, Copy, Option, ExtStatus;
48 u_int Present;
49 u_int CardValues; 49 u_int CardValues;
50 io_req_t io; 50 io_req_t io;
51 struct { 51 struct {
@@ -95,12 +95,6 @@ static inline void cs_socket_put(struct pcmcia_socket *skt)
95 } 95 }
96} 96}
97 97
98#define CHECK_SOCKET(s) \
99 (((s) >= sockets) || (socket_table[s]->ops == NULL))
100
101#define SOCKET(h) (h->socket)
102#define CONFIG(h) (&SOCKET(h)->config[(h)->func])
103
104/* In cardbus.c */ 98/* In cardbus.c */
105int cb_alloc(struct pcmcia_socket *s); 99int cb_alloc(struct pcmcia_socket *s);
106void cb_free(struct pcmcia_socket *s); 100void cb_free(struct pcmcia_socket *s);
@@ -133,10 +127,9 @@ extern struct class_interface pccard_sysfs_interface;
133extern struct rw_semaphore pcmcia_socket_list_rwsem; 127extern struct rw_semaphore pcmcia_socket_list_rwsem;
134extern struct list_head pcmcia_socket_list; 128extern struct list_head pcmcia_socket_list;
135int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req); 129int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, int idx, win_req_t *req);
136int pccard_get_configuration_info(struct pcmcia_socket *s, unsigned int function, config_info_t *config); 130int pccard_get_configuration_info(struct pcmcia_socket *s, struct pcmcia_device *p_dev, config_info_t *config);
137int pccard_reset_card(struct pcmcia_socket *skt); 131int pccard_reset_card(struct pcmcia_socket *skt);
138int pccard_get_status(struct pcmcia_socket *s, unsigned int function, cs_status_t *status); 132int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev, cs_status_t *status);
139int pccard_access_configuration_register(struct pcmcia_socket *s, unsigned int function, conf_reg_t *reg);
140 133
141 134
142struct pcmcia_callback{ 135struct pcmcia_callback{
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index bb96ce1db08c..ae10d1eed65e 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -10,10 +10,9 @@
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 - 2005 Dominik Brodowski 13 * (C) 2003 - 2006 Dominik Brodowski
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/init.h> 18#include <linux/init.h>
@@ -23,6 +22,7 @@
23#include <linux/workqueue.h> 22#include <linux/workqueue.h>
24#include <linux/crc32.h> 23#include <linux/crc32.h>
25#include <linux/firmware.h> 24#include <linux/firmware.h>
25#include <linux/kref.h>
26 26
27#define IN_CARD_SERVICES 27#define IN_CARD_SERVICES
28#include <pcmcia/cs_types.h> 28#include <pcmcia/cs_types.h>
@@ -343,12 +343,19 @@ void pcmcia_put_dev(struct pcmcia_device *p_dev)
343 put_device(&p_dev->dev); 343 put_device(&p_dev->dev);
344} 344}
345 345
346static void pcmcia_release_function(struct kref *ref)
347{
348 struct config_t *c = container_of(ref, struct config_t, ref);
349 kfree(c);
350}
351
346static void pcmcia_release_dev(struct device *dev) 352static void pcmcia_release_dev(struct device *dev)
347{ 353{
348 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 354 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
349 ds_dbg(1, "releasing dev %p\n", p_dev); 355 ds_dbg(1, "releasing dev %p\n", p_dev);
350 pcmcia_put_socket(p_dev->socket); 356 pcmcia_put_socket(p_dev->socket);
351 kfree(p_dev->devname); 357 kfree(p_dev->devname);
358 kref_put(&p_dev->function_config->ref, pcmcia_release_function);
352 kfree(p_dev); 359 kfree(p_dev);
353} 360}
354 361
@@ -377,29 +384,12 @@ static int pcmcia_device_probe(struct device * dev)
377 p_drv = to_pcmcia_drv(dev->driver); 384 p_drv = to_pcmcia_drv(dev->driver);
378 s = p_dev->socket; 385 s = p_dev->socket;
379 386
380 if ((!p_drv->probe) || (!try_module_get(p_drv->owner))) { 387 if ((!p_drv->probe) || (!p_dev->function_config) ||
388 (!try_module_get(p_drv->owner))) {
381 ret = -EINVAL; 389 ret = -EINVAL;
382 goto put_dev; 390 goto put_dev;
383 } 391 }
384 392
385 p_dev->state &= ~CLIENT_UNBOUND;
386
387 /* set up the device configuration, if it hasn't been done before */
388 if (!s->functions) {
389 cistpl_longlink_mfc_t mfc;
390 if (pccard_read_tuple(s, p_dev->func, CISTPL_LONGLINK_MFC,
391 &mfc) == CS_SUCCESS)
392 s->functions = mfc.nfn;
393 else
394 s->functions = 1;
395 s->config = kzalloc(sizeof(config_t) * s->functions,
396 GFP_KERNEL);
397 if (!s->config) {
398 ret = -ENOMEM;
399 goto put_module;
400 }
401 }
402
403 ret = p_drv->probe(p_dev); 393 ret = p_drv->probe(p_dev);
404 if (ret) 394 if (ret)
405 goto put_module; 395 goto put_module;
@@ -425,15 +415,61 @@ static int pcmcia_device_probe(struct device * dev)
425} 415}
426 416
427 417
418/*
419 * Removes a PCMCIA card from the device tree and socket list.
420 */
421static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *leftover)
422{
423 struct pcmcia_device *p_dev;
424 struct pcmcia_device *tmp;
425 unsigned long flags;
426
427 ds_dbg(2, "unbind_request(%d)\n", s->sock);
428
429
430 if (!leftover)
431 s->device_count = 0;
432 else
433 s->device_count = 1;
434
435 /* unregister all pcmcia_devices registered with this socket, except leftover */
436 list_for_each_entry_safe(p_dev, tmp, &s->devices_list, socket_device_list) {
437 if (p_dev == leftover)
438 continue;
439
440 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
441 list_del(&p_dev->socket_device_list);
442 p_dev->_removed=1;
443 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
444
445 device_unregister(&p_dev->dev);
446 }
447
448 return;
449}
450
451
428static int pcmcia_device_remove(struct device * dev) 452static int pcmcia_device_remove(struct device * dev)
429{ 453{
430 struct pcmcia_device *p_dev; 454 struct pcmcia_device *p_dev;
431 struct pcmcia_driver *p_drv; 455 struct pcmcia_driver *p_drv;
456 struct pcmcia_device_id *did;
432 int i; 457 int i;
433 458
434 /* detach the "instance" */
435 p_dev = to_pcmcia_dev(dev); 459 p_dev = to_pcmcia_dev(dev);
436 p_drv = to_pcmcia_drv(dev->driver); 460 p_drv = to_pcmcia_drv(dev->driver);
461
462 /* If we're removing the primary module driving a
463 * pseudo multi-function card, we need to unbind
464 * all devices
465 */
466 did = (struct pcmcia_device_id *) p_dev->dev.driver_data;
467 if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
468 (p_dev->socket->device_count != 0) &&
469 (p_dev->device_no == 0))
470 pcmcia_card_remove(p_dev->socket, p_dev);
471
472 /* detach the "instance" */
437 if (!p_drv) 473 if (!p_drv)
438 return 0; 474 return 0;
439 475
@@ -441,17 +477,16 @@ static int pcmcia_device_remove(struct device * dev)
441 p_drv->remove(p_dev); 477 p_drv->remove(p_dev);
442 478
443 /* check for proper unloading */ 479 /* check for proper unloading */
444 if (p_dev->state & (CLIENT_IRQ_REQ|CLIENT_IO_REQ|CLIENT_CONFIG_LOCKED)) 480 if (p_dev->_irq || p_dev->_io || p_dev->_locked)
445 printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", 481 printk(KERN_INFO "pcmcia: driver %s did not release config properly\n",
446 p_drv->drv.name); 482 p_drv->drv.name);
447 483
448 for (i = 0; i < MAX_WIN; i++) 484 for (i = 0; i < MAX_WIN; i++)
449 if (p_dev->state & CLIENT_WIN_REQ(i)) 485 if (p_dev->_win & CLIENT_WIN_REQ(i))
450 printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n", 486 printk(KERN_INFO "pcmcia: driver %s did not release windows properly\n",
451 p_drv->drv.name); 487 p_drv->drv.name);
452 488
453 /* references from pcmcia_probe_device */ 489 /* references from pcmcia_probe_device */
454 p_dev->state = CLIENT_UNBOUND;
455 pcmcia_put_dev(p_dev); 490 pcmcia_put_dev(p_dev);
456 module_put(p_drv->owner); 491 module_put(p_drv->owner);
457 492
@@ -460,37 +495,6 @@ static int pcmcia_device_remove(struct device * dev)
460 495
461 496
462/* 497/*
463 * Removes a PCMCIA card from the device tree and socket list.
464 */
465static void pcmcia_card_remove(struct pcmcia_socket *s)
466{
467 struct pcmcia_device *p_dev;
468 unsigned long flags;
469
470 ds_dbg(2, "unbind_request(%d)\n", s->sock);
471
472 s->device_count = 0;
473
474 for (;;) {
475 /* unregister all pcmcia_devices registered with this socket*/
476 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
477 if (list_empty(&s->devices_list)) {
478 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
479 return;
480 }
481 p_dev = list_entry((&s->devices_list)->next, struct pcmcia_device, socket_device_list);
482 list_del(&p_dev->socket_device_list);
483 p_dev->state |= CLIENT_STALE;
484 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
485
486 device_unregister(&p_dev->dev);
487 }
488
489 return;
490} /* unbind_request */
491
492
493/*
494 * pcmcia_device_query -- determine information about a pcmcia device 498 * pcmcia_device_query -- determine information about a pcmcia device
495 */ 499 */
496static int pcmcia_device_query(struct pcmcia_device *p_dev) 500static int pcmcia_device_query(struct pcmcia_device *p_dev)
@@ -546,7 +550,7 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
546 tmp = vers1->str + vers1->ofs[i]; 550 tmp = vers1->str + vers1->ofs[i];
547 551
548 length = strlen(tmp) + 1; 552 length = strlen(tmp) + 1;
549 if ((length < 3) || (length > 255)) 553 if ((length < 2) || (length > 255))
550 continue; 554 continue;
551 555
552 p_dev->prod_id[i] = kmalloc(sizeof(char) * length, 556 p_dev->prod_id[i] = kmalloc(sizeof(char) * length,
@@ -571,11 +575,11 @@ static int pcmcia_device_query(struct pcmcia_device *p_dev)
571 * won't work, this doesn't matter much at the moment: the driver core doesn't 575 * won't work, this doesn't matter much at the moment: the driver core doesn't
572 * support it either. 576 * support it either.
573 */ 577 */
574static DECLARE_MUTEX(device_add_lock); 578static DEFINE_MUTEX(device_add_lock);
575 579
576struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function) 580struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function)
577{ 581{
578 struct pcmcia_device *p_dev; 582 struct pcmcia_device *p_dev, *tmp_dev;
579 unsigned long flags; 583 unsigned long flags;
580 int bus_id_len; 584 int bus_id_len;
581 585
@@ -583,7 +587,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
583 if (!s) 587 if (!s)
584 return NULL; 588 return NULL;
585 589
586 down(&device_add_lock); 590 mutex_lock(&device_add_lock);
587 591
588 /* max of 2 devices per card */ 592 /* max of 2 devices per card */
589 if (s->device_count == 2) 593 if (s->device_count == 2)
@@ -596,6 +600,8 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
596 p_dev->socket = s; 600 p_dev->socket = s;
597 p_dev->device_no = (s->device_count++); 601 p_dev->device_no = (s->device_count++);
598 p_dev->func = function; 602 p_dev->func = function;
603 if (s->functions <= function)
604 s->functions = function + 1;
599 605
600 p_dev->dev.bus = &pcmcia_bus_type; 606 p_dev->dev.bus = &pcmcia_bus_type;
601 p_dev->dev.parent = s->dev.dev; 607 p_dev->dev.parent = s->dev.dev;
@@ -608,36 +614,55 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
608 sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id); 614 sprintf (p_dev->devname, "pcmcia%s", p_dev->dev.bus_id);
609 615
610 /* compat */ 616 /* compat */
611 p_dev->state = CLIENT_UNBOUND; 617 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
618
619 /*
620 * p_dev->function_config must be the same for all card functions.
621 * Note that this is serialized by the device_add_lock, so that
622 * only one such struct will be created.
623 */
624 list_for_each_entry(tmp_dev, &s->devices_list, socket_device_list)
625 if (p_dev->func == tmp_dev->func) {
626 p_dev->function_config = tmp_dev->function_config;
627 kref_get(&p_dev->function_config->ref);
628 }
612 629
613 /* Add to the list in pcmcia_bus_socket */ 630 /* Add to the list in pcmcia_bus_socket */
614 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
615 list_add_tail(&p_dev->socket_device_list, &s->devices_list); 631 list_add_tail(&p_dev->socket_device_list, &s->devices_list);
632
616 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 633 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
617 634
635 if (!p_dev->function_config) {
636 p_dev->function_config = kzalloc(sizeof(struct config_t),
637 GFP_KERNEL);
638 if (!p_dev->function_config)
639 goto err_unreg;
640 kref_init(&p_dev->function_config->ref);
641 }
642
618 printk(KERN_NOTICE "pcmcia: registering new device %s\n", 643 printk(KERN_NOTICE "pcmcia: registering new device %s\n",
619 p_dev->devname); 644 p_dev->devname);
620 645
621 pcmcia_device_query(p_dev); 646 pcmcia_device_query(p_dev);
622 647
623 if (device_register(&p_dev->dev)) { 648 if (device_register(&p_dev->dev))
624 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 649 goto err_unreg;
625 list_del(&p_dev->socket_device_list);
626 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
627
628 goto err_free;
629 }
630 650
631 up(&device_add_lock); 651 mutex_unlock(&device_add_lock);
632 652
633 return p_dev; 653 return p_dev;
634 654
655 err_unreg:
656 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
657 list_del(&p_dev->socket_device_list);
658 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
659
635 err_free: 660 err_free:
636 kfree(p_dev->devname); 661 kfree(p_dev->devname);
637 kfree(p_dev); 662 kfree(p_dev);
638 s->device_count--; 663 s->device_count--;
639 err_put: 664 err_put:
640 up(&device_add_lock); 665 mutex_unlock(&device_add_lock);
641 pcmcia_put_socket(s); 666 pcmcia_put_socket(s);
642 667
643 return NULL; 668 return NULL;
@@ -696,7 +721,7 @@ static void pcmcia_bus_rescan(struct pcmcia_socket *skt)
696 int no_devices=0; 721 int no_devices=0;
697 unsigned long flags; 722 unsigned long flags;
698 723
699 /* must be called with skt_sem held */ 724 /* must be called with skt_mutex held */
700 spin_lock_irqsave(&pcmcia_dev_list_lock, flags); 725 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
701 if (list_empty(&skt->devices_list)) 726 if (list_empty(&skt->devices_list))
702 no_devices=1; 727 no_devices=1;
@@ -819,9 +844,11 @@ static int pcmcia_bus_match(struct device * dev, struct device_driver * drv) {
819 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv); 844 struct pcmcia_driver * p_drv = to_pcmcia_drv(drv);
820 struct pcmcia_device_id *did = p_drv->id_table; 845 struct pcmcia_device_id *did = p_drv->id_table;
821 846
847#ifdef CONFIG_PCMCIA_IOCTL
822 /* matching by cardmgr */ 848 /* matching by cardmgr */
823 if (p_dev->cardmgr == p_drv) 849 if (p_dev->cardmgr == p_drv)
824 return 1; 850 return 1;
851#endif
825 852
826 while (did && did->match_flags) { 853 while (did && did->match_flags) {
827 if (pcmcia_devmatch(p_dev, did)) 854 if (pcmcia_devmatch(p_dev, did))
@@ -927,7 +954,7 @@ static ssize_t pcmcia_show_pm_state(struct device *dev, struct device_attribute
927{ 954{
928 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 955 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
929 956
930 if (p_dev->dev.power.power_state.event != PM_EVENT_ON) 957 if (p_dev->suspended)
931 return sprintf(buf, "off\n"); 958 return sprintf(buf, "off\n");
932 else 959 else
933 return sprintf(buf, "on\n"); 960 return sprintf(buf, "on\n");
@@ -942,11 +969,9 @@ static ssize_t pcmcia_store_pm_state(struct device *dev, struct device_attribute
942 if (!count) 969 if (!count)
943 return -EINVAL; 970 return -EINVAL;
944 971
945 if ((p_dev->dev.power.power_state.event == PM_EVENT_ON) && 972 if ((!p_dev->suspended) && !strncmp(buf, "off", 3))
946 (!strncmp(buf, "off", 3)))
947 ret = dpm_runtime_suspend(dev, PMSG_SUSPEND); 973 ret = dpm_runtime_suspend(dev, PMSG_SUSPEND);
948 else if ((p_dev->dev.power.power_state.event != PM_EVENT_ON) && 974 else if (p_dev->suspended && !strncmp(buf, "on", 2))
949 (!strncmp(buf, "on", 2)))
950 dpm_runtime_resume(dev); 975 dpm_runtime_resume(dev);
951 976
952 return ret ? ret : count; 977 return ret ? ret : count;
@@ -982,9 +1007,9 @@ static ssize_t pcmcia_store_allow_func_id_match(struct device *dev,
982 if (!count) 1007 if (!count)
983 return -EINVAL; 1008 return -EINVAL;
984 1009
985 down(&p_dev->socket->skt_sem); 1010 mutex_lock(&p_dev->socket->skt_mutex);
986 p_dev->allow_func_id_match = 1; 1011 p_dev->allow_func_id_match = 1;
987 up(&p_dev->socket->skt_sem); 1012 mutex_unlock(&p_dev->socket->skt_mutex);
988 1013
989 bus_rescan_devices(&pcmcia_bus_type); 1014 bus_rescan_devices(&pcmcia_bus_type);
990 1015
@@ -1012,14 +1037,27 @@ static int pcmcia_dev_suspend(struct device * dev, pm_message_t state)
1012{ 1037{
1013 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 1038 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1014 struct pcmcia_driver *p_drv = NULL; 1039 struct pcmcia_driver *p_drv = NULL;
1040 int ret = 0;
1015 1041
1016 if (dev->driver) 1042 if (dev->driver)
1017 p_drv = to_pcmcia_drv(dev->driver); 1043 p_drv = to_pcmcia_drv(dev->driver);
1018 1044
1019 if (p_drv && p_drv->suspend) 1045 if (!p_drv)
1020 return p_drv->suspend(p_dev); 1046 goto out;
1021 1047
1022 return 0; 1048 if (p_drv->suspend) {
1049 ret = p_drv->suspend(p_dev);
1050 if (ret)
1051 goto out;
1052 }
1053
1054 if (p_dev->device_no == p_dev->func)
1055 pcmcia_release_configuration(p_dev);
1056
1057 out:
1058 if (!ret)
1059 p_dev->suspended = 1;
1060 return ret;
1023} 1061}
1024 1062
1025 1063
@@ -1027,14 +1065,27 @@ static int pcmcia_dev_resume(struct device * dev)
1027{ 1065{
1028 struct pcmcia_device *p_dev = to_pcmcia_dev(dev); 1066 struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
1029 struct pcmcia_driver *p_drv = NULL; 1067 struct pcmcia_driver *p_drv = NULL;
1068 int ret = 0;
1030 1069
1031 if (dev->driver) 1070 if (dev->driver)
1032 p_drv = to_pcmcia_drv(dev->driver); 1071 p_drv = to_pcmcia_drv(dev->driver);
1033 1072
1034 if (p_drv && p_drv->resume) 1073 if (!p_drv)
1035 return p_drv->resume(p_dev); 1074 goto out;
1036 1075
1037 return 0; 1076 if (p_dev->device_no == p_dev->func) {
1077 ret = pcmcia_request_configuration(p_dev, &p_dev->conf);
1078 if (ret)
1079 goto out;
1080 }
1081
1082 if (p_drv->resume)
1083 ret = p_drv->resume(p_dev);
1084
1085 out:
1086 if (!ret)
1087 p_dev->suspended = 0;
1088 return ret;
1038} 1089}
1039 1090
1040 1091
@@ -1100,7 +1151,7 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1100 switch (event) { 1151 switch (event) {
1101 case CS_EVENT_CARD_REMOVAL: 1152 case CS_EVENT_CARD_REMOVAL:
1102 s->pcmcia_state.present = 0; 1153 s->pcmcia_state.present = 0;
1103 pcmcia_card_remove(skt); 1154 pcmcia_card_remove(skt, NULL);
1104 handle_event(skt, event); 1155 handle_event(skt, event);
1105 break; 1156 break;
1106 1157
@@ -1128,6 +1179,32 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority)
1128} /* ds_event */ 1179} /* ds_event */
1129 1180
1130 1181
1182struct pcmcia_device * pcmcia_dev_present(struct pcmcia_device *_p_dev)
1183{
1184 struct pcmcia_device *p_dev;
1185 struct pcmcia_device *ret = NULL;
1186
1187 p_dev = pcmcia_get_dev(_p_dev);
1188 if (!p_dev)
1189 return NULL;
1190
1191 if (!p_dev->socket->pcmcia_state.present)
1192 goto out;
1193
1194 if (p_dev->_removed)
1195 goto out;
1196
1197 if (p_dev->suspended)
1198 goto out;
1199
1200 ret = p_dev;
1201 out:
1202 pcmcia_put_dev(p_dev);
1203 return ret;
1204}
1205EXPORT_SYMBOL(pcmcia_dev_present);
1206
1207
1131static struct pcmcia_callback pcmcia_bus_callback = { 1208static struct pcmcia_callback pcmcia_bus_callback = {
1132 .owner = THIS_MODULE, 1209 .owner = THIS_MODULE,
1133 .event = ds_event, 1210 .event = ds_event,
diff --git a/drivers/pcmcia/ds_internal.h b/drivers/pcmcia/ds_internal.h
index d359bd25a51c..3a2b25e6ed73 100644
--- a/drivers/pcmcia/ds_internal.h
+++ b/drivers/pcmcia/ds_internal.h
@@ -8,6 +8,8 @@ extern void pcmcia_put_dev(struct pcmcia_device *p_dev);
8 8
9struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function); 9struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int function);
10 10
11extern int pcmcia_release_configuration(struct pcmcia_device *p_dev);
12
11#ifdef CONFIG_PCMCIA_IOCTL 13#ifdef CONFIG_PCMCIA_IOCTL
12extern void __init pcmcia_setup_ioctl(void); 14extern void __init pcmcia_setup_ioctl(void);
13extern void __exit pcmcia_cleanup_ioctl(void); 15extern void __exit pcmcia_cleanup_ioctl(void);
@@ -15,7 +17,7 @@ extern void handle_event(struct pcmcia_socket *s, event_t event);
15extern int handle_request(struct pcmcia_socket *s, event_t event); 17extern int handle_request(struct pcmcia_socket *s, event_t event);
16#else 18#else
17static inline void __init pcmcia_setup_ioctl(void) { return; } 19static inline void __init pcmcia_setup_ioctl(void) { return; }
18static inline void __init pcmcia_cleanup_ioctl(void) { return; } 20static inline void __exit pcmcia_cleanup_ioctl(void) { return; }
19static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; } 21static inline void handle_event(struct pcmcia_socket *s, event_t event) { return; }
20static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; } 22static inline int handle_request(struct pcmcia_socket *s, event_t event) { return CS_SUCCESS; }
21#endif 23#endif
diff --git a/drivers/pcmcia/i82092.c b/drivers/pcmcia/i82092.c
index 7979c85df3dc..d5f03a338c6c 100644
--- a/drivers/pcmcia/i82092.c
+++ b/drivers/pcmcia/i82092.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/pci.h> 14#include <linux/pci.h>
16#include <linux/init.h> 15#include <linux/init.h>
diff --git a/drivers/pcmcia/i82365.c b/drivers/pcmcia/i82365.c
index 35a92d1e4945..bd0308e89815 100644
--- a/drivers/pcmcia/i82365.c
+++ b/drivers/pcmcia/i82365.c
@@ -34,7 +34,6 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/config.h>
38#include <linux/types.h> 37#include <linux/types.h>
39#include <linux/fcntl.h> 38#include <linux/fcntl.h>
40#include <linux/string.h> 39#include <linux/string.h>
diff --git a/drivers/pcmcia/pcmcia_compat.c b/drivers/pcmcia/pcmcia_compat.c
deleted file mode 100644
index ebb161c4f819..000000000000
--- a/drivers/pcmcia/pcmcia_compat.c
+++ /dev/null
@@ -1,65 +0,0 @@
1/*
2 * PCMCIA 16-bit compatibility functions
3 *
4 * The initial developer of the original code is David A. Hinds
5 * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
6 * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
7 *
8 * Copyright (C) 2004 Dominik Brodowski
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 */
15
16#include <linux/config.h>
17#include <linux/module.h>
18#include <linux/init.h>
19
20#define IN_CARD_SERVICES
21#include <pcmcia/cs_types.h>
22#include <pcmcia/cs.h>
23#include <pcmcia/bulkmem.h>
24#include <pcmcia/cistpl.h>
25#include <pcmcia/ds.h>
26#include <pcmcia/ss.h>
27
28#include "cs_internal.h"
29
30int pcmcia_get_first_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
31{
32 return pccard_get_first_tuple(p_dev->socket, p_dev->func, tuple);
33}
34EXPORT_SYMBOL(pcmcia_get_first_tuple);
35
36int pcmcia_get_next_tuple(struct pcmcia_device *p_dev, tuple_t *tuple)
37{
38 return pccard_get_next_tuple(p_dev->socket, p_dev->func, tuple);
39}
40EXPORT_SYMBOL(pcmcia_get_next_tuple);
41
42int pcmcia_get_tuple_data(struct pcmcia_device *p_dev, tuple_t *tuple)
43{
44 return pccard_get_tuple_data(p_dev->socket, tuple);
45}
46EXPORT_SYMBOL(pcmcia_get_tuple_data);
47
48int pcmcia_parse_tuple(struct pcmcia_device *p_dev, tuple_t *tuple, cisparse_t *parse)
49{
50 return pccard_parse_tuple(tuple, parse);
51}
52EXPORT_SYMBOL(pcmcia_parse_tuple);
53
54int pcmcia_validate_cis(struct pcmcia_device *p_dev, cisinfo_t *info)
55{
56 return pccard_validate_cis(p_dev->socket, p_dev->func, info);
57}
58EXPORT_SYMBOL(pcmcia_validate_cis);
59
60
61int pcmcia_reset_card(struct pcmcia_device *p_dev, client_req_t *req)
62{
63 return pccard_reset_card(p_dev->socket);
64}
65EXPORT_SYMBOL(pcmcia_reset_card);
diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c
index 80969f7e7a0b..c53db7ceda5e 100644
--- a/drivers/pcmcia/pcmcia_ioctl.c
+++ b/drivers/pcmcia/pcmcia_ioctl.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20 20
21#include <linux/config.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/module.h> 22#include <linux/module.h>
24#include <linux/init.h> 23#include <linux/init.h>
@@ -70,10 +69,26 @@ extern int ds_pc_debug;
70#define ds_dbg(lvl, fmt, arg...) do { } while (0) 69#define ds_dbg(lvl, fmt, arg...) do { } while (0)
71#endif 70#endif
72 71
72static struct pcmcia_device *get_pcmcia_device(struct pcmcia_socket *s,
73 unsigned int function)
74{
75 struct pcmcia_device *p_dev = NULL;
76 unsigned long flags;
77
78 spin_lock_irqsave(&pcmcia_dev_list_lock, flags);
79 list_for_each_entry(p_dev, &s->devices_list, socket_device_list) {
80 if (p_dev->func == function) {
81 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
82 return pcmcia_get_dev(p_dev);
83 }
84 }
85 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
86 return NULL;
87}
73 88
74/* backwards-compatible accessing of driver --- by name! */ 89/* backwards-compatible accessing of driver --- by name! */
75 90
76static struct pcmcia_driver * get_pcmcia_driver (dev_info_t *dev_info) 91static struct pcmcia_driver *get_pcmcia_driver(dev_info_t *dev_info)
77{ 92{
78 struct device_driver *drv; 93 struct device_driver *drv;
79 struct pcmcia_driver *p_drv; 94 struct pcmcia_driver *p_drv;
@@ -214,7 +229,7 @@ static int bind_request(struct pcmcia_socket *s, bind_info_t *bind_info)
214 * by userspace before, we need to 229 * by userspace before, we need to
215 * return the "instance". */ 230 * return the "instance". */
216 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 231 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
217 bind_info->instance = p_dev->instance; 232 bind_info->instance = p_dev;
218 ret = -EBUSY; 233 ret = -EBUSY;
219 goto err_put_module; 234 goto err_put_module;
220 } else { 235 } else {
@@ -253,9 +268,9 @@ rescan:
253 /* 268 /*
254 * Prevent this racing with a card insertion. 269 * Prevent this racing with a card insertion.
255 */ 270 */
256 down(&s->skt_sem); 271 mutex_lock(&s->skt_mutex);
257 bus_rescan_devices(&pcmcia_bus_type); 272 bus_rescan_devices(&pcmcia_bus_type);
258 up(&s->skt_sem); 273 mutex_unlock(&s->skt_mutex);
259 274
260 /* check whether the driver indeed matched. I don't care if this 275 /* check whether the driver indeed matched. I don't care if this
261 * is racy or not, because it can only happen on cardmgr access 276 * is racy or not, because it can only happen on cardmgr access
@@ -289,6 +304,7 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
289{ 304{
290 dev_node_t *node; 305 dev_node_t *node;
291 struct pcmcia_device *p_dev; 306 struct pcmcia_device *p_dev;
307 struct pcmcia_driver *p_drv;
292 unsigned long flags; 308 unsigned long flags;
293 int ret = 0; 309 int ret = 0;
294 310
@@ -343,16 +359,16 @@ static int get_device_info(struct pcmcia_socket *s, bind_info_t *bind_info, int
343 found: 359 found:
344 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); 360 spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags);
345 361
346 if ((!p_dev->instance) || 362 p_drv = to_pcmcia_drv(p_dev->dev.driver);
347 (p_dev->instance->state & DEV_CONFIG_PENDING)) { 363 if (p_drv && !p_dev->_locked) {
348 ret = -EAGAIN; 364 ret = -EAGAIN;
349 goto err_put; 365 goto err_put;
350 } 366 }
351 367
352 if (first) 368 if (first)
353 node = p_dev->instance->dev; 369 node = p_dev->dev_node;
354 else 370 else
355 for (node = p_dev->instance->dev; node; node = node->next) 371 for (node = p_dev->dev_node; node; node = node->next)
356 if (node == bind_info->next) 372 if (node == bind_info->next)
357 break; 373 break;
358 if (!node) { 374 if (!node) {
@@ -583,14 +599,16 @@ static int ds_ioctl(struct inode * inode, struct file * file,
583 if (buf->config.Function && 599 if (buf->config.Function &&
584 (buf->config.Function >= s->functions)) 600 (buf->config.Function >= s->functions))
585 ret = CS_BAD_ARGS; 601 ret = CS_BAD_ARGS;
586 else 602 else {
587 ret = pccard_get_configuration_info(s, 603 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function);
588 buf->config.Function, &buf->config); 604 ret = pccard_get_configuration_info(s, p_dev, &buf->config);
605 pcmcia_put_dev(p_dev);
606 }
589 break; 607 break;
590 case DS_GET_FIRST_TUPLE: 608 case DS_GET_FIRST_TUPLE:
591 down(&s->skt_sem); 609 mutex_lock(&s->skt_mutex);
592 pcmcia_validate_mem(s); 610 pcmcia_validate_mem(s);
593 up(&s->skt_sem); 611 mutex_unlock(&s->skt_mutex);
594 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple); 612 ret = pccard_get_first_tuple(s, BIND_FN_ALL, &buf->tuple);
595 break; 613 break;
596 case DS_GET_NEXT_TUPLE: 614 case DS_GET_NEXT_TUPLE:
@@ -609,16 +627,19 @@ static int ds_ioctl(struct inode * inode, struct file * file,
609 ret = pccard_reset_card(s); 627 ret = pccard_reset_card(s);
610 break; 628 break;
611 case DS_GET_STATUS: 629 case DS_GET_STATUS:
612 if (buf->status.Function && 630 if (buf->status.Function &&
613 (buf->status.Function >= s->functions)) 631 (buf->status.Function >= s->functions))
614 ret = CS_BAD_ARGS; 632 ret = CS_BAD_ARGS;
615 else 633 else {
616 ret = pccard_get_status(s, buf->status.Function, &buf->status); 634 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function);
617 break; 635 ret = pccard_get_status(s, p_dev, &buf->status);
636 pcmcia_put_dev(p_dev);
637 }
638 break;
618 case DS_VALIDATE_CIS: 639 case DS_VALIDATE_CIS:
619 down(&s->skt_sem); 640 mutex_lock(&s->skt_mutex);
620 pcmcia_validate_mem(s); 641 pcmcia_validate_mem(s);
621 up(&s->skt_sem); 642 mutex_unlock(&s->skt_mutex);
622 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo); 643 ret = pccard_validate_cis(s, BIND_FN_ALL, &buf->cisinfo);
623 break; 644 break;
624 case DS_SUSPEND_CARD: 645 case DS_SUSPEND_CARD:
@@ -638,12 +659,16 @@ static int ds_ioctl(struct inode * inode, struct file * file,
638 err = -EPERM; 659 err = -EPERM;
639 goto free_out; 660 goto free_out;
640 } 661 }
641 if (buf->conf_reg.Function && 662
642 (buf->conf_reg.Function >= s->functions)) 663 ret = CS_BAD_ARGS;
643 ret = CS_BAD_ARGS; 664
644 else 665 if (!(buf->conf_reg.Function &&
645 ret = pccard_access_configuration_register(s, 666 (buf->conf_reg.Function >= s->functions))) {
646 buf->conf_reg.Function, &buf->conf_reg); 667 struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->conf_reg.Function);
668 if (p_dev)
669 ret = pcmcia_access_configuration_register(p_dev, &buf->conf_reg);
670 pcmcia_put_dev(p_dev);
671 }
647 break; 672 break;
648 case DS_GET_FIRST_REGION: 673 case DS_GET_FIRST_REGION:
649 case DS_GET_NEXT_REGION: 674 case DS_GET_NEXT_REGION:
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index 89022ad5b520..45063b4e5b78 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -14,7 +14,6 @@
14 * 14 *
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/interrupt.h> 19#include <linux/interrupt.h>
@@ -89,7 +88,7 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
89 } 88 }
90 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { 89 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) {
91 *base = s->io_offset | (*base & 0x0fff); 90 *base = s->io_offset | (*base & 0x0fff);
92 s->io[0].Attributes = attr; 91 s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
93 return 0; 92 return 0;
94 } 93 }
95 /* Check for an already-allocated window that must conflict with 94 /* Check for an already-allocated window that must conflict with
@@ -97,38 +96,36 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base,
97 * potential conflicts, just the most obvious ones. 96 * potential conflicts, just the most obvious ones.
98 */ 97 */
99 for (i = 0; i < MAX_IO_WIN; i++) 98 for (i = 0; i < MAX_IO_WIN; i++)
100 if ((s->io[i].NumPorts != 0) && 99 if ((s->io[i].res) &&
101 ((s->io[i].BasePort & (align-1)) == *base)) 100 ((s->io[i].res->start & (align-1)) == *base))
102 return 1; 101 return 1;
103 for (i = 0; i < MAX_IO_WIN; i++) { 102 for (i = 0; i < MAX_IO_WIN; i++) {
104 if (s->io[i].NumPorts == 0) { 103 if (!s->io[i].res) {
105 s->io[i].res = pcmcia_find_io_region(*base, num, align, s); 104 s->io[i].res = pcmcia_find_io_region(*base, num, align, s);
106 if (s->io[i].res) { 105 if (s->io[i].res) {
107 s->io[i].Attributes = attr; 106 *base = s->io[i].res->start;
108 s->io[i].BasePort = *base = s->io[i].res->start; 107 s->io[i].res->flags = (s->io[i].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS);
109 s->io[i].NumPorts = s->io[i].InUse = num; 108 s->io[i].InUse = num;
110 break; 109 break;
111 } else 110 } else
112 return 1; 111 return 1;
113 } else if (s->io[i].Attributes != attr) 112 } else if ((s->io[i].res->flags & IORESOURCE_BITS) != (attr & IORESOURCE_BITS))
114 continue; 113 continue;
115 /* Try to extend top of window */ 114 /* Try to extend top of window */
116 try = s->io[i].BasePort + s->io[i].NumPorts; 115 try = s->io[i].res->end + 1;
117 if ((*base == 0) || (*base == try)) 116 if ((*base == 0) || (*base == try))
118 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, 117 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start,
119 s->io[i].res->end + num, s) == 0) { 118 s->io[i].res->end + num, s) == 0) {
120 *base = try; 119 *base = try;
121 s->io[i].NumPorts += num;
122 s->io[i].InUse += num; 120 s->io[i].InUse += num;
123 break; 121 break;
124 } 122 }
125 /* Try to extend bottom of window */ 123 /* Try to extend bottom of window */
126 try = s->io[i].BasePort - num; 124 try = s->io[i].res->start - num;
127 if ((*base == 0) || (*base == try)) 125 if ((*base == 0) || (*base == try))
128 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, 126 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num,
129 s->io[i].res->end, s) == 0) { 127 s->io[i].res->end, s) == 0) {
130 s->io[i].BasePort = *base = try; 128 *base = try;
131 s->io[i].NumPorts += num;
132 s->io[i].InUse += num; 129 s->io[i].InUse += num;
133 break; 130 break;
134 } 131 }
@@ -143,12 +140,13 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
143 int i; 140 int i;
144 141
145 for (i = 0; i < MAX_IO_WIN; i++) { 142 for (i = 0; i < MAX_IO_WIN; i++) {
146 if ((s->io[i].BasePort <= base) && 143 if (!s->io[i].res)
147 (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { 144 continue;
145 if ((s->io[i].res->start <= base) &&
146 (s->io[i].res->end >= base+num-1)) {
148 s->io[i].InUse -= num; 147 s->io[i].InUse -= num;
149 /* Free the window if no one else is using it */ 148 /* Free the window if no one else is using it */
150 if (s->io[i].InUse == 0) { 149 if (s->io[i].InUse == 0) {
151 s->io[i].NumPorts = 0;
152 release_resource(s->io[i].res); 150 release_resource(s->io[i].res);
153 kfree(s->io[i].res); 151 kfree(s->io[i].res);
154 s->io[i].res = NULL; 152 s->io[i].res = NULL;
@@ -165,21 +163,19 @@ static void release_io_space(struct pcmcia_socket *s, ioaddr_t base,
165 * this and the tuple reading services. 163 * this and the tuple reading services.
166 */ 164 */
167 165
168int pccard_access_configuration_register(struct pcmcia_socket *s, 166int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
169 unsigned int function,
170 conf_reg_t *reg) 167 conf_reg_t *reg)
171{ 168{
169 struct pcmcia_socket *s;
172 config_t *c; 170 config_t *c;
173 int addr; 171 int addr;
174 u_char val; 172 u_char val;
175 173
176 if (!s || !s->config) 174 if (!p_dev || !p_dev->function_config)
177 return CS_NO_CARD; 175 return CS_NO_CARD;
178 176
179 c = &s->config[function]; 177 s = p_dev->socket;
180 178 c = p_dev->function_config;
181 if (c == NULL)
182 return CS_NO_CARD;
183 179
184 if (!(c->state & CONFIG_LOCKED)) 180 if (!(c->state & CONFIG_LOCKED))
185 return CS_CONFIGURATION_LOCKED; 181 return CS_CONFIGURATION_LOCKED;
@@ -200,20 +196,12 @@ int pccard_access_configuration_register(struct pcmcia_socket *s,
200 break; 196 break;
201 } 197 }
202 return CS_SUCCESS; 198 return CS_SUCCESS;
203} /* pccard_access_configuration_register */ 199} /* pcmcia_access_configuration_register */
204
205int pcmcia_access_configuration_register(struct pcmcia_device *p_dev,
206 conf_reg_t *reg)
207{
208 return pccard_access_configuration_register(p_dev->socket,
209 p_dev->func, reg);
210}
211EXPORT_SYMBOL(pcmcia_access_configuration_register); 200EXPORT_SYMBOL(pcmcia_access_configuration_register);
212 201
213 202
214
215int pccard_get_configuration_info(struct pcmcia_socket *s, 203int pccard_get_configuration_info(struct pcmcia_socket *s,
216 unsigned int function, 204 struct pcmcia_device *p_dev,
217 config_info_t *config) 205 config_info_t *config)
218{ 206{
219 config_t *c; 207 config_t *c;
@@ -221,7 +209,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
221 if (!(s->state & SOCKET_PRESENT)) 209 if (!(s->state & SOCKET_PRESENT))
222 return CS_NO_CARD; 210 return CS_NO_CARD;
223 211
224 config->Function = function; 212 config->Function = p_dev->func;
225 213
226#ifdef CONFIG_CARDBUS 214#ifdef CONFIG_CARDBUS
227 if (s->state & SOCKET_CARDBUS) { 215 if (s->state & SOCKET_CARDBUS) {
@@ -235,14 +223,14 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
235 config->AssignedIRQ = s->irq.AssignedIRQ; 223 config->AssignedIRQ = s->irq.AssignedIRQ;
236 if (config->AssignedIRQ) 224 if (config->AssignedIRQ)
237 config->Attributes |= CONF_ENABLE_IRQ; 225 config->Attributes |= CONF_ENABLE_IRQ;
238 config->BasePort1 = s->io[0].BasePort; 226 config->BasePort1 = s->io[0].res->start;
239 config->NumPorts1 = s->io[0].NumPorts; 227 config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1;
240 } 228 }
241 return CS_SUCCESS; 229 return CS_SUCCESS;
242 } 230 }
243#endif 231#endif
244 232
245 c = (s->config != NULL) ? &s->config[function] : NULL; 233 c = (p_dev) ? p_dev->function_config : NULL;
246 234
247 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { 235 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
248 config->Attributes = 0; 236 config->Attributes = 0;
@@ -271,7 +259,7 @@ int pccard_get_configuration_info(struct pcmcia_socket *s,
271int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, 259int pcmcia_get_configuration_info(struct pcmcia_device *p_dev,
272 config_info_t *config) 260 config_info_t *config)
273{ 261{
274 return pccard_get_configuration_info(p_dev->socket, p_dev->func, 262 return pccard_get_configuration_info(p_dev->socket, p_dev,
275 config); 263 config);
276} 264}
277EXPORT_SYMBOL(pcmcia_get_configuration_info); 265EXPORT_SYMBOL(pcmcia_get_configuration_info);
@@ -317,7 +305,7 @@ EXPORT_SYMBOL(pcmcia_get_window);
317 * SocketState yet: I haven't seen any point for it. 305 * SocketState yet: I haven't seen any point for it.
318 */ 306 */
319 307
320int pccard_get_status(struct pcmcia_socket *s, unsigned int function, 308int pccard_get_status(struct pcmcia_socket *s, struct pcmcia_device *p_dev,
321 cs_status_t *status) 309 cs_status_t *status)
322{ 310{
323 config_t *c; 311 config_t *c;
@@ -334,11 +322,12 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
334 if (!(s->state & SOCKET_PRESENT)) 322 if (!(s->state & SOCKET_PRESENT))
335 return CS_NO_CARD; 323 return CS_NO_CARD;
336 324
337 c = (s->config != NULL) ? &s->config[function] : NULL; 325 c = (p_dev) ? p_dev->function_config : NULL;
326
338 if ((c != NULL) && (c->state & CONFIG_LOCKED) && 327 if ((c != NULL) && (c->state & CONFIG_LOCKED) &&
339 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { 328 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) {
340 u_char reg; 329 u_char reg;
341 if (c->Present & PRESENT_PIN_REPLACE) { 330 if (c->CardValues & PRESENT_PIN_REPLACE) {
342 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg); 331 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, &reg);
343 status->CardState |= 332 status->CardState |=
344 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; 333 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0;
@@ -352,7 +341,7 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
352 /* No PRR? Then assume we're always ready */ 341 /* No PRR? Then assume we're always ready */
353 status->CardState |= CS_EVENT_READY_CHANGE; 342 status->CardState |= CS_EVENT_READY_CHANGE;
354 } 343 }
355 if (c->Present & PRESENT_EXT_STATUS) { 344 if (c->CardValues & PRESENT_EXT_STATUS) {
356 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg); 345 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, &reg);
357 status->CardState |= 346 status->CardState |=
358 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; 347 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0;
@@ -370,11 +359,9 @@ int pccard_get_status(struct pcmcia_socket *s, unsigned int function,
370 return CS_SUCCESS; 359 return CS_SUCCESS;
371} /* pccard_get_status */ 360} /* pccard_get_status */
372 361
373int pcmcia_get_status(client_handle_t handle, cs_status_t *status) 362int pcmcia_get_status(struct pcmcia_device *p_dev, cs_status_t *status)
374{ 363{
375 struct pcmcia_socket *s; 364 return pccard_get_status(p_dev->socket, p_dev, status);
376 s = SOCKET(handle);
377 return pccard_get_status(s, handle->func, status);
378} 365}
379EXPORT_SYMBOL(pcmcia_get_status); 366EXPORT_SYMBOL(pcmcia_get_status);
380 367
@@ -422,7 +409,8 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
422 config_t *c; 409 config_t *c;
423 410
424 s = p_dev->socket; 411 s = p_dev->socket;
425 c = CONFIG(p_dev); 412 c = p_dev->function_config;
413
426 if (!(s->state & SOCKET_PRESENT)) 414 if (!(s->state & SOCKET_PRESENT))
427 return CS_NO_CARD; 415 return CS_NO_CARD;
428 if (!(c->state & CONFIG_LOCKED)) 416 if (!(c->state & CONFIG_LOCKED))
@@ -454,6 +442,28 @@ int pcmcia_modify_configuration(struct pcmcia_device *p_dev,
454 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) 442 (mod->Attributes & CONF_VPP2_CHANGE_VALID))
455 return CS_BAD_VPP; 443 return CS_BAD_VPP;
456 444
445 if (mod->Attributes & CONF_IO_CHANGE_WIDTH) {
446 pccard_io_map io_off = { 0, 0, 0, 0, 1 };
447 pccard_io_map io_on;
448 int i;
449
450 io_on.speed = io_speed;
451 for (i = 0; i < MAX_IO_WIN; i++) {
452 if (!s->io[i].res)
453 continue;
454 io_off.map = i;
455 io_on.map = i;
456
457 io_on.flags = MAP_ACTIVE | IO_DATA_PATH_WIDTH_8;
458 io_on.start = s->io[i].res->start;
459 io_on.stop = s->io[i].res->end;
460
461 s->ops->set_io_map(s, &io_off);
462 mdelay(40);
463 s->ops->set_io_map(s, &io_on);
464 }
465 }
466
457 return CS_SUCCESS; 467 return CS_SUCCESS;
458} /* modify_configuration */ 468} /* modify_configuration */
459EXPORT_SYMBOL(pcmcia_modify_configuration); 469EXPORT_SYMBOL(pcmcia_modify_configuration);
@@ -463,23 +473,23 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
463{ 473{
464 pccard_io_map io = { 0, 0, 0, 0, 1 }; 474 pccard_io_map io = { 0, 0, 0, 0, 1 };
465 struct pcmcia_socket *s = p_dev->socket; 475 struct pcmcia_socket *s = p_dev->socket;
476 config_t *c = p_dev->function_config;
466 int i; 477 int i;
467 478
468 if (!(p_dev->state & CLIENT_CONFIG_LOCKED)) 479 if (p_dev->_locked) {
469 return CS_BAD_HANDLE; 480 p_dev->_locked = 0;
470 p_dev->state &= ~CLIENT_CONFIG_LOCKED;
471
472 if (!(p_dev->state & CLIENT_STALE)) {
473 config_t *c = CONFIG(p_dev);
474 if (--(s->lock_count) == 0) { 481 if (--(s->lock_count) == 0) {
475 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ 482 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */
476 s->socket.Vpp = 0; 483 s->socket.Vpp = 0;
477 s->socket.io_irq = 0; 484 s->socket.io_irq = 0;
478 s->ops->set_socket(s, &s->socket); 485 s->ops->set_socket(s, &s->socket);
479 } 486 }
487 }
488 if (c->state & CONFIG_LOCKED) {
489 c->state &= ~CONFIG_LOCKED;
480 if (c->state & CONFIG_IO_REQ) 490 if (c->state & CONFIG_IO_REQ)
481 for (i = 0; i < MAX_IO_WIN; i++) { 491 for (i = 0; i < MAX_IO_WIN; i++) {
482 if (s->io[i].NumPorts == 0) 492 if (!s->io[i].res)
483 continue; 493 continue;
484 s->io[i].Config--; 494 s->io[i].Config--;
485 if (s->io[i].Config != 0) 495 if (s->io[i].Config != 0)
@@ -487,12 +497,10 @@ int pcmcia_release_configuration(struct pcmcia_device *p_dev)
487 io.map = i; 497 io.map = i;
488 s->ops->set_io_map(s, &io); 498 s->ops->set_io_map(s, &io);
489 } 499 }
490 c->state &= ~CONFIG_LOCKED;
491 } 500 }
492 501
493 return CS_SUCCESS; 502 return CS_SUCCESS;
494} /* pcmcia_release_configuration */ 503} /* pcmcia_release_configuration */
495EXPORT_SYMBOL(pcmcia_release_configuration);
496 504
497 505
498/** pcmcia_release_io 506/** pcmcia_release_io
@@ -503,25 +511,23 @@ EXPORT_SYMBOL(pcmcia_release_configuration);
503 * don't bother checking the port ranges against the current socket 511 * don't bother checking the port ranges against the current socket
504 * values. 512 * values.
505 */ 513 */
506int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) 514static int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
507{ 515{
508 struct pcmcia_socket *s = p_dev->socket; 516 struct pcmcia_socket *s = p_dev->socket;
517 config_t *c = p_dev->function_config;
509 518
510 if (!(p_dev->state & CLIENT_IO_REQ)) 519 if (!p_dev->_io )
511 return CS_BAD_HANDLE; 520 return CS_BAD_HANDLE;
512 p_dev->state &= ~CLIENT_IO_REQ; 521
513 522 p_dev->_io = 0;
514 if (!(p_dev->state & CLIENT_STALE)) { 523
515 config_t *c = CONFIG(p_dev); 524 if ((c->io.BasePort1 != req->BasePort1) ||
516 if (c->state & CONFIG_LOCKED) 525 (c->io.NumPorts1 != req->NumPorts1) ||
517 return CS_CONFIGURATION_LOCKED; 526 (c->io.BasePort2 != req->BasePort2) ||
518 if ((c->io.BasePort1 != req->BasePort1) || 527 (c->io.NumPorts2 != req->NumPorts2))
519 (c->io.NumPorts1 != req->NumPorts1) || 528 return CS_BAD_ARGS;
520 (c->io.BasePort2 != req->BasePort2) || 529
521 (c->io.NumPorts2 != req->NumPorts2)) 530 c->state &= ~CONFIG_IO_REQ;
522 return CS_BAD_ARGS;
523 c->state &= ~CONFIG_IO_REQ;
524 }
525 531
526 release_io_space(s, req->BasePort1, req->NumPorts1); 532 release_io_space(s, req->BasePort1, req->NumPorts1);
527 if (req->NumPorts2) 533 if (req->NumPorts2)
@@ -529,28 +535,26 @@ int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req)
529 535
530 return CS_SUCCESS; 536 return CS_SUCCESS;
531} /* pcmcia_release_io */ 537} /* pcmcia_release_io */
532EXPORT_SYMBOL(pcmcia_release_io);
533 538
534 539
535int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) 540static int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
536{ 541{
537 struct pcmcia_socket *s = p_dev->socket; 542 struct pcmcia_socket *s = p_dev->socket;
538 if (!(p_dev->state & CLIENT_IRQ_REQ)) 543 config_t *c= p_dev->function_config;
544
545 if (!p_dev->_irq)
539 return CS_BAD_HANDLE; 546 return CS_BAD_HANDLE;
540 p_dev->state &= ~CLIENT_IRQ_REQ; 547 p_dev->_irq = 0;
541 548
542 if (!(p_dev->state & CLIENT_STALE)) { 549 if (c->state & CONFIG_LOCKED)
543 config_t *c = CONFIG(p_dev); 550 return CS_CONFIGURATION_LOCKED;
544 if (c->state & CONFIG_LOCKED) 551 if (c->irq.Attributes != req->Attributes)
545 return CS_CONFIGURATION_LOCKED; 552 return CS_BAD_ATTRIBUTE;
546 if (c->irq.Attributes != req->Attributes) 553 if (s->irq.AssignedIRQ != req->AssignedIRQ)
547 return CS_BAD_ATTRIBUTE; 554 return CS_BAD_IRQ;
548 if (s->irq.AssignedIRQ != req->AssignedIRQ) 555 if (--s->irq.Config == 0) {
549 return CS_BAD_IRQ; 556 c->state &= ~CONFIG_IRQ_REQ;
550 if (--s->irq.Config == 0) { 557 s->irq.AssignedIRQ = 0;
551 c->state &= ~CONFIG_IRQ_REQ;
552 s->irq.AssignedIRQ = 0;
553 }
554 } 558 }
555 559
556 if (req->Attributes & IRQ_HANDLE_PRESENT) { 560 if (req->Attributes & IRQ_HANDLE_PRESENT) {
@@ -563,7 +567,6 @@ int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req)
563 567
564 return CS_SUCCESS; 568 return CS_SUCCESS;
565} /* pcmcia_release_irq */ 569} /* pcmcia_release_irq */
566EXPORT_SYMBOL(pcmcia_release_irq);
567 570
568 571
569int pcmcia_release_window(window_handle_t win) 572int pcmcia_release_window(window_handle_t win)
@@ -573,7 +576,7 @@ int pcmcia_release_window(window_handle_t win)
573 if ((win == NULL) || (win->magic != WINDOW_MAGIC)) 576 if ((win == NULL) || (win->magic != WINDOW_MAGIC))
574 return CS_BAD_HANDLE; 577 return CS_BAD_HANDLE;
575 s = win->sock; 578 s = win->sock;
576 if (!(win->handle->state & CLIENT_WIN_REQ(win->index))) 579 if (!(win->handle->_win & CLIENT_WIN_REQ(win->index)))
577 return CS_BAD_HANDLE; 580 return CS_BAD_HANDLE;
578 581
579 /* Shut down memory window */ 582 /* Shut down memory window */
@@ -587,7 +590,7 @@ int pcmcia_release_window(window_handle_t win)
587 kfree(win->ctl.res); 590 kfree(win->ctl.res);
588 win->ctl.res = NULL; 591 win->ctl.res = NULL;
589 } 592 }
590 win->handle->state &= ~CLIENT_WIN_REQ(win->index); 593 win->handle->_win &= ~CLIENT_WIN_REQ(win->index);
591 594
592 win->magic = 0; 595 win->magic = 0;
593 596
@@ -610,16 +613,12 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
610 613
611 if (req->IntType & INT_CARDBUS) 614 if (req->IntType & INT_CARDBUS)
612 return CS_UNSUPPORTED_MODE; 615 return CS_UNSUPPORTED_MODE;
613 c = CONFIG(p_dev); 616 c = p_dev->function_config;
614 if (c->state & CONFIG_LOCKED) 617 if (c->state & CONFIG_LOCKED)
615 return CS_CONFIGURATION_LOCKED; 618 return CS_CONFIGURATION_LOCKED;
616 619
617 /* Do power control. We don't allow changes in Vcc. */ 620 /* Do power control. We don't allow changes in Vcc. */
618 if (s->socket.Vcc != req->Vcc) 621 s->socket.Vpp = req->Vpp;
619 return CS_BAD_VCC;
620 if (req->Vpp1 != req->Vpp2)
621 return CS_BAD_VPP;
622 s->socket.Vpp = req->Vpp1;
623 if (s->ops->set_socket(s, &s->socket)) 622 if (s->ops->set_socket(s, &s->socket))
624 return CS_BAD_VPP; 623 return CS_BAD_VPP;
625 624
@@ -643,7 +642,7 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
643 642
644 /* Set up CIS configuration registers */ 643 /* Set up CIS configuration registers */
645 base = c->ConfigBase = req->ConfigBase; 644 base = c->ConfigBase = req->ConfigBase;
646 c->Present = c->CardValues = req->Present; 645 c->CardValues = req->Present;
647 if (req->Present & PRESENT_COPY) { 646 if (req->Present & PRESENT_COPY) {
648 c->Copy = req->Copy; 647 c->Copy = req->Copy;
649 pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); 648 pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy);
@@ -690,10 +689,10 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
690 if (c->state & CONFIG_IO_REQ) { 689 if (c->state & CONFIG_IO_REQ) {
691 iomap.speed = io_speed; 690 iomap.speed = io_speed;
692 for (i = 0; i < MAX_IO_WIN; i++) 691 for (i = 0; i < MAX_IO_WIN; i++)
693 if (s->io[i].NumPorts != 0) { 692 if (s->io[i].res) {
694 iomap.map = i; 693 iomap.map = i;
695 iomap.flags = MAP_ACTIVE; 694 iomap.flags = MAP_ACTIVE;
696 switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { 695 switch (s->io[i].res->flags & IO_DATA_PATH_WIDTH) {
697 case IO_DATA_PATH_WIDTH_16: 696 case IO_DATA_PATH_WIDTH_16:
698 iomap.flags |= MAP_16BIT; break; 697 iomap.flags |= MAP_16BIT; break;
699 case IO_DATA_PATH_WIDTH_AUTO: 698 case IO_DATA_PATH_WIDTH_AUTO:
@@ -701,15 +700,15 @@ int pcmcia_request_configuration(struct pcmcia_device *p_dev,
701 default: 700 default:
702 break; 701 break;
703 } 702 }
704 iomap.start = s->io[i].BasePort; 703 iomap.start = s->io[i].res->start;
705 iomap.stop = iomap.start + s->io[i].NumPorts - 1; 704 iomap.stop = s->io[i].res->end;
706 s->ops->set_io_map(s, &iomap); 705 s->ops->set_io_map(s, &iomap);
707 s->io[i].Config++; 706 s->io[i].Config++;
708 } 707 }
709 } 708 }
710 709
711 c->state |= CONFIG_LOCKED; 710 c->state |= CONFIG_LOCKED;
712 p_dev->state |= CLIENT_CONFIG_LOCKED; 711 p_dev->_locked = 1;
713 return CS_SUCCESS; 712 return CS_SUCCESS;
714} /* pcmcia_request_configuration */ 713} /* pcmcia_request_configuration */
715EXPORT_SYMBOL(pcmcia_request_configuration); 714EXPORT_SYMBOL(pcmcia_request_configuration);
@@ -730,7 +729,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
730 729
731 if (!req) 730 if (!req)
732 return CS_UNSUPPORTED_MODE; 731 return CS_UNSUPPORTED_MODE;
733 c = CONFIG(p_dev); 732 c = p_dev->function_config;
734 if (c->state & CONFIG_LOCKED) 733 if (c->state & CONFIG_LOCKED)
735 return CS_CONFIGURATION_LOCKED; 734 return CS_CONFIGURATION_LOCKED;
736 if (c->state & CONFIG_IO_REQ) 735 if (c->state & CONFIG_IO_REQ)
@@ -755,7 +754,7 @@ int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req)
755 754
756 c->io = *req; 755 c->io = *req;
757 c->state |= CONFIG_IO_REQ; 756 c->state |= CONFIG_IO_REQ;
758 p_dev->state |= CLIENT_IO_REQ; 757 p_dev->_io = 1;
759 return CS_SUCCESS; 758 return CS_SUCCESS;
760} /* pcmcia_request_io */ 759} /* pcmcia_request_io */
761EXPORT_SYMBOL(pcmcia_request_io); 760EXPORT_SYMBOL(pcmcia_request_io);
@@ -786,7 +785,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
786 785
787 if (!(s->state & SOCKET_PRESENT)) 786 if (!(s->state & SOCKET_PRESENT))
788 return CS_NO_CARD; 787 return CS_NO_CARD;
789 c = CONFIG(p_dev); 788 c = p_dev->function_config;
790 if (c->state & CONFIG_LOCKED) 789 if (c->state & CONFIG_LOCKED)
791 return CS_CONFIGURATION_LOCKED; 790 return CS_CONFIGURATION_LOCKED;
792 if (c->state & CONFIG_IRQ_REQ) 791 if (c->state & CONFIG_IRQ_REQ)
@@ -851,7 +850,7 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
851 s->irq.Config++; 850 s->irq.Config++;
852 851
853 c->state |= CONFIG_IRQ_REQ; 852 c->state |= CONFIG_IRQ_REQ;
854 p_dev->state |= CLIENT_IRQ_REQ; 853 p_dev->_irq = 1;
855 854
856#ifdef CONFIG_PCMCIA_PROBE 855#ifdef CONFIG_PCMCIA_PROBE
857 pcmcia_used_irq[irq]++; 856 pcmcia_used_irq[irq]++;
@@ -911,7 +910,7 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
911 if (!win->ctl.res) 910 if (!win->ctl.res)
912 return CS_IN_USE; 911 return CS_IN_USE;
913 } 912 }
914 (*p_dev)->state |= CLIENT_WIN_REQ(w); 913 (*p_dev)->_win |= CLIENT_WIN_REQ(w);
915 914
916 /* Configure the socket controller */ 915 /* Configure the socket controller */
917 win->ctl.map = w+1; 916 win->ctl.map = w+1;
@@ -941,3 +940,14 @@ int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_h
941 return CS_SUCCESS; 940 return CS_SUCCESS;
942} /* pcmcia_request_window */ 941} /* pcmcia_request_window */
943EXPORT_SYMBOL(pcmcia_request_window); 942EXPORT_SYMBOL(pcmcia_request_window);
943
944void pcmcia_disable_device(struct pcmcia_device *p_dev) {
945 pcmcia_release_configuration(p_dev);
946 pcmcia_release_io(p_dev, &p_dev->io);
947 pcmcia_release_irq(p_dev, &p_dev->irq);
948 if (&p_dev->win)
949 pcmcia_release_window(p_dev->win);
950
951 p_dev->dev_node = NULL;
952}
953EXPORT_SYMBOL(pcmcia_disable_device);
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c
index f2789afb22b2..16d1ea7b0a18 100644
--- a/drivers/pcmcia/pd6729.c
+++ b/drivers/pcmcia/pd6729.c
@@ -8,7 +8,6 @@
8 */ 8 */
9 9
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13#include <linux/pci.h> 12#include <linux/pci.h>
14#include <linux/init.h> 13#include <linux/init.h>
diff --git a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
index 514609369836..81dfc2cac2b4 100644
--- a/drivers/pcmcia/rsrc_mgr.c
+++ b/drivers/pcmcia/rsrc_mgr.c
@@ -12,7 +12,6 @@
12 * (C) 1999 David A. Hinds 12 * (C) 1999 David A. Hinds
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18 17
@@ -22,6 +21,8 @@
22#include "cs_internal.h" 21#include "cs_internal.h"
23 22
24 23
24#ifdef CONFIG_PCMCIA_IOCTL
25
25#ifdef CONFIG_PCMCIA_PROBE 26#ifdef CONFIG_PCMCIA_PROBE
26 27
27static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj) 28static int adjust_irq(struct pcmcia_socket *s, adjust_t *adj)
@@ -98,6 +99,8 @@ int pcmcia_adjust_resource_info(adjust_t *adj)
98} 99}
99EXPORT_SYMBOL(pcmcia_adjust_resource_info); 100EXPORT_SYMBOL(pcmcia_adjust_resource_info);
100 101
102#endif
103
101int pcmcia_validate_mem(struct pcmcia_socket *s) 104int pcmcia_validate_mem(struct pcmcia_socket *s)
102{ 105{
103 if (s->resource_ops->validate_mem) 106 if (s->resource_ops->validate_mem)
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 5301ac60358f..0f8b157c9717 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -12,7 +12,6 @@
12 * (C) 1999 David A. Hinds 12 * (C) 1999 David A. Hinds
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
18#include <linux/init.h> 17#include <linux/init.h>
@@ -61,7 +60,7 @@ struct socket_data {
61 unsigned int rsrc_mem_probe; 60 unsigned int rsrc_mem_probe;
62}; 61};
63 62
64static DECLARE_MUTEX(rsrc_sem); 63static DEFINE_MUTEX(rsrc_mutex);
65#define MEM_PROBE_LOW (1 << 0) 64#define MEM_PROBE_LOW (1 << 0)
66#define MEM_PROBE_HIGH (1 << 1) 65#define MEM_PROBE_HIGH (1 << 1)
67 66
@@ -484,7 +483,7 @@ static int validate_mem(struct pcmcia_socket *s, unsigned int probe_mask)
484 483
485 484
486/* 485/*
487 * Locking note: Must be called with skt_sem held! 486 * Locking note: Must be called with skt_mutex held!
488 */ 487 */
489static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s) 488static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
490{ 489{
@@ -495,7 +494,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
495 if (!probe_mem) 494 if (!probe_mem)
496 return 0; 495 return 0;
497 496
498 down(&rsrc_sem); 497 mutex_lock(&rsrc_mutex);
499 498
500 if (s->features & SS_CAP_PAGE_REGS) 499 if (s->features & SS_CAP_PAGE_REGS)
501 probe_mask = MEM_PROBE_HIGH; 500 probe_mask = MEM_PROBE_HIGH;
@@ -507,7 +506,7 @@ static int pcmcia_nonstatic_validate_mem(struct pcmcia_socket *s)
507 s_data->rsrc_mem_probe |= probe_mask; 506 s_data->rsrc_mem_probe |= probe_mask;
508 } 507 }
509 508
510 up(&rsrc_sem); 509 mutex_unlock(&rsrc_mutex);
511 510
512 return ret; 511 return ret;
513} 512}
@@ -585,7 +584,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
585 struct socket_data *s_data = s->resource_data; 584 struct socket_data *s_data = s->resource_data;
586 int ret = -ENOMEM; 585 int ret = -ENOMEM;
587 586
588 down(&rsrc_sem); 587 mutex_lock(&rsrc_mutex);
589 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) { 588 for (m = s_data->io_db.next; m != &s_data->io_db; m = m->next) {
590 unsigned long start = m->base; 589 unsigned long start = m->base;
591 unsigned long end = m->base + m->num - 1; 590 unsigned long end = m->base + m->num - 1;
@@ -596,7 +595,7 @@ static int nonstatic_adjust_io_region(struct resource *res, unsigned long r_star
596 ret = adjust_resource(res, r_start, r_end - r_start + 1); 595 ret = adjust_resource(res, r_start, r_end - r_start + 1);
597 break; 596 break;
598 } 597 }
599 up(&rsrc_sem); 598 mutex_unlock(&rsrc_mutex);
600 599
601 return ret; 600 return ret;
602} 601}
@@ -630,7 +629,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
630 data.offset = base & data.mask; 629 data.offset = base & data.mask;
631 data.map = &s_data->io_db; 630 data.map = &s_data->io_db;
632 631
633 down(&rsrc_sem); 632 mutex_lock(&rsrc_mutex);
634#ifdef CONFIG_PCI 633#ifdef CONFIG_PCI
635 if (s->cb_dev) { 634 if (s->cb_dev) {
636 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1, 635 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 1,
@@ -639,7 +638,7 @@ static struct resource *nonstatic_find_io_region(unsigned long base, int num,
639#endif 638#endif
640 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL, 639 ret = allocate_resource(&ioport_resource, res, num, min, ~0UL,
641 1, pcmcia_align, &data); 640 1, pcmcia_align, &data);
642 up(&rsrc_sem); 641 mutex_unlock(&rsrc_mutex);
643 642
644 if (ret != 0) { 643 if (ret != 0) {
645 kfree(res); 644 kfree(res);
@@ -672,7 +671,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
672 min = 0x100000UL + base; 671 min = 0x100000UL + base;
673 } 672 }
674 673
675 down(&rsrc_sem); 674 mutex_lock(&rsrc_mutex);
676#ifdef CONFIG_PCI 675#ifdef CONFIG_PCI
677 if (s->cb_dev) { 676 if (s->cb_dev) {
678 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num, 677 ret = pci_bus_alloc_resource(s->cb_dev->bus, res, num,
@@ -682,7 +681,7 @@ static struct resource * nonstatic_find_mem_region(u_long base, u_long num,
682#endif 681#endif
683 ret = allocate_resource(&iomem_resource, res, num, min, 682 ret = allocate_resource(&iomem_resource, res, num, min,
684 max, 1, pcmcia_align, &data); 683 max, 1, pcmcia_align, &data);
685 up(&rsrc_sem); 684 mutex_unlock(&rsrc_mutex);
686 if (ret == 0 || low) 685 if (ret == 0 || low)
687 break; 686 break;
688 low = 1; 687 low = 1;
@@ -705,7 +704,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
705 if (end < start) 704 if (end < start)
706 return -EINVAL; 705 return -EINVAL;
707 706
708 down(&rsrc_sem); 707 mutex_lock(&rsrc_mutex);
709 switch (action) { 708 switch (action) {
710 case ADD_MANAGED_RESOURCE: 709 case ADD_MANAGED_RESOURCE:
711 ret = add_interval(&data->mem_db, start, size); 710 ret = add_interval(&data->mem_db, start, size);
@@ -723,7 +722,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
723 default: 722 default:
724 ret = -EINVAL; 723 ret = -EINVAL;
725 } 724 }
726 up(&rsrc_sem); 725 mutex_unlock(&rsrc_mutex);
727 726
728 return ret; 727 return ret;
729} 728}
@@ -741,7 +740,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
741 if (end > IO_SPACE_LIMIT) 740 if (end > IO_SPACE_LIMIT)
742 return -EINVAL; 741 return -EINVAL;
743 742
744 down(&rsrc_sem); 743 mutex_lock(&rsrc_mutex);
745 switch (action) { 744 switch (action) {
746 case ADD_MANAGED_RESOURCE: 745 case ADD_MANAGED_RESOURCE:
747 if (add_interval(&data->io_db, start, size) != 0) { 746 if (add_interval(&data->io_db, start, size) != 0) {
@@ -760,7 +759,7 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
760 ret = -EINVAL; 759 ret = -EINVAL;
761 break; 760 break;
762 } 761 }
763 up(&rsrc_sem); 762 mutex_unlock(&rsrc_mutex);
764 763
765 return ret; 764 return ret;
766} 765}
@@ -867,7 +866,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
867 struct socket_data *data = s->resource_data; 866 struct socket_data *data = s->resource_data;
868 struct resource_map *p, *q; 867 struct resource_map *p, *q;
869 868
870 down(&rsrc_sem); 869 mutex_lock(&rsrc_mutex);
871 for (p = data->mem_db.next; p != &data->mem_db; p = q) { 870 for (p = data->mem_db.next; p != &data->mem_db; p = q) {
872 q = p->next; 871 q = p->next;
873 kfree(p); 872 kfree(p);
@@ -876,7 +875,7 @@ static void nonstatic_release_resource_db(struct pcmcia_socket *s)
876 q = p->next; 875 q = p->next;
877 kfree(p); 876 kfree(p);
878 } 877 }
879 up(&rsrc_sem); 878 mutex_unlock(&rsrc_mutex);
880} 879}
881 880
882 881
@@ -901,7 +900,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
901 struct resource_map *p; 900 struct resource_map *p;
902 ssize_t ret = 0; 901 ssize_t ret = 0;
903 902
904 down(&rsrc_sem); 903 mutex_lock(&rsrc_mutex);
905 data = s->resource_data; 904 data = s->resource_data;
906 905
907 for (p = data->io_db.next; p != &data->io_db; p = p->next) { 906 for (p = data->io_db.next; p != &data->io_db; p = p->next) {
@@ -913,7 +912,7 @@ static ssize_t show_io_db(struct class_device *class_dev, char *buf)
913 ((unsigned long) p->base + p->num - 1)); 912 ((unsigned long) p->base + p->num - 1));
914 } 913 }
915 914
916 up(&rsrc_sem); 915 mutex_unlock(&rsrc_mutex);
917 return (ret); 916 return (ret);
918} 917}
919 918
@@ -953,7 +952,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
953 struct resource_map *p; 952 struct resource_map *p;
954 ssize_t ret = 0; 953 ssize_t ret = 0;
955 954
956 down(&rsrc_sem); 955 mutex_lock(&rsrc_mutex);
957 data = s->resource_data; 956 data = s->resource_data;
958 957
959 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) { 958 for (p = data->mem_db.next; p != &data->mem_db; p = p->next) {
@@ -965,7 +964,7 @@ static ssize_t show_mem_db(struct class_device *class_dev, char *buf)
965 ((unsigned long) p->base + p->num - 1)); 964 ((unsigned long) p->base + p->num - 1));
966 } 965 }
967 966
968 up(&rsrc_sem); 967 mutex_unlock(&rsrc_mutex);
969 return (ret); 968 return (ret);
970} 969}
971 970
diff --git a/drivers/pcmcia/sa1100_cerf.c b/drivers/pcmcia/sa1100_cerf.c
index 2b3c2895b43d..eb89928f2338 100644
--- a/drivers/pcmcia/sa1100_cerf.c
+++ b/drivers/pcmcia/sa1100_cerf.c
@@ -5,7 +5,6 @@
5 * Based off the Assabet. 5 * Based off the Assabet.
6 * 6 *
7 */ 7 */
8#include <linux/config.h>
9#include <linux/module.h> 8#include <linux/module.h>
10#include <linux/kernel.h> 9#include <linux/kernel.h>
11#include <linux/sched.h> 10#include <linux/sched.h>
diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c
index 5ab1cdef7c48..c5d7476da471 100644
--- a/drivers/pcmcia/socket_sysfs.c
+++ b/drivers/pcmcia/socket_sysfs.c
@@ -12,7 +12,6 @@
12#include <linux/moduleparam.h> 12#include <linux/moduleparam.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/config.h>
16#include <linux/string.h> 15#include <linux/string.h>
17#include <linux/major.h> 16#include <linux/major.h>
18#include <linux/errno.h> 17#include <linux/errno.h>
@@ -25,6 +24,7 @@
25#include <linux/pm.h> 24#include <linux/pm.h>
26#include <linux/pci.h> 25#include <linux/pci.h>
27#include <linux/device.h> 26#include <linux/device.h>
27#include <linux/mutex.h>
28#include <asm/system.h> 28#include <asm/system.h>
29#include <asm/irq.h> 29#include <asm/irq.h>
30 30
@@ -183,7 +183,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
183 s->resource_setup_done = 1; 183 s->resource_setup_done = 1;
184 spin_unlock_irqrestore(&s->lock, flags); 184 spin_unlock_irqrestore(&s->lock, flags);
185 185
186 down(&s->skt_sem); 186 mutex_lock(&s->skt_mutex);
187 if ((s->callback) && 187 if ((s->callback) &&
188 (s->state & SOCKET_PRESENT) && 188 (s->state & SOCKET_PRESENT) &&
189 !(s->state & SOCKET_CARDBUS)) { 189 !(s->state & SOCKET_CARDBUS)) {
@@ -192,7 +192,7 @@ static ssize_t pccard_store_resource(struct class_device *dev, const char *buf,
192 module_put(s->callback->owner); 192 module_put(s->callback->owner);
193 } 193 }
194 } 194 }
195 up(&s->skt_sem); 195 mutex_unlock(&s->skt_mutex);
196 196
197 return count; 197 return count;
198} 198}
@@ -322,7 +322,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
322 kfree(cis); 322 kfree(cis);
323 323
324 if (!ret) { 324 if (!ret) {
325 down(&s->skt_sem); 325 mutex_lock(&s->skt_mutex);
326 if ((s->callback) && (s->state & SOCKET_PRESENT) && 326 if ((s->callback) && (s->state & SOCKET_PRESENT) &&
327 !(s->state & SOCKET_CARDBUS)) { 327 !(s->state & SOCKET_CARDBUS)) {
328 if (try_module_get(s->callback->owner)) { 328 if (try_module_get(s->callback->owner)) {
@@ -330,7 +330,7 @@ static ssize_t pccard_store_cis(struct kobject *kobj, char *buf, loff_t off, siz
330 module_put(s->callback->owner); 330 module_put(s->callback->owner);
331 } 331 }
332 } 332 }
333 up(&s->skt_sem); 333 mutex_unlock(&s->skt_mutex);
334 } 334 }
335 335
336 336
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h
index d5b4ff74462e..7a3d1b8e16b9 100644
--- a/drivers/pcmcia/ti113x.h
+++ b/drivers/pcmcia/ti113x.h
@@ -30,7 +30,6 @@
30#ifndef _LINUX_TI113X_H 30#ifndef _LINUX_TI113X_H
31#define _LINUX_TI113X_H 31#define _LINUX_TI113X_H
32 32
33#include <linux/config.h>
34 33
35/* Register definitions for TI 113X PCI-to-CardBus bridges */ 34/* Register definitions for TI 113X PCI-to-CardBus bridges */
36 35