Ejemplo n.º 1
0
static hw_info_t *get_hwinfo(struct pcmcia_device *link)
{
    struct net_device *dev = link->priv;
    u_char __iomem *base, *virt;
    int i, j;

    /* Allocate a small memory window */
    link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
    link->resource[2]->start = 0; link->resource[2]->end = 0;
    i = pcmcia_request_window(link, link->resource[2], 0);
    if (i != 0)
	return NULL;

    virt = ioremap(link->resource[2]->start,
	    resource_size(link->resource[2]));
    for (i = 0; i < NR_INFO; i++) {
	pcmcia_map_mem_page(link, link->resource[2],
		hw_info[i].offset & ~(resource_size(link->resource[2])-1));
	base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)];
	if ((readb(base+0) == hw_info[i].a0) &&
	    (readb(base+2) == hw_info[i].a1) &&
	    (readb(base+4) == hw_info[i].a2)) {
		for (j = 0; j < 6; j++)
		    dev->dev_addr[j] = readb(base + (j<<1));
		break;
	}
    }

    iounmap(virt);
    j = pcmcia_release_window(link, link->resource[2]);
    return (i < NR_INFO) ? hw_info+i : NULL;
} /* get_hwinfo */
Ejemplo n.º 2
0
static int b43_pcmcia_probe(struct pcmcia_device *dev)
{
	struct ssb_bus *ssb;
	int err = -ENOMEM;
	int res = 0;

	ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
	if (!ssb)
		goto out_error;

	err = -ENODEV;

	dev->config_flags |= CONF_ENABLE_IRQ;

	dev->resource[2]->flags |=  WIN_ENABLE | WIN_DATA_WIDTH_16 |
			 WIN_USE_WAIT;
	dev->resource[2]->start = 0;
	dev->resource[2]->end = SSB_CORE_SIZE;
	res = pcmcia_request_window(dev, dev->resource[2], 250);
	if (res != 0)
		goto err_kfree_ssb;

	res = pcmcia_map_mem_page(dev, dev->resource[2], 0);
	if (res != 0)
		goto err_disable;

	if (!dev->irq)
		goto err_disable;

	res = pcmcia_enable_device(dev);
	if (res != 0)
		goto err_disable;

	err = ssb_bus_pcmciabus_register(ssb, dev, dev->resource[2]->start);
	if (err)
		goto err_disable;
	dev->priv = ssb;

	return 0;

err_disable:
	pcmcia_disable_device(dev);
err_kfree_ssb:
	kfree(ssb);
out_error:
	printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
	       res, err);
	return err;
}
Ejemplo n.º 3
0
static int __devinit ems_pcmcia_probe(struct pcmcia_device *dev)
{
	int csval;

	/*                              */
	dev->config_flags |= CONF_ENABLE_IRQ;
	dev->config_index = 1;
	dev->config_regs = PRESENT_OPTION;

	/*                                            */
	dev->resource[0]->end = 16;
	dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
	dev->resource[1]->end = 16;
	dev->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
	dev->io_lines = 5;

	/*                          */
	dev->resource[2]->flags =
		(WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_CM | WIN_ENABLE);
	dev->resource[2]->start = dev->resource[2]->end = 0;

	csval = pcmcia_request_window(dev, dev->resource[2], 0);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_request_window failed (err=%d)\n",
			csval);
		return 0;
	}

	csval = pcmcia_map_mem_page(dev, dev->resource[2], dev->config_base);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_map_mem_page failed (err=%d)\n",
			csval);
		return 0;
	}

	csval = pcmcia_enable_device(dev);
	if (csval) {
		dev_err(&dev->dev, "pcmcia_enable_device failed (err=%d)\n",
			csval);
		return 0;
	}

	ems_pcmcia_add_card(dev, dev->resource[2]->start);
	return 0;
}
Ejemplo n.º 4
0
/*
 * pcmcia check
 */
