Exemplo n.º 1
0
/*
 * This creates an "instance" of the driver, allocating local data
 * structures for one device.  The device is registered with Card
 * Services.
 *
 * The dev_link structure is initialized, but we don't actually
 * configure the card at this point -- we wait until we receive a card
 * insertion event.  */
static int
spectrum_cs_probe(struct pcmcia_device *link)
{
	struct orinoco_private *priv;
	struct orinoco_pccard *card;

	priv = alloc_orinocodev(sizeof(*card), &link->dev,
				spectrum_cs_hard_reset,
				spectrum_cs_stop_firmware);
	if (!priv)
		return -ENOMEM;
	card = priv->card;

	/* Link both structures together */
	card->p_dev = link;
	link->priv = priv;

	/* General socket configuration defaults can go here.  In this
	 * client, we assume very little, and rely on the CIS for
	 * almost everything.  In most clients, many details (i.e.,
	 * number, sizes, and attributes of IO windows) are fixed by
	 * the nature of the device, and can be hard-wired here. */
	link->conf.Attributes = 0;
	link->conf.IntType = INT_MEMORY_AND_IO;

	return spectrum_cs_config(link);
}				/* spectrum_cs_attach */
Exemplo n.º 2
0
static int
orinoco_cs_probe(struct pcmcia_device *link)
{
	struct orinoco_private *priv;
	struct orinoco_pccard *card;

	priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
				orinoco_cs_hard_reset, NULL);
	if (!priv)
		return -ENOMEM;
	card = priv->card;

	
	card->p_dev = link;
	link->priv = priv;

	
	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
	link->irq.Handler = orinoco_interrupt;
	link->irq.Instance = priv;

	
	link->conf.Attributes = 0;
	link->conf.IntType = INT_MEMORY_AND_IO;

	return orinoco_cs_config(link);
}				
Exemplo n.º 3
0
static int
spectrum_cs_probe(struct pcmcia_device *link)
{
	struct orinoco_private *priv;
	struct orinoco_pccard *card;

	priv = alloc_orinocodev(sizeof(*card), &link->dev,
				spectrum_cs_hard_reset,
				spectrum_cs_stop_firmware);
	if (!priv)
		return -ENOMEM;
	card = priv->card;

	/* Link both structures together */
	card->p_dev = link;
	link->priv = priv;

	/* Interrupt setup */
	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
	link->irq.Handler = orinoco_interrupt;
	link->conf.Attributes = 0;
	link->conf.IntType = INT_MEMORY_AND_IO;

	return spectrum_cs_config(link);
}				/* spectrum_cs_attach */
Exemplo n.º 4
0
/*
 * This creates an "instance" of the driver, allocating local data
 * structures for one device.  The device is registered with Card
 * Services.
 *
 * The dev_link structure is initialized, but we don't actually
 * configure the card at this point -- we wait until we receive a card
 * insertion event.  */
static int
orinoco_cs_probe(struct pcmcia_device *link)
{
	struct net_device *dev;
	struct orinoco_private *priv;
	struct orinoco_pccard *card;

	dev = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
			       orinoco_cs_hard_reset, NULL);
	if (!dev)
		return -ENOMEM;
	priv = netdev_priv(dev);
	card = priv->card;

	/* Link both structures together */
	card->p_dev = link;
	link->priv = dev;

	/* Interrupt setup */
	link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
	link->irq.Handler = orinoco_interrupt;
	link->irq.Instance = dev;

	/* General socket configuration defaults can go here.  In this
	 * client, we assume very little, and rely on the CIS for
	 * almost everything.  In most clients, many details (i.e.,
	 * number, sizes, and attributes of IO windows) are fixed by
	 * the nature of the device, and can be hard-wired here. */
	link->conf.Attributes = 0;
	link->conf.IntType = INT_MEMORY_AND_IO;

	return orinoco_cs_config(link);
}				/* orinoco_cs_attach */
Exemplo n.º 5
0
/*
 * This creates an "instance" of the driver, allocating local data
 * structures for one device.  The device is registered with Card
 * Services.
 * 
 * The dev_link structure is initialized, but we don't actually
 * configure the card at this point -- we wait until we receive a card
 * insertion event.  */
