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