aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pcmcia/pcmcia_resource.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pcmcia/pcmcia_resource.c')
-rw-r--r--drivers/pcmcia/pcmcia_resource.c228
1 files changed, 119 insertions, 109 deletions
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);