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