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