static dev_link_t *
orinoco_cs_attach(void)
{
	struct net_device *dev;
	struct orinoco_private *priv;
	struct orinoco_pccard *card;
	dev_link_t *link;
	client_reg_t client_reg;
	int ret;

	dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
	if (! dev)
		return NULL;
	priv = netdev_priv(dev);
	card = priv->card;

	/* Link both structures together */
	link = &card->link;
	link->priv = dev;

	/* Interrupt setup */
	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
	link->irq.Handler = orinoco_interrupt;
	link->irq.Instance = dev; 

	/* General socket configuration defaults can go here.  In this
	 * client, we assume very little, and rely on the CIS for
	 * almost everything.  In most clients, many details (i.e.,
	 * number, sizes, and attributes of IO windows) are fixed by
	 * the nature of the device, and can be hard-wired here. */
	link->conf.Attributes = 0;
	link->conf.IntType = INT_MEMORY_AND_IO;

	/* Register with Card Services */
	/* FIXME: need a lock? */
	link->next = dev_list;
	dev_list = link;

	client_reg.dev_info = &dev_info;
	client_reg.EventMask =
		CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
		CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
		CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
	client_reg.event_handler = &orinoco_cs_event;
	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
	client_reg.event_callback_args.client_data = link;

	ret = pcmcia_register_client(&link->handle, &client_reg);
	if (ret != CS_SUCCESS) {
		cs_error(link->handle, RegisterClient, ret);
		orinoco_cs_detach(link);
		return NULL;
	}

	return link;
}				/* orinoco_cs_attach */
Exemplo n.º 6
0
static int
orinoco_cs_probe(struct pcmcia_device *link)
{
	struct orinoco_private *priv;
	struct orinoco_pccard *card;

	priv = alloc_orinocodev(sizeof(*card), &link->dev,
				orinoco_cs_hard_reset, NULL);
	if (!priv)
		return -ENOMEM;
	card = priv->card;

	/*                               */
	card->p_dev = link;
	link->priv = priv;

	return orinoco_cs_config(link);
}				/*                   */
Exemplo n.º 7
0
static int
spectrum_cs_probe(struct pcmcia_device *link)
{
    struct orinoco_private *priv;
    struct orinoco_pccard *card;

    priv = alloc_orinocodev(sizeof(*card), &link->dev,
                            spectrum_cs_hard_reset,
                            spectrum_cs_stop_firmware);
    if (!priv)
        return -ENOMEM;
    card = priv->card;

    /* Link both structures together */
    card->p_dev = link;
    link->priv = priv;

    return spectrum_cs_config(link);
}				/* spectrum_cs_attach */
Exemplo n.º 8
0
static int orinoco_plx_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err = 0;
	u8 __iomem *attr_mem = NULL;
	u32 csr_reg, plx_addr;
	struct orinoco_private *priv = NULL;
	struct orinoco_plx_card *card;
	unsigned long pccard_ioaddr = 0;
	unsigned long pccard_iolen = 0;
	struct net_device *dev = NULL;
	void __iomem *mem;
	int i;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err != 0) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	/* Resource 1 is mapped to PLX-specific registers */
	plx_addr = pci_resource_start(pdev, 1);

	/* Resource 2 is mapped to the PCMCIA attribute memory */
	attr_mem = ioremap(pci_resource_start(pdev, 2),
			   pci_resource_len(pdev, 2));
	if (!attr_mem) {
		printk(KERN_ERR PFX "Cannot remap PCMCIA space\n");
		goto fail_map_attr;
	}

	/* Resource 3 is mapped to the PCMCIA I/O address space */
	pccard_ioaddr = pci_resource_start(pdev, 3);
	pccard_iolen = pci_resource_len(pdev, 3);

	mem = pci_iomap(pdev, 3, 0);
	if (!mem) {
		err = -ENOMEM;
		goto fail_map_io;
	}

	/* Allocate network device */
	dev = alloc_orinocodev(sizeof(*card), orinoco_plx_cor_reset);
	if (!dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		err = -ENOMEM;
		goto fail_alloc;
	}

	priv = netdev_priv(dev);
	card = priv->card;
	card->attr_mem = attr_mem;
	dev->base_addr = pccard_ioaddr;
	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	hermes_struct_init(&priv->hw, mem, HERMES_16BIT_REGSPACING);

	printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 PLX device "
	       "at %s irq:%d, io addr:0x%lx\n", pci_name(pdev), pdev->irq,
	       pccard_ioaddr);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
			  dev->name, dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}
	dev->irq = pdev->irq;

	/* bjoern: We need to tell the card to enable interrupts, in
	   case the serial eprom didn't do this already.  See the
	   PLX9052 data book, p8-1 and 8-24 for reference. */
	csr_reg = inl(plx_addr + PLX_INTCSR);
	if (!(csr_reg & PLX_INTCSR_INTEN)) {
		csr_reg |= PLX_INTCSR_INTEN;
		outl(csr_reg, plx_addr + PLX_INTCSR);
		csr_reg = inl(plx_addr + PLX_INTCSR);
		if (!(csr_reg & PLX_INTCSR_INTEN)) {
			printk(KERN_ERR PFX "Cannot enable interrupts\n");
			goto fail;
		}
	}

	err = orinoco_plx_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}

	printk(KERN_DEBUG PFX "CIS: ");
	for (i = 0; i < 16; i++) {
		printk("%02X:", readb(attr_mem + 2*i));
	}
	printk("\n");

	/* Verify whether a supported PC card is present */
	/* FIXME: we probably need to be smarted about this */
	for (i = 0; i < sizeof(cis_magic); i++) {
		if (cis_magic[i] != readb(attr_mem +2*i)) {
			printk(KERN_ERR PFX "The CIS value of Prism2 PC "
			       "card is unexpected\n");
			err = -EIO;
			goto fail;
		}
	}

	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot register network device\n");
		goto fail;
	}

	pci_set_drvdata(pdev, dev);

	return 0;

 fail:
	free_irq(pdev->irq, dev);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);

 fail_alloc:
	pci_iounmap(pdev, mem);

 fail_map_io:
	iounmap(attr_mem);

 fail_map_attr:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 9
