1 /* 2 * PCMCIA 16-bit resource management 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) 1999 David A. Hinds 9 * Copyright (C) 2004-2005 Dominik Brodowski 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 * 15 */ 16 17 #include <linux/config.h> 18 #include <linux/module.h> 19 #include <linux/kernel.h> 20 #include <linux/interrupt.h> 21 #include <linux/delay.h> 22 #include <linux/pci.h> 23 #include <linux/device.h> 24 25 #define IN_CARD_SERVICES 26 #include <pcmcia/cs_types.h> 27 #include <pcmcia/ss.h> 28 #include <pcmcia/cs.h> 29 #include <pcmcia/bulkmem.h> 30 #include <pcmcia/cistpl.h> 31 #include <pcmcia/cisreg.h> 32 #include <pcmcia/ds.h> 33 34 #include "cs_internal.h" 35 #include "ds_internal.h" 36 37 38 /* Access speed for IO windows */ 39 static int io_speed = 0; 40 module_param(io_speed, int, 0444); 41 42 43 #ifdef CONFIG_PCMCIA_PROBE 44 #include <asm/irq.h> 45 /* mask of IRQs already reserved by other cards, we should avoid using them */ 46 static u8 pcmcia_used_irq[NR_IRQS]; 47 #endif 48 49 50 #ifdef DEBUG 51 extern int ds_pc_debug; 52 #define cs_socket_name(skt) ((skt)->dev.class_id) 53 54 #define ds_dbg(skt, lvl, fmt, arg...) do { \ 55 if (ds_pc_debug >= lvl) \ 56 printk(KERN_DEBUG "pcmcia_resource: %s: " fmt, \ 57 cs_socket_name(skt) , ## arg); \ 58 } while (0) 59 #else 60 #define ds_dbg(lvl, fmt, arg...) do { } while (0) 61 #endif 62 63 64 65 /** alloc_io_space 66 * 67 * Special stuff for managing IO windows, because they are scarce 68 */ 69 70 static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, 71 ioaddr_t num, u_int lines) 72 { 73 int i; 74 kio_addr_t try, align; 75 76 align = (*base) ? (lines ? 1<<lines : 0) : 1; 77 if (align && (align < num)) { 78 if (*base) { 79 ds_dbg(s, 0, "odd IO request: num %#x align %#lx\n", 80 num, align); 81 align = 0; 82 } else 83 while (align && (align < num)) align <<= 1; 84 } 85 if (*base & ~(align-1)) { 86 ds_dbg(s, 0, "odd IO request: base %#x align %#lx\n", 87 *base, align); 88 align = 0; 89 } 90 if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { 91 *base = s->io_offset | (*base & 0x0fff); 92 s->io[0].Attributes = attr; 93 return 0; 94 } 95 /* Check for an already-allocated window that must conflict with 96 * what was asked for. It is a hack because it does not catch all 97 * potential conflicts, just the most obvious ones. 98 */ 99 for (i = 0; i < MAX_IO_WIN; i++) 100 if ((s->io[i].NumPorts != 0) && 101 ((s->io[i].BasePort & (align-1)) == *base)) 102 return 1; 103 for (i = 0; i < MAX_IO_WIN; i++) { 104 if (s->io[i].NumPorts == 0) { 105 s->io[i].res = pcmcia_find_io_region(*base, num, align, s); 106 if (s->io[i].res) { 107 s->io[i].Attributes = attr; 108 s->io[i].BasePort = *base = s->io[i].res->start; 109 s->io[i].NumPorts = s->io[i].InUse = num; 110 break; 111 } else 112 return 1; 113 } else if (s->io[i].Attributes != attr) 114 continue; 115 /* Try to extend top of window */ 116 try = s->io[i].BasePort + s->io[i].NumPorts; 117 if ((*base == 0) || (*base == try)) 118 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start, 119 s->io[i].res->end + num, s) == 0) { 120 *base = try; 121 s->io[i].NumPorts += num; 122 s->io[i].InUse += num; 123 break; 124 } 125 /* Try to extend bottom of window */ 126 try = s->io[i].BasePort - num; 127 if ((*base == 0) || (*base == try)) 128 if (pcmcia_adjust_io_region(s->io[i].res, s->io[i].res->start - num, 129 s->io[i].res->end, s) == 0) { 130 s->io[i].BasePort = *base = try; 131 s->io[i].NumPorts += num; 132 s->io[i].InUse += num; 133 break; 134 } 135 } 136 return (i == MAX_IO_WIN); 137 } /* alloc_io_space */ 138 139 140 static void release_io_space(struct pcmcia_socket *s, ioaddr_t base, 141 ioaddr_t num) 142 { 143 int i; 144 145 for (i = 0; i < MAX_IO_WIN; i++) { 146 if ((s->io[i].BasePort <= base) && 147 (s->io[i].BasePort+s->io[i].NumPorts >= base+num)) { 148 s->io[i].InUse -= num; 149 /* Free the window if no one else is using it */ 150 if (s->io[i].InUse == 0) { 151 s->io[i].NumPorts = 0; 152 release_resource(s->io[i].res); 153 kfree(s->io[i].res); 154 s->io[i].res = NULL; 155 } 156 } 157 } 158 } /* release_io_space */ 159 160 161 /** pccard_access_configuration_register 162 * 163 * Access_configuration_register() reads and writes configuration 164 * registers in attribute memory. Memory window 0 is reserved for 165 * this and the tuple reading services. 166 */ 167 168 int pccard_access_configuration_register(struct pcmcia_socket *s, 169 unsigned int function, 170 conf_reg_t *reg) 171 { 172 config_t *c; 173 int addr; 174 u_char val; 175 176 if (!s || !s->config) 177 return CS_NO_CARD; 178 179 c = &s->config[function]; 180 181 if (c == NULL) 182 return CS_NO_CARD; 183 184 if (!(c->state & CONFIG_LOCKED)) 185 return CS_CONFIGURATION_LOCKED; 186 187 addr = (c->ConfigBase + reg->Offset) >> 1; 188 189 switch (reg->Action) { 190 case CS_READ: 191 pcmcia_read_cis_mem(s, 1, addr, 1, &val); 192 reg->Value = val; 193 break; 194 case CS_WRITE: 195 val = reg->Value; 196 pcmcia_write_cis_mem(s, 1, addr, 1, &val); 197 break; 198 default: 199 return CS_BAD_ARGS; 200 break; 201 } 202 return CS_SUCCESS; 203 } /* pccard_access_configuration_register */ 204 205 int 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 } 211 EXPORT_SYMBOL(pcmcia_access_configuration_register); 212 213 214 215 int pccard_get_configuration_info(struct pcmcia_socket *s, 216 unsigned int function, 217 config_info_t *config) 218 { 219 config_t *c; 220 221 if (!(s->state & SOCKET_PRESENT)) 222 return CS_NO_CARD; 223 224 config->Function = function; 225 226 #ifdef CONFIG_CARDBUS 227 if (s->state & SOCKET_CARDBUS) { 228 memset(config, 0, sizeof(config_info_t)); 229 config->Vcc = s->socket.Vcc; 230 config->Vpp1 = config->Vpp2 = s->socket.Vpp; 231 config->Option = s->cb_dev->subordinate->number; 232 if (s->state & SOCKET_CARDBUS_CONFIG) { 233 config->Attributes = CONF_VALID_CLIENT; 234 config->IntType = INT_CARDBUS; 235 config->AssignedIRQ = s->irq.AssignedIRQ; 236 if (config->AssignedIRQ) 237 config->Attributes |= CONF_ENABLE_IRQ; 238 config->BasePort1 = s->io[0].BasePort; 239 config->NumPorts1 = s->io[0].NumPorts; 240 } 241 return CS_SUCCESS; 242 } 243 #endif 244 245 c = (s->config != NULL) ? &s->config[function] : NULL; 246 247 if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { 248 config->Attributes = 0; 249 config->Vcc = s->socket.Vcc; 250 config->Vpp1 = config->Vpp2 = s->socket.Vpp; 251 return CS_SUCCESS; 252 } 253 254 /* !!! This is a hack !!! */ 255 memcpy(&config->Attributes, &c->Attributes, sizeof(config_t)); 256 config->Attributes |= CONF_VALID_CLIENT; 257 config->CardValues = c->CardValues; 258 config->IRQAttributes = c->irq.Attributes; 259 config->AssignedIRQ = s->irq.AssignedIRQ; 260 config->BasePort1 = c->io.BasePort1; 261 config->NumPorts1 = c->io.NumPorts1; 262 config->Attributes1 = c->io.Attributes1; 263 config->BasePort2 = c->io.BasePort2; 264 config->NumPorts2 = c->io.NumPorts2; 265 config->Attributes2 = c->io.Attributes2; 266 config->IOAddrLines = c->io.IOAddrLines; 267 268 return CS_SUCCESS; 269 } /* pccard_get_configuration_info */ 270 271 int pcmcia_get_configuration_info(struct pcmcia_device *p_dev, 272 config_info_t *config) 273 { 274 return pccard_get_configuration_info(p_dev->socket, p_dev->func, 275 config); 276 } 277 EXPORT_SYMBOL(pcmcia_get_configuration_info); 278 279 280 /** pcmcia_get_window 281 */ 282 int pcmcia_get_window(struct pcmcia_socket *s, window_handle_t *handle, 283 int idx, win_req_t *req) 284 { 285 window_t *win; 286 int w; 287 288 if (!s || !(s->state & SOCKET_PRESENT)) 289 return CS_NO_CARD; 290 for (w = idx; w < MAX_WIN; w++) 291 if (s->state & SOCKET_WIN_REQ(w)) 292 break; 293 if (w == MAX_WIN) 294 return CS_NO_MORE_ITEMS; 295 win = &s->win[w]; 296 req->Base = win->ctl.res->start; 297 req->Size = win->ctl.res->end - win->ctl.res->start + 1; 298 req->AccessSpeed = win->ctl.speed; 299 req->Attributes = 0; 300 if (win->ctl.flags & MAP_ATTRIB) 301 req->Attributes |= WIN_MEMORY_TYPE_AM; 302 if (win->ctl.flags & MAP_ACTIVE) 303 req->Attributes |= WIN_ENABLE; 304 if (win->ctl.flags & MAP_16BIT) 305 req->Attributes |= WIN_DATA_WIDTH_16; 306 if (win->ctl.flags & MAP_USE_WAIT) 307 req->Attributes |= WIN_USE_WAIT; 308 *handle = win; 309 return CS_SUCCESS; 310 } /* pcmcia_get_window */ 311 EXPORT_SYMBOL(pcmcia_get_window); 312 313 314 /** pccard_get_status 315 * 316 * Get the current socket state bits. We don't support the latched 317 * SocketState yet: I haven't seen any point for it. 318 */ 319 320 int pccard_get_status(struct pcmcia_socket *s, unsigned int function, 321 cs_status_t *status) 322 { 323 config_t *c; 324 int val; 325 326 s->ops->get_status(s, &val); 327 status->CardState = status->SocketState = 0; 328 status->CardState |= (val & SS_DETECT) ? CS_EVENT_CARD_DETECT : 0; 329 status->CardState |= (val & SS_CARDBUS) ? CS_EVENT_CB_DETECT : 0; 330 status->CardState |= (val & SS_3VCARD) ? CS_EVENT_3VCARD : 0; 331 status->CardState |= (val & SS_XVCARD) ? CS_EVENT_XVCARD : 0; 332 if (s->state & SOCKET_SUSPEND) 333 status->CardState |= CS_EVENT_PM_SUSPEND; 334 if (!(s->state & SOCKET_PRESENT)) 335 return CS_NO_CARD; 336 337 c = (s->config != NULL) ? &s->config[function] : NULL; 338 if ((c != NULL) && (c->state & CONFIG_LOCKED) && 339 (c->IntType & (INT_MEMORY_AND_IO | INT_ZOOMED_VIDEO))) { 340 u_char reg; 341 if (c->Present & PRESENT_PIN_REPLACE) { 342 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_PRR)>>1, 1, ®); 343 status->CardState |= 344 (reg & PRR_WP_STATUS) ? CS_EVENT_WRITE_PROTECT : 0; 345 status->CardState |= 346 (reg & PRR_READY_STATUS) ? CS_EVENT_READY_CHANGE : 0; 347 status->CardState |= 348 (reg & PRR_BVD2_STATUS) ? CS_EVENT_BATTERY_LOW : 0; 349 status->CardState |= 350 (reg & PRR_BVD1_STATUS) ? CS_EVENT_BATTERY_DEAD : 0; 351 } else { 352 /* No PRR? Then assume we're always ready */ 353 status->CardState |= CS_EVENT_READY_CHANGE; 354 } 355 if (c->Present & PRESENT_EXT_STATUS) { 356 pcmcia_read_cis_mem(s, 1, (c->ConfigBase+CISREG_ESR)>>1, 1, ®); 357 status->CardState |= 358 (reg & ESR_REQ_ATTN) ? CS_EVENT_REQUEST_ATTENTION : 0; 359 } 360 return CS_SUCCESS; 361 } 362 status->CardState |= 363 (val & SS_WRPROT) ? CS_EVENT_WRITE_PROTECT : 0; 364 status->CardState |= 365 (val & SS_BATDEAD) ? CS_EVENT_BATTERY_DEAD : 0; 366 status->CardState |= 367 (val & SS_BATWARN) ? CS_EVENT_BATTERY_LOW : 0; 368 status->CardState |= 369 (val & SS_READY) ? CS_EVENT_READY_CHANGE : 0; 370 return CS_SUCCESS; 371 } /* pccard_get_status */ 372 373 int pcmcia_get_status(client_handle_t handle, cs_status_t *status) 374 { 375 struct pcmcia_socket *s; 376 s = SOCKET(handle); 377 return pccard_get_status(s, handle->func, status); 378 } 379 EXPORT_SYMBOL(pcmcia_get_status); 380 381 382 383 /** pcmcia_get_mem_page 384 * 385 * Change the card address of an already open memory window. 386 */ 387 int pcmcia_get_mem_page(window_handle_t win, memreq_t *req) 388 { 389 if ((win == NULL) || (win->magic != WINDOW_MAGIC)) 390 return CS_BAD_HANDLE; 391 req->Page = 0; 392 req->CardOffset = win->ctl.card_start; 393 return CS_SUCCESS; 394 } /* pcmcia_get_mem_page */ 395 EXPORT_SYMBOL(pcmcia_get_mem_page); 396 397 398 int pcmcia_map_mem_page(window_handle_t win, memreq_t *req) 399 { 400 struct pcmcia_socket *s; 401 if ((win == NULL) || (win->magic != WINDOW_MAGIC)) 402 return CS_BAD_HANDLE; 403 if (req->Page != 0) 404 return CS_BAD_PAGE; 405 s = win->sock; 406 win->ctl.card_start = req->CardOffset; 407 if (s->ops->set_mem_map(s, &win->ctl) != 0) 408 return CS_BAD_OFFSET; 409 return CS_SUCCESS; 410 } /* pcmcia_map_mem_page */ 411 EXPORT_SYMBOL(pcmcia_map_mem_page); 412 413 414 /** pcmcia_modify_configuration 415 * 416 * Modify a locked socket configuration 417 */ 418 int pcmcia_modify_configuration(struct pcmcia_device *p_dev, 419 modconf_t *mod) 420 { 421 struct pcmcia_socket *s; 422 config_t *c; 423 424 s = p_dev->socket; 425 c = CONFIG(p_dev); 426 if (!(s->state & SOCKET_PRESENT)) 427 return CS_NO_CARD; 428 if (!(c->state & CONFIG_LOCKED)) 429 return CS_CONFIGURATION_LOCKED; 430 431 if (mod->Attributes & CONF_IRQ_CHANGE_VALID) { 432 if (mod->Attributes & CONF_ENABLE_IRQ) { 433 c->Attributes |= CONF_ENABLE_IRQ; 434 s->socket.io_irq = s->irq.AssignedIRQ; 435 } else { 436 c->Attributes &= ~CONF_ENABLE_IRQ; 437 s->socket.io_irq = 0; 438 } 439 s->ops->set_socket(s, &s->socket); 440 } 441 442 if (mod->Attributes & CONF_VCC_CHANGE_VALID) 443 return CS_BAD_VCC; 444 445 /* We only allow changing Vpp1 and Vpp2 to the same value */ 446 if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) && 447 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) { 448 if (mod->Vpp1 != mod->Vpp2) 449 return CS_BAD_VPP; 450 s->socket.Vpp = mod->Vpp1; 451 if (s->ops->set_socket(s, &s->socket)) 452 return CS_BAD_VPP; 453 } else if ((mod->Attributes & CONF_VPP1_CHANGE_VALID) || 454 (mod->Attributes & CONF_VPP2_CHANGE_VALID)) 455 return CS_BAD_VPP; 456 457 return CS_SUCCESS; 458 } /* modify_configuration */ 459 EXPORT_SYMBOL(pcmcia_modify_configuration); 460 461 462 int pcmcia_release_configuration(struct pcmcia_device *p_dev) 463 { 464 pccard_io_map io = { 0, 0, 0, 0, 1 }; 465 struct pcmcia_socket *s = p_dev->socket; 466 int i; 467 468 if (!(p_dev->state & CLIENT_CONFIG_LOCKED)) 469 return CS_BAD_HANDLE; 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) { 475 s->socket.flags = SS_OUTPUT_ENA; /* Is this correct? */ 476 s->socket.Vpp = 0; 477 s->socket.io_irq = 0; 478 s->ops->set_socket(s, &s->socket); 479 } 480 if (c->state & CONFIG_IO_REQ) 481 for (i = 0; i < MAX_IO_WIN; i++) { 482 if (s->io[i].NumPorts == 0) 483 continue; 484 s->io[i].Config--; 485 if (s->io[i].Config != 0) 486 continue; 487 io.map = i; 488 s->ops->set_io_map(s, &io); 489 } 490 c->state &= ~CONFIG_LOCKED; 491 } 492 493 return CS_SUCCESS; 494 } /* pcmcia_release_configuration */ 495 EXPORT_SYMBOL(pcmcia_release_configuration); 496 497 498 /** pcmcia_release_io 499 * 500 * Release_io() releases the I/O ranges allocated by a client. This 501 * may be invoked some time after a card ejection has already dumped 502 * the actual socket configuration, so if the client is "stale", we 503 * don't bother checking the port ranges against the current socket 504 * values. 505 */ 506 int pcmcia_release_io(struct pcmcia_device *p_dev, io_req_t *req) 507 { 508 struct pcmcia_socket *s = p_dev->socket; 509 510 if (!(p_dev->state & CLIENT_IO_REQ)) 511 return CS_BAD_HANDLE; 512 p_dev->state &= ~CLIENT_IO_REQ; 513 514 if (!(p_dev->state & CLIENT_STALE)) { 515 config_t *c = CONFIG(p_dev); 516 if (c->state & CONFIG_LOCKED) 517 return CS_CONFIGURATION_LOCKED; 518 if ((c->io.BasePort1 != req->BasePort1) || 519 (c->io.NumPorts1 != req->NumPorts1) || 520 (c->io.BasePort2 != req->BasePort2) || 521 (c->io.NumPorts2 != req->NumPorts2)) 522 return CS_BAD_ARGS; 523 c->state &= ~CONFIG_IO_REQ; 524 } 525 526 release_io_space(s, req->BasePort1, req->NumPorts1); 527 if (req->NumPorts2) 528 release_io_space(s, req->BasePort2, req->NumPorts2); 529 530 return CS_SUCCESS; 531 } /* pcmcia_release_io */ 532 EXPORT_SYMBOL(pcmcia_release_io); 533 534 535 int pcmcia_release_irq(struct pcmcia_device *p_dev, irq_req_t *req) 536 { 537 struct pcmcia_socket *s = p_dev->socket; 538 if (!(p_dev->state & CLIENT_IRQ_REQ)) 539 return CS_BAD_HANDLE; 540 p_dev->state &= ~CLIENT_IRQ_REQ; 541 542 if (!(p_dev->state & CLIENT_STALE)) { 543 config_t *c = CONFIG(p_dev); 544 if (c->state & CONFIG_LOCKED) 545 return CS_CONFIGURATION_LOCKED; 546 if (c->irq.Attributes != req->Attributes) 547 return CS_BAD_ATTRIBUTE; 548 if (s->irq.AssignedIRQ != req->AssignedIRQ) 549 return CS_BAD_IRQ; 550 if (--s->irq.Config == 0) { 551 c->state &= ~CONFIG_IRQ_REQ; 552 s->irq.AssignedIRQ = 0; 553 } 554 } 555 556 if (req->Attributes & IRQ_HANDLE_PRESENT) { 557 free_irq(req->AssignedIRQ, req->Instance); 558 } 559 560 #ifdef CONFIG_PCMCIA_PROBE 561 pcmcia_used_irq[req->AssignedIRQ]--; 562 #endif 563 564 return CS_SUCCESS; 565 } /* pcmcia_release_irq */ 566 EXPORT_SYMBOL(pcmcia_release_irq); 567 568 569 int pcmcia_release_window(window_handle_t win) 570 { 571 struct pcmcia_socket *s; 572 573 if ((win == NULL) || (win->magic != WINDOW_MAGIC)) 574 return CS_BAD_HANDLE; 575 s = win->sock; 576 if (!(win->handle->state & CLIENT_WIN_REQ(win->index))) 577 return CS_BAD_HANDLE; 578 579 /* Shut down memory window */ 580 win->ctl.flags &= ~MAP_ACTIVE; 581 s->ops->set_mem_map(s, &win->ctl); 582 s->state &= ~SOCKET_WIN_REQ(win->index); 583 584 /* Release system memory */ 585 if (win->ctl.res) { 586 release_resource(win->ctl.res); 587 kfree(win->ctl.res); 588 win->ctl.res = NULL; 589 } 590 win->handle->state &= ~CLIENT_WIN_REQ(win->index); 591 592 win->magic = 0; 593 594 return CS_SUCCESS; 595 } /* pcmcia_release_window */ 596 EXPORT_SYMBOL(pcmcia_release_window); 597 598 599 int pcmcia_request_configuration(struct pcmcia_device *p_dev, 600 config_req_t *req) 601 { 602 int i; 603 u_int base; 604 struct pcmcia_socket *s = p_dev->socket; 605 config_t *c; 606 pccard_io_map iomap; 607 608 if (!(s->state & SOCKET_PRESENT)) 609 return CS_NO_CARD; 610 611 if (req->IntType & INT_CARDBUS) 612 return CS_UNSUPPORTED_MODE; 613 c = CONFIG(p_dev); 614 if (c->state & CONFIG_LOCKED) 615 return CS_CONFIGURATION_LOCKED; 616 617 /* Do power control. We don't allow changes in Vcc. */ 618 if (s->socket.Vcc != req->Vcc) 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)) 624 return CS_BAD_VPP; 625 626 /* Pick memory or I/O card, DMA mode, interrupt */ 627 c->IntType = req->IntType; 628 c->Attributes = req->Attributes; 629 if (req->IntType & INT_MEMORY_AND_IO) 630 s->socket.flags |= SS_IOCARD; 631 if (req->IntType & INT_ZOOMED_VIDEO) 632 s->socket.flags |= SS_ZVCARD | SS_IOCARD; 633 if (req->Attributes & CONF_ENABLE_DMA) 634 s->socket.flags |= SS_DMA_MODE; 635 if (req->Attributes & CONF_ENABLE_SPKR) 636 s->socket.flags |= SS_SPKR_ENA; 637 if (req->Attributes & CONF_ENABLE_IRQ) 638 s->socket.io_irq = s->irq.AssignedIRQ; 639 else 640 s->socket.io_irq = 0; 641 s->ops->set_socket(s, &s->socket); 642 s->lock_count++; 643 644 /* Set up CIS configuration registers */ 645 base = c->ConfigBase = req->ConfigBase; 646 c->Present = c->CardValues = req->Present; 647 if (req->Present & PRESENT_COPY) { 648 c->Copy = req->Copy; 649 pcmcia_write_cis_mem(s, 1, (base + CISREG_SCR)>>1, 1, &c->Copy); 650 } 651 if (req->Present & PRESENT_OPTION) { 652 if (s->functions == 1) { 653 c->Option = req->ConfigIndex & COR_CONFIG_MASK; 654 } else { 655 c->Option = req->ConfigIndex & COR_MFC_CONFIG_MASK; 656 c->Option |= COR_FUNC_ENA|COR_IREQ_ENA; 657 if (req->Present & PRESENT_IOBASE_0) 658 c->Option |= COR_ADDR_DECODE; 659 } 660 if (c->state & CONFIG_IRQ_REQ) 661 if (!(c->irq.Attributes & IRQ_FORCED_PULSE)) 662 c->Option |= COR_LEVEL_REQ; 663 pcmcia_write_cis_mem(s, 1, (base + CISREG_COR)>>1, 1, &c->Option); 664 mdelay(40); 665 } 666 if (req->Present & PRESENT_STATUS) { 667 c->Status = req->Status; 668 pcmcia_write_cis_mem(s, 1, (base + CISREG_CCSR)>>1, 1, &c->Status); 669 } 670 if (req->Present & PRESENT_PIN_REPLACE) { 671 c->Pin = req->Pin; 672 pcmcia_write_cis_mem(s, 1, (base + CISREG_PRR)>>1, 1, &c->Pin); 673 } 674 if (req->Present & PRESENT_EXT_STATUS) { 675 c->ExtStatus = req->ExtStatus; 676 pcmcia_write_cis_mem(s, 1, (base + CISREG_ESR)>>1, 1, &c->ExtStatus); 677 } 678 if (req->Present & PRESENT_IOBASE_0) { 679 u_char b = c->io.BasePort1 & 0xff; 680 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_0)>>1, 1, &b); 681 b = (c->io.BasePort1 >> 8) & 0xff; 682 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOBASE_1)>>1, 1, &b); 683 } 684 if (req->Present & PRESENT_IOSIZE) { 685 u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1; 686 pcmcia_write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b); 687 } 688 689 /* Configure I/O windows */ 690 if (c->state & CONFIG_IO_REQ) { 691 iomap.speed = io_speed; 692 for (i = 0; i < MAX_IO_WIN; i++) 693 if (s->io[i].NumPorts != 0) { 694 iomap.map = i; 695 iomap.flags = MAP_ACTIVE; 696 switch (s->io[i].Attributes & IO_DATA_PATH_WIDTH) { 697 case IO_DATA_PATH_WIDTH_16: 698 iomap.flags |= MAP_16BIT; break; 699 case IO_DATA_PATH_WIDTH_AUTO: 700 iomap.flags |= MAP_AUTOSZ; break; 701 default: 702 break; 703 } 704 iomap.start = s->io[i].BasePort; 705 iomap.stop = iomap.start + s->io[i].NumPorts - 1; 706 s->ops->set_io_map(s, &iomap); 707 s->io[i].Config++; 708 } 709 } 710 711 c->state |= CONFIG_LOCKED; 712 p_dev->state |= CLIENT_CONFIG_LOCKED; 713 return CS_SUCCESS; 714 } /* pcmcia_request_configuration */ 715 EXPORT_SYMBOL(pcmcia_request_configuration); 716 717 718 /** pcmcia_request_io 719 * 720 * Request_io() reserves ranges of port addresses for a socket. 721 * I have not implemented range sharing or alias addressing. 722 */ 723 int pcmcia_request_io(struct pcmcia_device *p_dev, io_req_t *req) 724 { 725 struct pcmcia_socket *s = p_dev->socket; 726 config_t *c; 727 728 if (!(s->state & SOCKET_PRESENT)) 729 return CS_NO_CARD; 730 731 if (!req) 732 return CS_UNSUPPORTED_MODE; 733 c = CONFIG(p_dev); 734 if (c->state & CONFIG_LOCKED) 735 return CS_CONFIGURATION_LOCKED; 736 if (c->state & CONFIG_IO_REQ) 737 return CS_IN_USE; 738 if (req->Attributes1 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS)) 739 return CS_BAD_ATTRIBUTE; 740 if ((req->NumPorts2 > 0) && 741 (req->Attributes2 & (IO_SHARED | IO_FORCE_ALIAS_ACCESS))) 742 return CS_BAD_ATTRIBUTE; 743 744 if (alloc_io_space(s, req->Attributes1, &req->BasePort1, 745 req->NumPorts1, req->IOAddrLines)) 746 return CS_IN_USE; 747 748 if (req->NumPorts2) { 749 if (alloc_io_space(s, req->Attributes2, &req->BasePort2, 750 req->NumPorts2, req->IOAddrLines)) { 751 release_io_space(s, req->BasePort1, req->NumPorts1); 752 return CS_IN_USE; 753 } 754 } 755 756 c->io = *req; 757 c->state |= CONFIG_IO_REQ; 758 p_dev->state |= CLIENT_IO_REQ; 759 return CS_SUCCESS; 760 } /* pcmcia_request_io */ 761 EXPORT_SYMBOL(pcmcia_request_io); 762 763 764 /** pcmcia_request_irq 765 * 766 * Request_irq() reserves an irq for this client. 767 * 768 * Also, since Linux only reserves irq's when they are actually 769 * hooked, we don't guarantee that an irq will still be available 770 * when the configuration is locked. Now that I think about it, 771 * there might be a way to fix this using a dummy handler. 772 */ 773 774 #ifdef CONFIG_PCMCIA_PROBE 775 static irqreturn_t test_action(int cpl, void *dev_id, struct pt_regs *regs) 776 { 777 return IRQ_NONE; 778 } 779 #endif 780 781 int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req) 782 { 783 struct pcmcia_socket *s = p_dev->socket; 784 config_t *c; 785 int ret = CS_IN_USE, irq = 0; 786 787 if (!(s->state & SOCKET_PRESENT)) 788 return CS_NO_CARD; 789 c = CONFIG(p_dev); 790 if (c->state & CONFIG_LOCKED) 791 return CS_CONFIGURATION_LOCKED; 792 if (c->state & CONFIG_IRQ_REQ) 793 return CS_IN_USE; 794 795 #ifdef CONFIG_PCMCIA_PROBE 796 if (s->irq.AssignedIRQ != 0) { 797 /* If the interrupt is already assigned, it must be the same */ 798 irq = s->irq.AssignedIRQ; 799 } else { 800 int try; 801 u32 mask = s->irq_mask; 802 void *data = &p_dev->dev.driver; /* something unique to this device */ 803 804 for (try = 0; try < 64; try++) { 805 irq = try % 32; 806 807 /* marked as available by driver, and not blocked by userspace? */ 808 if (!((mask >> irq) & 1)) 809 continue; 810 811 /* avoid an IRQ which is already used by a PCMCIA card */ 812 if ((try < 32) && pcmcia_used_irq[irq]) 813 continue; 814 815 /* register the correct driver, if possible, of check whether 816 * registering a dummy handle works, i.e. if the IRQ isn't 817 * marked as used by the kernel resource management core */ 818 ret = request_irq(irq, 819 (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Handler : test_action, 820 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 821 (s->functions > 1) || 822 (irq == s->pci_irq)) ? SA_SHIRQ : 0, 823 p_dev->devname, 824 (req->Attributes & IRQ_HANDLE_PRESENT) ? req->Instance : data); 825 if (!ret) { 826 if (!(req->Attributes & IRQ_HANDLE_PRESENT)) 827 free_irq(irq, data); 828 break; 829 } 830 } 831 } 832 #endif 833 /* only assign PCI irq if no IRQ already assigned */ 834 if (ret && !s->irq.AssignedIRQ) { 835 if (!s->pci_irq) 836 return ret; 837 irq = s->pci_irq; 838 } 839 840 if (ret && req->Attributes & IRQ_HANDLE_PRESENT) { 841 if (request_irq(irq, req->Handler, 842 ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) || 843 (s->functions > 1) || 844 (irq == s->pci_irq)) ? SA_SHIRQ : 0, 845 p_dev->devname, req->Instance)) 846 return CS_IN_USE; 847 } 848 849 c->irq.Attributes = req->Attributes; 850 s->irq.AssignedIRQ = req->AssignedIRQ = irq; 851 s->irq.Config++; 852 853 c->state |= CONFIG_IRQ_REQ; 854 p_dev->state |= CLIENT_IRQ_REQ; 855 856 #ifdef CONFIG_PCMCIA_PROBE 857 pcmcia_used_irq[irq]++; 858 #endif 859 860 return CS_SUCCESS; 861 } /* pcmcia_request_irq */ 862 EXPORT_SYMBOL(pcmcia_request_irq); 863 864 865 /** pcmcia_request_window 866 * 867 * Request_window() establishes a mapping between card memory space 868 * and system memory space. 869 */ 870 int pcmcia_request_window(struct pcmcia_device **p_dev, win_req_t *req, window_handle_t *wh) 871 { 872 struct pcmcia_socket *s = (*p_dev)->socket; 873 window_t *win; 874 u_long align; 875 int w; 876 877 if (!(s->state & SOCKET_PRESENT)) 878 return CS_NO_CARD; 879 if (req->Attributes & (WIN_PAGED | WIN_SHARED)) 880 return CS_BAD_ATTRIBUTE; 881 882 /* Window size defaults to smallest available */ 883 if (req->Size == 0) 884 req->Size = s->map_size; 885 align = (((s->features & SS_CAP_MEM_ALIGN) || 886 (req->Attributes & WIN_STRICT_ALIGN)) ? 887 req->Size : s->map_size); 888 if (req->Size & (s->map_size-1)) 889 return CS_BAD_SIZE; 890 if ((req->Base && (s->features & SS_CAP_STATIC_MAP)) || 891 (req->Base & (align-1))) 892 return CS_BAD_BASE; 893 if (req->Base) 894 align = 0; 895 896 /* Allocate system memory window */ 897 for (w = 0; w < MAX_WIN; w++) 898 if (!(s->state & SOCKET_WIN_REQ(w))) break; 899 if (w == MAX_WIN) 900 return CS_OUT_OF_RESOURCE; 901 902 win = &s->win[w]; 903 win->magic = WINDOW_MAGIC; 904 win->index = w; 905 win->handle = *p_dev; 906 win->sock = s; 907 908 if (!(s->features & SS_CAP_STATIC_MAP)) { 909 win->ctl.res = pcmcia_find_mem_region(req->Base, req->Size, align, 910 (req->Attributes & WIN_MAP_BELOW_1MB), s); 911 if (!win->ctl.res) 912 return CS_IN_USE; 913 } 914 (*p_dev)->state |= CLIENT_WIN_REQ(w); 915 916 /* Configure the socket controller */ 917 win->ctl.map = w+1; 918 win->ctl.flags = 0; 919 win->ctl.speed = req->AccessSpeed; 920 if (req->Attributes & WIN_MEMORY_TYPE) 921 win->ctl.flags |= MAP_ATTRIB; 922 if (req->Attributes & WIN_ENABLE) 923 win->ctl.flags |= MAP_ACTIVE; 924 if (req->Attributes & WIN_DATA_WIDTH_16) 925 win->ctl.flags |= MAP_16BIT; 926 if (req->Attributes & WIN_USE_WAIT) 927 win->ctl.flags |= MAP_USE_WAIT; 928 win->ctl.card_start = 0; 929 if (s->ops->set_mem_map(s, &win->ctl) != 0) 930 return CS_BAD_ARGS; 931 s->state |= SOCKET_WIN_REQ(w); 932 933 /* Return window handle */ 934 if (s->features & SS_CAP_STATIC_MAP) { 935 req->Base = win->ctl.static_start; 936 } else { 937 req->Base = win->ctl.res->start; 938 } 939 *wh = win; 940 941 return CS_SUCCESS; 942 } /* pcmcia_request_window */ 943 EXPORT_SYMBOL(pcmcia_request_window); 944