bool HashAggregator::Finalize() { for (auto entry : aggregates_map) { // Construct a container for the first tuple ContainerTuple<std::vector<type::Value>> first_tuple( &entry.second->first_tuple_values); if (Helper(node, entry.second->aggregates, output_table, &first_tuple, this->executor_context) == false) { return false; } } return true; }
/* gpib_config() is scheduled to run after a CARD_INSERTION event is received, to configure the PCMCIA socket, and to make the ethernet device available to the system. */ static void ines_gpib_config( struct pcmcia_device *link ) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int i; u_char buf[64]; win_req_t req; memreq_t mem; void *virt; dev = link->priv; DEBUG(0, "ines_gpib_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(link, &tuple); if (i != 0) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(link, &tuple); if (i != 0) break; i = PCMCIA_PARSE_TUPLE(&tuple, &parse); if (i != 0) break; link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; } while (0); if (i != 0) { cs_error(link, ParseTuple, i); return; } /* Configure card */ do { /* * try to get manufacturer and card ID */ tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; if( first_tuple(link,&tuple,&parse) == 0 ) { dev->manfid = parse.manfid.manf; dev->cardid = parse.manfid.card; printk(KERN_DEBUG "ines_cs: manufacturer: 0x%x card: 0x%x\n", dev->manfid, dev->cardid); } /* try to get board information from CIS */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; if( first_tuple(link,&tuple,&parse) == 0 ) { while(1) { if( parse.cftable_entry.io.nwin > 0) { link->io.BasePort1 = parse.cftable_entry.io.win[0].base; link->io.NumPorts1 = 32; link->io.BasePort2 = 0; link->io.NumPorts2 = 0; i = pcmcia_request_io(link, &link->io); if (i == 0) { printk( KERN_DEBUG "ines_cs: base=0x%x len=%d registered\n", link->io.BasePort1, link->io.NumPorts1 ); link->conf.ConfigIndex = parse.cftable_entry.index; break; } } if ( next_tuple(link,&tuple,&parse) != 0 ) break; } if (i != 0) { cs_error(link, RequestIO, i); } } else { printk("ines_cs: can't get card information\n"); } link->conf.Status = CCSR_IOIS8; /* for the ines card we have to setup the configuration registers in attribute memory here */ req.Attributes=WIN_MEMORY_TYPE_AM | WIN_DATA_WIDTH_8 | WIN_ENABLE; req.Base=0; req.Size=0x1000; req.AccessSpeed=250; i= pcmcia_request_window(&link, &req, &link->win); if (i != 0) { cs_error(link, RequestWindow, i); break; } mem.CardOffset=0; mem.Page=0; i= pcmcia_map_mem_page(link->win, &mem); if (i != 0) { cs_error(link, MapMemPage, i); break; } virt = ioremap( req.Base, req.Size ); writeb( ( link->io.BasePort1 >> 2 ) & 0xff, virt + 0xf0 ); // IOWindow base iounmap( ( void* ) virt ); } while (0); /* Now allocate an interrupt line. */ if (link->conf.Attributes & CONF_ENABLE_IRQ) { i = pcmcia_request_irq(link, &link->irq); if (i != 0) { cs_error(link, RequestIRQ, i); } printk(KERN_DEBUG "ines_cs: IRQ_Line=%d\n",link->irq.AssignedIRQ); } /* This actually configures the PCMCIA socket -- setting up the I/O windows and the interrupt mapping. */ i = pcmcia_request_configuration(link, &link->conf); if (i != 0) { cs_error(link, RequestConfiguration, i); } /* If any step failed, release any partially configured state */ if (i != 0) { ines_gpib_release(link); return; } printk(KERN_DEBUG "ines gpib device loaded\n"); } /* gpib_config */
static void btuart_config(dev_link_t *link) { static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; client_handle_t handle = link->handle; btuart_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; config_info_t config; int i, j, try, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; last_ret = first_tuple(handle, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; i = pcmcia_get_configuration_info(handle, &config); link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); cs_error(link->handle, RequestIO, i); goto failed; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); goto failed; } if (btuart_open(info) != 0) goto failed; strcpy(info->node.dev_name, info->hdev->name); link->dev = &info->node; link->state &= ~DEV_CONFIG_PENDING; return; cs_failed: cs_error(link->handle, last_fn, last_ret); failed: btuart_release(link); }
void serial_config(dev_link_t * link) { client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; int i, last_ret, last_fn; DEBUG(0, "serial_config(0x%p)\n", link); cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) goto failed; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; /* Get configuration register information */ tuple->DesiredTuple = CISTPL_CONFIG; last_ret = first_tuple(handle, tuple, parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse->config.base; link->conf.Present = parse->config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; info->multi = (first_tuple(handle, tuple, parse) == CS_SUCCESS); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { info->manfid = parse->manfid.manf; for (i = 0; i < MULTI_COUNT; i++) if ((info->manfid == multi_id[i].manfid) && (parse->manfid.card == multi_id[i].prodid)) break; if (i < MULTI_COUNT) info->multi = multi_id[i].multi; } /* Another check for dual-serial cards: look for either serial or multifunction cards that ask for appropriate IO port ranges */ tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && ((first_tuple(handle, tuple, parse) != CS_SUCCESS) || (parse->funcid.func == CISTPL_FUNCID_MULTI) || (parse->funcid.func == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && (cf->io.win[1].len == 8)) info->multi = 2; } }
static int multi_config(dev_link_t * link) { client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; config_info_t config; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; i = pcmcia_get_configuration_info(handle, &config); if (i != CS_SUCCESS) { cs_error(handle, GetConfigurationInfo, i); rc = -1; goto free_cfg_mem; } link->conf.Vcc = config.Vcc; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(handle, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(handle, tuple, parse); } } if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); rc = -1; goto free_cfg_mem; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ if (info->multi && (info->manfid == MANFID_SOCKET)) { link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: 8 registers are for the UART, the others are extra registers */ if (info->manfid == MANFID_OXSEMI) { if (cf->index == 1 || cf->index == 3) { setup_serial(handle, info, base2, link->irq.AssignedIRQ); outb(12, link->io.BasePort1 + 1); } else { setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); outb(12, base2 + 1); } rc = 0; goto free_cfg_mem; } setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) { rc = 0; goto free_cfg_mem; } for (i = 0; i < info->multi - 1; i++) setup_serial(handle, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: kfree(cfg_mem); return rc; }
static int simple_config(dev_link_t *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; static int size_table[2] = { 8, 16 }; client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; config_info_t config; int i, j, try; int s; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; /* If the card is already configured, look up the port and irq */ i = pcmcia_get_configuration_info(handle, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { kio_addr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { port = config.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && (config.NumPorts1 == 0x40)) { port = config.BasePort1 + 0x28; info->slave = 1; } if (info->slave) { kfree(cfg_mem); return setup_serial(handle, info, port, config.AssignedIRQ); } } link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (s = 0; s < 2; s++) { for (try = 0; try < 2; try++) { i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == size_table[s]) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, tuple, parse); } } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, tuple, parse); } found_port: if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link->handle, RequestIO, i); kfree(cfg_mem); return -1; } i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); kfree(cfg_mem); return -1; } kfree(cfg_mem); return setup_serial(handle, info, link->io.BasePort1, link->irq.AssignedIRQ); }
static int simple_config(dev_link_t *link) { static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; client_handle_t handle = link->handle; serial_info_t *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; config_info_t config; int i, j, try; /* If the card is already configured, look up the port and irq */ i = CardServices(GetConfigurationInfo, handle, &config); if ((i == CS_SUCCESS) && (config.Attributes & CONF_VALID_CLIENT)) { ioaddr_t port = 0; if ((config.BasePort2 != 0) && (config.NumPorts2 == 8)) { port = config.BasePort2; info->slave = 1; } else if ((info->manfid == MANFID_OSITECH) && (config.NumPorts1 == 0x40)) { port = config.BasePort1 + 0x28; info->slave = 1; } if (info->slave) return setup_serial(info, port, config.AssignedIRQ); } link->conf.Vcc = config.Vcc; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM]/10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(handle, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); return -1; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } if (info->multi && (info->manfid == MANFID_3COM)) link->conf.ConfigIndex &= ~(0x08); i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); return -1; } return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); }
static int btuart_config(struct pcmcia_device *link) { static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; btuart_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i, j, try; /* First pass: look for a config entry that looks normal. */ tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* Two tries: without IO aliases, then with aliases */ for (try = 0; try < 2; try++) { i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if (i != CS_SUCCESS) goto next_entry; if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM)) link->conf.Vpp = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000; if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } next_entry: i = next_tuple(link, &tuple, &parse); } } /* Second pass: try to find an entry that isn't picky about its base address, then try to grab any standard serial port address, and finally try to get any free port. */ i = first_tuple(link, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) { link->conf.ConfigIndex = cf->index; for (j = 0; j < 5; j++) { link->io.BasePort1 = base[j]; link->io.IOAddrLines = base[j] ? 16 : 3; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { BT_ERR("No usable port range found"); cs_error(link, RequestIO, i); goto failed; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); goto failed; } if (btuart_open(info) != 0) goto failed; strcpy(info->node.dev_name, info->hdev->name); link->dev_node = &info->node; return 0; failed: btuart_release(link); return -ENODEV; }
void bluecard_config(dev_link_t *link) { client_handle_t handle = link->handle; bluecard_info_t *info = link->priv; tuple_t tuple; u_short buf[256]; cisparse_t parse; config_info_t config; int i, n, last_ret, last_fn; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; /* Get configuration register information */ tuple.DesiredTuple = CISTPL_CONFIG; last_ret = first_tuple(handle, &tuple, &parse); if (last_ret != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; i = CardServices(GetConfigurationInfo, handle, &config); link->conf.Vcc = config.Vcc; link->conf.ConfigIndex = 0x20; link->io.NumPorts1 = 64; link->io.IOAddrLines = 6; for (n = 0; n < 0x400; n += 0x40) { link->io.BasePort1 = n ^ 0x300; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); goto failed; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); goto failed; } MOD_INC_USE_COUNT; if (bluecard_open(info) != 0) goto failed; strcpy(info->node.dev_name, info->hdev.name); link->dev = &info->node; link->state &= ~DEV_CONFIG_PENDING; return; cs_failed: cs_error(link->handle, last_fn, last_ret); failed: bluecard_release((u_long)link); }
static int serial_config(struct pcmcia_device * link) { struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; int i; DEBUG(0, "serial_config(0x%p)\n", link); cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) goto failed; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; /* Is this a compliant multifunction card? */ tuple->DesiredTuple = CISTPL_LONGLINK_MFC; tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; info->multi = (first_tuple(link, tuple, parse) == CS_SUCCESS); /* Is this a multiport card? */ tuple->DesiredTuple = CISTPL_MANFID; info->manfid = link->manf_id; info->prodid = link->card_id; for (i = 0; i < ARRAY_SIZE(quirks); i++) if ((quirks[i].manfid == ~0 || quirks[i].manfid == info->manfid) && (quirks[i].prodid == ~0 || quirks[i].prodid == info->prodid)) { info->quirk = &quirks[i]; break; } /* Another check for dual-serial cards: look for either serial or multifunction cards that ask for appropriate IO port ranges */ tuple->DesiredTuple = CISTPL_FUNCID; if ((info->multi == 0) && (link->has_func_id) && ((link->func_id == CISTPL_FUNCID_MULTI) || (link->func_id == CISTPL_FUNCID_SERIAL))) { tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; if (first_tuple(link, tuple, parse) == CS_SUCCESS) { if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0)) info->multi = cf->io.win[0].len >> 3; if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) && (cf->io.win[1].len == 8)) info->multi = 2; } }
static int multi_config(struct pcmcia_device * link) { struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; tuple_t *tuple; u_char *buf; cisparse_t *parse; cistpl_cftable_entry_t *cf; int i, rc, base2 = 0; cfg_mem = kmalloc(sizeof(struct serial_cfg_mem), GFP_KERNEL); if (!cfg_mem) return -1; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->TupleData = (cisdata_t *) buf; tuple->TupleOffset = 0; tuple->TupleDataMax = 255; tuple->Attributes = 0; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = pcmcia_request_io(link, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } } if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); rc = -1; goto free_cfg_mem; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { printk(KERN_NOTICE "serial_cs: no usable port range found, giving up\n"); cs_error(link, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* * Apply any configuration quirks. */ if (info->quirk && info->quirk->config) info->quirk->config(link); i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); rc = -1; goto free_cfg_mem; } /* The Oxford Semiconductor OXCF950 cards are in fact single-port: * 8 registers are for the UART, the others are extra registers. * Siemen's MC45 PCMCIA (Possio's GCC) is OXCF950 based too. */ if (info->manfid == MANFID_OXSEMI || (info->manfid == MANFID_POSSIO && info->prodid == PRODID_POSSIO_GCC)) { int err; if (cf->index == 1 || cf->index == 3) { err = setup_serial(link, info, base2, link->irq.AssignedIRQ); base2 = link->io.BasePort1; } else { err = setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); } info->c950ctrl = base2; /* * FIXME: We really should wake up the port prior to * handing it over to the serial layer. */ if (info->quirk && info->quirk->wakeup) info->quirk->wakeup(link); rc = 0; goto free_cfg_mem; } setup_serial(link, info, link->io.BasePort1, link->irq.AssignedIRQ); for (i = 0; i < info->multi - 1; i++) setup_serial(link, info, base2 + (8 * i), link->irq.AssignedIRQ); rc = 0; free_cfg_mem: kfree(cfg_mem); return rc; }
static int elsa_cs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev_node = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); elsa_cs_release(link); } else ((local_info_t*)link->priv)->cardnr = i; return 0; cs_failed: cs_error(link, last_fn, i); elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */
static void avma1cs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u8 buf[64]; char devname[128]; int busy = 0; handle = link->handle; dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = CardServices(GetFirstTuple, handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = CardServices(GetTupleData, handle, &tuple); if (i != CS_SUCCESS) break; i = CardServices(ParseTuple, handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link->handle, ParseTuple, i); link->state &= ~DEV_CONFIG_PENDING; return; } /* Configure card */ link->state |= DEV_CONFIG; do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); break; } /* * allocate an interrupt line */ i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); CardServices(ReleaseIO, link->handle, &link->io); break; } /* * configure the PCMCIA socket */ i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); CardServices(ReleaseIO, link->handle, &link->io); CardServices(ReleaseIRQ, link->handle, &link->irq); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; link->dev = &dev->node; link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); return; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", link->io.BasePort1, link->irq.AssignedIRQ); if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1, link->irq.AssignedIRQ, &busy, isdnprot) != 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); return; } i = 0; /* no returncode for cardnr :-( */ dev->node.minor = i; } /* avma1cs_config */
static int multi_config(dev_link_t *link) { client_handle_t handle = link->handle; serial_info_t *info = link->priv; tuple_t tuple; u_char buf[256]; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; int i, base2 = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; /* First, look for a generic full-sized window */ link->io.NumPorts1 = info->multi * 8; i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { /* The quad port cards have bad CIS's, so just look for a window larger than 8 ports and assume it will be right */ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); base2 = link->io.BasePort1 + 8; if (i == CS_SUCCESS) break; } i = next_tuple(handle, &tuple, &parse); } /* If that didn't work, look for two windows */ if (i != CS_SUCCESS) { link->io.NumPorts1 = link->io.NumPorts2 = 8; info->multi = 2; i = first_tuple(handle, &tuple, &parse); while (i != CS_NO_MORE_ITEMS) { if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.BasePort2 = cf->io.win[1].base; link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; i = CardServices(RequestIO, link->handle, &link->io); base2 = link->io.BasePort2; if (i == CS_SUCCESS) break; } i = next_tuple(handle, &tuple, &parse); } } if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); return -1; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); link->irq.AssignedIRQ = 0; } /* Socket Dual IO: this enables irq's for second port */ if (info->multi && (info->manfid == MANFID_SOCKET)) { link->conf.Present |= PRESENT_EXT_STATUS; link->conf.ExtStatus = ESR_REQ_ATTN_ENA; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); return -1; } setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ); /* The Nokia cards are not really multiport cards */ if (info->manfid == MANFID_NOKIA) return 0; for (i = 0; i < info->multi-1; i++) setup_serial(info, base2+(8*i), link->irq.AssignedIRQ); return 0; }
static int avma1cs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; IsdnCard_t icard; int busy = 0; dev = link->priv; DEBUG(0, "avma1cs_config(0x%p)\n", link); /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(link, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(link, &tuple); if (i != CS_SUCCESS) break; i = pcmcia_parse_tuple(link, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link, ParseTuple, i); return -ENODEV; } do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(link, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1 - 1); i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ strcpy(dev->node.dev_name, "A1"); dev->node.major = 45; dev->node.minor = 0; link->dev_node = &dev->node; /* If any step failed, release any partially configured state */ if (i != 0) { avma1cs_release(link); return -ENODEV; } printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n", link->io.BasePort1, link->irq.AssignedIRQ); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = isdnprot; icard.typ = ISDN_CTYPE_A1_PCMCIA; i = hisax_init_pcmcia(link, &busy, &icard); if (i < 0) { printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); avma1cs_release(link); return -ENODEV; } dev->node.minor = i; return 0; } /* avma1cs_config */
static void elsa_cs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; DEBUG(0, "elsa_config(0x%p)\n", link); handle = link->handle; dev = link->priv; /* This reads the card's CONFIG tuple to find its configuration registers. */ tuple.DesiredTuple = CISTPL_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; i = first_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(handle, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; elsa_init_pcmcia(link->io.BasePort1, link->irq.AssignedIRQ, &(((local_info_t*)link->priv)->busy), protocol); return; cs_failed: cs_error(link->handle, last_fn, i); elsa_cs_release((u_long)link); } /* elsa_cs_config */
static int avmcs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); dev = link->priv; do { devname[0] = 0; if (link->prod_id[1]) strlcpy(devname, link->prod_id[1], sizeof(devname)); /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(link, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { cs_error(link, RequestIRQ, i); /* undo */ pcmcia_disable_device(link); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { cs_error(link, RequestConfiguration, i); pcmcia_disable_device(link); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ if (devname[0]) { char *s = strrchr(devname, ' '); if (!s) s = devname; else s++; strcpy(dev->node.dev_name, s); if (strcmp("M1", s) == 0) { cardtype = AVM_CARDTYPE_M1; } else if (strcmp("M2", s) == 0) { cardtype = AVM_CARDTYPE_M2; } else { cardtype = AVM_CARDTYPE_B1; } } else { strcpy(dev->node.dev_name, "b1"); cardtype = AVM_CARDTYPE_B1; } dev->node.major = 64; dev->node.minor = 0; link->dev_node = &dev->node; /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); return -ENODEV; } switch (cardtype) { case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); return -ENODEV; } dev->node.minor = i; return 0; } /* avmcs_config */
static void avmcs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; cistpl_cftable_entry_t *cf = &parse.cftable_entry; local_info_t *dev; int i; u_char buf[64]; char devname[128]; int cardtype; int (*addcard)(unsigned int port, unsigned irq); handle = link->handle; dev = link->priv; /* This reads the card's CONFIG tuple to find its configuration registers. */ do { tuple.DesiredTuple = CISTPL_CONFIG; i = pcmcia_get_first_tuple(handle, &tuple); if (i != CS_SUCCESS) break; tuple.TupleData = buf; tuple.TupleDataMax = 64; tuple.TupleOffset = 0; i = pcmcia_get_tuple_data(handle, &tuple); if (i != CS_SUCCESS) break; i = pcmcia_parse_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) break; link->conf.ConfigBase = parse.config.base; } while (0); if (i != CS_SUCCESS) { cs_error(link->handle, ParseTuple, i); link->state &= ~DEV_CONFIG_PENDING; return; } /* Configure card */ link->state |= DEV_CONFIG; do { tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = 254; tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_VERS_1; devname[0] = 0; if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) { strlcpy(devname,parse.version_1.str + parse.version_1.ofs[1], sizeof(devname)); } /* * find IO port */ tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if (cf->io.nwin > 0) { link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; link->io.NumPorts1 = cf->io.win[0].len; link->io.NumPorts2 = 0; printk(KERN_INFO "avm_cs: testing i/o %#x-%#x\n", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); i = pcmcia_request_io(link->handle, &link->io); if (i == CS_SUCCESS) goto found_port; } i = next_tuple(handle, &tuple, &parse); } found_port: if (i != CS_SUCCESS) { cs_error(link->handle, RequestIO, i); break; } /* * allocate an interrupt line */ i = pcmcia_request_irq(link->handle, &link->irq); if (i != CS_SUCCESS) { cs_error(link->handle, RequestIRQ, i); pcmcia_release_io(link->handle, &link->io); break; } /* * configure the PCMCIA socket */ i = pcmcia_request_configuration(link->handle, &link->conf); if (i != CS_SUCCESS) { cs_error(link->handle, RequestConfiguration, i); pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); break; } } while (0); /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. */ if (devname[0]) { char *s = strrchr(devname, ' '); if (!s) s = devname; else s++; strcpy(dev->node.dev_name, s); if (strcmp("M1", s) == 0) { cardtype = AVM_CARDTYPE_M1; } else if (strcmp("M2", s) == 0) { cardtype = AVM_CARDTYPE_M2; } else { cardtype = AVM_CARDTYPE_B1; } } else { strcpy(dev->node.dev_name, "b1"); cardtype = AVM_CARDTYPE_B1; } dev->node.major = 64; dev->node.minor = 0; link->dev = &dev->node; link->state &= ~DEV_CONFIG_PENDING; /* If any step failed, release any partially configured state */ if (i != 0) { avmcs_release(link); return; } switch (cardtype) { case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break; case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break; default: case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break; } if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) { printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n", dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ); avmcs_release(link); return; } dev->node.minor = i; } /* avmcs_config */
static void mio_cs_config(struct pcmcia_device *link) { tuple_t tuple; u_short buf[128]; cisparse_t parse; int manfid = 0, prodid = 0; int ret; DPRINTK("mio_cs_config(link=%p)\n", link); tuple.TupleData = (cisdata_t *) buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CONFIG; ret = pcmcia_get_first_tuple(link, &tuple); ret = pcmcia_get_tuple_data(link, &tuple); ret = pcmcia_parse_tuple(&tuple, &parse); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; #if 0 tuple.DesiredTuple = CISTPL_LONGLINK_MFC; tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK; info->multi(first_tuple(link, &tuple, &parse) == 0); #endif tuple.DesiredTuple = CISTPL_MANFID; tuple.Attributes = TUPLE_RETURN_COMMON; if ((pcmcia_get_first_tuple(link, &tuple) == 0) && (pcmcia_get_tuple_data(link, &tuple) == 0)) { manfid = le16_to_cpu(buf[0]); prodid = le16_to_cpu(buf[1]); } tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; ret = pcmcia_get_first_tuple(link, &tuple); ret = pcmcia_get_tuple_data(link, &tuple); ret = pcmcia_parse_tuple(&tuple, &parse); #if 0 printk(" index: 0x%x\n", parse.cftable_entry.index); printk(" flags: 0x%x\n", parse.cftable_entry.flags); printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags); printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin); printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base); printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len); printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1); printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2); printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags); printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin); printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples); #endif #if 0 link->io.NumPorts1 = 0x20; link->io.IOAddrLines = 5; link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; #endif link->io.NumPorts1 = parse.cftable_entry.io.win[0].len; link->io.IOAddrLines = parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK; link->io.NumPorts2 = 0; { int base; for (base = 0x000; base < 0x400; base += 0x20) { link->io.BasePort1 = base; ret = pcmcia_request_io(link, &link->io); if (!ret) break; } } link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1; link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2; ret = pcmcia_request_irq(link, &link->irq); if (ret) { printk("pcmcia_request_irq() returned error: %i\n", ret); } link->conf.ConfigIndex = 1; ret = pcmcia_request_configuration(link, &link->conf); link->dev_node = &dev_node; }