static int softingcs_probe_config(struct pcmcia_device *pcmcia, void *priv_data)
{
	struct softing_platform_data *pdat = priv_data;
	struct resource *pres;
	int memspeed = 0;

	WARN_ON(!pdat);
	pres = pcmcia->resource[PCMCIA_IOMEM_0];
	if (resource_size(pres) < 0x1000)
		return -ERANGE;

	pres->flags |= WIN_MEMORY_TYPE_CM | WIN_ENABLE;
	if (pdat->generation < 2) {
		pres->flags |= WIN_USE_WAIT | WIN_DATA_WIDTH_8;
		memspeed = 3;
	} else {
		pres->flags |= WIN_DATA_WIDTH_16;
	}
	return pcmcia_request_window(pcmcia, pres, memspeed);
}
Ejemplo n.º 5
0
int MTDHelperEntry(int func, void *a1, void *a2)
{
    switch (func) {
    case MTDRequestWindow:
    {
	window_handle_t w;
        int ret = pcmcia_request_window(a1, a2, &w);
        (window_handle_t *)a1 = w;
	return  ret;
    }
        break;
    case MTDReleaseWindow:
	return pcmcia_release_window(a1);
    case MTDModifyWindow:
	return mtd_modify_window(a1, a2); break;
    case MTDSetVpp:
	return mtd_set_vpp(a1, a2); break;
    case MTDRDYMask:
	return mtd_rdy_mask(a1, a2); break;
    default:
	return CS_UNSUPPORTED_FUNCTION; break;
    }
} /* MTDHelperEntry */
Ejemplo n.º 6
0
static void labpc_config(struct pcmcia_device *link)
{
	struct local_info_t *dev = link->priv;
	tuple_t tuple;
	cisparse_t parse;
	int last_ret;
	u_char buf[64];
	win_req_t req;
	memreq_t map;
	cistpl_cftable_entry_t dflt = { 0 };

	DEBUG(0, "labpc_config(0x%p)\n", link);

	/*
	   This reads the card's CONFIG tuple to find its configuration
	   registers.
	 */
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret) {
		cs_error(link, GetFirstTuple, last_ret);
		goto cs_failed;
	}

	last_ret = pcmcia_get_tuple_data(link, &tuple);
	if (last_ret) {
		cs_error(link, GetTupleData, last_ret);
		goto cs_failed;
	}

	last_ret = pcmcia_parse_tuple(&tuple, &parse);
	if (last_ret) {
		cs_error(link, ParseTuple, last_ret);
		goto cs_failed;
	}
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/*
	   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.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	last_ret = pcmcia_get_first_tuple(link, &tuple);
	if (last_ret) {
		cs_error(link, GetFirstTuple, last_ret);
		goto cs_failed;
	}
	while (1) {
		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
		if (pcmcia_get_tuple_data(link, &tuple))
			goto next_entry;
		if (pcmcia_parse_tuple(&tuple, &parse))
			goto next_entry;

		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
			dflt = *cfg;
		if (cfg->index == 0)
			goto next_entry;
		link->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;
		}

		/* Do we need to allocate 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 (io->nwin > 1) {
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->io.NumPorts2 = io->win[1].len;
			}
			/* This reserves IO space but doesn't actually enable it */
			if (pcmcia_request_io(link, &link->io))
				goto next_entry;
		}

		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.Attributes |= WIN_ENABLE;
			req.Base = mem->win[0].host_addr;
			req.Size = mem->win[0].len;
			if (req.Size < 0x1000)
				req.Size = 0x1000;
			req.AccessSpeed = 0;
			link->win = (window_handle_t) link;
			if (pcmcia_request_window(&link, &req, &link->win))
				goto next_entry;
			map.Page = 0;
			map.CardOffset = mem->win[0].card_addr;
			if (pcmcia_map_mem_page(link->win, &map))
				goto next_entry;
		}
		/* If we got this far, we're cool! */
		break;

	      next_entry:
		last_ret = pcmcia_get_next_tuple(link, &tuple);
		if (last_ret) {
			cs_error(link, GetNextTuple, last_ret);
			goto cs_failed;
		}
	}

	/*
	   Allocate an interrupt line.  Note that this does not assign a
	   handler to the interrupt, unless the 'Handler' member of the
	   irq structure is initialized.
	 */
	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
		last_ret = pcmcia_request_irq(link, &link->irq);
		if (last_ret) {
			cs_error(link, RequestIRQ, last_ret);
			goto cs_failed;
		}
	}

	/*
	   This actually configures the PCMCIA socket -- setting up
	   the I/O windows and the interrupt mapping, and putting the
	   card and host interface into "Memory and IO" mode.
	 */
	last_ret = pcmcia_request_configuration(link, &link->conf);
	if (last_ret) {
		cs_error(link, RequestConfiguration, last_ret);
		goto cs_failed;
	}

	/*
	   At this point, the dev_node_t structure(s) need to be
	   initialized and arranged in a linked list at link->dev.
	 */
	sprintf(dev->node.dev_name, "daqcard-1200");
	dev->node.major = dev->node.minor = 0;
	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);
	if (link->win)
		printk(", mem 0x%06lx-0x%06lx", req.Base,
			req.Base + req.Size - 1);
	printk("\n");

	return;

      cs_failed:
	labpc_release(link);

}				/* labpc_config */
Ejemplo n.º 7
0
Archivo: main.c Proyecto: avagin/linux
static int ipwireless_probe(struct pcmcia_device *p_dev, void *priv_data)
{
	struct ipw_dev *ipw = priv_data;
	int ret;

	p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;

	/* 0x40 causes it to generate level mode interrupts. */
	/* 0x04 enables IREQ pin. */
	p_dev->config_index |= 0x44;
	p_dev->io_lines = 16;
	ret = pcmcia_request_io(p_dev);
	if (ret)
		return ret;

	if (!request_region(p_dev->resource[0]->start,
			    resource_size(p_dev->resource[0]),
			    IPWIRELESS_PCCARD_NAME)) {
		ret = -EBUSY;
		goto exit;
	}

	p_dev->resource[2]->flags |=
		WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;

	ret = pcmcia_request_window(p_dev, p_dev->resource[2], 0);
	if (ret != 0)
		goto exit1;

	ret = pcmcia_map_mem_page(p_dev, p_dev->resource[2], p_dev->card_addr);
	if (ret != 0)
		goto exit1;

	ipw->is_v2_card = resource_size(p_dev->resource[2]) == 0x100;

	ipw->common_memory = ioremap(p_dev->resource[2]->start,
				resource_size(p_dev->resource[2]));
	if (!ipw->common_memory) {
		ret = -ENOMEM;
		goto exit1;
	}
	if (!request_mem_region(p_dev->resource[2]->start,
				resource_size(p_dev->resource[2]),
				IPWIRELESS_PCCARD_NAME)) {
		ret = -EBUSY;
		goto exit2;
	}

	p_dev->resource[3]->flags |= WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM |
					WIN_ENABLE;
	p_dev->resource[3]->end = 0; /* this used to be 0x1000 */
	ret = pcmcia_request_window(p_dev, p_dev->resource[3], 0);
	if (ret != 0)
		goto exit3;

	ret = pcmcia_map_mem_page(p_dev, p_dev->resource[3], 0);
	if (ret != 0)
		goto exit3;

	ipw->attr_memory = ioremap(p_dev->resource[3]->start,
				resource_size(p_dev->resource[3]));
	if (!ipw->attr_memory) {
		ret = -ENOMEM;
		goto exit3;
	}
	if (!request_mem_region(p_dev->resource[3]->start,
				resource_size(p_dev->resource[3]),
				IPWIRELESS_PCCARD_NAME)) {
		ret = -EBUSY;
		goto exit4;
	}

	return 0;

exit4:
	iounmap(ipw->attr_memory);
exit3:
	release_mem_region(p_dev->resource[2]->start,
			resource_size(p_dev->resource[2]));
exit2:
	iounmap(ipw->common_memory);
exit1:
	release_region(p_dev->resource[0]->start,
		       resource_size(p_dev->resource[0]));
exit:
	pcmcia_disable_device(p_dev);
	return ret;
}
Ejemplo n.º 8
0
static void pcmciamtd_config(dev_link_t *link)
{
	struct pcmciamtd_dev *dev = link->priv;
	struct mtd_info *mtd = NULL;
	cs_status_t status;
	win_req_t req;
	int last_ret = 0, last_fn = 0;
	int ret;
	int i;
	config_info_t t;
	static char *probes[] = { "jedec_probe", "cfi_probe" };
	cisinfo_t cisinfo;
	int new_name = 0;

	DEBUG(3, "link=0x%p", link);

	/* Configure card */
	link->state |= DEV_CONFIG;

	DEBUG(2, "Validating CIS");
	ret = pcmcia_validate_cis(link->handle, &cisinfo);
	if(ret != CS_SUCCESS) {
		cs_error(link->handle, GetTupleData, ret);
	} else {
		DEBUG(2, "ValidateCIS found %d chains", cisinfo.Chains);
	}

	card_settings(dev, link, &new_name);

	dev->pcmcia_map.phys = NO_XIP;
	dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
	dev->pcmcia_map.copy_to = pcmcia_copy_to_remap;
	if (dev->pcmcia_map.bankwidth == 1) {
		dev->pcmcia_map.read = pcmcia_read8_remap;
		dev->pcmcia_map.write = pcmcia_write8_remap;
	} else {
		dev->pcmcia_map.read = pcmcia_read16_remap;
		dev->pcmcia_map.write = pcmcia_write16_remap;
	}
	if(setvpp == 1)
		dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;

	/* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
	   that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the
	   whole card - otherwise we try smaller windows until we succeed */

	req.Attributes =  WIN_MEMORY_TYPE_CM | WIN_ENABLE;
	req.Attributes |= (dev->pcmcia_map.bankwidth == 1) ? WIN_DATA_WIDTH_8 : WIN_DATA_WIDTH_16;
	req.Base = 0;
	req.AccessSpeed = mem_speed;
	link->win = (window_handle_t)link->handle;
	req.Size = (force_size) ? force_size << 20 : MAX_PCMCIA_ADDR;
	dev->win_size = 0;

	do {
		int ret;
		DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
		      req.Size >> 10, req.AccessSpeed);
		ret = pcmcia_request_window(&link->handle, &req, &link->win);
		DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
		if(ret) {
			req.Size >>= 1;
		} else {
			DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
			dev->win_size = req.Size;
			break;
		}
	} while(req.Size >= 0x1000);
