static int sl811_cs_config(struct pcmcia_device *link) { struct device *parent = &link->dev; int ret; dev_dbg(&link->dev, "sl811_cs_config\n"); link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC | CONF_AUTO_SET_IO; if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) goto failed; /* require an IRQ and two registers */ if (resource_size(link->resource[0]) < 2) goto failed; if (!link->irq) goto failed; ret = pcmcia_enable_device(link); if (ret) goto failed; if (sl811_hc_init(parent, link->resource[0]->start, link->irq) < 0) { failed: printk(KERN_WARNING "sl811_cs_config failed\n"); sl811_cs_release(link); return -ENODEV; } return 0; }
static int sl811_cs_config(struct pcmcia_device *link) { struct device *parent = &link->dev; local_info_t *dev = link->priv; int ret; dev_dbg(&link->dev, "sl811_cs_config\n"); if (pcmcia_loop_config(link, sl811_cs_config_check, NULL)) goto failed; /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) { ret = pcmcia_request_irq(link, &link->irq); if (ret) goto failed; } else goto failed; ret = pcmcia_request_configuration(link, &link->conf); if (ret) goto failed; sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; link->dev_node = &dev->node; printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Vpp) printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { failed: printk(KERN_WARNING "sl811_cs_config failed\n"); sl811_cs_release(link); return -ENODEV; } return 0; }
static void sl811_cs_config(dev_link_t *link) { client_handle_t handle = link->handle; struct device *parent = &handle_to_dev(handle); local_info_t *dev = link->priv; tuple_t tuple; cisparse_t parse; int last_fn, last_ret; u_char buf[64]; config_info_t conf; cistpl_cftable_entry_t dflt = { 0 }; DBG(0, "sl811_cs_config(0x%p)\n", link); tuple.DesiredTuple = CISTPL_CONFIG; tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; /* Look up the current Vcc */ CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf)); link->conf.Vcc = conf.Vcc; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); while (1) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); if (pcmcia_get_tuple_data(handle, &tuple) != 0 || pcmcia_parse_tuple(handle, &tuple, &parse) != 0) goto next_entry; if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; } if (cfg->index == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 != conf.Vcc) goto next_entry; } if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp1 = link->conf.Vpp2 = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* we need an interrupt */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; /* IO window settings */ link->io.NumPorts1 = link->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; if (pcmcia_request_io(link->handle, &link->io) != 0) goto next_entry; } break; next_entry: if (link->io.NumPorts1) pcmcia_release_io(link->handle, &link->io); last_ret = pcmcia_get_next_tuple(handle, &tuple); } /* require an IRQ and two registers */ if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) goto cs_failed; if (link->conf.Attributes & CONF_ENABLE_IRQ) CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); else goto cs_failed; CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf)); sprintf(dev->node.dev_name, driver_name); dev->node.major = dev->node.minor = 0; link->dev = &dev->node; 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); printk(", irq %d", link->irq.AssignedIRQ); printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) < 0) { cs_failed: printk("sl811_cs_config failed\n"); cs_error(link->handle, last_fn, last_ret); sl811_cs_release(link); link->state &= ~DEV_CONFIG_PENDING; } }