0
static int orinoco_nortel_init_one(struct pci_dev *pdev,
				   const struct pci_device_id *ent)
{
	int err;
	struct orinoco_private *priv;
	struct orinoco_pci_card *card;
	struct net_device *dev;
	void __iomem *hermes_io, *bridge_io, *attr_io;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	bridge_io = pci_iomap(pdev, 0, 0);
	if (!bridge_io) {
		printk(KERN_ERR PFX "Cannot map bridge registers\n");
		err = -EIO;
		goto fail_map_bridge;
	}

	attr_io = pci_iomap(pdev, 1, 0);
	if (!attr_io) {
		printk(KERN_ERR PFX "Cannot map PCMCIA attributes\n");
		err = -EIO;
		goto fail_map_attr;
	}

	hermes_io = pci_iomap(pdev, 2, 0);
	if (!hermes_io) {
		printk(KERN_ERR PFX "Cannot map chipset registers\n");
		err = -EIO;
		goto fail_map_hermes;
	}

	/* Allocate network device */
	dev = alloc_orinocodev(sizeof(*card), &pdev->dev,
			       orinoco_nortel_cor_reset, NULL);
	if (!dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		err = -ENOMEM;
		goto fail_alloc;
	}

	priv = netdev_priv(dev);
	card = priv->card;
	card->bridge_io = bridge_io;
	card->attr_io = attr_io;
	SET_NETDEV_DEV(dev, &pdev->dev);

	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);

	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
			  dev->name, dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}

	err = orinoco_nortel_hw_init(card);
	if (err) {
		printk(KERN_ERR PFX "Hardware initialization failed\n");
		goto fail;
	}

	err = orinoco_nortel_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}

	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot register network device\n");
		goto fail;
	}

	pci_set_drvdata(pdev, dev);
	printk(KERN_DEBUG "%s: " DRIVER_NAME " at %s\n", dev->name,
	       pci_name(pdev));

	return 0;

 fail:
	free_irq(pdev->irq, dev);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);

 fail_alloc:
	pci_iounmap(pdev, hermes_io);

 fail_map_hermes:
	pci_iounmap(pdev, attr_io);

 fail_map_attr:
	pci_iounmap(pdev, bridge_io);

 fail_map_bridge:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 10