Ejemplo n.º 9
0
static int airo_cs_config_check(struct pcmcia_device *p_dev,
				cistpl_cftable_entry_t *cfg,
				cistpl_cftable_entry_t *dflt,
				unsigned int vcc,
				void *priv_data)
{
	win_req_t *req = priv_data;

	if (cfg->index == 0)
		return -ENODEV;

	/* Does this card need audio output? */
	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
		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))
		p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
	else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;

	/* Do we need to allocate an interrupt? */
	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;

	/* IO window settings */
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
			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) {
			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(p_dev, &p_dev->io) != 0)
		return -ENODEV;

	/*
	  Now set up a common memory window, if needed.  There is room
	  in the struct pcmcia_device structure for one memory window handle,
	  but if the base addresses need to be saved, or if multiple
	  windows are needed, the info should go in the private data
	  structure for this device.

	  Note that the memory window base is a physical address, and
	  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;
		memreq_t map;
		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(&p_dev, 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! */
	return 0;
}
Ejemplo n.º 10
0
static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
{
    struct ssb_bus *ssb;
    win_req_t win;
    memreq_t mem;
    tuple_t tuple;
    cisparse_t parse;
    int err = -ENOMEM;
    int res = 0;
    unsigned char buf[64];

    ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
    if (!ssb)
        goto out_error;

    err = -ENODEV;
    tuple.DesiredTuple = CISTPL_CONFIG;
    tuple.Attributes = 0;
    tuple.TupleData = buf;
    tuple.TupleDataMax = sizeof(buf);
    tuple.TupleOffset = 0;

    res = pcmcia_get_first_tuple(dev, &tuple);
    if (res != CS_SUCCESS)
        goto err_kfree_ssb;
    res = pcmcia_get_tuple_data(dev, &tuple);
    if (res != CS_SUCCESS)
        goto err_kfree_ssb;
    res = pcmcia_parse_tuple(dev, &tuple, &parse);
    if (res != CS_SUCCESS)
        goto err_kfree_ssb;

    dev->conf.ConfigBase = parse.config.base;
    dev->conf.Present = parse.config.rmask[0];

    dev->io.BasePort2 = 0;
    dev->io.NumPorts2 = 0;
    dev->io.Attributes2 = 0;

    win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
                     WIN_ENABLE | WIN_DATA_WIDTH_16 |
                     WIN_USE_WAIT;
    win.Base = 0;
    win.Size = SSB_CORE_SIZE;
    win.AccessSpeed = 250;
    res = pcmcia_request_window(&dev, &win, &dev->win);
    if (res != CS_SUCCESS)
        goto err_kfree_ssb;

    mem.CardOffset = 0;
    mem.Page = 0;
    res = pcmcia_map_mem_page(dev->win, &mem);
    if (res != CS_SUCCESS)
        goto err_disable;

    dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED;
    dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID;
    dev->irq.Handler = NULL; /* The handler is registered later. */
    dev->irq.Instance = NULL;
    res = pcmcia_request_irq(dev, &dev->irq);
    if (res != CS_SUCCESS)
        goto err_disable;

    res = pcmcia_request_configuration(dev, &dev->conf);
    if (res != CS_SUCCESS)
        goto err_disable;

    err = ssb_bus_pcmciabus_register(ssb, dev, win.Base);
    if (err)
        goto err_disable;
    dev->priv = ssb;

    return 0;

err_disable:
    pcmcia_disable_device(dev);
err_kfree_ssb:
    kfree(ssb);
out_error:
    printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n",
           res, err);
    return err;
}
Ejemplo n.º 11
0
static int config_ipwireless(struct ipw_dev *ipw)
{
	struct pcmcia_device *link = ipw->link;
	int ret;
	tuple_t tuple;
	unsigned short buf[64];
	cisparse_t parse;
	unsigned short cor_value;
	memreq_t memreq_attr_memory;
	memreq_t memreq_common_memory;

	ipw->is_v2_card = 0;

	tuple.Attributes = 0;
	tuple.TupleData = (cisdata_t *) buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;

	tuple.DesiredTuple = RETURN_FIRST_TUPLE;

	ret = pcmcia_get_first_tuple(link, &tuple);

	while (ret == 0) {
		ret = pcmcia_get_tuple_data(link, &tuple);

		if (ret != 0) {
			cs_error(link, GetTupleData, ret);
			goto exit0;
		}
		ret = pcmcia_get_next_tuple(link, &tuple);
	}

	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetFirstTuple, ret);
		goto exit0;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}

	ret = pcmcia_parse_tuple(&tuple, &parse);

	if (ret != 0) {
		cs_error(link, ParseTuple, ret);
		goto exit0;
	}

	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
	link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
	link->io.IOAddrLines = 16;

	link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;

	/* 0x40 causes it to generate level mode interrupts. */
	/* 0x04 enables IREQ pin. */
	cor_value = parse.cftable_entry.index | 0x44;
	link->conf.ConfigIndex = cor_value;

	/* IRQ and I/O settings */
	tuple.DesiredTuple = CISTPL_CONFIG;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetFirstTuple, ret);
		goto exit0;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}

	ret = pcmcia_parse_tuple(&tuple, &parse);

	if (ret != 0) {
		cs_error(link, GetTupleData, ret);
		goto exit0;
	}
	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];
	link->conf.IntType = INT_MEMORY_AND_IO;

	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
	link->irq.Handler = ipwireless_interrupt;
	link->irq.Instance = ipw->hardware;

	ret = pcmcia_request_io(link, &link->io);

	if (ret != 0) {
		cs_error(link, RequestIO, ret);
		goto exit0;
	}

	request_region(link->io.BasePort1, link->io.NumPorts1,
			IPWIRELESS_PCCARD_NAME);

	/* memory settings */

	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;

	ret = pcmcia_get_first_tuple(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetFirstTuple, ret);
		goto exit1;
	}

	ret = pcmcia_get_tuple_data(link, &tuple);

	if (ret != 0) {
		cs_error(link, GetTupleData, ret);
		goto exit1;
	}

	ret = pcmcia_parse_tuple(&tuple, &parse);

	if (ret != 0) {
		cs_error(link, ParseTuple, ret);
		goto exit1;
	}

	if (parse.cftable_entry.mem.nwin > 0) {
		ipw->request_common_memory.Attributes =
			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
		ipw->request_common_memory.Base =
			parse.cftable_entry.mem.win[0].host_addr;
		ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
		if (ipw->request_common_memory.Size < 0x1000)
			ipw->request_common_memory.Size = 0x1000;
		ipw->request_common_memory.AccessSpeed = 0;

		ret = pcmcia_request_window(&link, &ipw->request_common_memory,
				&ipw->handle_common_memory);

		if (ret != 0) {
			cs_error(link, RequestWindow, ret);
			goto exit1;
		}

		memreq_common_memory.CardOffset =
			parse.cftable_entry.mem.win[0].card_addr;
		memreq_common_memory.Page = 0;

		ret = pcmcia_map_mem_page(ipw->handle_common_memory,
				&memreq_common_memory);

		if (ret != 0) {
			cs_error(link, MapMemPage, ret);
			goto exit1;
		}

		ipw->is_v2_card =
			parse.cftable_entry.mem.win[0].len == 0x100;

		ipw->common_memory = ioremap(ipw->request_common_memory.Base,
				ipw->request_common_memory.Size);
		request_mem_region(ipw->request_common_memory.Base,
				ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);

		ipw->request_attr_memory.Attributes =
			WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
		ipw->request_attr_memory.Base = 0;
		ipw->request_attr_memory.Size = 0;	/* this used to be 0x1000 */
		ipw->request_attr_memory.AccessSpeed = 0;

		ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
				&ipw->handle_attr_memory);

		if (ret != 0) {
			cs_error(link, RequestWindow, ret);
			goto exit2;
		}

		memreq_attr_memory.CardOffset = 0;
		memreq_attr_memory.Page = 0;

		ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
				&memreq_attr_memory);

		if (ret != 0) {
			cs_error(link, MapMemPage, ret);
			goto exit2;
		}

		ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
				ipw->request_attr_memory.Size);
		request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
				IPWIRELESS_PCCARD_NAME);
	}

	INIT_WORK(&ipw->work_reboot, signalled_reboot_work);

	ipwireless_init_hardware_v1(ipw->hardware, link->io.BasePort1,
				    ipw->attr_memory, ipw->common_memory,
				    ipw->is_v2_card, signalled_reboot_callback,
				    ipw);

	ret = pcmcia_request_irq(link, &link->irq);

	if (ret != 0) {
		cs_error(link, RequestIRQ, ret);
		goto exit3;
	}

	printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
			ipw->is_v2_card ? "V2/V3" : "V1");
	printk(KERN_INFO IPWIRELESS_PCCARD_NAME
			": I/O ports 0x%04x-0x%04x, irq %d\n",
			(unsigned int) link->io.BasePort1,
			(unsigned int) (link->io.BasePort1 +
				link->io.NumPorts1 - 1),
			(unsigned int) link->irq.AssignedIRQ);
	if (ipw->attr_memory && ipw->common_memory)
		printk(KERN_INFO IPWIRELESS_PCCARD_NAME
			": attr memory 0x%08lx-0x%08lx, common memory 0x%08lx-0x%08lx\n",
			ipw->request_attr_memory.Base,
			ipw->request_attr_memory.Base
			+ ipw->request_attr_memory.Size - 1,
			ipw->request_common_memory.Base,
			ipw->request_common_memory.Base
			+ ipw->request_common_memory.Size - 1);

	ipw->network = ipwireless_network_create(ipw->hardware);
	if (!ipw->network)
		goto exit3;

	ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
			ipw->nodes);
	if (!ipw->tty)
		goto exit3;

	ipwireless_init_hardware_v2_v3(ipw->hardware);

	/*
	 * Do the RequestConfiguration last, because it enables interrupts.
	 * Then we don't get any interrupts before we're ready for them.
	 */
	ret = pcmcia_request_configuration(link, &link->conf);

	if (ret != 0) {
		cs_error(link, RequestConfiguration, ret);
		goto exit4;
	}

	link->dev_node = &ipw->nodes[0];

	return 0;

