Пример #1
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;
}
Пример #2
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;
}
Пример #3
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;
}