0
static int
airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
	struct orinoco_private *priv;
	struct net_device *dev;
	struct airport *card;
	unsigned long phys_addr;
	hermes_t *hw;

	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
		printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
		return -ENODEV;
	}

	/* Allocate space for private device-specific data */
	dev = alloc_orinocodev(sizeof(*card), airport_hard_reset);
	if (! dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		return -ENODEV;
	}
	priv = netdev_priv(dev);
	card = priv->card;

	hw = &priv->hw;
	card->mdev = mdev;

	if (macio_request_resource(mdev, 0, "airport")) {
		printk(KERN_ERR PFX "can't request IO resource !\n");
		free_orinocodev(dev);
		return -EBUSY;
	}

	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &mdev->ofdev.dev);

	macio_set_drvdata(mdev, dev);

	/* Setup interrupts & base address */
	dev->irq = macio_irq(mdev, 0);
	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
	dev->base_addr = phys_addr;
	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
	if (!card->vaddr) {
		printk(KERN_ERR PFX "ioremap() failed\n");
		goto failed;
	}

	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);
		
	/* Power up card */
	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, macio_get_of_node(mdev), 0, 1);
	ssleep(1);

	/* Reset it before we get the interrupt */
	hermes_init(hw);

	if (request_irq(dev->irq, orinoco_interrupt, 0, dev->name, dev)) {
		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", dev->irq);
		goto failed;
	}
	card->irq_requested = 1;

	/* Tell the stack we exist */
	if (register_netdev(dev) != 0) {
		printk(KERN_ERR PFX "register_netdev() failed\n");
		goto failed;
	}
	printk(KERN_DEBUG PFX "Card registered for interface %s\n", dev->name);
	card->ndev_registered = 1;
	return 0;
 failed:
	airport_detach(mdev);
	return -ENODEV;
}				/* airport_attach */
Exemplo n.º 11
0
static int orinoco_tmd_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err;
	struct orinoco_private *priv;
	struct orinoco_pci_card *card;
	void __iomem *hermes_io, *bridge_io;

	err = pci_enable_device(pdev);
	if (err) {
;
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err) {
;
		goto fail_resources;
	}

	bridge_io = pci_iomap(pdev, 1, 0);
	if (!bridge_io) {
;
		err = -EIO;
		goto fail_map_bridge;
	}

	hermes_io = pci_iomap(pdev, 2, 0);
	if (!hermes_io) {
;
		err = -EIO;
		goto fail_map_hermes;
	}

	/* Allocate network device */
	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
				orinoco_tmd_cor_reset, NULL);
	if (!priv) {
;
		err = -ENOMEM;
		goto fail_alloc;
	}

	card = priv->card;
	card->bridge_io = bridge_io;

	hermes_struct_init(&priv->hw, hermes_io, HERMES_16BIT_REGSPACING);

	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
			  DRIVER_NAME, priv);
	if (err) {
;
		err = -EBUSY;
		goto fail_irq;
	}

	err = orinoco_tmd_cor_reset(priv);
	if (err) {
;
		goto fail;
	}

	err = orinoco_init(priv);
	if (err) {
;
		goto fail;
	}

	err = orinoco_if_add(priv, 0, 0, NULL);
	if (err) {
;
		goto fail;
	}

	pci_set_drvdata(pdev, priv);

	return 0;

 fail:
	free_irq(pdev->irq, priv);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(priv);

 fail_alloc:
	pci_iounmap(pdev, hermes_io);

 fail_map_hermes:
	pci_iounmap(pdev, bridge_io);

 fail_map_bridge:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 12
0
/*
 * Initialise a card. Mostly similar to PLX code.
 */
