示例#1
0
/*
 * This deletes a driver "instance".  The device is de-registered with
 * Card Services.  If it has been released, all local data structures
 * are freed.  Otherwise, the structures will be freed when the device
 * is released.
 */
static void spectrum_cs_detach(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;

	orinoco_if_del(priv);

	spectrum_cs_release(link);

	free_orinocodev(priv);
}				/* spectrum_cs_detach */
示例#2
0
/*
 * This deletes a driver "instance".  The device is de-registered with
 * Card Services.  If it has been released, all local data structures
 * are freed.  Otherwise, the structures will be freed when the device
 * is released.
 */
static void spectrum_cs_detach(struct pcmcia_device *link)
{
	struct net_device *dev = link->priv;

	if (link->dev_node)
		unregister_netdev(dev);

	spectrum_cs_release(link);

	free_orinocodev(dev);
}				/* spectrum_cs_detach */
示例#3
0
static int
spectrum_cs_config(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	hermes_t *hw = &priv->hw;
	int ret;
	void __iomem *mem;

	/*
	 * 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, spectrum_cs_config_check, NULL);
	if (ret) {
		if (!ignore_cis_vcc)
			printk(KERN_ERR PFX "GetNextTuple(): No matching "
			       "CIS configuration.  Maybe you need the "
			       "ignore_cis_vcc=1 parameter.\n");
		goto failed;
	}

	ret = pcmcia_request_irq(link, orinoco_interrupt);
	if (ret)
		goto failed;

	/* We initialize the hermes structure before completing PCMCIA
	 * configuration just in case the interrupt handler gets
	 * called. */
	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
	if (!mem)
		goto failed;

	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
	hw->eeprom_pda = true;

	/*
	 * 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;

	/* Reset card */
	if (spectrum_cs_hard_reset(priv) != 0)
		goto failed;

	/* Initialise the main driver */
	if (orinoco_init(priv) != 0) {
		printk(KERN_ERR PFX "orinoco_init() failed\n");
		goto failed;
	}

	/* Register an interface with the stack */
	if (orinoco_if_add(priv, link->io.BasePort1,
			   link->irq, NULL) != 0) {
		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
		goto failed;
	}

	return 0;

 failed:
	spectrum_cs_release(link);
	return -ENODEV;
}				/* spectrum_cs_config */
示例#4
0
static int
spectrum_cs_config(struct pcmcia_device *link)
{
    struct orinoco_private *priv = link->priv;
    hermes_t *hw = &priv->hw;
    int ret;
    void __iomem *mem;

    link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
                          CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
    if (ignore_cis_vcc)
        link->config_flags &= ~CONF_AUTO_CHECK_VCC;
    ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
    if (ret) {
        if (!ignore_cis_vcc)
//			printk(KERN_ERR PFX "GetNextTuple(): No matching "
//			       "CIS configuration.  Maybe you need the "
            ;
        goto failed;
    }

    mem = ioport_map(link->resource[0]->start,
                     resource_size(link->resource[0]));
    if (!mem)
        goto failed;

    /* We initialize the hermes structure before completing PCMCIA
     * configuration just in case the interrupt handler gets
     * called. */
    hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
    hw->eeprom_pda = true;

    ret = pcmcia_request_irq(link, orinoco_interrupt);
    if (ret)
        goto failed;

    ret = pcmcia_enable_device(link);
    if (ret)
        goto failed;

    /* Reset card */
    if (spectrum_cs_hard_reset(priv) != 0)
        goto failed;

    /* Initialise the main driver */
    if (orinoco_init(priv) != 0) {
        ;
        goto failed;
    }

    /* Register an interface with the stack */
    if (orinoco_if_add(priv, link->resource[0]->start,
                       link->irq, NULL) != 0) {
        ;
        goto failed;
    }

    return 0;

failed:
    spectrum_cs_release(link);
    return -ENODEV;
}				/* spectrum_cs_config */
示例#5
0
static int
spectrum_cs_config(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	struct hermes *hw = &priv->hw;
	int ret;
	void __iomem *mem;

#if 0 /* Not in RHEL */
	link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
		CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
	if (ignore_cis_vcc)
		link->config_flags &= ~CONF_AUTO_CHECK_VCC;
#endif
	ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
	if (ret) {
		if (!ignore_cis_vcc)
			printk(KERN_ERR PFX "GetNextTuple(): No matching "
			       "CIS configuration.  Maybe you need the "
			       "ignore_cis_vcc=1 parameter.\n");
		goto failed;
	}

#if 0 /* Not in RHEL */
	mem = ioport_map(link->resource[0]->start,
			resource_size(link->resource[0]));
#else
	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
#endif
	if (!mem)
		goto failed;

	/* We initialize the hermes structure before completing PCMCIA
	 * configuration just in case the interrupt handler gets
	 * called. */
	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
	hw->eeprom_pda = true;

#if 0 /* Not in RHEL */
	ret = pcmcia_request_irq(link, orinoco_interrupt);
#else
	ret = pcmcia_request_irq(link, &link->irq);
#endif
	if (ret)
		goto failed;

	ret = pcmcia_enable_device(link);
	if (ret)
		goto failed;

	/* Reset card */
	if (spectrum_cs_hard_reset(priv) != 0)
		goto failed;

	/* Initialise the main driver */
	if (orinoco_init(priv) != 0) {
		printk(KERN_ERR PFX "orinoco_init() failed\n");
		goto failed;
	}

	/* Register an interface with the stack */
#if 0 /* Not in RHEL */
	if (orinoco_if_add(priv, link->resource[0]->start,
			   link->irq, NULL) != 0) {
#elif 0 /* Not in RHEL */
	if (orinoco_if_add(priv, link->io.BasePort1,
			   link->irq, NULL) != 0) {
#else
	if (orinoco_if_add(priv, link->io.BasePort1,
			   link->irq.AssignedIRQ, NULL) != 0) {
#endif
		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
		goto failed;
	}

	return 0;

 failed:
	spectrum_cs_release(link);
	return -ENODEV;
}				/* spectrum_cs_config */

static void
spectrum_cs_release(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	unsigned long flags;

	/* We're committed to taking the device away now, so mark the
	 * hardware as unavailable */
	priv->hw.ops->lock_irqsave(&priv->lock, &flags);
	priv->hw_unavailable++;
	priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);

	pcmcia_disable_device(link);
	if (priv->hw.iobase)
		ioport_unmap(priv->hw.iobase);
}				/* spectrum_cs_release */


static int
spectrum_cs_suspend(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	int err = 0;

	/* Mark the device as stopped, to block IO until later */
	orinoco_down(priv);

	return err;
}

static int
spectrum_cs_resume(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	int err = orinoco_up(priv);

	return err;
}


/********************************************************************/
/* Module initialization					    */
/********************************************************************/

static struct pcmcia_device_id spectrum_cs_ids[] = {
	PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
	PCMCIA_DEVICE_NULL,
};
MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);

