Loading drivers/net/pcmcia/axnet_cs.c +30 −41 Original line number Diff line number Diff line Loading @@ -284,58 +284,47 @@ static int try_io_port(struct pcmcia_device *link) } } static int axnet_configcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { int i; cistpl_io_t *io = &cfg->io; if (cfg->index == 0 || cfg->io.nwin == 0) return -ENODEV; p_dev->conf.ConfigIndex = 0x05; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); p_dev->io.BasePort2 = io->win[1-i].base; p_dev->io.NumPorts2 = io->win[1-i].len; } else { i = p_dev->io.NumPorts2 = 0; } p_dev->io.BasePort1 = io->win[i].base; p_dev->io.NumPorts1 = io->win[i].len; p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) return try_io_port(p_dev); return -ENODEV; } static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, j, last_ret, last_fn; u_short buf[64]; DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); tuple.Attributes = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; link->conf.ConfigIndex = 0x05; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); link->io.BasePort2 = io->win[1-i].base; link->io.NumPorts2 = io->win[1-i].len; } else { i = link->io.NumPorts2 = 0; } link->io.BasePort1 = io->win[i].base; link->io.NumPorts1 = io->win[i].len; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { last_ret = try_io_port(link); if (last_ret == CS_SUCCESS) break; } next_entry: last_ret = pcmcia_get_next_tuple(link, &tuple); } last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); if (last_ret != CS_SUCCESS) { cs_error(link, RequestIO, last_ret); goto failed; Loading drivers/net/pcmcia/pcnet_cs.c +37 −42 Original line number Diff line number Diff line Loading @@ -512,58 +512,53 @@ static int try_io_port(struct pcmcia_device *link) } } static int pcnet_config(struct pcmcia_device *link) static int pcnet_confcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; u_short buf[64]; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); int *has_shmem = priv_data; int i; cistpl_io_t *io = &cfg->io; DEBUG(0, "pcnet_config(0x%p)\n", link); if (cfg->index == 0 || cfg->io.nwin == 0) return -EINVAL; p_dev->conf.ConfigIndex = cfg->index; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); link->io.BasePort2 = io->win[1-i].base; link->io.NumPorts2 = io->win[1-i].len; p_dev->io.BasePort2 = io->win[1-i].base; p_dev->io.NumPorts2 = io->win[1-i].len; } else { i = link->io.NumPorts2 = 0; i = p_dev->io.NumPorts2 = 0; } has_shmem = ((cfg->mem.nwin == 1) && *has_shmem = ((cfg->mem.nwin == 1) && (cfg->mem.win[0].len >= 0x4000)); link->io.BasePort1 = io->win[i].base; link->io.NumPorts1 = io->win[i].len; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { last_ret = try_io_port(link); if (last_ret == CS_SUCCESS) break; } next_entry: last_ret = pcmcia_get_next_tuple(link, &tuple); p_dev->io.BasePort1 = io->win[i].base; p_dev->io.NumPorts1 = io->win[i].len; p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) return try_io_port(p_dev); return 0; } if (last_ret != CS_SUCCESS) { static int pcnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); int last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); DEBUG(0, "pcnet_config(0x%p)\n", link); last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); if (last_ret) { cs_error(link, RequestIO, last_ret); goto failed; } Loading drivers/net/pcmcia/smc91c92_cs.c +33 −63 Original line number Diff line number Diff line Loading @@ -459,28 +459,36 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } static int mhz_mfc_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { int k; p_dev->conf.ConfigIndex = cf->index; p_dev->io.BasePort2 = cf->io.win[0].base; for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; p_dev->io.BasePort1 = k ^ 0x300; if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } return -ENODEV; } static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; tuple_t *tuple; cisparse_t *parse; cistpl_cftable_entry_t *cf; u_char *buf; win_req_t req; memreq_t mem; int i, k; int i; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) return CS_OUT_OF_RESOURCE; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; link->irq.Attributes = Loading @@ -489,27 +497,9 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; tuple->Attributes = tuple->TupleOffset = 0; tuple->TupleData = (cisdata_t *)buf; tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ while (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort2 = cf->io.win[0].base; for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; link->io.BasePort1 = k ^ 0x300; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i == CS_SUCCESS) break; i = next_tuple(link, tuple, parse); } if (i != CS_SUCCESS) if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) goto free_cfg_mem; dev->base_addr = link->io.BasePort1; Loading @@ -533,7 +523,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) free_cfg_mem: kfree(cfg_mem); return i; return -ENODEV; } static int mhz_setup(struct pcmcia_device *link) Loading Loading @@ -660,46 +650,26 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ static int smc_configcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { p_dev->conf.ConfigIndex = cf->index; p_dev->io.BasePort1 = cf->io.win[0].base; p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; return pcmcia_request_io(p_dev, &p_dev->io); } static int smc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; cisparse_t *parse; cistpl_cftable_entry_t *cf; u_char *buf; int i; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) return CS_OUT_OF_RESOURCE; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->Attributes = tuple->TupleOffset = 0; tuple->TupleData = (cisdata_t *)buf; tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; link->io.NumPorts1 = 16; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i == CS_SUCCESS) { 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); if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } if (i == CS_SUCCESS) i = pcmcia_loop_config(link, smc_configcheck, NULL); if (!i) dev->base_addr = link->io.BasePort1; kfree(cfg_mem); return i; } Loading drivers/net/pcmcia/xirc2ps_cs.c +44 −29 Original line number Diff line number Diff line Loading @@ -715,6 +715,45 @@ has_ce2_string(struct pcmcia_device * p_dev) return 0; } static int xirc2ps_config_modem(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { unsigned int ioaddr; if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { p_dev->conf.ConfigIndex = cf->index ; p_dev->io.BasePort2 = cf->io.win[0].base; p_dev->io.BasePort1 = ioaddr; if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } } return -ENODEV; } static int xirc2ps_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { int *pass = priv_data; if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { p_dev->conf.ConfigIndex = cf->index ; p_dev->io.BasePort2 = cf->io.win[0].base; p_dev->io.BasePort1 = p_dev->io.BasePort2 + (*pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } return -ENODEV; } /**************** * xirc2ps_config() is scheduled to run after a CARD_INSERTION event * is received, to configure the PCMCIA socket, and to make the Loading @@ -725,13 +764,12 @@ xirc2ps_config(struct pcmcia_device * link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); unsigned int ioaddr; tuple_t tuple; cisparse_t parse; unsigned int ioaddr; int err, i; u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; cistpl_cftable_entry_t *cf = &parse.cftable_entry; DECLARE_MAC_BUF(mac); local->dingo_ccr = NULL; Loading Loading @@ -846,19 +884,8 @@ xirc2ps_config(struct pcmcia_device * link) /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; for (err = first_tuple(link, &tuple, &parse); !err; err = next_tuple(link, &tuple, &parse)) { if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = ioaddr; if (!(err=pcmcia_request_io(link, &link->io))) if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) goto port_found; } } } } else { link->io.NumPorts1 = 18; /* We do 2 passes here: The first one uses the regular mapping and Loading @@ -866,21 +893,9 @@ xirc2ps_config(struct pcmcia_device * link) * mirrored every 32 bytes. Actually we use a mirrored port for * the Mako if (on the first pass) the COR bit 5 is set. */ for (pass=0; pass < 2; pass++) { tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; for (err = first_tuple(link, &tuple, &parse); !err; err = next_tuple(link, &tuple, &parse)){ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = link->io.BasePort2 + (pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); if (!(err=pcmcia_request_io(link, &link->io))) for (pass=0; pass < 2; pass++) if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) goto port_found; } } } /* if special option: * try to configure as Ethernet only. * .... */ Loading drivers/net/wireless/airo_cs.c +119 −111 Original line number Diff line number Diff line Loading @@ -206,89 +206,63 @@ static void airo_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int airo_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int last_fn, last_ret; u_char buf[64]; struct airo_cs_config_data { cistpl_cftable_entry_t dflt; win_req_t req; memreq_t map; }; dev = link->priv; static int airo_cs_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { struct airo_cs_config_data *cfg_mem = priv_data; DEBUG(0, "airo_config(0x%p)\n", link); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) cfg_mem->dflt = *cfg; /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including voltage, IO window, memory window, and interrupt settings. We make no assumptions about the card to be configured: we use just the information available in the CIS. In an ideal world, this would work for any PCMCIA card, but it requires a complete and accurate CIS. In practice, a driver usually "knows" most of these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &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; if (cfg->index == 0) return -ENODEV; p_dev->conf.ConfigIndex = cfg->index; /* Does this card need audio output? */ if (cfg->flags & CISTPL_CFTABLE_AUDIO) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; p_dev->conf.Attributes |= CONF_ENABLE_SPKR; p_dev->conf.Status = CCSR_AUDIO_ENA; } /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1) p_dev->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_AUTO; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.BasePort1 = io->win[0].base; p_dev->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { link->io.Attributes2 = link->io.Attributes1; link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; p_dev->io.Attributes2 = p_dev->io.Attributes1; p_dev->io.BasePort2 = io->win[1].base; p_dev->io.NumPorts2 = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; if (pcmcia_request_io(p_dev, &p_dev->io) != 0) return -ENODEV; /* Now set up a common memory window, if needed. There is room Loading @@ -301,26 +275,57 @@ static int airo_config(struct pcmcia_device *link) needs to be mapped to virtual space with ioremap() before it is used. */ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; req.AccessSpeed = 0; if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) goto next_entry; if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) { cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem; memreq_t map; cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; cfg_mem->req.Base = mem->win[0].host_addr; cfg_mem->req.Size = mem->win[0].len; cfg_mem->req.AccessSpeed = 0; if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) return -ENODEV; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(p_dev->win, &map) != 0) return -ENODEV; } /* If we got this far, we're cool! */ break; next_entry: CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); return 0; } static int airo_config(struct pcmcia_device *link) { local_info_t *dev; struct airo_cs_config_data *cfg_mem; int last_fn, last_ret; dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); cfg_mem = kzalloc(sizeof(struct airo_cs_config_data), GFP_KERNEL); if (!cfg_mem) return -ENOMEM; /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card * configuration, including voltage, IO window, memory window, * and interrupt settings. * * We make no assumptions about the card to be configured: we * use just the information available in the CIS. In an ideal * world, this would work for any PCMCIA card, but it requires * a complete and accurate CIS. In practice, a driver usually * "knows" most of these things without consulting the CIS, * and most client drivers will only use the CIS to fill in * implementation-defined details. */ last_ret = pcmcia_loop_config(link, airo_cs_config_check, cfg_mem); if (last_ret) goto failed; /* Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the Loading Loading @@ -362,14 +367,17 @@ static int airo_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, cfg_mem->req.Base+cfg_mem->req.Size-1); printk("\n"); kfree(cfg_mem); return 0; cs_failed: cs_error(link, last_fn, last_ret); failed: airo_release(link); kfree(cfg_mem); return -ENODEV; } /* airo_config */ Loading Loading
drivers/net/pcmcia/axnet_cs.c +30 −41 Original line number Diff line number Diff line Loading @@ -284,58 +284,47 @@ static int try_io_port(struct pcmcia_device *link) } } static int axnet_configcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { int i; cistpl_io_t *io = &cfg->io; if (cfg->index == 0 || cfg->io.nwin == 0) return -ENODEV; p_dev->conf.ConfigIndex = 0x05; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); p_dev->io.BasePort2 = io->win[1-i].base; p_dev->io.NumPorts2 = io->win[1-i].len; } else { i = p_dev->io.NumPorts2 = 0; } p_dev->io.BasePort1 = io->win[i].base; p_dev->io.NumPorts1 = io->win[i].len; p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) return try_io_port(p_dev); return -ENODEV; } static int axnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; axnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, j, last_ret, last_fn; u_short buf[64]; DECLARE_MAC_BUF(mac); DEBUG(0, "axnet_config(0x%p)\n", link); tuple.Attributes = 0; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; /* don't trust the CIS on this; Linksys got it wrong */ link->conf.Present = 0x63; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; link->conf.ConfigIndex = 0x05; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); link->io.BasePort2 = io->win[1-i].base; link->io.NumPorts2 = io->win[1-i].len; } else { i = link->io.NumPorts2 = 0; } link->io.BasePort1 = io->win[i].base; link->io.NumPorts1 = io->win[i].len; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { last_ret = try_io_port(link); if (last_ret == CS_SUCCESS) break; } next_entry: last_ret = pcmcia_get_next_tuple(link, &tuple); } last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL); if (last_ret != CS_SUCCESS) { cs_error(link, RequestIO, last_ret); goto failed; Loading
drivers/net/pcmcia/pcnet_cs.c +37 −42 Original line number Diff line number Diff line Loading @@ -512,58 +512,53 @@ static int try_io_port(struct pcmcia_device *link) } } static int pcnet_config(struct pcmcia_device *link) static int pcnet_confcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); tuple_t tuple; cisparse_t parse; int i, last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; u_short buf[64]; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); int *has_shmem = priv_data; int i; cistpl_io_t *io = &cfg->io; DEBUG(0, "pcnet_config(0x%p)\n", link); if (cfg->index == 0 || cfg->io.nwin == 0) return -EINVAL; p_dev->conf.ConfigIndex = cfg->index; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; tuple.Attributes = 0; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (last_ret == CS_SUCCESS) { cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); cistpl_io_t *io = &(parse.cftable_entry.io); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &tuple, &parse) != 0 || cfg->index == 0 || cfg->io.nwin == 0) goto next_entry; link->conf.ConfigIndex = cfg->index; /* For multifunction cards, by convention, we configure the network function with window 0, and serial with window 1 */ if (io->nwin > 1) { i = (io->win[1].len > io->win[0].len); link->io.BasePort2 = io->win[1-i].base; link->io.NumPorts2 = io->win[1-i].len; p_dev->io.BasePort2 = io->win[1-i].base; p_dev->io.NumPorts2 = io->win[1-i].len; } else { i = link->io.NumPorts2 = 0; i = p_dev->io.NumPorts2 = 0; } has_shmem = ((cfg->mem.nwin == 1) && *has_shmem = ((cfg->mem.nwin == 1) && (cfg->mem.win[0].len >= 0x4000)); link->io.BasePort1 = io->win[i].base; link->io.NumPorts1 = io->win[i].len; link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (link->io.NumPorts1 + link->io.NumPorts2 >= 32) { last_ret = try_io_port(link); if (last_ret == CS_SUCCESS) break; } next_entry: last_ret = pcmcia_get_next_tuple(link, &tuple); p_dev->io.BasePort1 = io->win[i].base; p_dev->io.NumPorts1 = io->win[i].len; p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32) return try_io_port(p_dev); return 0; } if (last_ret != CS_SUCCESS) { static int pcnet_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; pcnet_dev_t *info = PRIV(dev); int last_ret, last_fn, start_pg, stop_pg, cm_offset; int has_shmem = 0; hw_info_t *local_hw_info; DECLARE_MAC_BUF(mac); DEBUG(0, "pcnet_config(0x%p)\n", link); last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem); if (last_ret) { cs_error(link, RequestIO, last_ret); goto failed; } Loading
drivers/net/pcmcia/smc91c92_cs.c +33 −63 Original line number Diff line number Diff line Loading @@ -459,28 +459,36 @@ static int mhz_3288_power(struct pcmcia_device *link) return 0; } static int mhz_mfc_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { int k; p_dev->conf.ConfigIndex = cf->index; p_dev->io.BasePort2 = cf->io.win[0].base; for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; p_dev->io.BasePort1 = k ^ 0x300; if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } return -ENODEV; } static int mhz_mfc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_private *smc = netdev_priv(dev); struct smc_cfg_mem *cfg_mem; tuple_t *tuple; cisparse_t *parse; cistpl_cftable_entry_t *cf; u_char *buf; win_req_t req; memreq_t mem; int i, k; int i; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) return CS_OUT_OF_RESOURCE; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; link->irq.Attributes = Loading @@ -489,27 +497,9 @@ static int mhz_mfc_config(struct pcmcia_device *link) link->io.Attributes2 = IO_DATA_PATH_WIDTH_8; link->io.NumPorts2 = 8; tuple->Attributes = tuple->TupleOffset = 0; tuple->TupleData = (cisdata_t *)buf; tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, tuple, parse); /* The Megahertz combo cards have modem-like CIS entries, so we have to explicitly try a bunch of port combinations. */ while (i == CS_SUCCESS) { link->conf.ConfigIndex = cf->index; link->io.BasePort2 = cf->io.win[0].base; for (k = 0; k < 0x400; k += 0x10) { if (k & 0x80) continue; link->io.BasePort1 = k ^ 0x300; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } if (i == CS_SUCCESS) break; i = next_tuple(link, tuple, parse); } if (i != CS_SUCCESS) if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL)) goto free_cfg_mem; dev->base_addr = link->io.BasePort1; Loading @@ -533,7 +523,7 @@ static int mhz_mfc_config(struct pcmcia_device *link) free_cfg_mem: kfree(cfg_mem); return i; return -ENODEV; } static int mhz_setup(struct pcmcia_device *link) Loading Loading @@ -660,46 +650,26 @@ static int mot_setup(struct pcmcia_device *link) /*====================================================================*/ static int smc_configcheck(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { p_dev->conf.ConfigIndex = cf->index; p_dev->io.BasePort1 = cf->io.win[0].base; p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK; return pcmcia_request_io(p_dev, &p_dev->io); } static int smc_config(struct pcmcia_device *link) { struct net_device *dev = link->priv; struct smc_cfg_mem *cfg_mem; tuple_t *tuple; cisparse_t *parse; cistpl_cftable_entry_t *cf; u_char *buf; int i; cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL); if (!cfg_mem) return CS_OUT_OF_RESOURCE; tuple = &cfg_mem->tuple; parse = &cfg_mem->parse; cf = &parse->cftable_entry; buf = cfg_mem->buf; tuple->Attributes = tuple->TupleOffset = 0; tuple->TupleData = (cisdata_t *)buf; tuple->TupleDataMax = 255; tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; link->io.NumPorts1 = 16; i = first_tuple(link, tuple, parse); while (i != CS_NO_MORE_ITEMS) { if (i == CS_SUCCESS) { 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); if (i == CS_SUCCESS) break; } i = next_tuple(link, tuple, parse); } if (i == CS_SUCCESS) i = pcmcia_loop_config(link, smc_configcheck, NULL); if (!i) dev->base_addr = link->io.BasePort1; kfree(cfg_mem); return i; } Loading
drivers/net/pcmcia/xirc2ps_cs.c +44 −29 Original line number Diff line number Diff line Loading @@ -715,6 +715,45 @@ has_ce2_string(struct pcmcia_device * p_dev) return 0; } static int xirc2ps_config_modem(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { unsigned int ioaddr; if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { p_dev->conf.ConfigIndex = cf->index ; p_dev->io.BasePort2 = cf->io.win[0].base; p_dev->io.BasePort1 = ioaddr; if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } } return -ENODEV; } static int xirc2ps_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cf, void *priv_data) { int *pass = priv_data; if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { p_dev->conf.ConfigIndex = cf->index ; p_dev->io.BasePort2 = cf->io.win[0].base; p_dev->io.BasePort1 = p_dev->io.BasePort2 + (*pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); if (!pcmcia_request_io(p_dev, &p_dev->io)) return 0; } return -ENODEV; } /**************** * xirc2ps_config() is scheduled to run after a CARD_INSERTION event * is received, to configure the PCMCIA socket, and to make the Loading @@ -725,13 +764,12 @@ xirc2ps_config(struct pcmcia_device * link) { struct net_device *dev = link->priv; local_info_t *local = netdev_priv(dev); unsigned int ioaddr; tuple_t tuple; cisparse_t parse; unsigned int ioaddr; int err, i; u_char buf[64]; cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data; cistpl_cftable_entry_t *cf = &parse.cftable_entry; DECLARE_MAC_BUF(mac); local->dingo_ccr = NULL; Loading Loading @@ -846,19 +884,8 @@ xirc2ps_config(struct pcmcia_device * link) /* Take the Modem IO port from the CIS and scan for a free * Ethernet port */ link->io.NumPorts1 = 16; /* no Mako stuff anymore */ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; for (err = first_tuple(link, &tuple, &parse); !err; err = next_tuple(link, &tuple, &parse)) { if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) { for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) { link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = ioaddr; if (!(err=pcmcia_request_io(link, &link->io))) if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL)) goto port_found; } } } } else { link->io.NumPorts1 = 18; /* We do 2 passes here: The first one uses the regular mapping and Loading @@ -866,21 +893,9 @@ xirc2ps_config(struct pcmcia_device * link) * mirrored every 32 bytes. Actually we use a mirrored port for * the Mako if (on the first pass) the COR bit 5 is set. */ for (pass=0; pass < 2; pass++) { tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; for (err = first_tuple(link, &tuple, &parse); !err; err = next_tuple(link, &tuple, &parse)){ if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8){ link->conf.ConfigIndex = cf->index ; link->io.BasePort2 = cf->io.win[0].base; link->io.BasePort1 = link->io.BasePort2 + (pass ? (cf->index & 0x20 ? -24:8) : (cf->index & 0x20 ? 8:-24)); if (!(err=pcmcia_request_io(link, &link->io))) for (pass=0; pass < 2; pass++) if (!pcmcia_loop_config(link, xirc2ps_config_check, &pass)) goto port_found; } } } /* if special option: * try to configure as Ethernet only. * .... */ Loading
drivers/net/wireless/airo_cs.c +119 −111 Original line number Diff line number Diff line Loading @@ -206,89 +206,63 @@ static void airo_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) static int airo_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int last_fn, last_ret; u_char buf[64]; struct airo_cs_config_data { cistpl_cftable_entry_t dflt; win_req_t req; memreq_t map; }; dev = link->priv; static int airo_cs_config_check(struct pcmcia_device *p_dev, cistpl_cftable_entry_t *cfg, void *priv_data) { struct airo_cs_config_data *cfg_mem = priv_data; DEBUG(0, "airo_config(0x%p)\n", link); if (cfg->flags & CISTPL_CFTABLE_DEFAULT) cfg_mem->dflt = *cfg; /* In this loop, we scan the CIS for configuration table entries, each of which describes a valid card configuration, including voltage, IO window, memory window, and interrupt settings. We make no assumptions about the card to be configured: we use just the information available in the CIS. In an ideal world, this would work for any PCMCIA card, but it requires a complete and accurate CIS. In practice, a driver usually "knows" most of these things without consulting the CIS, and most client drivers will only use the CIS to fill in implementation-defined details. */ tuple.Attributes = 0; tuple.TupleData = buf; tuple.TupleDataMax = sizeof(buf); tuple.TupleOffset = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple)); while (1) { cistpl_cftable_entry_t dflt = { 0 }; cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); if (pcmcia_get_tuple_data(link, &tuple) != 0 || pcmcia_parse_tuple(link, &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; if (cfg->index == 0) return -ENODEV; p_dev->conf.ConfigIndex = cfg->index; /* Does this card need audio output? */ if (cfg->flags & CISTPL_CFTABLE_AUDIO) { link->conf.Attributes |= CONF_ENABLE_SPKR; link->conf.Status = CCSR_AUDIO_ENA; p_dev->conf.Attributes |= CONF_ENABLE_SPKR; p_dev->conf.Status = CCSR_AUDIO_ENA; } /* Use power settings for Vcc and Vpp if present */ /* Note that the CIS values need to be rescaled */ if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; else if (cfg_mem->dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) p_dev->conf.Vpp = cfg_mem->dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; /* Do we need to allocate an interrupt? */ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) link->conf.Attributes |= CONF_ENABLE_IRQ; if (cfg->irq.IRQInfo1 || cfg_mem->dflt.irq.IRQInfo1) p_dev->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_AUTO; p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0; if ((cfg->io.nwin > 0) || (cfg_mem->dflt.io.nwin > 0)) { cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &cfg_mem->dflt.io; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; if (!(io->flags & CISTPL_IO_8BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16; if (!(io->flags & CISTPL_IO_16BIT)) link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; link->io.BasePort1 = io->win[0].base; link->io.NumPorts1 = io->win[0].len; p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8; p_dev->io.BasePort1 = io->win[0].base; p_dev->io.NumPorts1 = io->win[0].len; if (io->nwin > 1) { link->io.Attributes2 = link->io.Attributes1; link->io.BasePort2 = io->win[1].base; link->io.NumPorts2 = io->win[1].len; p_dev->io.Attributes2 = p_dev->io.Attributes1; p_dev->io.BasePort2 = io->win[1].base; p_dev->io.NumPorts2 = io->win[1].len; } } /* This reserves IO space but doesn't actually enable it */ if (pcmcia_request_io(link, &link->io) != 0) goto next_entry; if (pcmcia_request_io(p_dev, &p_dev->io) != 0) return -ENODEV; /* Now set up a common memory window, if needed. There is room Loading @@ -301,26 +275,57 @@ static int airo_config(struct pcmcia_device *link) needs to be mapped to virtual space with ioremap() before it is used. */ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; req.Base = mem->win[0].host_addr; req.Size = mem->win[0].len; req.AccessSpeed = 0; if (pcmcia_request_window(&link, &req, &link->win) != 0) goto next_entry; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(link->win, &map) != 0) goto next_entry; if ((cfg->mem.nwin > 0) || (cfg_mem->dflt.mem.nwin > 0)) { cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &cfg_mem->dflt.mem; memreq_t map; cfg_mem->req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM; cfg_mem->req.Base = mem->win[0].host_addr; cfg_mem->req.Size = mem->win[0].len; cfg_mem->req.AccessSpeed = 0; if (pcmcia_request_window(&p_dev, &cfg_mem->req, &p_dev->win) != 0) return -ENODEV; map.Page = 0; map.CardOffset = mem->win[0].card_addr; if (pcmcia_map_mem_page(p_dev->win, &map) != 0) return -ENODEV; } /* If we got this far, we're cool! */ break; next_entry: CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple)); return 0; } static int airo_config(struct pcmcia_device *link) { local_info_t *dev; struct airo_cs_config_data *cfg_mem; int last_fn, last_ret; dev = link->priv; DEBUG(0, "airo_config(0x%p)\n", link); cfg_mem = kzalloc(sizeof(struct airo_cs_config_data), GFP_KERNEL); if (!cfg_mem) return -ENOMEM; /* * In this loop, we scan the CIS for configuration table * entries, each of which describes a valid card * configuration, including voltage, IO window, memory window, * and interrupt settings. * * We make no assumptions about the card to be configured: we * use just the information available in the CIS. In an ideal * world, this would work for any PCMCIA card, but it requires * a complete and accurate CIS. In practice, a driver usually * "knows" most of these things without consulting the CIS, * and most client drivers will only use the CIS to fill in * implementation-defined details. */ last_ret = pcmcia_loop_config(link, airo_cs_config_check, cfg_mem); if (last_ret) goto failed; /* Allocate an interrupt line. Note that this does not assign a handler to the interrupt, unless the 'Handler' member of the Loading Loading @@ -362,14 +367,17 @@ static int airo_config(struct pcmcia_device *link) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); if (link->win) printk(", mem 0x%06lx-0x%06lx", req.Base, req.Base+req.Size-1); printk(", mem 0x%06lx-0x%06lx", cfg_mem->req.Base, cfg_mem->req.Base+cfg_mem->req.Size-1); printk("\n"); kfree(cfg_mem); return 0; cs_failed: cs_error(link, last_fn, last_ret); failed: airo_release(link); kfree(cfg_mem); return -ENODEV; } /* airo_config */ Loading