static int orinoco_pci_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err = 0;
	unsigned long pci_iorange;
	u16 *pci_ioaddr = NULL;
	unsigned long pci_iolen;
	struct orinoco_private *priv = NULL;
	struct net_device *dev = NULL;
	int netdev_registered = 0;

	err = pci_enable_device(pdev);
	if (err)
		return -EIO;

	/* Resource 0 is mapped to the hermes registers */
	pci_iorange = pci_resource_start(pdev, 0);
	pci_iolen = pci_resource_len(pdev, 0);
	pci_ioaddr = ioremap(pci_iorange, pci_iolen);
	if (! pci_iorange)
		goto fail;

	/* Usual setup of structures */
	dev = alloc_orinocodev(0, NULL);
	if (! dev) {
		err = -ENOMEM;
		goto fail;
	}
	priv = dev->priv;

	dev->base_addr = (int) pci_ioaddr;
        dev->mem_start = (unsigned long) pci_iorange;
        dev->mem_end = ((unsigned long) pci_iorange) + pci_iolen - 1;

	SET_MODULE_OWNER(dev);

	printk(KERN_DEBUG
	       "Detected Orinoco/Prism2 PCI device at %s, mem:0x%lX to 0x%lX -> 0x%p, irq:%d\n",
	       pdev->slot_name, dev->mem_start, dev->mem_end, pci_ioaddr, pdev->irq);

	hermes_struct_init(&(priv->hw), dev->base_addr, HERMES_MEM, HERMES_32BIT_REGSPACING);
	pci_set_drvdata(pdev, dev);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev);
	if (err) {
		printk(KERN_ERR "orinoco_pci: Error allocating IRQ %d.\n", pdev->irq);
		err = -EBUSY;
		goto fail;
	}
	dev->irq = pdev->irq;
	/* Perform a COR reset to start the card */
	if(orinoco_pci_cor_reset(priv) != 0) {
		printk(KERN_ERR "%s: Failed to start the card\n", dev->name);
		err = -ETIMEDOUT;
		goto fail;
	}

	/* Override the normal firmware detection - the Prism 2.5 PCI
	 * cards look like Lucent firmware but are actually Intersil */
	priv->firmware_type = FIRMWARE_TYPE_INTERSIL;

	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR "%s: Failed to register net device\n", dev->name);
		goto fail;
	}
	netdev_registered = 1;

        return 0;               /* succeeded */
 fail:
	if (dev) {
		if (netdev_registered)
			unregister_netdev(dev);

		if (dev->irq)
			free_irq(dev->irq, dev);

		kfree(dev);
	}

	if (pci_ioaddr)
		iounmap(pci_ioaddr);

	return err;
}
Exemplo n.º 13
0
static int orinoco_tmd_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err = 0;
	u32 reg, addr;
	struct orinoco_private *priv = NULL;
	unsigned long pccard_ioaddr = 0;
	unsigned long pccard_iolen = 0;
	struct net_device *dev = NULL;

	err = pci_enable_device(pdev);
	if (err)
		return -EIO;

	printk(KERN_DEBUG "TMD setup\n");
	pccard_ioaddr = pci_resource_start(pdev, 2);
	pccard_iolen = pci_resource_len(pdev, 2);
	if (! request_region(pccard_ioaddr, pccard_iolen, dev_info)) {
		printk(KERN_ERR "orinoco_tmd: I/O resource at 0x%lx len 0x%lx busy\n",
			pccard_ioaddr, pccard_iolen);
		pccard_ioaddr = 0;
		err = -EBUSY;
		goto fail;
	}
	addr = pci_resource_start(pdev, 1);
	outb(COR_VALUE, addr);
	mdelay(1);
	reg = inb(addr);
	if (reg != COR_VALUE) {
		printk(KERN_ERR "orinoco_tmd: Error setting TMD COR values %x should be %x\n", reg, COR_VALUE);
		err = -EIO;
		goto fail;
	}

	dev = alloc_orinocodev(0, NULL);
	if (! dev) {
		err = -ENOMEM;
		goto fail;
	}

	priv = dev->priv;
	dev->base_addr = pccard_ioaddr;
	SET_MODULE_OWNER(dev);

	printk(KERN_DEBUG
	       "Detected Orinoco/Prism2 TMD device at %s irq:%d, io addr:0x%lx\n",
	       pci_name(pdev), pdev->irq, pccard_ioaddr);

	hermes_struct_init(&(priv->hw), dev->base_addr,
			HERMES_IO, HERMES_16BIT_REGSPACING);
	pci_set_drvdata(pdev, dev);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name,
			  dev);
	if (err) {
		printk(KERN_ERR "orinoco_tmd: Error allocating IRQ %d.\n",
		       pdev->irq);
		err = -EBUSY;
		goto fail;
	}
	dev->irq = pdev->irq;

	err = register_netdev(dev);
	if (err)
		goto fail;

	return 0;		/* succeeded */

 fail:	
	printk(KERN_DEBUG "orinoco_tmd: init_one(), FAIL!\n");

	if (dev) {
		if (dev->irq)
			free_irq(dev->irq, dev);
		
		kfree(dev);
	}

	if (pccard_ioaddr)
		release_region(pccard_ioaddr, pccard_iolen);

	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 14
