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