exit4:
	pcmcia_disable_device(link);
exit3:
	if (ipw->attr_memory) {
		release_mem_region(ipw->request_attr_memory.Base,
				ipw->request_attr_memory.Size);
		iounmap(ipw->attr_memory);
		pcmcia_release_window(ipw->handle_attr_memory);
		pcmcia_disable_device(link);
	}
exit2:
	if (ipw->common_memory) {
		release_mem_region(ipw->request_common_memory.Base,
				ipw->request_common_memory.Size);
		iounmap(ipw->common_memory);
		pcmcia_release_window(ipw->handle_common_memory);
	}
exit1:
	pcmcia_disable_device(link);
exit0:
	return -1;
}
Ejemplo n.º 12
0
static void ni_gpib_config(struct pcmcia_device *link)
{
	//local_info_t *info = link->priv;
	//gpib_board_t *dev = info->dev;
	tuple_t tuple;
	cisparse_t parse;
	int last_fn, last_ret;
	u_char buf[64];
	win_req_t req;
	memreq_t map;
	cistpl_cftable_entry_t dflt = { 0 };
	DEBUG(0, "ni_gpib_config(0x%p)\n", link);

	/*
	This reads the card's CONFIG tuple to find its configuration
	registers.
	*/
	tuple.DesiredTuple = CISTPL_CONFIG;
	tuple.Attributes = 0;
	tuple.TupleData = buf;
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;
	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
	CS_CHECK(ParseTuple, PCMCIA_PARSE_TUPLE(&tuple, &parse));
	link->conf.ConfigBase = parse.config.base;
	link->conf.Present = parse.config.rmask[0];

	/* Configure card */

  /*
	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.DesiredTuple = CISTPL_CFTABLE_ENTRY;
	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
	while (1)
	{
		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
		CS_CHECK(ParseTuple, PCMCIA_PARSE_TUPLE(&tuple, &parse));
		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
		if (cfg->index == 0) goto next_entry;
		link->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;
		}

		/* Do we need to allocate 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_AUTO;
			if (!(io->flags & CISTPL_IO_8BIT))
				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
			if (!(io->flags & CISTPL_IO_16BIT))
				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 (io->nwin > 1)
			{
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->io.NumPorts2 = io->win[1].len;
			}
			/* This reserves IO space but doesn't actually enable it */
			last_ret = pcmcia_request_io(link, &link->io);
			if(last_ret != 0)
			{
				goto next_entry;
			}
		}

		/*
		Now set up a common memory window, if needed.  There is room
		in the dev_link_t structure for one memory window handle,
		but if the base addresses need to be saved, or if multiple
		windows are needed, the info should go in the private data
		structure for this device.

		Note that the memory window base is a physical address, and
		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.Attributes |= WIN_ENABLE;
			req.Base = mem->win[0].host_addr;
			req.Size = mem->win[0].len;
			if (req.Size < 0x1000)
			req.Size = 0x1000;
			req.AccessSpeed = 0;
			link->win = (window_handle_t)link;
			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 we got this far, we're cool! */
		break;

		next_entry:
		CS_CHECK( GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
	}

	/*
	Allocate an interrupt line.  Note that this does not assign a
	handler to the interrupt, unless the 'Handler' member of the
	irq structure is initialized.
	*/
	if (link->conf.Attributes & CONF_ENABLE_IRQ)
		CS_CHECK( RequestIRQ, pcmcia_request_irq(link, &link->irq) );

	/*
	This actually configures the PCMCIA socket -- setting up
	the I/O windows and the interrupt mapping, and putting the
	card and host interface into "Memory and IO" mode.
	*/
	CS_CHECK( RequestConfiguration, pcmcia_request_configuration(link, &link->conf) );

	/*
	At this point, the dev_node_t structure(s) need to be
	initialized and arranged in a linked list at link->dev.
	*/
	return;

	cs_failed:
	cs_error(link, last_fn, last_ret);
	ni_gpib_release(link);
} /* ni_gpib_config */
Ejemplo n.º 13
0
static void cif60_config(dev_link_t *link)
{
    client_handle_t handle = link->handle;
    cif60_dev_t *info = link->priv;
    //CARD_DEVICE *dev = info->dev;
    tuple_t tuple;
    cisparse_t parse;
    win_req_t req;
    memreq_t mem;
    int last_ret, last_fn;
    u_char buf[64];

    DEBUG(0, "cif60_config(0x%p)\n", link);

    tuple.Attributes = 0;
    tuple.TupleData = buf;
    tuple.TupleDataMax = 64;
    tuple.TupleOffset = 0;
    tuple.DesiredTuple = CISTPL_CONFIG;
    CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
    DEBUG(0, "cif60_config:GetFirstTuple\n");
    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
    DEBUG(0, "cif60_config:GetTupleData\n");
    CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
    DEBUG(0, "cif60_config:ParseTuple\n");
    link->conf.ConfigBase = parse.config.base;
    DEBUG(0, "cif60_config:link->conf.ConfigBase=%d\n", link->conf.ConfigBase);

    /* Configure card */
    link->state |= DEV_CONFIG;

    //link->conf.ConfigIndex = 0x61;

    /* Determine if this is PRIMARY or ALTERNATE. */

    /* Try PRIMARY card at 0xA20-0xA23 */
    /*
    link->io.BasePort1 = 0xd0000;
    i = pcmcia_request_io(link->handle, &link->io);
    DEBUG(0, "cif60_config:request_io ret=%d\n", i);
    if (i != CS_SUCCESS) {
        / * Couldn't get 0xA20-0xA23.  Try ALTERNATE at 0xA24-0xA27. * /
        link->io.BasePort1 = 0xA24;
        CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));
        DEBUG(0, "cif60_config:retry request_io\n");
    }
    dev->base_addr = link->io.BasePort1;
    DEBUG(0, "cif60_config:base_addr=%lx\n", dev->base_addr);
    */
    
    /*
    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
    dev->irq = link->irq.AssignedIRQ;
    DEBUG(0, "cif60_config:irq=%d\n", dev->irq);
    */
    /* Allocate the MMIO memory window */
    /*
    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
    req.Attributes |= WIN_USE_WAIT;
    req.Base = 0; 
    req.Size = 0x2000;
    req.AccessSpeed = 250;
    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &link->win));
    DEBUG(0, "cif60_config:RequestWindow\n");

    mem.CardOffset = mmiobase;
    mem.Page = 0;
    CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
    dev->mmio = ioremap(req.Base, req.Size);
    */
    
    /* Allocate the SRAM memory window */
    req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE;
    req.Attributes |= WIN_USE_WAIT;
    req.Base = 0;
    req.Size = sramsize * 1024;
    req.AccessSpeed = 250;
    CS_CHECK(RequestWindow, pcmcia_request_window(&link->handle, &req, &info->sram_win_handle));
    DEBUG(0, "cif60_config:RequestWindow2\n");

    mem.CardOffset = srambase;
    mem.Page = 0;
    CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
    DEBUG(0, "cif60_config:MapMemPage\n");

    //dev->sram_base = mem.CardOffset >> 12;
    //dev->sram_virt = (u_long)ioremap(req.Base, req.Size);

    //CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));
    //DEBUG(0, "cif60_config:RequestConfiguration\n");

    DEBUG(0, "cif60_config:return\n");
    return;
/*    
    link->dev = &info->node;
    link->state &= ~DEV_CONFIG_PENDING;

    i = cif_scan_pci();   
    // i = cif60_probe_card(dev);
    if(i != -ENODEV) {
        printk(KERN_NOTICE "cif_cs: register_cif() failed\n");
        link->dev = NULL;
        goto failed;
    }

    strcpy(info->node.dev_name, dev->name);

    printk(KERN_INFO "%s: port %#3lx, irq %d,",
           dev->name, dev->base_addr, dev->irq);
    printk("\n");
    
    return;
*/
cs_failed:
    DEBUG(0, "cif60_config:cs_failed\n");
    cs_error(link->handle, last_fn, last_ret);
/*
failed:
    cif60_release(link);
*/
} /* cif60_config */
static int
xirc2ps_config(struct pcmcia_device * link)
{
    struct net_device *dev = link->priv;
    local_info_t *local = netdev_priv(dev);
    unsigned int ioaddr;
    int err;
    u8 *buf;
    size_t len;

    local->dingo_ccr = NULL;

    dev_dbg(&link->dev, "config\n");

    
    if (link->has_manf_id == 0) {
	pr_notice("manfid not found in CIS\n");
	goto failure;
    }

    switch (link->manf_id) {
      case MANFID_XIRCOM:
	local->manf_str = "Xircom";
	break;
      case MANFID_ACCTON:
	local->manf_str = "Accton";
	break;
      case MANFID_COMPAQ:
      case MANFID_COMPAQ2:
	local->manf_str = "Compaq";
	break;
      case MANFID_INTEL:
	local->manf_str = "Intel";
	break;
      case MANFID_TOSHIBA:
	local->manf_str = "Toshiba";
	break;
      default:
	pr_notice("Unknown Card Manufacturer ID: 0x%04x\n",
		  (unsigned)link->manf_id);
	goto failure;
    }
    dev_dbg(&link->dev, "found %s card\n", local->manf_str);

    if (!set_card_type(link)) {
	pr_notice("this card is not supported\n");
	goto failure;
    }

    
    err = pcmcia_get_mac_from_cis(link, dev);

    
    if (err) {
	    len = pcmcia_get_tuple(link, 0x89, &buf);
	    
	    if (buf && len == 8) {
		    if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
			    int i;
			    for (i = 2; i < 6; i++)
				    dev->dev_addr[i] = buf[i+2];
		    } else
			    err = -1;
	    }
	    kfree(buf);
    }

    if (err)
	err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);

    if (err) {
	pr_notice("node-id not found in CIS\n");
	goto failure;
    }

    if (local->modem) {
	int pass;
	link->config_flags |= CONF_AUTO_SET_IO;

	if (local->dingo) {
	    if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
		    goto port_found;
	} else {
	    for (pass=0; pass < 2; pass++)
		    if (!pcmcia_loop_config(link, xirc2ps_config_check,
						    &pass))
			    goto port_found;
	}
	pr_notice("no ports available\n");
    } else {
	link->io_lines = 10;
	link->resource[0]->end = 16;
	link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
	for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
	    link->resource[0]->start = ioaddr;
	    if (!(err = pcmcia_request_io(link)))
		goto port_found;
	}
	link->resource[0]->start = 0; 
	if ((err = pcmcia_request_io(link)))
	    goto config_error;
    }
  port_found:
    if (err)
	 goto config_error;

    if ((err=pcmcia_request_irq(link, xirc2ps_interrupt)))
	goto config_error;

    link->config_flags |= CONF_ENABLE_IRQ;
    if (do_sound)
	    link->config_flags |= CONF_ENABLE_SPKR;

    if ((err = pcmcia_enable_device(link)))
	goto config_error;

    if (local->dingo) {
	/* Reset the modem's BAR to the correct value
	 * This is necessary because in the RequestConfiguration call,
	 * the base address of the ethernet port (BasePort1) is written
	 * to the BAR registers of the modem.
	 */
	err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8)
				link->resource[1]->start & 0xff);
	if (err)
	    goto config_error;

	err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
				(link->resource[1]->start >> 8) & 0xff);
	if (err)
	    goto config_error;

	link->resource[2]->flags = WIN_DATA_WIDTH_8 | WIN_MEMORY_TYPE_AM |
					WIN_ENABLE;
	link->resource[2]->start = link->resource[2]->end = 0;
	if ((err = pcmcia_request_window(link, link->resource[2], 0)))
	    goto config_error;

	local->dingo_ccr = ioremap(link->resource[2]->start, 0x1000) + 0x0800;
	if ((err = pcmcia_map_mem_page(link, link->resource[2], 0)))
	    goto config_error;

	writeb(0x47, local->dingo_ccr + CISREG_COR);
	ioaddr = link->resource[0]->start;
	writeb(ioaddr & 0xff	  , local->dingo_ccr + CISREG_IOBASE_0);
	writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1);

      #if 0
	{
	    u_char tmp;
	    pr_info("ECOR:");
	    for (i=0; i < 7; i++) {
		tmp = readb(local->dingo_ccr + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	    pr_info("DCOR:");
	    for (i=0; i < 4; i++) {
		tmp = readb(local->dingo_ccr + 0x20 + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	    pr_info("SCOR:");
	    for (i=0; i < 10; i++) {
		tmp = readb(local->dingo_ccr + 0x40 + i*2);
		pr_cont(" %02x", tmp);
	    }
	    pr_cont("\n");
	}
      #endif

	writeb(0x01, local->dingo_ccr + 0x20);
	writeb(0x0c, local->dingo_ccr + 0x22);
	writeb(0x00, local->dingo_ccr + 0x24);
	writeb(0x00, local->dingo_ccr + 0x26);
	writeb(0x00, local->dingo_ccr + 0x28);
    }
Ejemplo n.º 15
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];
	win_req_t req;
	memreq_t map;

	dev = link->priv;

	DEBUG(0, "airo_config(0x%p)\n", link);

	/*
	  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;
		
		/* Does this card need audio output? */
		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
			link->conf.Attributes |= CONF_ENABLE_SPKR;
			link->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;
		
		/* Do we need to allocate 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_AUTO;
			if (!(io->flags & CISTPL_IO_8BIT))
				link->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;
			if (io->nwin > 1) {
				link->io.Attributes2 = link->io.Attributes1;
				link->io.BasePort2 = io->win[1].base;
				link->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;
		
		/*
		  Now set up a common memory window, if needed.  There is room
		  in the struct pcmcia_device structure for one memory window handle,
		  but if the base addresses need to be saved, or if multiple
		  windows are needed, the info should go in the private data
		  structure for this device.
		  
		  Note that the memory window base is a physical address, and
		  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 we got this far, we're cool! */
		break;
		
	next_entry:
		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
	}
	
    /*
      Allocate an interrupt line.  Note that this does not assign a
      handler to the interrupt, unless the 'Handler' member of the
      irq structure is initialized.
    */
	if (link->conf.Attributes & CONF_ENABLE_IRQ)
		CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
	
	/*
	  This actually configures the PCMCIA socket -- setting up
	  the I/O windows and the interrupt mapping, and putting the
	  card and host interface into "Memory and IO" mode.
	*/
	CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
	((local_info_t*)link->priv)->eth_dev = 
		init_airo_card( link->irq.AssignedIRQ,
				link->io.BasePort1, 1, &handle_to_dev(link) );
	if (!((local_info_t*)link->priv)->eth_dev) goto cs_failed;
	
	/*
	  At this point, the dev_node_t structure(s) need to be
	  initialized and arranged in a linked list at link->dev_node.
	*/
	strcpy(dev->node.dev_name, ((local_info_t*)link->priv)->eth_dev->name );
	dev->node.major = dev->node.minor = 0;
	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.Vpp)
		printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%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);
	if (link->win)
		printk(", mem 0x%06lx-0x%06lx", req.Base,
		       req.Base+req.Size-1);
	printk("\n");
	return 0;

 cs_failed:
	cs_error(link, last_fn, last_ret);
	airo_release(link);
	return -ENODEV;
} /* airo_config */
Ejemplo n.º 16
0
/*
    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 */