0
static int
airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
{
	struct orinoco_private *priv;
	struct airport *card;
	unsigned long phys_addr;
	hermes_t *hw;

	if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) {
		printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n");
		return -ENODEV;
	}

	/* Allocate space for private device-specific data */
	priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev,
				airport_hard_reset, NULL);
	if (!priv) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		return -ENODEV;
	}
	card = priv->card;

	hw = &priv->hw;
	card->mdev = mdev;

	if (macio_request_resource(mdev, 0, DRIVER_NAME)) {
		printk(KERN_ERR PFX "can't request IO resource !\n");
		free_orinocodev(priv);
		return -EBUSY;
	}

	macio_set_drvdata(mdev, priv);

	/* Setup interrupts & base address */
	card->irq = macio_irq(mdev, 0);
	phys_addr = macio_resource_start(mdev, 0);  /* Physical address */
	printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr);
	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
	if (!card->vaddr) {
		printk(KERN_ERR PFX "ioremap() failed\n");
		goto failed;
	}

	hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING);

	/* Power up card */
	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE,
			  macio_get_of_node(mdev), 0, 1);
	ssleep(1);

	/* Reset it before we get the interrupt */
	hermes_init(hw);

	if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
		printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq);
		goto failed;
	}
	card->irq_requested = 1;

	/* 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, phys_addr, card->irq) != 0) {
		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
		goto failed;
	}
	card->ndev_registered = 1;
	return 0;
 failed:
	airport_detach(mdev);
	return -ENODEV;
}				/* airport_attach */
Exemplo n.º 15
0
/*
 * Initialise a card. Mostly similar to PLX code.
 */
static int orinoco_pci_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err = 0;
	unsigned long pci_iorange;
	u16 __iomem *pci_ioaddr = NULL;
	unsigned long pci_iolen;
	struct orinoco_private *priv = NULL;
	struct orinoco_pci_card *card;
	struct net_device *dev = NULL;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err != 0) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	/* Resource 0 is mapped to the hermes registers */
	pci_iorange = pci_resource_start(pdev, 0);
	pci_iolen = pci_resource_len(pdev, 0);
	pci_ioaddr = ioremap(pci_iorange, pci_iolen);
	if (!pci_iorange) {
		printk(KERN_ERR PFX "Cannot remap hardware registers\n");
		goto fail_map;
	}

	/* Allocate network device */
	dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset);
	if (! dev) {
		err = -ENOMEM;
		goto fail_alloc;
	}

	priv = netdev_priv(dev);
	card = priv->card;
	card->pci_ioaddr = pci_ioaddr;
	dev->mem_start = pci_iorange;
	dev->mem_end = pci_iorange + pci_iolen - 1;
	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING);

	printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n",
	       pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
			  dev->name, dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}
	dev->irq = pdev->irq;

	/* Perform a COR reset to start the card */
	err = orinoco_pci_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}

	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR PFX "Failed to register net device\n");
		goto fail;
	}

	pci_set_drvdata(pdev, dev);

	return 0;

 fail:
	free_irq(pdev->irq, dev);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);

 fail_alloc:
	iounmap(pci_ioaddr);

 fail_map:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 16
0
static struct net_device *
airport_attach(struct device_node *of_node)
{
	struct orinoco_private *priv;
	struct net_device *dev;
	struct airport *card;
	unsigned long phys_addr;
	hermes_t *hw;

	if (of_node->n_addrs < 1 || of_node->n_intrs < 1) {
		printk(KERN_ERR "airport: wrong interrupt/addresses in OF tree\n");
		return NULL;
	}

	/* Allocate space for private device-specific data */
	dev = alloc_orinocodev(sizeof(*card), airport_hard_reset);
	if (! dev) {
		printk(KERN_ERR "airport: can't allocate device datas\n");
		return NULL;
	}
	priv = dev->priv;
	card = priv->card;

	hw = &priv->hw;
	card->node = of_node;

	if (! request_OF_resource(of_node, 0, " (airport)")) {
		printk(KERN_ERR "airport: can't request IO resource !\n");
		kfree(dev);
		return NULL;
	}

	dev->name[0] = '\0';	/* register_netdev will give us an ethX name */
	SET_MODULE_OWNER(dev);

	/* Setup interrupts & base address */
	dev->irq = of_node->intrs[0].line;
	phys_addr = of_node->addrs[0].address;  /* Physical address */
	printk(KERN_DEBUG "Airport at physical address %lx\n", phys_addr);
	dev->base_addr = phys_addr;
	card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN);
	if (! card->vaddr) {
		printk("airport: ioremap() failed\n");
		goto failed;
	}

	hermes_struct_init(hw, (ulong)card->vaddr,
			HERMES_MEM, HERMES_16BIT_REGSPACING);
		
	/* Power up card */
	pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, card->node, 0, 1);
	current->state = TASK_UNINTERRUPTIBLE;
	schedule_timeout(HZ);

	/* Reset it before we get the interrupt */
	hermes_init(hw);

	if (request_irq(dev->irq, orinoco_interrupt, 0, "Airport", (void *)priv)) {
		printk(KERN_ERR "airport: Couldn't get IRQ %d\n", dev->irq);
		goto failed;
	}
	card->irq_requested = 1;

	/* Tell the stack we exist */
	if (register_netdev(dev) != 0) {
		printk(KERN_ERR "airport: register_netdev() failed\n");
		goto failed;
	}
	printk(KERN_DEBUG "airport: card registered for interface %s\n", dev->name);
	card->ndev_registered = 1;

