Beispiel #1
0
static void airo_detach(dev_link_t *link)
{
	dev_link_t **linkp;
	
	DEBUG(0, "airo_detach(0x%p)\n", link);
	
	/* Locate device structure */
	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
		if (*linkp == link) break;
	if (*linkp == NULL)
		return;
	
	if (link->state & DEV_CONFIG)
		airo_release(link);
	
	if ( ((local_info_t*)link->priv)->eth_dev ) {
		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
	}
	((local_info_t*)link->priv)->eth_dev = NULL;   
	
	/* Break the link with Card Services */
	if (link->handle)
		pcmcia_deregister_client(link->handle);
	
	
	
	/* Unlink device structure, free pieces */
	*linkp = link->next;
	if (link->priv) {
		kfree(link->priv);
	}
	kfree(link);
	
} /* airo_detach */
static int airo_config(struct pcmcia_device *link)
{
    local_info_t *dev;
    int ret;

    dev = link->priv;

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

    link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_VPP |
                          CONF_AUTO_AUDIO | CONF_AUTO_SET_IO;

    ret = pcmcia_loop_config(link, airo_cs_config_check, NULL);
    if (ret)
        goto failed;

    if (!link->irq)
        goto failed;

    ret = pcmcia_enable_device(link);
    if (ret)
        goto failed;
    ((local_info_t *)link->priv)->eth_dev =
        init_airo_card(link->irq,
                       link->resource[0]->start, 1, &link->dev);
    if (!((local_info_t *)link->priv)->eth_dev)
        goto failed;

    return 0;

failed:
    airo_release(link);
    return -ENODEV;
}
Beispiel #3
0
static void airo_cs_cleanup(void)
{
	DEBUG(0, "airo_cs: unloading\n");
	unregister_pcmcia_driver(&dev_info);
	while (dev_list != NULL) {
		if (dev_list->state & DEV_CONFIG)
			airo_release((u_long)dev_list);
		airo_detach(dev_list);
	}
}
Beispiel #4
0
static void airo_detach(struct pcmcia_device *link)
{
	DEBUG(0, "airo_detach(0x%p)\n", link);

	airo_release(link);

	if ( ((local_info_t*)link->priv)->eth_dev ) {
		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
	}
	((local_info_t*)link->priv)->eth_dev = NULL;

	kfree(link->priv);
} /* airo_detach */
static void airo_detach(struct pcmcia_device *link)
{
    dev_dbg(&link->dev, "airo_detach\n");

    airo_release(link);

    if (((local_info_t *)link->priv)->eth_dev) {
        stop_airo_card(((local_info_t *)link->priv)->eth_dev, 0);
    }
    ((local_info_t *)link->priv)->eth_dev = NULL;

    kfree(link->priv);
}
Beispiel #6
0
static int airo_event(event_t event, int priority,
		      event_callback_args_t *args)
{
	dev_link_t *link = args->client_data;
	local_info_t *local = link->priv;
	
	DEBUG(1, "airo_event(0x%06x)\n", event);
	
	switch (event) {
	case CS_EVENT_CARD_REMOVAL:
		link->state &= ~DEV_PRESENT;
		if (link->state & DEV_CONFIG) {
			netif_device_detach(local->eth_dev);
			airo_release(link);
		}
		break;
	case CS_EVENT_CARD_INSERTION:
		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
		airo_config(link);
		break;
	case CS_EVENT_PM_SUSPEND:
		link->state |= DEV_SUSPEND;
		/* Fall through... */
	case CS_EVENT_RESET_PHYSICAL:
		if (link->state & DEV_CONFIG) {
			netif_device_detach(local->eth_dev);
			pcmcia_release_configuration(link->handle);
		}
		break;
	case CS_EVENT_PM_RESUME:
		link->state &= ~DEV_SUSPEND;
		/* Fall through... */
	case CS_EVENT_CARD_RESET:
		if (link->state & DEV_CONFIG) {
			pcmcia_request_configuration(link->handle, &link->conf);
			reset_airo_card(local->eth_dev);
			netif_device_attach(local->eth_dev);
		}
		break;
	}
	return 0;
} /* airo_event */
Beispiel #7
0
static void airo_detach(dev_link_t *link)
{
	dev_link_t **linkp;
	
	DEBUG(0, "airo_detach(0x%p)\n", link);
	
	/* Locate device structure */
	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
		if (*linkp == link) break;
	if (*linkp == NULL)
		return;
	
	del_timer(&link->release);
	if ( link->state & DEV_CONFIG ) {
		airo_release( (int)link );
		if ( link->state & DEV_STALE_CONFIG ) {
			link->state |= DEV_STALE_LINK;
			return;
		}
	}
	
	if ( ((local_info_t*)link->priv)->eth_dev ) {
		stop_airo_card( ((local_info_t*)link->priv)->eth_dev, 0 );
	}
	((local_info_t*)link->priv)->eth_dev = 0;   
	
	/* Break the link with Card Services */
	if (link->handle)
		CardServices(DeregisterClient, link->handle);
	
	
	
	/* Unlink device structure, free pieces */
	*linkp = link->next;
	if (link->priv) {
		kfree(link->priv);
	}
	kfree(link);
	
} /* airo_detach */
Beispiel #8
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 */
Beispiel #9
0
static int airo_config(struct pcmcia_device *link)
{
	local_info_t *dev;
	win_req_t *req;
	int last_fn, last_ret;

	dev = link->priv;

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

	req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
	if (!req)
		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, req);
	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
	  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");
	kfree(req);
	return 0;

 cs_failed:
	cs_error(link, last_fn, last_ret);
 failed:
	airo_release(link);
	kfree(req);
	return -ENODEV;
} /* airo_config */
static int airo_config(struct pcmcia_device *link)
{
	local_info_t *dev;
	win_req_t *req;
	int ret;

	dev = link->priv;

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

	req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
	if (!req)
		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.
	 */
	ret = pcmcia_loop_config(link, airo_cs_config_check, req);
	if (ret)
		goto failed;

	if (!link->irq)
		goto 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.
	*/
	ret = pcmcia_request_configuration(link, &link->conf);
	if (ret)
		goto failed;
	((local_info_t *)link->priv)->eth_dev =
		init_airo_card(link->irq,
			       link->io.BasePort1, 1, &link->dev);
	if (!((local_info_t *)link->priv)->eth_dev)
		goto failed;

	/* Finally, report what we've done */
	dev_info(&link->dev, "index 0x%02x: ",
	       link->conf.ConfigIndex);
	if (link->conf.Vpp)
		printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
	printk(", irq %d", link->irq);
	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");
	kfree(req);
	return 0;

 failed:
	airo_release(link);
	kfree(req);
	return -ENODEV;
} /* airo_config */
Beispiel #11
0
static int airo_config(struct pcmcia_device *link)
{
	local_info_t *dev;
	win_req_t *req;
	int last_fn, last_ret;

	dev = link->priv;

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

	req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
	if (!req)
		return -ENOMEM;

	
	last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
	if (last_ret)
		goto failed;

	
	if (link->conf.Attributes & CONF_ENABLE_IRQ)
		CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));

	
	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;

	
	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;

	
	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");
	kfree(req);
	return 0;

 cs_failed:
	cs_error(link, last_fn, last_ret);
 failed:
	airo_release(link);
	kfree(req);
	return -ENODEV;
}