Ejemplo n.º 17
0
static int airo_cs_config_check(struct pcmcia_device *p_dev,
				cistpl_cftable_entry_t *cfg,
				cistpl_cftable_entry_t *dflt,
				unsigned int vcc,
				void *priv_data)
{
	win_req_t *req = priv_data;

	if (cfg->index == 0)
		return -ENODEV;

	
	if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
		p_dev->conf.Attributes |= CONF_ENABLE_SPKR;
		p_dev->conf.Status = CCSR_AUDIO_ENA;
	}

	
	
	if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
	else if (dflt->vpp1.present & (1<<CISTPL_POWER_VNOM))
		p_dev->conf.Vpp = dflt->vpp1.param[CISTPL_POWER_VNOM]/10000;

	
	if (cfg->irq.IRQInfo1 || dflt->irq.IRQInfo1)
		p_dev->conf.Attributes |= CONF_ENABLE_IRQ;

	
	p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
	if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
		cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
		p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
		if (!(io->flags & CISTPL_IO_8BIT))
			p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
		if (!(io->flags & CISTPL_IO_16BIT))
			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) {
			p_dev->io.Attributes2 = p_dev->io.Attributes1;
			p_dev->io.BasePort2 = io->win[1].base;
			p_dev->io.NumPorts2 = io->win[1].len;
		}
	}

	
	if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
		return -ENODEV;

	
	if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
		cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
		memreq_t map;
		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(&p_dev, 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;
	}
	
	return 0;
}