#ifdef CONFIG_PMAC_PBOOK
	pmu_register_sleep_notifier(&airport_sleep_notifier);
#endif
	return dev;
	
 failed:
	airport_detach(dev);
	return NULL;
}				/* airport_attach */
Exemplo n.º 17
0
static int orinoco_pci_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err;
	struct orinoco_private *priv;
	struct orinoco_pci_card *card;
	void __iomem *hermes_io;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	hermes_io = pci_iomap(pdev, 0, 0);
	if (!hermes_io) {
		printk(KERN_ERR PFX "Cannot remap chipset registers\n");
		err = -EIO;
		goto fail_map_hermes;
	}

	/* Allocate network device */
	priv = alloc_orinocodev(sizeof(*card), &pdev->dev,
				orinoco_pci_cor_reset, NULL);
	if (!priv) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		err = -ENOMEM;
		goto fail_alloc;
	}

	card = priv->card;

	hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING);

	err = request_irq(pdev->irq, orinoco_interrupt, IRQF_SHARED,
			  DRIVER_NAME, priv);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}

	err = orinoco_pci_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}

	err = orinoco_init(priv);
	if (err) {
		printk(KERN_ERR PFX "orinoco_init() failed\n");
		goto fail;
	}

	err = orinoco_if_add(priv, 0, 0, NULL);
	if (err) {
		printk(KERN_ERR PFX "orinoco_if_add() failed\n");
		goto fail_wiphy;
	}

	pci_set_drvdata(pdev, priv);

	return 0;

 fail_wiphy:
	wiphy_unregister(priv_to_wiphy(priv));
 fail:
	free_irq(pdev->irq, priv);

 fail_irq:
	free_orinocodev(priv);

 fail_alloc:
	pci_iounmap(pdev, hermes_io);

 fail_map_hermes:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}