static struct pcmcia_driver orinoco_driver = {
	.owner		= THIS_MODULE,
#if 0 /* Not in RHEL */
	.name		= DRIVER_NAME,
#else
	.drv		= {
		.name	= DRIVER_NAME,
	},
#endif
	.probe		= spectrum_cs_probe,
	.remove		= spectrum_cs_detach,
	.suspend	= spectrum_cs_suspend,
	.resume		= spectrum_cs_resume,
	.id_table       = spectrum_cs_ids,
};

static int __init
init_spectrum_cs(void)
{
	return pcmcia_register_driver(&orinoco_driver);
}

static void __exit
exit_spectrum_cs(void)
{
	pcmcia_unregister_driver(&orinoco_driver);
}
static int
spectrum_cs_config(struct pcmcia_device *link)
{
	struct orinoco_private *priv = link->priv;
	struct hermes *hw = &priv->hw;
	int ret;
	void __iomem *mem;

	link->config_flags |= CONF_AUTO_SET_VPP | CONF_AUTO_CHECK_VCC |
		CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
	if (ignore_cis_vcc)
		link->config_flags &= ~CONF_AUTO_CHECK_VCC;
	ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
	if (ret) {
		if (!ignore_cis_vcc)
			printk(KERN_ERR PFX "GetNextTuple(): No matching "
			       "CIS configuration.  Maybe you need the "
			       "ignore_cis_vcc=1 parameter.\n");
		goto failed;
	}

	mem = ioport_map(link->resource[0]->start,
			resource_size(link->resource[0]));
	if (!mem)
		goto failed;

	/*                                                            
                                                         
            */
	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
	hw->eeprom_pda = true;

	ret = pcmcia_request_irq(link, orinoco_interrupt);
	if (ret)
		goto failed;

	ret = pcmcia_enable_device(link);
	if (ret)
		goto failed;

	/*            */
	if (spectrum_cs_hard_reset(priv) != 0)
		goto failed;

	/*                            */
	if (orinoco_init(priv) != 0) {
		printk(KERN_ERR PFX "orinoco_init() failed\n");
		goto failed;
	}

	/*                                      */
	if (orinoco_if_add(priv, link->resource[0]->start,
			   link->irq, NULL) != 0) {
		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
		goto failed;
	}

	return 0;

 failed:
	spectrum_cs_release(link);
	return -ENODEV;
}				/*                    */
示例#7
0
static int
spectrum_cs_config(struct pcmcia_device *link)
{
	struct net_device *dev = link->priv;
	struct orinoco_private *priv = netdev_priv(dev);
	struct orinoco_pccard *card = priv->card;
	hermes_t *hw = &priv->hw;
	int last_fn, last_ret;
	void __iomem *mem;

	/*
	 * 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, spectrum_cs_config_check, NULL);
	if (last_ret) {
		if (!ignore_cis_vcc)
			printk(KERN_ERR PFX "GetNextTuple(): No matching "
			       "CIS configuration.  Maybe you need the "
			       "ignore_cis_vcc=1 parameter.\n");
		cs_error(link, RequestIO, 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.
	 */
	CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));

	/* We initialize the hermes structure before completing PCMCIA
	 * configuration just in case the interrupt handler gets
	 * called. */
	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
	if (!mem)
		goto cs_failed;

	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);

	/*
	 * 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));

	/* Ok, we have the configuration, prepare to register the netdev */
	dev->base_addr = link->io.BasePort1;
	dev->irq = link->irq.AssignedIRQ;
	card->node.major = card->node.minor = 0;

	/* Reset card */
	if (spectrum_cs_hard_reset(priv) != 0) {
		goto failed;
	}

	SET_NETDEV_DEV(dev, &handle_to_dev(link));
	/* Tell the stack we exist */
	if (register_netdev(dev) != 0) {
		printk(KERN_ERR PFX "register_netdev() failed\n");
		goto failed;
	}

	/* At this point, the dev_node_t structure(s) needs to be
	 * initialized and arranged in a linked list at link->dev_node. */
	strcpy(card->node.dev_name, dev->name);
	link->dev_node = &card->node; /* link->dev_node being non-NULL is also
                                    used to indicate that the
                                    net_device has been registered */

	/* Finally, report what we've done */
	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s, irq %d, io "
	       "0x%04x-0x%04x\n", dev->name, dev_name(dev->dev.parent),
	       link->irq.AssignedIRQ, link->io.BasePort1,
	       link->io.BasePort1 + link->io.NumPorts1 - 1);

	return 0;

 cs_failed:
	cs_error(link, last_fn, last_ret);

 failed:
	spectrum_cs_release(link);
	return -ENODEV;
}				/* spectrum_cs_config */