Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.16-rc1 1004 lines 28 kB view raw
1/* 2 * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as 3 * Symbol Wireless Networker LA4100, CompactFlash cards by Socket 4 * Communications and Intel PRO/Wireless 2011B. 5 * 6 * The driver implements Symbol firmware download. The rest is handled 7 * in hermes.c and orinoco.c. 8 * 9 * Utilities for downloading the Symbol firmware are available at 10 * http://sourceforge.net/projects/orinoco/ 11 * 12 * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org> 13 * Portions based on orinoco_cs.c: 14 * Copyright (C) David Gibson, Linuxcare Australia 15 * Portions based on Spectrum24tDnld.c from original spectrum24 driver: 16 * Copyright (C) Symbol Technologies. 17 * 18 * See copyright notice in file orinoco.c. 19 */ 20 21#define DRIVER_NAME "spectrum_cs" 22#define PFX DRIVER_NAME ": " 23 24#include <linux/config.h> 25#include <linux/module.h> 26#include <linux/kernel.h> 27#include <linux/init.h> 28#include <linux/delay.h> 29#include <linux/firmware.h> 30#include <pcmcia/cs_types.h> 31#include <pcmcia/cs.h> 32#include <pcmcia/cistpl.h> 33#include <pcmcia/cisreg.h> 34#include <pcmcia/ds.h> 35 36#include "orinoco.h" 37 38static unsigned char *primsym; 39static unsigned char *secsym; 40static const char primary_fw_name[] = "symbol_sp24t_prim_fw"; 41static const char secondary_fw_name[] = "symbol_sp24t_sec_fw"; 42 43/********************************************************************/ 44/* Module stuff */ 45/********************************************************************/ 46 47MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>"); 48MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader"); 49MODULE_LICENSE("Dual MPL/GPL"); 50 51/* Module parameters */ 52 53/* Some D-Link cards have buggy CIS. They do work at 5v properly, but 54 * don't have any CIS entry for it. This workaround it... */ 55static int ignore_cis_vcc; /* = 0 */ 56module_param(ignore_cis_vcc, int, 0); 57MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket"); 58 59/********************************************************************/ 60/* Data structures */ 61/********************************************************************/ 62 63/* PCMCIA specific device information (goes in the card field of 64 * struct orinoco_private */ 65struct orinoco_pccard { 66 dev_link_t link; 67 dev_node_t node; 68}; 69 70/********************************************************************/ 71/* Function prototypes */ 72/********************************************************************/ 73 74static void spectrum_cs_config(dev_link_t *link); 75static void spectrum_cs_release(dev_link_t *link); 76 77/********************************************************************/ 78/* Firmware downloader */ 79/********************************************************************/ 80 81/* Position of PDA in the adapter memory */ 82#define EEPROM_ADDR 0x3000 83#define EEPROM_LEN 0x200 84#define PDA_OFFSET 0x100 85 86#define PDA_ADDR (EEPROM_ADDR + PDA_OFFSET) 87#define PDA_WORDS ((EEPROM_LEN - PDA_OFFSET) / 2) 88 89/* Constants for the CISREG_CCSR register */ 90#define HCR_RUN 0x07 /* run firmware after reset */ 91#define HCR_IDLE 0x0E /* don't run firmware after reset */ 92#define HCR_MEM16 0x10 /* memory width bit, should be preserved */ 93 94/* 95 * AUX port access. To unlock the AUX port write the access keys to the 96 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL 97 * register. Then read it and make sure it's HERMES_AUX_ENABLED. 98 */ 99#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */ 100#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */ 101#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */ 102 103#define HERMES_AUX_PW0 0xFE01 104#define HERMES_AUX_PW1 0xDC23 105#define HERMES_AUX_PW2 0xBA45 106 107/* End markers */ 108#define PDI_END 0x00000000 /* End of PDA */ 109#define BLOCK_END 0xFFFFFFFF /* Last image block */ 110#define TEXT_END 0x1A /* End of text header */ 111 112/* 113 * The following structures have little-endian fields denoted by 114 * the leading underscore. Don't access them directly - use inline 115 * functions defined below. 116 */ 117 118/* 119 * The binary image to be downloaded consists of series of data blocks. 120 * Each block has the following structure. 121 */ 122struct dblock { 123 __le32 _addr; /* adapter address where to write the block */ 124 __le16 _len; /* length of the data only, in bytes */ 125 char data[0]; /* data to be written */ 126} __attribute__ ((packed)); 127 128/* 129 * Plug Data References are located in in the image after the last data 130 * block. They refer to areas in the adapter memory where the plug data 131 * items with matching ID should be written. 132 */ 133struct pdr { 134 __le32 _id; /* record ID */ 135 __le32 _addr; /* adapter address where to write the data */ 136 __le32 _len; /* expected length of the data, in bytes */ 137 char next[0]; /* next PDR starts here */ 138} __attribute__ ((packed)); 139 140 141/* 142 * Plug Data Items are located in the EEPROM read from the adapter by 143 * primary firmware. They refer to the device-specific data that should 144 * be plugged into the secondary firmware. 145 */ 146struct pdi { 147 __le16 _len; /* length of ID and data, in words */ 148 __le16 _id; /* record ID */ 149 char data[0]; /* plug data */ 150} __attribute__ ((packed));; 151 152 153/* Functions for access to little-endian data */ 154static inline u32 155dblock_addr(const struct dblock *blk) 156{ 157 return le32_to_cpu(blk->_addr); 158} 159 160static inline u32 161dblock_len(const struct dblock *blk) 162{ 163 return le16_to_cpu(blk->_len); 164} 165 166static inline u32 167pdr_id(const struct pdr *pdr) 168{ 169 return le32_to_cpu(pdr->_id); 170} 171 172static inline u32 173pdr_addr(const struct pdr *pdr) 174{ 175 return le32_to_cpu(pdr->_addr); 176} 177 178static inline u32 179pdr_len(const struct pdr *pdr) 180{ 181 return le32_to_cpu(pdr->_len); 182} 183 184static inline u32 185pdi_id(const struct pdi *pdi) 186{ 187 return le16_to_cpu(pdi->_id); 188} 189 190/* Return length of the data only, in bytes */ 191static inline u32 192pdi_len(const struct pdi *pdi) 193{ 194 return 2 * (le16_to_cpu(pdi->_len) - 1); 195} 196 197 198/* Set address of the auxiliary port */ 199static inline void 200spectrum_aux_setaddr(hermes_t *hw, u32 addr) 201{ 202 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7)); 203 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F)); 204} 205 206 207/* Open access to the auxiliary port */ 208static int 209spectrum_aux_open(hermes_t *hw) 210{ 211 int i; 212 213 /* Already open? */ 214 if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED) 215 return 0; 216 217 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0); 218 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1); 219 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2); 220 hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE); 221 222 for (i = 0; i < 20; i++) { 223 udelay(10); 224 if (hermes_read_reg(hw, HERMES_CONTROL) == 225 HERMES_AUX_ENABLED) 226 return 0; 227 } 228 229 return -EBUSY; 230} 231 232 233#define CS_CHECK(fn, ret) \ 234 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) 235 236/* 237 * Reset the card using configuration registers COR and CCSR. 238 * If IDLE is 1, stop the firmware, so that it can be safely rewritten. 239 */ 240static int 241spectrum_reset(dev_link_t *link, int idle) 242{ 243 int last_ret, last_fn; 244 conf_reg_t reg; 245 u_int save_cor; 246 247 /* Doing it if hardware is gone is guaranteed crash */ 248 if (!(link->state & DEV_CONFIG)) 249 return -ENODEV; 250 251 /* Save original COR value */ 252 reg.Function = 0; 253 reg.Action = CS_READ; 254 reg.Offset = CISREG_COR; 255 CS_CHECK(AccessConfigurationRegister, 256 pcmcia_access_configuration_register(link->handle, &reg)); 257 save_cor = reg.Value; 258 259 /* Soft-Reset card */ 260 reg.Action = CS_WRITE; 261 reg.Offset = CISREG_COR; 262 reg.Value = (save_cor | COR_SOFT_RESET); 263 CS_CHECK(AccessConfigurationRegister, 264 pcmcia_access_configuration_register(link->handle, &reg)); 265 udelay(1000); 266 267 /* Read CCSR */ 268 reg.Action = CS_READ; 269 reg.Offset = CISREG_CCSR; 270 CS_CHECK(AccessConfigurationRegister, 271 pcmcia_access_configuration_register(link->handle, &reg)); 272 273 /* 274 * Start or stop the firmware. Memory width bit should be 275 * preserved from the value we've just read. 276 */ 277 reg.Action = CS_WRITE; 278 reg.Offset = CISREG_CCSR; 279 reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16); 280 CS_CHECK(AccessConfigurationRegister, 281 pcmcia_access_configuration_register(link->handle, &reg)); 282 udelay(1000); 283 284 /* Restore original COR configuration index */ 285 reg.Action = CS_WRITE; 286 reg.Offset = CISREG_COR; 287 reg.Value = (save_cor & ~COR_SOFT_RESET); 288 CS_CHECK(AccessConfigurationRegister, 289 pcmcia_access_configuration_register(link->handle, &reg)); 290 udelay(1000); 291 return 0; 292 293 cs_failed: 294 cs_error(link->handle, last_fn, last_ret); 295 return -ENODEV; 296} 297 298 299/* 300 * Scan PDR for the record with the specified RECORD_ID. 301 * If it's not found, return NULL. 302 */ 303static struct pdr * 304spectrum_find_pdr(struct pdr *first_pdr, u32 record_id) 305{ 306 struct pdr *pdr = first_pdr; 307 308 while (pdr_id(pdr) != PDI_END) { 309 /* 310 * PDR area is currently not terminated by PDI_END. 311 * It's followed by CRC records, which have the type 312 * field where PDR has length. The type can be 0 or 1. 313 */ 314 if (pdr_len(pdr) < 2) 315 return NULL; 316 317 /* If the record ID matches, we are done */ 318 if (pdr_id(pdr) == record_id) 319 return pdr; 320 321 pdr = (struct pdr *) pdr->next; 322 } 323 return NULL; 324} 325 326 327/* Process one Plug Data Item - find corresponding PDR and plug it */ 328static int 329spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi) 330{ 331 struct pdr *pdr; 332 333 /* Find the PDI corresponding to this PDR */ 334 pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi)); 335 336 /* No match is found, safe to ignore */ 337 if (!pdr) 338 return 0; 339 340 /* Lengths of the data in PDI and PDR must match */ 341 if (pdi_len(pdi) != pdr_len(pdr)) 342 return -EINVAL; 343 344 /* do the actual plugging */ 345 spectrum_aux_setaddr(hw, pdr_addr(pdr)); 346 hermes_write_words(hw, HERMES_AUXDATA, pdi->data, 347 pdi_len(pdi) / 2); 348 349 return 0; 350} 351 352 353/* Read PDA from the adapter */ 354static int 355spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len) 356{ 357 int ret; 358 int pda_size; 359 360 /* Issue command to read EEPROM */ 361 ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL); 362 if (ret) 363 return ret; 364 365 /* Open auxiliary port */ 366 ret = spectrum_aux_open(hw); 367 if (ret) 368 return ret; 369 370 /* read PDA from EEPROM */ 371 spectrum_aux_setaddr(hw, PDA_ADDR); 372 hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2); 373 374 /* Check PDA length */ 375 pda_size = le16_to_cpu(pda[0]); 376 if (pda_size > pda_len) 377 return -EINVAL; 378 379 return 0; 380} 381 382 383/* Parse PDA and write the records into the adapter */ 384static int 385spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block, 386 __le16 *pda) 387{ 388 int ret; 389 struct pdi *pdi; 390 struct pdr *first_pdr; 391 const struct dblock *blk = first_block; 392 393 /* Skip all blocks to locate Plug Data References */ 394 while (dblock_addr(blk) != BLOCK_END) 395 blk = (struct dblock *) &blk->data[dblock_len(blk)]; 396 397 first_pdr = (struct pdr *) blk; 398 399 /* Go through every PDI and plug them into the adapter */ 400 pdi = (struct pdi *) (pda + 2); 401 while (pdi_id(pdi) != PDI_END) { 402 ret = spectrum_plug_pdi(hw, first_pdr, pdi); 403 if (ret) 404 return ret; 405 406 /* Increment to the next PDI */ 407 pdi = (struct pdi *) &pdi->data[pdi_len(pdi)]; 408 } 409 return 0; 410} 411 412 413/* Load firmware blocks into the adapter */ 414static int 415spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block) 416{ 417 const struct dblock *blk; 418 u32 blkaddr; 419 u32 blklen; 420 421 blk = first_block; 422 blkaddr = dblock_addr(blk); 423 blklen = dblock_len(blk); 424 425 while (dblock_addr(blk) != BLOCK_END) { 426 spectrum_aux_setaddr(hw, blkaddr); 427 hermes_write_words(hw, HERMES_AUXDATA, blk->data, 428 blklen / 2); 429 430 blk = (struct dblock *) &blk->data[blklen]; 431 blkaddr = dblock_addr(blk); 432 blklen = dblock_len(blk); 433 } 434 return 0; 435} 436 437 438/* 439 * Process a firmware image - stop the card, load the firmware, reset 440 * the card and make sure it responds. For the secondary firmware take 441 * care of the PDA - read it and then write it on top of the firmware. 442 */ 443static int 444spectrum_dl_image(hermes_t *hw, dev_link_t *link, 445 const unsigned char *image) 446{ 447 int ret; 448 const unsigned char *ptr; 449 const struct dblock *first_block; 450 451 /* Plug Data Area (PDA) */ 452 __le16 pda[PDA_WORDS]; 453 454 /* Binary block begins after the 0x1A marker */ 455 ptr = image; 456 while (*ptr++ != TEXT_END); 457 first_block = (const struct dblock *) ptr; 458 459 /* Read the PDA */ 460 if (image != primsym) { 461 ret = spectrum_read_pda(hw, pda, sizeof(pda)); 462 if (ret) 463 return ret; 464 } 465 466 /* Stop the firmware, so that it can be safely rewritten */ 467 ret = spectrum_reset(link, 1); 468 if (ret) 469 return ret; 470 471 /* Program the adapter with new firmware */ 472 ret = spectrum_load_blocks(hw, first_block); 473 if (ret) 474 return ret; 475 476 /* Write the PDA to the adapter */ 477 if (image != primsym) { 478 ret = spectrum_apply_pda(hw, first_block, pda); 479 if (ret) 480 return ret; 481 } 482 483 /* Run the firmware */ 484 ret = spectrum_reset(link, 0); 485 if (ret) 486 return ret; 487 488 /* Reset hermes chip and make sure it responds */ 489 ret = hermes_init(hw); 490 491 /* hermes_reset() should return 0 with the secondary firmware */ 492 if (image != primsym && ret != 0) 493 return -ENODEV; 494 495 /* And this should work with any firmware */ 496 if (!hermes_present(hw)) 497 return -ENODEV; 498 499 return 0; 500} 501 502 503/* 504 * Download the firmware into the card, this also does a PCMCIA soft 505 * reset on the card, to make sure it's in a sane state. 506 */ 507static int 508spectrum_dl_firmware(hermes_t *hw, dev_link_t *link) 509{ 510 int ret; 511 client_handle_t handle = link->handle; 512 const struct firmware *fw_entry; 513 514 if (request_firmware(&fw_entry, primary_fw_name, 515 &handle_to_dev(handle)) == 0) { 516 primsym = fw_entry->data; 517 } else { 518 printk(KERN_ERR PFX "Cannot find firmware: %s\n", 519 primary_fw_name); 520 return -ENOENT; 521 } 522 523 if (request_firmware(&fw_entry, secondary_fw_name, 524 &handle_to_dev(handle)) == 0) { 525 secsym = fw_entry->data; 526 } else { 527 printk(KERN_ERR PFX "Cannot find firmware: %s\n", 528 secondary_fw_name); 529 return -ENOENT; 530 } 531 532 /* Load primary firmware */ 533 ret = spectrum_dl_image(hw, link, primsym); 534 if (ret) { 535 printk(KERN_ERR PFX "Primary firmware download failed\n"); 536 return ret; 537 } 538 539 /* Load secondary firmware */ 540 ret = spectrum_dl_image(hw, link, secsym); 541 542 if (ret) { 543 printk(KERN_ERR PFX "Secondary firmware download failed\n"); 544 } 545 546 return ret; 547} 548 549/********************************************************************/ 550/* Device methods */ 551/********************************************************************/ 552 553static int 554spectrum_cs_hard_reset(struct orinoco_private *priv) 555{ 556 struct orinoco_pccard *card = priv->card; 557 dev_link_t *link = &card->link; 558 int err; 559 560 if (!hermes_present(&priv->hw)) { 561 /* The firmware needs to be reloaded */ 562 if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) { 563 printk(KERN_ERR PFX "Firmware download failed\n"); 564 err = -ENODEV; 565 } 566 } else { 567 /* Soft reset using COR and HCR */ 568 spectrum_reset(link, 0); 569 } 570 571 return 0; 572} 573 574/********************************************************************/ 575/* PCMCIA stuff */ 576/********************************************************************/ 577 578/* 579 * This creates an "instance" of the driver, allocating local data 580 * structures for one device. The device is registered with Card 581 * Services. 582 * 583 * The dev_link structure is initialized, but we don't actually 584 * configure the card at this point -- we wait until we receive a card 585 * insertion event. */ 586static int 587spectrum_cs_attach(struct pcmcia_device *p_dev) 588{ 589 struct net_device *dev; 590 struct orinoco_private *priv; 591 struct orinoco_pccard *card; 592 dev_link_t *link; 593 594 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset); 595 if (! dev) 596 return -ENOMEM; 597 priv = netdev_priv(dev); 598 card = priv->card; 599 600 /* Link both structures together */ 601 link = &card->link; 602 link->priv = dev; 603 604 /* Interrupt setup */ 605 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 606 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 607 link->irq.Handler = orinoco_interrupt; 608 link->irq.Instance = dev; 609 610 /* General socket configuration defaults can go here. In this 611 * client, we assume very little, and rely on the CIS for 612 * almost everything. In most clients, many details (i.e., 613 * number, sizes, and attributes of IO windows) are fixed by 614 * the nature of the device, and can be hard-wired here. */ 615 link->conf.Attributes = 0; 616 link->conf.IntType = INT_MEMORY_AND_IO; 617 618 link->handle = p_dev; 619 p_dev->instance = link; 620 621 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 622 spectrum_cs_config(link); 623 624 return 0; 625} /* spectrum_cs_attach */ 626 627/* 628 * This deletes a driver "instance". The device is de-registered with 629 * Card Services. If it has been released, all local data structures 630 * are freed. Otherwise, the structures will be freed when the device 631 * is released. 632 */ 633static void spectrum_cs_detach(struct pcmcia_device *p_dev) 634{ 635 dev_link_t *link = dev_to_instance(p_dev); 636 struct net_device *dev = link->priv; 637 638 if (link->state & DEV_CONFIG) 639 spectrum_cs_release(link); 640 641 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); 642 if (link->dev) { 643 DEBUG(0, PFX "About to unregister net device %p\n", 644 dev); 645 unregister_netdev(dev); 646 } 647 free_orinocodev(dev); 648} /* spectrum_cs_detach */ 649 650/* 651 * spectrum_cs_config() is scheduled to run after a CARD_INSERTION 652 * event is received, to configure the PCMCIA socket, and to make the 653 * device available to the system. 654 */ 655 656static void 657spectrum_cs_config(dev_link_t *link) 658{ 659 struct net_device *dev = link->priv; 660 client_handle_t handle = link->handle; 661 struct orinoco_private *priv = netdev_priv(dev); 662 struct orinoco_pccard *card = priv->card; 663 hermes_t *hw = &priv->hw; 664 int last_fn, last_ret; 665 u_char buf[64]; 666 config_info_t conf; 667 cisinfo_t info; 668 tuple_t tuple; 669 cisparse_t parse; 670 void __iomem *mem; 671 672 CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); 673 674 /* 675 * This reads the card's CONFIG tuple to find its 676 * configuration registers. 677 */ 678 tuple.DesiredTuple = CISTPL_CONFIG; 679 tuple.Attributes = 0; 680 tuple.TupleData = buf; 681 tuple.TupleDataMax = sizeof(buf); 682 tuple.TupleOffset = 0; 683 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 684 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 685 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 686 link->conf.ConfigBase = parse.config.base; 687 link->conf.Present = parse.config.rmask[0]; 688 689 /* Configure card */ 690 link->state |= DEV_CONFIG; 691 692 /* Look up the current Vcc */ 693 CS_CHECK(GetConfigurationInfo, 694 pcmcia_get_configuration_info(handle, &conf)); 695 link->conf.Vcc = conf.Vcc; 696 697 /* 698 * In this loop, we scan the CIS for configuration table 699 * entries, each of which describes a valid card 700 * configuration, including voltage, IO window, memory window, 701 * and interrupt settings. 702 * 703 * We make no assumptions about the card to be configured: we 704 * use just the information available in the CIS. In an ideal 705 * world, this would work for any PCMCIA card, but it requires 706 * a complete and accurate CIS. In practice, a driver usually 707 * "knows" most of these things without consulting the CIS, 708 * and most client drivers will only use the CIS to fill in 709 * implementation-defined details. 710 */ 711 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 712 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 713 while (1) { 714 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 715 cistpl_cftable_entry_t dflt = { .index = 0 }; 716 717 if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) 718 || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) 719 goto next_entry; 720 721 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 722 dflt = *cfg; 723 if (cfg->index == 0) 724 goto next_entry; 725 link->conf.ConfigIndex = cfg->index; 726 727 /* Does this card need audio output? */ 728 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 729 link->conf.Attributes |= CONF_ENABLE_SPKR; 730 link->conf.Status = CCSR_AUDIO_ENA; 731 } 732 733 /* Use power settings for Vcc and Vpp if present */ 734 /* Note that the CIS values need to be rescaled */ 735 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) { 736 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) { 737 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000); 738 if (!ignore_cis_vcc) 739 goto next_entry; 740 } 741 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) { 742 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) { 743 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000); 744 if(!ignore_cis_vcc) 745 goto next_entry; 746 } 747 } 748 749 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 750 link->conf.Vpp1 = link->conf.Vpp2 = 751 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 752 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 753 link->conf.Vpp1 = link->conf.Vpp2 = 754 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 755 756 /* Do we need to allocate an interrupt? */ 757 link->conf.Attributes |= CONF_ENABLE_IRQ; 758 759 /* IO window settings */ 760 link->io.NumPorts1 = link->io.NumPorts2 = 0; 761 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 762 cistpl_io_t *io = 763 (cfg->io.nwin) ? &cfg->io : &dflt.io; 764 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 765 if (!(io->flags & CISTPL_IO_8BIT)) 766 link->io.Attributes1 = 767 IO_DATA_PATH_WIDTH_16; 768 if (!(io->flags & CISTPL_IO_16BIT)) 769 link->io.Attributes1 = 770 IO_DATA_PATH_WIDTH_8; 771 link->io.IOAddrLines = 772 io->flags & CISTPL_IO_LINES_MASK; 773 link->io.BasePort1 = io->win[0].base; 774 link->io.NumPorts1 = io->win[0].len; 775 if (io->nwin > 1) { 776 link->io.Attributes2 = 777 link->io.Attributes1; 778 link->io.BasePort2 = io->win[1].base; 779 link->io.NumPorts2 = io->win[1].len; 780 } 781 782 /* This reserves IO space but doesn't actually enable it */ 783 if (pcmcia_request_io(link->handle, &link->io) != 0) 784 goto next_entry; 785 } 786 787 788 /* If we got this far, we're cool! */ 789 790 break; 791 792 next_entry: 793 if (link->io.NumPorts1) 794 pcmcia_release_io(link->handle, &link->io); 795 last_ret = pcmcia_get_next_tuple(handle, &tuple); 796 if (last_ret == CS_NO_MORE_ITEMS) { 797 printk(KERN_ERR PFX "GetNextTuple(): No matching " 798 "CIS configuration. Maybe you need the " 799 "ignore_cis_vcc=1 parameter.\n"); 800 goto cs_failed; 801 } 802 } 803 804 /* 805 * Allocate an interrupt line. Note that this does not assign 806 * a handler to the interrupt, unless the 'Handler' member of 807 * the irq structure is initialized. 808 */ 809 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 810 811 /* We initialize the hermes structure before completing PCMCIA 812 * configuration just in case the interrupt handler gets 813 * called. */ 814 mem = ioport_map(link->io.BasePort1, link->io.NumPorts1); 815 if (!mem) 816 goto cs_failed; 817 818 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); 819 820 /* 821 * This actually configures the PCMCIA socket -- setting up 822 * the I/O windows and the interrupt mapping, and putting the 823 * card and host interface into "Memory and IO" mode. 824 */ 825 CS_CHECK(RequestConfiguration, 826 pcmcia_request_configuration(link->handle, &link->conf)); 827 828 /* Ok, we have the configuration, prepare to register the netdev */ 829 dev->base_addr = link->io.BasePort1; 830 dev->irq = link->irq.AssignedIRQ; 831 SET_MODULE_OWNER(dev); 832 card->node.major = card->node.minor = 0; 833 834 /* Reset card and download firmware */ 835 if (spectrum_cs_hard_reset(priv) != 0) { 836 goto failed; 837 } 838 839 SET_NETDEV_DEV(dev, &handle_to_dev(handle)); 840 /* Tell the stack we exist */ 841 if (register_netdev(dev) != 0) { 842 printk(KERN_ERR PFX "register_netdev() failed\n"); 843 goto failed; 844 } 845 846 /* At this point, the dev_node_t structure(s) needs to be 847 * initialized and arranged in a linked list at link->dev. */ 848 strcpy(card->node.dev_name, dev->name); 849 link->dev = &card->node; /* link->dev being non-NULL is also 850 used to indicate that the 851 net_device has been registered */ 852 link->state &= ~DEV_CONFIG_PENDING; 853 854 /* Finally, report what we've done */ 855 printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", 856 dev->name, link->conf.ConfigIndex, 857 link->conf.Vcc / 10, link->conf.Vcc % 10); 858 if (link->conf.Vpp1) 859 printk(", Vpp %d.%d", link->conf.Vpp1 / 10, 860 link->conf.Vpp1 % 10); 861 printk(", irq %d", link->irq.AssignedIRQ); 862 if (link->io.NumPorts1) 863 printk(", io 0x%04x-0x%04x", link->io.BasePort1, 864 link->io.BasePort1 + link->io.NumPorts1 - 1); 865 if (link->io.NumPorts2) 866 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 867 link->io.BasePort2 + link->io.NumPorts2 - 1); 868 printk("\n"); 869 870 return; 871 872 cs_failed: 873 cs_error(link->handle, last_fn, last_ret); 874 875 failed: 876 spectrum_cs_release(link); 877} /* spectrum_cs_config */ 878 879/* 880 * After a card is removed, spectrum_cs_release() will unregister the 881 * device, and release the PCMCIA configuration. If the device is 882 * still open, this will be postponed until it is closed. 883 */ 884static void 885spectrum_cs_release(dev_link_t *link) 886{ 887 struct net_device *dev = link->priv; 888 struct orinoco_private *priv = netdev_priv(dev); 889 unsigned long flags; 890 891 /* We're committed to taking the device away now, so mark the 892 * hardware as unavailable */ 893 spin_lock_irqsave(&priv->lock, flags); 894 priv->hw_unavailable++; 895 spin_unlock_irqrestore(&priv->lock, flags); 896 897 /* Don't bother checking to see if these succeed or not */ 898 pcmcia_release_configuration(link->handle); 899 if (link->io.NumPorts1) 900 pcmcia_release_io(link->handle, &link->io); 901 if (link->irq.AssignedIRQ) 902 pcmcia_release_irq(link->handle, &link->irq); 903 link->state &= ~DEV_CONFIG; 904 if (priv->hw.iobase) 905 ioport_unmap(priv->hw.iobase); 906} /* spectrum_cs_release */ 907 908 909static int 910spectrum_cs_suspend(struct pcmcia_device *p_dev) 911{ 912 dev_link_t *link = dev_to_instance(p_dev); 913 struct net_device *dev = link->priv; 914 struct orinoco_private *priv = netdev_priv(dev); 915 unsigned long flags; 916 int err = 0; 917 918 link->state |= DEV_SUSPEND; 919 /* Mark the device as stopped, to block IO until later */ 920 if (link->state & DEV_CONFIG) { 921 spin_lock_irqsave(&priv->lock, flags); 922 923 err = __orinoco_down(dev); 924 if (err) 925 printk(KERN_WARNING "%s: Error %d downing interface\n", 926 dev->name, err); 927 928 netif_device_detach(dev); 929 priv->hw_unavailable++; 930 931 spin_unlock_irqrestore(&priv->lock, flags); 932 933 pcmcia_release_configuration(link->handle); 934 } 935 936 return 0; 937} 938 939static int 940spectrum_cs_resume(struct pcmcia_device *p_dev) 941{ 942 dev_link_t *link = dev_to_instance(p_dev); 943 struct net_device *dev = link->priv; 944 struct orinoco_private *priv = netdev_priv(dev); 945 946 link->state &= ~DEV_SUSPEND; 947 if (link->state & DEV_CONFIG) { 948 /* FIXME: should we double check that this is 949 * the same card as we had before */ 950 pcmcia_request_configuration(link->handle, &link->conf); 951 netif_device_attach(dev); 952 priv->hw_unavailable--; 953 schedule_work(&priv->reset_work); 954 } 955 return 0; 956} 957 958 959/********************************************************************/ 960/* Module initialization */ 961/********************************************************************/ 962 963/* Can't be declared "const" or the whole __initdata section will 964 * become const */ 965static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION 966 " (Pavel Roskin <proski@gnu.org>," 967 " David Gibson <hermes@gibson.dropbear.id.au>, et al)"; 968 969static struct pcmcia_device_id spectrum_cs_ids[] = { 970 PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */ 971 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */ 972 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */ 973 PCMCIA_DEVICE_NULL, 974}; 975MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids); 976 977static struct pcmcia_driver orinoco_driver = { 978 .owner = THIS_MODULE, 979 .drv = { 980 .name = DRIVER_NAME, 981 }, 982 .probe = spectrum_cs_attach, 983 .remove = spectrum_cs_detach, 984 .suspend = spectrum_cs_suspend, 985 .resume = spectrum_cs_resume, 986 .id_table = spectrum_cs_ids, 987}; 988 989static int __init 990init_spectrum_cs(void) 991{ 992 printk(KERN_DEBUG "%s\n", version); 993 994 return pcmcia_register_driver(&orinoco_driver); 995} 996 997static void __exit 998exit_spectrum_cs(void) 999{ 1000 pcmcia_unregister_driver(&orinoco_driver); 1001} 1002 1003module_init(init_spectrum_cs); 1004module_exit(exit_spectrum_cs);