static int orinoco_plx_init_one(struct pci_dev *pdev,
				const struct pci_device_id *ent)
{
	int err = 0;
	u16 *attr_mem = NULL;
	u32 reg, addr;
	struct orinoco_private *priv = NULL;
	unsigned long pccard_ioaddr = 0;
	unsigned long pccard_iolen = 0;
	struct net_device *dev = NULL;
	int i;

	err = pci_enable_device(pdev);
	if (err)
		return -EIO;

	/* Resource 2 is mapped to the PCMCIA space */
	attr_mem = ioremap(pci_resource_start(pdev, 2), PAGE_SIZE);
	if (! attr_mem)
		goto fail;

	printk(KERN_DEBUG "orinoco_plx: CIS: ");
	for (i = 0; i < 16; i++) {
		printk("%02X:", (int)attr_mem[i]);
	}
	printk("\n");

	/* Verify whether PC card is present */
	/* FIXME: we probably need to be smarted about this */
	if (memcmp(attr_mem, cis_magic, sizeof(cis_magic)) != 0) {
		printk(KERN_ERR "orinoco_plx: The CIS value of Prism2 PC card is invalid.\n");
		err = -EIO;
		goto fail;
	}

	/* PCMCIA COR is the first byte following CIS: this write should
	 * enable I/O mode and select level-triggered interrupts */
	attr_mem[COR_OFFSET] = COR_VALUE;
	mdelay(1);
	reg = attr_mem[COR_OFFSET];
	if (reg != COR_VALUE) {
		printk(KERN_ERR "orinoco_plx: Error setting COR value (reg=%x)\n", reg);
		goto fail;
	}			

	iounmap(attr_mem);
	attr_mem = NULL; /* done with this now, it seems */

	/* bjoern: We need to tell the card to enable interrupts, in
	   case the serial eprom didn't do this already. See the
	   PLX9052 data book, p8-1 and 8-24 for reference. */
	addr = pci_resource_start(pdev, 1);
	reg = 0;
	reg = inl(addr+PLX_INTCSR);
	if (reg & PLX_INTCSR_INTEN)
		printk(KERN_DEBUG "orinoco_plx: "
		       "Local Interrupt already enabled\n");
	else {
		reg |= PLX_INTCSR_INTEN;
		outl(reg, addr+PLX_INTCSR);
		reg = inl(addr+PLX_INTCSR);
		if(!(reg & PLX_INTCSR_INTEN)) {
			printk(KERN_ERR "orinoco_plx: "
			       "Couldn't enable Local Interrupts\n");
			goto fail;
		}
	}

	/* and 3 to the PCMCIA slot I/O address space */
	pccard_ioaddr = pci_resource_start(pdev, 3);
	pccard_iolen = pci_resource_len(pdev, 3);
	if (! request_region(pccard_ioaddr, pccard_iolen, dev_info)) {
		printk(KERN_ERR "orinoco_plx: I/O resource 0x%lx @ 0x%lx busy\n",
		       pccard_iolen, pccard_ioaddr);
		pccard_ioaddr = 0;
		err = -EBUSY;
		goto fail;
	}

	dev = alloc_orinocodev(0, NULL);
	if (! dev) {
		err = -ENOMEM;
		goto fail;
	}

	priv = dev->priv;
	dev->base_addr = pccard_ioaddr;
	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	printk(KERN_DEBUG
	       "Detected Orinoco/Prism2 PLX device at %s irq:%d, io addr:0x%lx\n",
	       pci_name(pdev), pdev->irq, pccard_ioaddr);

	hermes_struct_init(&(priv->hw), dev->base_addr,
			HERMES_IO, HERMES_16BIT_REGSPACING);
	pci_set_drvdata(pdev, dev);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, dev->name, dev);
	if (err) {
		printk(KERN_ERR "orinoco_plx: Error allocating IRQ %d.\n", pdev->irq);
		err = -EBUSY;
		goto fail;
	}
	dev->irq = pdev->irq;

	err = register_netdev(dev);
	if (err)
		goto fail;

	return 0;		/* succeeded */

 fail:	
	printk(KERN_DEBUG "orinoco_plx: init_one(), FAIL!\n");

	if (dev) {
		if (dev->irq)
			free_irq(dev->irq, dev);
		
		free_netdev(dev);
	}

	if (pccard_ioaddr)
		release_region(pccard_ioaddr, pccard_iolen);

	if (attr_mem)
		iounmap(attr_mem);

	pci_disable_device(pdev);

	return err;
}
Exemplo n.º 19
0
static int nortel_pci_init_one(struct pci_dev *pdev,
			       const struct pci_device_id *ent)
{
	int err;
	struct orinoco_private *priv;
	struct nortel_pci_card *card;
	struct net_device *dev;
	void __iomem *iomem;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR PFX "Cannot enable PCI device\n");
		return err;
	}

	err = pci_request_regions(pdev, DRIVER_NAME);
	if (err != 0) {
		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
		goto fail_resources;
	}

	iomem = pci_iomap(pdev, 2, 0);
	if (!iomem) {
		err = -ENOMEM;
		goto fail_map_io;
	}

	/* Allocate network device */
	dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
	if (!dev) {
		printk(KERN_ERR PFX "Cannot allocate network device\n");
		err = -ENOMEM;
		goto fail_alloc;
	}

	priv = netdev_priv(dev);
	card = priv->card;
	card->iobase1 = pci_resource_start(pdev, 0);
	card->iobase2 = pci_resource_start(pdev, 1);
	dev->base_addr = pci_resource_start(pdev, 2);
	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &pdev->dev);

	hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);

	printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
	       "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);

	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
			  dev->name, dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
		err = -EBUSY;
		goto fail_irq;
	}
	dev->irq = pdev->irq;

	err = nortel_pci_hw_init(card);
	if (err) {
		printk(KERN_ERR PFX "Hardware initialization failed\n");
		goto fail;
	}

	err = nortel_pci_cor_reset(priv);
	if (err) {
		printk(KERN_ERR PFX "Initial reset failed\n");
		goto fail;
	}


	err = register_netdev(dev);
	if (err) {
		printk(KERN_ERR PFX "Cannot register network device\n");
		goto fail;
	}

	pci_set_drvdata(pdev, dev);

	return 0;

 fail:
	free_irq(pdev->irq, dev);

 fail_irq:
	pci_set_drvdata(pdev, NULL);
	free_orinocodev(dev);

 fail_alloc:
	pci_iounmap(pdev, iomem);

 fail_map_io:
	pci_release_regions(pdev);

 fail_resources:
	pci_disable_device(pdev);

	return err;
}