static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id) { int err; struct dt3155_priv *pd; err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); if (err) return -ENODEV; pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL); if (!pd) return -ENOMEM; err = v4l2_device_register(&pdev->dev, &pd->v4l2_dev); if (err) return err; pd->vdev = dt3155_vdev; pd->vdev.v4l2_dev = &pd->v4l2_dev; video_set_drvdata(&pd->vdev, pd); /* for use in video_fops */ pd->pdev = pdev; pd->std = V4L2_STD_625_50; pd->csr2 = VT_50HZ; pd->width = 768; pd->height = 576; INIT_LIST_HEAD(&pd->dmaq); mutex_init(&pd->mux); pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */ pd->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; pd->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; pd->vidq.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; pd->vidq.ops = &q_ops; pd->vidq.mem_ops = &vb2_dma_contig_memops; pd->vidq.drv_priv = pd; pd->vidq.min_buffers_needed = 2; pd->vidq.gfp_flags = GFP_DMA32; pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */ pd->vidq.dev = &pdev->dev; pd->vdev.queue = &pd->vidq; err = vb2_queue_init(&pd->vidq); if (err < 0) goto err_v4l2_dev_unreg; spin_lock_init(&pd->lock); pd->config = ACQ_MODE_EVEN; err = pci_enable_device(pdev); if (err) goto err_v4l2_dev_unreg; err = pci_request_region(pdev, 0, pci_name(pdev)); if (err) goto err_pci_disable; pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0)); if (!pd->regs) { err = -ENOMEM; goto err_free_reg; } err = dt3155_init_board(pd); if (err) goto err_iounmap; err = request_irq(pd->pdev->irq, dt3155_irq_handler_even, IRQF_SHARED, DT3155_NAME, pd); if (err) goto err_iounmap; err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1); if (err) goto err_free_irq; dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor); return 0; /* success */ err_free_irq: free_irq(pd->pdev->irq, pd); err_iounmap: pci_iounmap(pdev, pd->regs); err_free_reg: pci_release_region(pdev, 0); err_pci_disable: pci_disable_device(pdev); err_v4l2_dev_unreg: v4l2_device_unregister(&pd->v4l2_dev); return err; }
int __ref cpci_configure_slot(struct slot *slot) { struct pci_bus *parent; int fn; dbg("%s - enter", __func__); if (slot->dev == NULL) { dbg("pci_dev null, finding %02x:%02x:%x", slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn)); slot->dev = pci_get_slot(slot->bus, slot->devfn); } /* Still NULL? Well then scan for it! */ if (slot->dev == NULL) { int n; dbg("pci_dev still null"); /* * This will generate pci_dev structures for all functions, but * we will only call this case when lookup fails. */ n = pci_scan_slot(slot->bus, slot->devfn); dbg("%s: pci_scan_slot returned %d", __func__, n); slot->dev = pci_get_slot(slot->bus, slot->devfn); if (slot->dev == NULL) { err("Could not find PCI device for slot %02x", slot->number); return -ENODEV; } } parent = slot->dev->bus; for (fn = 0; fn < 8; fn++) { struct pci_dev *dev; dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); if (!dev) continue; if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) { /* Find an unused bus number for the new bridge */ struct pci_bus *child; unsigned char busnr, start = parent->secondary; unsigned char end = parent->subordinate; for (busnr = start; busnr <= end; busnr++) { if (!pci_find_bus(pci_domain_nr(parent), busnr)) break; } if (busnr >= end) { err("No free bus for hot-added bridge\n"); pci_dev_put(dev); continue; } child = pci_add_new_bus(parent, dev, busnr); if (!child) { err("Cannot add new bus for %s\n", pci_name(dev)); pci_dev_put(dev); continue; } child->subordinate = pci_do_scan_bus(child); pci_bus_size_bridges(child); } pci_dev_put(dev); } pci_bus_assign_resources(parent); pci_bus_add_devices(parent); pci_enable_bridges(parent); dbg("%s - exit", __func__); return 0; }
/** * stmmac_pci_probe * * @pdev: pci device pointer * @id: pointer to table of device id/id's. * * Description: This probing function gets called for all PCI devices which * match the ID table and are not "owned" by other driver yet. This function * gets passed a "struct pci_dev *" for each device whose entry in the ID table * matches the device. The probe functions returns zero when the driver choose * to take "ownership" of the device or an error code(-ve no) otherwise. */ static int stmmac_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct stmmac_pci_info *info = (struct stmmac_pci_info *)id->driver_data; struct plat_stmmacenet_data *plat; struct stmmac_resources res; int i; int ret; plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); if (!plat) return -ENOMEM; plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(*plat->mdio_bus_data), GFP_KERNEL); if (!plat->mdio_bus_data) return -ENOMEM; plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), GFP_KERNEL); if (!plat->dma_cfg) return -ENOMEM; /* Enable pci device */ ret = pcim_enable_device(pdev); if (ret) { dev_err(&pdev->dev, "%s: ERROR: failed to enable device\n", __func__); return ret; } /* Get the base address of device */ for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { if (pci_resource_len(pdev, i) == 0) continue; ret = pcim_iomap_regions(pdev, BIT(i), pci_name(pdev)); if (ret) return ret; break; } pci_set_master(pdev); if (info) { info->pdev = pdev; if (info->setup) { ret = info->setup(plat, info); if (ret) return ret; } } else stmmac_default_data(plat); pci_enable_msi(pdev); memset(&res, 0, sizeof(res)); res.addr = pcim_iomap_table(pdev)[i]; res.wol_irq = pdev->irq; res.irq = pdev->irq; return stmmac_dvr_probe(&pdev->dev, plat, &res); }
static int r82600_probe1(struct pci_dev *pdev, int dev_idx) { struct mem_ctl_info *mci; u8 dramcr; u32 eapr; u32 scrub_disabled; u32 sdram_refresh_rate; struct r82600_error_info discard; debugf0("%s()\n", __func__); pci_read_config_byte(pdev, R82600_DRAMC, &dramcr); pci_read_config_dword(pdev, R82600_EAP, &eapr); scrub_disabled = eapr & BIT(31); sdram_refresh_rate = dramcr & (BIT(0) | BIT(1)); debugf2("%s(): sdram refresh rate = %#0x\n", __func__, sdram_refresh_rate); debugf2("%s(): DRAMC register = %#0x\n", __func__, dramcr); mci = edac_mc_alloc(0, R82600_NR_CSROWS, R82600_NR_CHANS, 0); if (mci == NULL) return -ENOMEM; debugf0("%s(): mci = %p\n", __func__, mci); mci->dev = &pdev->dev; mci->mtype_cap = MEM_FLAG_RDDR | MEM_FLAG_DDR; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; /* FIXME try to work out if the chip leads have been used for COM2 * instead on this board? [MA6?] MAYBE: */ /* On the R82600, the pins for memory bits 72:65 - i.e. the * * EC bits are shared with the pins for COM2 (!), so if COM2 * * is enabled, we assume COM2 is wired up, and thus no EDAC * * is possible. */ mci->edac_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; if (ecc_enabled(dramcr)) { if (scrub_disabled) debugf3("%s(): mci = %p - Scrubbing disabled! EAP: " "%#0x\n", __func__, mci, eapr); } else mci->edac_cap = EDAC_FLAG_NONE; mci->mod_name = EDAC_MOD_STR; mci->mod_ver = R82600_REVISION; mci->ctl_name = "R82600"; mci->dev_name = pci_name(pdev); mci->edac_check = r82600_check; mci->ctl_page_to_phys = NULL; r82600_init_csrows(mci, pdev, dramcr); r82600_get_error_info(mci, &discard); /* clear counters */ /* Here we assume that we will never see multiple instances of this * type of memory controller. The ID is therefore hardcoded to 0. */ if (edac_mc_add_mc(mci)) { debugf3("%s(): failed edac_mc_add_mc()\n", __func__); goto fail; } /* get this far and it's successful */ if (disable_hardware_scrub) { debugf3("%s(): Disabling Hardware Scrub (scrub on error)\n", __func__); pci_write_bits32(pdev, R82600_EAP, BIT(31), BIT(31)); } /* allocating generic PCI control info */ r82600_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); if (!r82600_pci) { printk(KERN_WARNING "%s(): Unable to create PCI control\n", __func__); printk(KERN_WARNING "%s(): PCI error report via EDAC not setup\n", __func__); } debugf3("%s(): success\n", __func__); return 0; fail: edac_mc_free(mci); return -ENODEV; }
const char *usnic_vnic_pci_name(struct usnic_vnic *vnic) { return pci_name(usnic_vnic_get_pdev(vnic)); }
static int vfio_msi_set_vector_signal(struct vfio_pci_device *vdev, int vector, int fd, bool msix) { struct pci_dev *pdev = vdev->pdev; int irq = msix ? vdev->msix[vector].vector : pdev->irq + vector; char *name = msix ? "vfio-msix" : "vfio-msi"; struct eventfd_ctx *trigger; int ret; if (vector >= vdev->num_ctx) return -EINVAL; if (vdev->ctx[vector].trigger) { free_irq(irq, vdev->ctx[vector].trigger); irq_bypass_unregister_producer(&vdev->ctx[vector].producer); kfree(vdev->ctx[vector].name); eventfd_ctx_put(vdev->ctx[vector].trigger); vdev->ctx[vector].trigger = NULL; } if (fd < 0) return 0; vdev->ctx[vector].name = kasprintf(GFP_KERNEL, "%s[%d](%s)", name, vector, pci_name(pdev)); if (!vdev->ctx[vector].name) return -ENOMEM; trigger = eventfd_ctx_fdget(fd); if (IS_ERR(trigger)) { kfree(vdev->ctx[vector].name); return PTR_ERR(trigger); } /* * The MSIx vector table resides in device memory which may be cleared * via backdoor resets. We don't allow direct access to the vector * table so even if a userspace driver attempts to save/restore around * such a reset it would be unsuccessful. To avoid this, restore the * cached value of the message prior to enabling. */ if (msix) { struct msi_msg msg; get_cached_msi_msg(irq, &msg); pci_write_msi_msg(irq, &msg); } ret = request_irq(irq, vfio_msihandler, 0, vdev->ctx[vector].name, trigger); if (ret) { kfree(vdev->ctx[vector].name); eventfd_ctx_put(trigger); return ret; } vdev->ctx[vector].producer.token = trigger; vdev->ctx[vector].producer.irq = irq; ret = irq_bypass_register_producer(&vdev->ctx[vector].producer); if (unlikely(ret)) dev_info(&pdev->dev, "irq bypass producer (token %p) registration fails: %d\n", vdev->ctx[vector].producer.token, ret); vdev->ctx[vector].trigger = trigger; return 0; }
static int orinoco_tmd_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int err = 0; struct orinoco_private *priv = NULL; struct orinoco_tmd_card *card; struct net_device *dev = NULL; void __iomem *mem; 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; } mem = pci_iomap(pdev, 2, 0); if (! mem) { err = -ENOMEM; goto fail_iomap; } /* Allocate network device */ dev = alloc_orinocodev(sizeof(*card), orinoco_tmd_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->tmd_io = 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, mem, HERMES_16BIT_REGSPACING); printk(KERN_DEBUG PFX "Detected Orinoco/Prism2 TMD 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 = orinoco_tmd_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, mem); fail_iomap: pci_release_regions(pdev); fail_resources: pci_disable_device(pdev); return err; }
static int lpp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { DEV *dev; int rc; uint minor; unsigned long plx_base; dbg("%s(): pci_dev->vendor=%04X device=%04X\n pci_device_id->vendor=%04X device=%04X", __FUNCTION__, pdev->vendor, pdev->device, ent->vendor, ent->device); //return -ENODEV; dev = kmalloc (sizeof(DEV), GFP_KERNEL); if (!dev) return -ENOMEM; memset (dev, 0x00, sizeof (*dev)); /* Enable tasklet for the device */ tasklet_init(&dev->Dpc, DpcForIsr, (unsigned long) dev); /* enable device (incl. PCI PM wakeup), and bus-mastering */ rc = pci_enable_device(pdev); dbg1("pci_enable_device()=%d dev=%p", rc, dev); if (rc) goto err_out_free; rc = pci_set_mwi(pdev); dbg1("pci_set_mwi()=%d", rc); if (rc) goto err_out_disable; rc = pci_request_regions(pdev, DRIVER_MOD_NAME); dbg1("pci_request_regions()=%d", rc); if (rc) goto err_out_mwi; if (pdev->irq < 2) { rc = -EIO; printk(KERN_ERR PFX "invalid irq (%d) for pci dev %s\n", pdev->irq, pci_name(pdev)); // pdev->slot_name); goto err_out_res; } plx_base = pci_resource_start (pdev, 1); dev->PlxIntCsrPort = plx_base + P9050_INTCSR; dev->cport = pci_resource_start (pdev, 2); dev->rport = pci_resource_start (pdev, 3); dev->wport = dev->rport; dev->wtcport = pci_resource_start (pdev, 5); dev->irq = pdev->irq; /* pio_end = pci_resource_end (pdev, 0); pio_flags = pci_resource_flags (pdev, 0); pio_len = pci_resource_len (pdev, 0); */ // rc = register_netdev(dev); // if (rc) goto err_out_iomap; /* select a "subminor" number (part of a minor number) */ down (&minor_table_mutex); for (minor = MAX_LPCS; minor < MAX_DEVICES; ++minor) { if (minor_table[minor] == NULL) break; } if (minor >= MAX_DEVICES) { info ("Too many devices plugged in, can not handle this device."); rc = -EINVAL; goto err_minor_table; } dev->minor = minor; minor_table[minor] = dev; pci_set_drvdata(pdev, dev); #ifdef CONFIG_DEVFS_FS devfs_mk_cdev(MKDEV(major, minor), S_IFCHR | S_IRUGO | S_IWUGO, "lpc/%d", minor); #endif up (&minor_table_mutex); dbg1("%s(): minor=%d return 0", __FUNCTION__, minor); return 0; err_minor_table: up (&minor_table_mutex); //err_out_iomap: // iounmap(regs); err_out_res: pci_release_regions(pdev); err_out_mwi: pci_clear_mwi(pdev); err_out_disable: pci_disable_device(pdev); err_out_free: tasklet_kill(&dev->Dpc); kfree(dev); dbg1("%s(): return %d", __FUNCTION__, rc); return rc; }
int mthca_reset(struct mthca_dev *mdev) { int i; int err = 0; u32 *hca_header = NULL; u32 *bridge_header = NULL; struct pci_dev *bridge = NULL; int bridge_pcix_cap = 0; int hca_pcie_cap = 0; int hca_pcix_cap = 0; u16 devctl; u16 linkctl; #define MTHCA_RESET_OFFSET 0xf0010 #define MTHCA_RESET_VALUE swab32(1) /* * Reset the chip. This is somewhat ugly because we have to * save off the PCI header before reset and then restore it * after the chip reboots. We skip config space offsets 22 * and 23 since those have a special meaning. * * To make matters worse, for Tavor (PCI-X HCA) we have to * find the associated bridge device and save off its PCI * header as well. */ if (!(mdev->mthca_flags & MTHCA_FLAG_PCIE)) { /* Look for the bridge -- its device ID will be 2 more than HCA's device ID. */ #ifdef __linux__ while ((bridge = pci_get_device(mdev->pdev->vendor, mdev->pdev->device + 2, bridge)) != NULL) { if (bridge->hdr_type == PCI_HEADER_TYPE_BRIDGE && bridge->subordinate == mdev->pdev->bus) { mthca_dbg(mdev, "Found bridge: %s\n", pci_name(bridge)); break; } } if (!bridge) { /* * Didn't find a bridge for a Tavor device -- * assume we're in no-bridge mode and hope for * the best. */ mthca_warn(mdev, "No bridge found for %s\n", pci_name(mdev->pdev)); } #else mthca_warn(mdev, "Reset on PCI-X is not supported.\n"); goto out; #endif } /* For Arbel do we need to save off the full 4K PCI Express header?? */ hca_header = kmalloc(256, GFP_KERNEL); if (!hca_header) { err = -ENOMEM; mthca_err(mdev, "Couldn't allocate memory to save HCA " "PCI header, aborting.\n"); goto out; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(mdev->pdev, i * 4, hca_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA " "PCI header, aborting.\n"); goto out; } } hca_pcix_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_PCIX); hca_pcie_cap = pci_find_capability(mdev->pdev, PCI_CAP_ID_EXP); #ifdef __linux__ if (bridge) { bridge_header = kmalloc(256, GFP_KERNEL); if (!bridge_header) { err = -ENOMEM; mthca_err(mdev, "Couldn't allocate memory to save HCA " "bridge PCI header, aborting.\n"); goto out; } for (i = 0; i < 64; ++i) { if (i == 22 || i == 23) continue; if (pci_read_config_dword(bridge, i * 4, bridge_header + i)) { err = -ENODEV; mthca_err(mdev, "Couldn't save HCA bridge " "PCI header, aborting.\n"); goto out; } } bridge_pcix_cap = pci_find_capability(bridge, PCI_CAP_ID_PCIX); if (!bridge_pcix_cap) { err = -ENODEV; mthca_err(mdev, "Couldn't locate HCA bridge " "PCI-X capability, aborting.\n"); goto out; } } #endif /* actually hit reset */ { void __iomem *reset = ioremap(pci_resource_start(mdev->pdev, 0) + MTHCA_RESET_OFFSET, 4); if (!reset) { err = -ENOMEM; mthca_err(mdev, "Couldn't map HCA reset register, " "aborting.\n"); goto out; } writel(MTHCA_RESET_VALUE, reset); iounmap(reset); } /* Docs say to wait one second before accessing device */ msleep(1000); /* Now wait for PCI device to start responding again */ { u32 v; int c = 0; for (c = 0; c < 100; ++c) { if (pci_read_config_dword(bridge ? bridge : mdev->pdev, 0, &v)) { err = -ENODEV; mthca_err(mdev, "Couldn't access HCA after reset, " "aborting.\n"); goto out; } if (v != 0xffffffff) goto good; msleep(100); } err = -ENODEV; mthca_err(mdev, "PCI device did not come back after reset, " "aborting.\n"); goto out; } good: /* Now restore the PCI headers */ if (bridge) { if (pci_write_config_dword(bridge, bridge_pcix_cap + 0x8, bridge_header[(bridge_pcix_cap + 0x8) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Upstream " "split transaction control, aborting.\n"); goto out; } if (pci_write_config_dword(bridge, bridge_pcix_cap + 0xc, bridge_header[(bridge_pcix_cap + 0xc) / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge Downstream " "split transaction control, aborting.\n"); goto out; } /* * Bridge control register is at 0x3e, so we'll * naturally restore it last in this loop. */ for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(bridge, i * 4, bridge_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge reg %x, " "aborting.\n", i); goto out; } } if (pci_write_config_dword(bridge, PCI_COMMAND, bridge_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA bridge COMMAND, " "aborting.\n"); goto out; } } if (hca_pcix_cap) { if (pci_write_config_dword(mdev->pdev, hca_pcix_cap, hca_header[hca_pcix_cap / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI-X " "command register, aborting.\n"); goto out; } } if (hca_pcie_cap) { devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL, devctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Device Control register, aborting.\n"); goto out; } linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL, linkctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Link control register, aborting.\n"); goto out; } } for (i = 0; i < 16; ++i) { if (i * 4 == PCI_COMMAND) continue; if (pci_write_config_dword(mdev->pdev, i * 4, hca_header[i])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA reg %x, " "aborting.\n", i); goto out; } } if (pci_write_config_dword(mdev->pdev, PCI_COMMAND, hca_header[PCI_COMMAND / 4])) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA COMMAND, " "aborting.\n"); goto out; } out: #ifdef __linux__ if (bridge) pci_dev_put(bridge); #endif kfree(bridge_header); kfree(hca_header); return err; }
static int __devinit snd_ymfpci_create_gameport(struct snd_ymfpci *chip, int dev, int legacy_ctrl, int legacy_ctrl2) { struct gameport *gp; struct resource *r = NULL; int io_port = joystick_port[dev]; if (!io_port) return -ENODEV; if (chip->pci->device >= 0x0010) { /* YMF 744/754 */ if (io_port == 1) { /* auto-detect */ if (!(io_port = pci_resource_start(chip->pci, 2))) return -ENODEV; } } else { if (io_port == 1) { /* auto-detect */ for (io_port = 0x201; io_port <= 0x205; io_port++) { if (io_port == 0x203) continue; if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL) break; } if (!r) { printk(KERN_ERR "ymfpci: no gameport ports available\n"); return -EBUSY; } } switch (io_port) { case 0x201: legacy_ctrl2 |= 0 << 6; break; case 0x202: legacy_ctrl2 |= 1 << 6; break; case 0x204: legacy_ctrl2 |= 2 << 6; break; case 0x205: legacy_ctrl2 |= 3 << 6; break; default: printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port); return -EINVAL; } } if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) { printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port); return -EBUSY; } chip->gameport = gp = gameport_allocate_port(); if (!gp) { printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n"); release_and_free_resource(r); return -ENOMEM; } gameport_set_name(gp, "Yamaha YMF Gameport"); gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); gameport_set_dev_parent(gp, &chip->pci->dev); gp->io = io_port; gameport_set_port_data(gp, r); if (chip->pci->device >= 0x0010) /* YMF 744/754 */ pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port); pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, legacy_ctrl | YMFPCI_LEGACY_JPEN); pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); gameport_register_port(chip->gameport); return 0; }
/** * eeh_handle_event - Reset a PCI device after hard lockup. * @event: EEH event * * While PHB detects address or data parity errors on particular PCI * slot, the associated PE will be frozen. Besides, DMA's occurring * to wild addresses (which usually happen due to bugs in device * drivers or in PCI adapter firmware) can cause EEH error. #SERR, * #PERR or other misc PCI-related errors also can trigger EEH errors. * * Recovery process consists of unplugging the device driver (which * generated hotplug events to userspace), then issuing a PCI #RST to * the device, then reconfiguring the PCI config space for all bridges * & devices under this slot, and then finally restarting the device * drivers (which cause a second set of hotplug events to go out to * userspace). */ struct eeh_dev *handle_eeh_events(struct eeh_event *event) { struct device_node *frozen_dn; struct eeh_dev *frozen_edev; struct pci_bus *frozen_bus; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; const char *location, *pci_str, *drv_str, *bus_pci_str, *bus_drv_str; frozen_dn = eeh_find_device_pe(eeh_dev_to_of_node(event->edev)); if (!frozen_dn) { location = of_get_property(eeh_dev_to_of_node(event->edev), "ibm,loc-code", NULL); location = location ? location : "unknown"; printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " "for location=%s pci addr=%s\n", location, eeh_pci_name(eeh_dev_to_pci_dev(event->edev))); return NULL; } frozen_bus = pcibios_find_pci_bus(frozen_dn); location = of_get_property(frozen_dn, "ibm,loc-code", NULL); location = location ? location : "unknown"; /* There are two different styles for coming up with the PE. * In the old style, it was the highest EEH-capable device * which was always an EADS pci bridge. In the new style, * there might not be any EADS bridges, and even when there are, * the firmware marks them as "EEH incapable". So another * two-step is needed to find the pci bus.. */ if (!frozen_bus) frozen_bus = pcibios_find_pci_bus(frozen_dn->parent); if (!frozen_bus) { printk(KERN_ERR "EEH: Cannot find PCI bus " "for location=%s dn=%s\n", location, frozen_dn->full_name); return NULL; } frozen_edev = of_node_to_eeh_dev(frozen_dn); frozen_edev->freeze_count++; pci_str = eeh_pci_name(eeh_dev_to_pci_dev(event->edev)); drv_str = eeh_pcid_name(eeh_dev_to_pci_dev(event->edev)); if (frozen_edev->freeze_count > EEH_MAX_ALLOWED_FREEZES) goto excess_failures; printk(KERN_WARNING "EEH: This PCI device has failed %d times in the last hour:\n", frozen_edev->freeze_count); if (frozen_edev->pdev) { bus_pci_str = pci_name(frozen_edev->pdev); bus_drv_str = eeh_pcid_name(frozen_edev->pdev); printk(KERN_WARNING "EEH: Bus location=%s driver=%s pci addr=%s\n", location, bus_drv_str, bus_pci_str); } printk(KERN_WARNING "EEH: Device location=%s driver=%s pci addr=%s\n", location, drv_str, pci_str); /* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs * to accomplish the reset. Each child gets a report of the * status ... if any child can't handle the reset, then the entire * slot is dlpar removed and added. */ pci_walk_bus(frozen_bus, eeh_report_error, &result); /* Get the current PCI slot state. This can take a long time, * sometimes over 3 seconds for certain systems. */ rc = eeh_ops->wait_state(eeh_dev_to_of_node(frozen_edev), MAX_WAIT_FOR_RECOVERY*1000); if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) { printk(KERN_WARNING "EEH: Permanent failure\n"); goto hard_fail; } /* Since rtas may enable MMIO when posting the error log, * don't post the error log until after all dev drivers * have been informed. */ eeh_slot_error_detail(frozen_edev, EEH_LOG_TEMP); /* If all device drivers were EEH-unaware, then shut * down all of the device drivers, and hope they * go down willingly, without panicing the system. */ if (result == PCI_ERS_RESULT_NONE) { rc = eeh_reset_device(frozen_edev, frozen_bus); if (rc) { printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc); goto hard_fail; } } /* If all devices reported they can proceed, then re-enable MMIO */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_MMIO); if (rc < 0) goto hard_fail; if (rc) { result = PCI_ERS_RESULT_NEED_RESET; } else { result = PCI_ERS_RESULT_NONE; pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result); } } /* If all devices reported they can proceed, then re-enable DMA */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_DMA); if (rc < 0) goto hard_fail; if (rc) result = PCI_ERS_RESULT_NEED_RESET; else result = PCI_ERS_RESULT_RECOVERED; } /* If any device has a hard failure, then shut off everything. */ if (result == PCI_ERS_RESULT_DISCONNECT) { printk(KERN_WARNING "EEH: Device driver gave up\n"); goto hard_fail; } /* If any device called out for a reset, then reset the slot */ if (result == PCI_ERS_RESULT_NEED_RESET) { rc = eeh_reset_device(frozen_edev, NULL); if (rc) { printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc); goto hard_fail; } result = PCI_ERS_RESULT_NONE; pci_walk_bus(frozen_bus, eeh_report_reset, &result); } /* All devices should claim they have recovered by now. */ if ((result != PCI_ERS_RESULT_RECOVERED) && (result != PCI_ERS_RESULT_NONE)) { printk(KERN_WARNING "EEH: Not recovered\n"); goto hard_fail; } /* Tell all device drivers that they can resume operations */ pci_walk_bus(frozen_bus, eeh_report_resume, NULL); return frozen_edev; excess_failures: /* * About 90% of all real-life EEH failures in the field * are due to poorly seated PCI cards. Only 10% or so are * due to actual, failed cards. */ printk(KERN_ERR "EEH: PCI device at location=%s driver=%s pci addr=%s\n" "has failed %d times in the last hour " "and has been permanently disabled.\n" "Please try reseating this device or replacing it.\n", location, drv_str, pci_str, frozen_edev->freeze_count); goto perm_error; hard_fail: printk(KERN_ERR "EEH: Unable to recover from failure of PCI device " "at location=%s driver=%s pci addr=%s\n" "Please try reseating this device or replacing it.\n", location, drv_str, pci_str); perm_error: eeh_slot_error_detail(frozen_edev, EEH_LOG_PERM); /* Notify all devices that they're about to go down. */ pci_walk_bus(frozen_bus, eeh_report_failure, NULL); /* Shut down the device drivers for good. */ pcibios_remove_pci_devices(frozen_bus); return NULL; }
static int adm8211_read_eeprom(struct ieee80211_hw *dev) { struct adm8211_priv *priv = dev->priv; unsigned int words, i; struct ieee80211_chan_range chan_range; u16 cr49; struct eeprom_93cx6 eeprom = { .data = priv, .register_read = adm8211_eeprom_register_read, .register_write = adm8211_eeprom_register_write }; if (ADM8211_CSR_READ(CSR_TEST0) & ADM8211_CSR_TEST0_EPTYP) { /* 256 * 16-bit = 512 bytes */ eeprom.width = PCI_EEPROM_WIDTH_93C66; words = 256; } else { /* 64 * 16-bit = 128 bytes */ eeprom.width = PCI_EEPROM_WIDTH_93C46; words = 64; } priv->eeprom_len = words * 2; priv->eeprom = kmalloc(priv->eeprom_len, GFP_KERNEL); if (!priv->eeprom) return -ENOMEM; eeprom_93cx6_multiread(&eeprom, 0, (__le16 *)priv->eeprom, words); cr49 = le16_to_cpu(priv->eeprom->cr49); priv->rf_type = (cr49 >> 3) & 0x7; switch (priv->rf_type) { case ADM8211_TYPE_INTERSIL: case ADM8211_TYPE_RFMD: case ADM8211_TYPE_MARVEL: case ADM8211_TYPE_AIROHA: case ADM8211_TYPE_ADMTEK: break; default: if (priv->pdev->revision < ADM8211_REV_CA) priv->rf_type = ADM8211_TYPE_RFMD; else priv->rf_type = ADM8211_TYPE_AIROHA; printk(KERN_WARNING "%s (adm8211): Unknown RFtype %d\n", pci_name(priv->pdev), (cr49 >> 3) & 0x7); } priv->bbp_type = cr49 & 0x7; switch (priv->bbp_type) { case ADM8211_TYPE_INTERSIL: case ADM8211_TYPE_RFMD: case ADM8211_TYPE_MARVEL: case ADM8211_TYPE_AIROHA: case ADM8211_TYPE_ADMTEK: break; default: if (priv->pdev->revision < ADM8211_REV_CA) priv->bbp_type = ADM8211_TYPE_RFMD; else priv->bbp_type = ADM8211_TYPE_ADMTEK; printk(KERN_WARNING "%s (adm8211): Unknown BBPtype: %d\n", pci_name(priv->pdev), cr49 >> 3); } if (priv->eeprom->country_code >= ARRAY_SIZE(cranges)) { printk(KERN_WARNING "%s (adm8211): Invalid country code (%d)\n", pci_name(priv->pdev), priv->eeprom->country_code); chan_range = cranges[2]; } else chan_range = cranges[priv->eeprom->country_code]; printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n", pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max); BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels)); memcpy(priv->channels, adm8211_channels, sizeof(priv->channels)); priv->band.channels = priv->channels; priv->band.n_channels = ARRAY_SIZE(adm8211_channels); priv->band.bitrates = adm8211_rates; priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates); for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++) if (i < chan_range.min || i > chan_range.max) priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED; switch (priv->eeprom->specific_bbptype) { case ADM8211_BBP_RFMD3000: case ADM8211_BBP_RFMD3002: case ADM8211_BBP_ADM8011: priv->specific_bbptype = priv->eeprom->specific_bbptype; break; default: if (priv->pdev->revision < ADM8211_REV_CA) priv->specific_bbptype = ADM8211_BBP_RFMD3000; else priv->specific_bbptype = ADM8211_BBP_ADM8011; printk(KERN_WARNING "%s (adm8211): Unknown specific BBP: %d\n", pci_name(priv->pdev), priv->eeprom->specific_bbptype); } switch (priv->eeprom->specific_rftype) { case ADM8211_RFMD2948: case ADM8211_RFMD2958: case ADM8211_RFMD2958_RF3000_CONTROL_POWER: case ADM8211_MAX2820: case ADM8211_AL2210L: priv->transceiver_type = priv->eeprom->specific_rftype; break; default: if (priv->pdev->revision == ADM8211_REV_BA) priv->transceiver_type = ADM8211_RFMD2958_RF3000_CONTROL_POWER; else if (priv->pdev->revision == ADM8211_REV_CA) priv->transceiver_type = ADM8211_AL2210L; else if (priv->pdev->revision == ADM8211_REV_AB) priv->transceiver_type = ADM8211_RFMD2948; printk(KERN_WARNING "%s (adm8211): Unknown transceiver: %d\n", pci_name(priv->pdev), priv->eeprom->specific_rftype); break; } printk(KERN_DEBUG "%s (adm8211): RFtype=%d BBPtype=%d Specific BBP=%d " "Transceiver=%d\n", pci_name(priv->pdev), priv->rf_type, priv->bbp_type, priv->specific_bbptype, priv->transceiver_type); return 0; }
static void quirk_system_pci_resources(struct pnp_dev *dev) { struct pci_dev *pdev = NULL; struct resource *res; resource_size_t pnp_start, pnp_end, pci_start, pci_end; int i, j; /* * Some BIOSes have PNP motherboard devices with resources that * partially overlap PCI BARs. The PNP system driver claims these * motherboard resources, which prevents the normal PCI driver from * requesting them later. * * This patch disables the PNP resources that conflict with PCI BARs * so they won't be claimed by the PNP system driver. */ for_each_pci_dev(pdev) { for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { if (!(pci_resource_flags(pdev, i) & IORESOURCE_MEM) || pci_resource_len(pdev, i) == 0) continue; pci_start = pci_resource_start(pdev, i); pci_end = pci_resource_end(pdev, i); for (j = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, j)); j++) { if (res->flags & IORESOURCE_UNSET || (res->start == 0 && res->end == 0)) continue; pnp_start = res->start; pnp_end = res->end; /* * If the PNP region doesn't overlap the PCI * region at all, there's no problem. */ if (pnp_end < pci_start || pnp_start > pci_end) continue; /* * If the PNP region completely encloses (or is * at least as large as) the PCI region, that's * also OK. For example, this happens when the * PNP device describes a bridge with PCI * behind it. */ if (pnp_start <= pci_start && pnp_end >= pci_end) continue; /* * Otherwise, the PNP region overlaps *part* of * the PCI region, and that might prevent a PCI * driver from requesting its resources. */ dev_warn(&dev->dev, "mem resource " "(0x%llx-0x%llx) overlaps %s BAR %d " "(0x%llx-0x%llx), disabling\n", (unsigned long long) pnp_start, (unsigned long long) pnp_end, pci_name(pdev), i, (unsigned long long) pci_start, (unsigned long long) pci_end); res->flags |= IORESOURCE_DISABLED; } } } }
/** * gcu_probe - Device Initialization Routine * @pdev: PCI device information struct * @ent: entry in gcu_pci_tbl * * Returns 0 on success, negative on failure * * gcu_probe initializes an adapter identified by a pci_dev structure. * The OS initialization, configuring of the adapter private structure, * and a hardware reset occur. **/ static int __devinit gcu_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct gcu_adapter *adapter=0; uint32_t mmio_start, mmio_len; int err; GCU_DBG("%s\n", __func__); if((err = pci_enable_device(pdev))) { GCU_DBG("Unable to enable PCI Device\n"); return err; } if((err = pci_request_regions(pdev, gcu_driver_name))) { GCU_DBG("Unable to acquire requested memory regions\n"); return err; } /* * acquire the adapter spinlock. Once the module is loaded, it is possible for * someone to access the adapter struct via the interface functions exported * in gcu_if.c */ spin_lock(&global_adapter_spinlock); adapter = alloc_gcu_adapter(); if(!adapter) { gcu_probe_err(err_alloc_gcu_adapter, pdev, adapter); spin_unlock(&global_adapter_spinlock); return -ENOMEM; } SET_MODULE_OWNER(adapter); pci_set_drvdata(pdev, adapter); adapter->pdev = pdev; adapter->msg_enable = (1 << debug) - 1; mmio_start = pci_resource_start(pdev, BAR_0); mmio_len = pci_resource_len(pdev, BAR_0); adapter->hw_addr = ioremap(mmio_start, mmio_len); if(!adapter->hw_addr) { GCU_DBG("Unable to map mmio\n"); gcu_probe_err(err_ioremap, pdev, adapter); spin_unlock(&global_adapter_spinlock); return -EIO; } strncpy(adapter->name, pci_name(pdev), sizeof(adapter->name)-1); adapter->mem_start = mmio_start; adapter->mem_end = mmio_start + mmio_len; adapter->vendor_id = pdev->vendor; adapter->device_id = pdev->device; adapter->subsystem_vendor_id = pdev->subsystem_vendor; adapter->subsystem_id = pdev->subsystem_device; pci_read_config_byte(pdev, PCI_REVISION_ID, &adapter->revision_id); pci_read_config_word(pdev, PCI_COMMAND, &adapter->pci_cmd_word); global_adapter = adapter; spin_unlock(&global_adapter_spinlock); DPRINTK(PROBE, INFO, "Intel(R) GCU Initialized\n"); return 0; }
static int i3000_probe1(struct pci_dev *pdev, int dev_idx) { int rc; int i; struct mem_ctl_info *mci = NULL; unsigned long last_cumul_size; int interleaved, nr_channels; unsigned char dra[I3000_RANKS / 2], drb[I3000_RANKS]; unsigned char *c0dra = dra, *c1dra = &dra[I3000_RANKS_PER_CHANNEL / 2]; unsigned char *c0drb = drb, *c1drb = &drb[I3000_RANKS_PER_CHANNEL]; unsigned long mchbar; void __iomem *window; debugf0("MC: %s()\n", __func__); pci_read_config_dword(pdev, I3000_MCHBAR, (u32 *) & mchbar); mchbar &= I3000_MCHBAR_MASK; window = ioremap_nocache(mchbar, I3000_MMR_WINDOW_SIZE); if (!window) { printk(KERN_ERR "i3000: cannot map mmio space at 0x%lx\n", mchbar); return -ENODEV; } c0dra[0] = readb(window + I3000_C0DRA + 0); /* ranks 0,1 */ c0dra[1] = readb(window + I3000_C0DRA + 1); /* ranks 2,3 */ c1dra[0] = readb(window + I3000_C1DRA + 0); /* ranks 0,1 */ c1dra[1] = readb(window + I3000_C1DRA + 1); /* ranks 2,3 */ for (i = 0; i < I3000_RANKS_PER_CHANNEL; i++) { c0drb[i] = readb(window + I3000_C0DRB + i); c1drb[i] = readb(window + I3000_C1DRB + i); } iounmap(window); /* Figure out how many channels we have. * * If we have what the datasheet calls "asymmetric channels" * (essentially the same as what was called "virtual single * channel mode" in the i82875) then it's a single channel as * far as EDAC is concerned. */ interleaved = i3000_is_interleaved(c0dra, c1dra, c0drb, c1drb); nr_channels = interleaved ? 2 : 1; mci = edac_mc_alloc(0, I3000_RANKS / nr_channels, nr_channels, 0); if (!mci) return -ENOMEM; debugf3("MC: %s(): init mci\n", __func__); mci->dev = &pdev->dev; mci->mtype_cap = MEM_FLAG_DDR2; mci->edac_ctl_cap = EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_SECDED; mci->mod_name = EDAC_MOD_STR; mci->mod_ver = I3000_REVISION; mci->ctl_name = i3000_devs[dev_idx].ctl_name; mci->dev_name = pci_name(pdev); mci->edac_check = i3000_check; mci->ctl_page_to_phys = NULL; /* * The dram rank boundary (DRB) reg values are boundary addresses * for each DRAM rank with a granularity of 32MB. DRB regs are * cumulative; the last one will contain the total memory * contained in all ranks. * * If we're in interleaved mode then we're only walking through * the ranks of controller 0, so we double all the values we see. */ for (last_cumul_size = i = 0; i < mci->nr_csrows; i++) { u8 value; u32 cumul_size; struct csrow_info *csrow = &mci->csrows[i]; value = drb[i]; cumul_size = value << (I3000_DRB_SHIFT - PAGE_SHIFT); if (interleaved) cumul_size <<= 1; debugf3("MC: %s(): (%d) cumul_size 0x%x\n", __func__, i, cumul_size); if (cumul_size == last_cumul_size) { csrow->mtype = MEM_EMPTY; continue; } csrow->first_page = last_cumul_size; csrow->last_page = cumul_size - 1; csrow->nr_pages = cumul_size - last_cumul_size; last_cumul_size = cumul_size; csrow->grain = I3000_DEAP_GRAIN; csrow->mtype = MEM_DDR2; csrow->dtype = DEV_UNKNOWN; csrow->edac_mode = EDAC_UNKNOWN; } /* Clear any error bits. * (Yes, we really clear bits by writing 1 to them.) */ pci_write_bits16(pdev, I3000_ERRSTS, I3000_ERRSTS_BITS, I3000_ERRSTS_BITS); rc = -ENODEV; if (edac_mc_add_mc(mci)) { debugf3("MC: %s(): failed edac_mc_add_mc()\n", __func__); goto fail; } /* allocating generic PCI control info */ i3000_pci = edac_pci_create_generic_ctl(&pdev->dev, EDAC_MOD_STR); if (!i3000_pci) { printk(KERN_WARNING "%s(): Unable to create PCI control\n", __func__); printk(KERN_WARNING "%s(): PCI error report via EDAC not setup\n", __func__); } /* get this far and it's successful */ debugf3("MC: %s(): success\n", __func__); return 0; fail: if (mci) edac_mc_free(mci); return rc; }
/* * PCI Parity polling * */ static void edac_pci_dev_parity_test(struct pci_dev *dev) { u16 status; u8 header_type; /* read the STATUS register on this device */ status = get_pci_parity_status(dev, 0); debugf2("PCI STATUS= 0x%04x %s\n", status, dev->dev.bus_id ); /* check the status reg for errors */ if (status) { if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) edac_printk(KERN_CRIT, EDAC_PCI, "Signaled System Error on %s\n", pci_name(dev)); if (status & (PCI_STATUS_PARITY)) { edac_printk(KERN_CRIT, EDAC_PCI, "Master Data Parity Error on %s\n", pci_name(dev)); atomic_inc(&pci_parity_count); } if (status & (PCI_STATUS_DETECTED_PARITY)) { edac_printk(KERN_CRIT, EDAC_PCI, "Detected Parity Error on %s\n", pci_name(dev)); atomic_inc(&pci_parity_count); } } /* read the device TYPE, looking for bridges */ pci_read_config_byte(dev, PCI_HEADER_TYPE, &header_type); debugf2("PCI HEADER TYPE= 0x%02x %s\n", header_type, dev->dev.bus_id ); if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* On bridges, need to examine secondary status register */ status = get_pci_parity_status(dev, 1); debugf2("PCI SEC_STATUS= 0x%04x %s\n", status, dev->dev.bus_id ); /* check the secondary status reg for errors */ if (status) { if (status & (PCI_STATUS_SIG_SYSTEM_ERROR)) edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " "Signaled System Error on %s\n", pci_name(dev)); if (status & (PCI_STATUS_PARITY)) { edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " "Master Data Parity Error on " "%s\n", pci_name(dev)); atomic_inc(&pci_parity_count); } if (status & (PCI_STATUS_DETECTED_PARITY)) { edac_printk(KERN_CRIT, EDAC_PCI, "Bridge " "Detected Parity Error on %s\n", pci_name(dev)); atomic_inc(&pci_parity_count); } } } }
static int __devinit i5100_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { int rc; struct mem_ctl_info *mci; struct i5100_priv *priv; struct pci_dev *ch0mm, *ch1mm; int ret = 0; u32 dw; int ranksperch; if (PCI_FUNC(pdev->devfn) != 1) return -ENODEV; rc = pci_enable_device(pdev); if (rc < 0) { ret = rc; goto bail; } /* ECC enabled? */ pci_read_config_dword(pdev, I5100_MC, &dw); if (!i5100_mc_errdeten(dw)) { printk(KERN_INFO "i5100_edac: ECC not enabled.\n"); ret = -ENODEV; goto bail_pdev; } /* figure out how many ranks, from strapped state of 48GB_Mode input */ pci_read_config_dword(pdev, I5100_MS, &dw); ranksperch = !!(dw & (1 << 8)) * 2 + 4; if (ranksperch != 4) { /* FIXME: get 6 ranks / controller to work - need hw... */ printk(KERN_INFO "i5100_edac: unsupported configuration.\n"); ret = -ENODEV; goto bail_pdev; } /* enable error reporting... */ pci_read_config_dword(pdev, I5100_EMASK_MEM, &dw); dw &= ~I5100_FERR_NF_MEM_ANY_MASK; pci_write_config_dword(pdev, I5100_EMASK_MEM, dw); /* device 21, func 0, Channel 0 Memory Map, Error Flag/Mask, etc... */ ch0mm = pci_get_device_func(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_21, 0); if (!ch0mm) { ret = -ENODEV; goto bail_pdev; } rc = pci_enable_device(ch0mm); if (rc < 0) { ret = rc; goto bail_ch0; } /* device 22, func 0, Channel 1 Memory Map, Error Flag/Mask, etc... */ ch1mm = pci_get_device_func(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5100_22, 0); if (!ch1mm) { ret = -ENODEV; goto bail_disable_ch0; } rc = pci_enable_device(ch1mm); if (rc < 0) { ret = rc; goto bail_ch1; } mci = edac_mc_alloc(sizeof(*priv), ranksperch * 2, 1, 0); if (!mci) { ret = -ENOMEM; goto bail_disable_ch1; } mci->dev = &pdev->dev; priv = mci->pvt_info; priv->ranksperctlr = ranksperch; priv->mc = pdev; priv->ch0mm = ch0mm; priv->ch1mm = ch1mm; i5100_init_dimm_layout(pdev, mci); i5100_init_interleaving(pdev, mci); mci->mtype_cap = MEM_FLAG_FB_DDR2; mci->edac_ctl_cap = EDAC_FLAG_SECDED; mci->edac_cap = EDAC_FLAG_SECDED; mci->mod_name = "i5100_edac.c"; mci->mod_ver = "not versioned"; mci->ctl_name = "i5100"; mci->dev_name = pci_name(pdev); mci->ctl_page_to_phys = NULL; mci->edac_check = i5100_check_error; i5100_init_csrows(mci); /* this strange construction seems to be in every driver, dunno why */ switch (edac_op_state) { case EDAC_OPSTATE_POLL: case EDAC_OPSTATE_NMI: break; default: edac_op_state = EDAC_OPSTATE_POLL; break; } if (edac_mc_add_mc(mci)) { ret = -ENODEV; goto bail_mc; } return ret; bail_mc: edac_mc_free(mci); bail_disable_ch1: pci_disable_device(ch1mm); bail_ch1: pci_dev_put(ch1mm); bail_disable_ch0: pci_disable_device(ch0mm); bail_ch0: pci_dev_put(ch0mm); bail_pdev: pci_disable_device(pdev); bail: return ret; }
int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { struct saa7146_fh *fh = file->private_data; struct saa7146_dev *dev = fh->dev; struct saa7146_vv *vv = dev->vv_data; int err = 0, result = 0, ee = 0; struct saa7146_use_ops *ops; struct videobuf_queue *q; /* check if extension handles the command */ for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) { if( cmd == dev->ext_vv_data->ioctls[ee].cmd ) break; } if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) { DEB_D(("extension handles ioctl exclusive.\n")); result = dev->ext_vv_data->ioctl(fh, cmd, arg); return result; } if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) { DEB_D(("extension handles ioctl before.\n")); result = dev->ext_vv_data->ioctl(fh, cmd, arg); if( -EAGAIN != result ) { return result; } } /* fixme: add handle "after" case (is it still needed?) */ switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: { ops = &saa7146_video_uops; q = &fh->video_q; break; } case V4L2_BUF_TYPE_VBI_CAPTURE: { ops = &saa7146_vbi_uops; q = &fh->vbi_q; break; } default: BUG(); return 0; } switch (cmd) { case VIDIOC_QUERYCAP: { struct v4l2_capability *cap = arg; memset(cap,0,sizeof(*cap)); DEB_EE(("VIDIOC_QUERYCAP\n")); strcpy(cap->driver, "saa7146 v4l2"); strlcpy(cap->card, dev->ext->name, sizeof(cap->card)); sprintf(cap->bus_info,"PCI:%s", pci_name(dev->pci)); cap->version = SAA7146_VERSION_CODE; cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; cap->capabilities |= dev->ext_vv_data->capabilities; return 0; } case VIDIOC_G_FBUF: { struct v4l2_framebuffer *fb = arg; DEB_EE(("VIDIOC_G_FBUF\n")); *fb = vv->ov_fb; fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; return 0; } case VIDIOC_S_FBUF: { struct v4l2_framebuffer *fb = arg; struct saa7146_format *fmt; DEB_EE(("VIDIOC_S_FBUF\n")); if(!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) return -EPERM; /* check args */ fmt = format_by_fourcc(dev,fb->fmt.pixelformat); if (NULL == fmt) { return -EINVAL; } /* planar formats are not allowed for overlay video, clipping and video dma would clash */ if (0 != (fmt->flags & FORMAT_IS_PLANAR)) { DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat)); } /* check if overlay is running */ if (IS_OVERLAY_ACTIVE(fh) != 0) { if (vv->video_fh != fh) { DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n")); return -EBUSY; } } mutex_lock(&dev->lock); /* ok, accept it */ vv->ov_fb = *fb; vv->ov_fmt = fmt; if (0 == vv->ov_fb.fmt.bytesperline) vv->ov_fb.fmt.bytesperline = vv->ov_fb.fmt.width*fmt->depth/8; mutex_unlock(&dev->lock); return 0; } case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; int index; switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OVERLAY: { index = f->index; if (index < 0 || index >= NUM_FORMATS) { return -EINVAL; } memset(f,0,sizeof(*f)); f->index = index; strlcpy(f->description,formats[index].name,sizeof(f->description)); f->pixelformat = formats[index].pixelformat; break; } default: return -EINVAL; } DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index)); return 0; } case VIDIOC_QUERYCTRL: { const struct v4l2_queryctrl *ctrl; struct v4l2_queryctrl *c = arg; if ((c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1) && (c->id < V4L2_CID_PRIVATE_BASE || c->id >= V4L2_CID_PRIVATE_LASTP1)) return -EINVAL; ctrl = ctrl_by_id(c->id); if( NULL == ctrl ) { return -EINVAL; /* c->flags = V4L2_CTRL_FLAG_DISABLED; return 0; */ } DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id)); *c = *ctrl; return 0; } case VIDIOC_G_CTRL: { DEB_EE(("VIDIOC_G_CTRL\n")); return get_control(fh,arg); } case VIDIOC_S_CTRL: { DEB_EE(("VIDIOC_S_CTRL\n")); err = set_control(fh,arg); return err; } case VIDIOC_G_PARM: { struct v4l2_streamparm *parm = arg; if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) { return -EINVAL; } memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm)); parm->parm.capture.readbuffers = 1; // fixme: only for PAL! parm->parm.capture.timeperframe.numerator = 1; parm->parm.capture.timeperframe.denominator = 25; return 0; } case VIDIOC_G_FMT: { struct v4l2_format *f = arg; DEB_EE(("VIDIOC_G_FMT\n")); return g_fmt(fh,f); } case VIDIOC_S_FMT: { struct v4l2_format *f = arg; DEB_EE(("VIDIOC_S_FMT\n")); return s_fmt(fh,f); } case VIDIOC_TRY_FMT: { struct v4l2_format *f = arg; DEB_EE(("VIDIOC_TRY_FMT\n")); return try_fmt(fh,f); } case VIDIOC_G_STD: { v4l2_std_id *id = arg; DEB_EE(("VIDIOC_G_STD\n")); *id = vv->standard->id; return 0; } /* the saa7146 supfhrts (used in conjunction with the saa7111a for example) PAL / NTSC / SECAM. if your hardware does not (or does more) -- override this function in your extension */ case VIDIOC_ENUMSTD: { struct v4l2_standard *e = arg; if (e->index < 0 ) return -EINVAL; if( e->index < dev->ext_vv_data->num_stds ) { DEB_EE(("VIDIOC_ENUMSTD: index:%d\n",e->index)); v4l2_video_std_construct(e, dev->ext_vv_data->stds[e->index].id, dev->ext_vv_data->stds[e->index].name); return 0; } return -EINVAL; } case VIDIOC_S_STD: { v4l2_std_id *id = arg; int found = 0; int i, err; DEB_EE(("VIDIOC_S_STD\n")); if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) { DEB_D(("cannot change video standard while streaming capture is active\n")); return -EBUSY; } if ((vv->video_status & STATUS_OVERLAY) != 0) { vv->ov_suspend = vv->video_fh; err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */ if (0 != err) { DEB_D(("suspending video failed. aborting\n")); return err; } } mutex_lock(&dev->lock); for(i = 0; i < dev->ext_vv_data->num_stds; i++) if (*id & dev->ext_vv_data->stds[i].id) break; if (i != dev->ext_vv_data->num_stds) { vv->standard = &dev->ext_vv_data->stds[i]; if( NULL != dev->ext_vv_data->std_callback ) dev->ext_vv_data->std_callback(dev, vv->standard); found = 1; } mutex_unlock(&dev->lock); if (vv->ov_suspend != NULL) { saa7146_start_preview(vv->ov_suspend); vv->ov_suspend = NULL; } if( 0 == found ) { DEB_EE(("VIDIOC_S_STD: standard not found.\n")); return -EINVAL; } DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name)); return 0; } case VIDIOC_OVERLAY: { int on = *(int *)arg; int err = 0; DEB_D(("VIDIOC_OVERLAY on:%d\n",on)); if (on != 0) { err = saa7146_start_preview(fh); } else { err = saa7146_stop_preview(fh); } return err; } case VIDIOC_REQBUFS: { struct v4l2_requestbuffers *req = arg; DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type)); return videobuf_reqbufs(q,req); } case VIDIOC_QUERYBUF: { struct v4l2_buffer *buf = arg; DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset)); return videobuf_querybuf(q,buf); } case VIDIOC_QBUF: { struct v4l2_buffer *buf = arg; int ret = 0; ret = videobuf_qbuf(q,buf); DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index)); return ret; } case VIDIOC_DQBUF: { struct v4l2_buffer *buf = arg; int ret = 0; ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK); DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index)); return ret; } case VIDIOC_STREAMON: { int *type = arg; DEB_D(("VIDIOC_STREAMON, type:%d\n",*type)); err = video_begin(fh); if( 0 != err) { return err; } err = videobuf_streamon(q); return err; } case VIDIOC_STREAMOFF: { int *type = arg; DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type)); /* ugly: we need to copy some checks from video_end(), because videobuf_streamoff() relies on the capture running. check and fix this */ if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) { DEB_S(("not capturing.\n")); return 0; } if (vv->video_fh != fh) { DEB_S(("capturing, but in another open.\n")); return -EBUSY; } err = videobuf_streamoff(q); if (0 != err) { DEB_D(("warning: videobuf_streamoff() failed.\n")); video_end(fh, file); } else { err = video_end(fh, file); } return err; } #ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGMBUF: { struct video_mbuf *mbuf = arg; struct videobuf_queue *q; int i; /* fixme: number of capture buffers and sizes for v4l apps */ int gbuffers = 2; int gbufsize = 768*576*4; DEB_D(("VIDIOCGMBUF \n")); q = &fh->video_q; mutex_lock(&q->lock); err = videobuf_mmap_setup(q,gbuffers,gbufsize, V4L2_MEMORY_MMAP); if (err < 0) { mutex_unlock(&q->lock); return err; } memset(mbuf,0,sizeof(*mbuf)); mbuf->frames = gbuffers; mbuf->size = gbuffers * gbufsize; for (i = 0; i < gbuffers; i++) mbuf->offsets[i] = i * gbufsize; mutex_unlock(&q->lock); return 0; } #endif default: return v4l_compat_translate_ioctl(inode,file,cmd,arg, saa7146_video_do_ioctl); } return 0; }
//------------------------------------------------------------------------------ static INT initOnePciDev(struct pci_dev* pPciDev_p, const struct pci_device_id* pId_p) { INT result = 0; UINT8 barCount = 0; tBarInfo* pBarInfo = NULL; UNUSED_PARAMETER(pId_p); if (pcieDrvInstance_l.pPciDev != NULL) { // This driver is already connected to a PCIe device DEBUG_LVL_DRVINTF_TRACE("%s device %s discarded\n", __FUNCTION__, pci_name(pPciDev_p)); result = -ENODEV; goto Exit; } pcieDrvInstance_l.pPciDev = pPciDev_p; // Enable the PCIe device DEBUG_LVL_DRVINTF_TRACE("%s enable device\n", __FUNCTION__); result = pci_enable_device(pPciDev_p); if (result != 0) { goto Exit; } DEBUG_LVL_DRVINTF_TRACE("%s request PCIe regions\n", __FUNCTION__); result = pci_request_regions(pPciDev_p, PLK_DRV_NAME); if (result != 0) { goto ExitFail; } // Ignoring whether or not any BAR is accessible for (barCount = 0; barCount < OPLK_MAX_BAR_COUNT; barCount++) { pBarInfo = &pcieDrvInstance_l.aBarInfo[barCount]; if (pBarInfo->virtualAddr != (ULONG)NULL) { // The instance is already present result = -EIO; goto ExitFail; } // Look for the MMIO BARs if ((pci_resource_flags(pPciDev_p, barCount) & IORESOURCE_MEM) == 0) { continue; } // get the size of this field pBarInfo->length = pci_resource_len(pPciDev_p, barCount); // $$: Add check for weird broken IO regions pBarInfo->virtualAddr = (ULONG)ioremap_nocache(pci_resource_start(pPciDev_p, barCount), pBarInfo->length); if (pBarInfo->virtualAddr == (ULONG)NULL) { // Remap of controller's register space failed result = -EIO; goto ExitFail; } pBarInfo->busAddr = (ULONG)pci_resource_start(pPciDev_p, barCount); DEBUG_LVL_DRVINTF_TRACE("%s() --> ioremap\n", __FUNCTION__); DEBUG_LVL_DRVINTF_TRACE("\tbar#\t%u\n", barCount); DEBUG_LVL_DRVINTF_TRACE("\tbarLen\t%lu\n", pBarInfo->length); DEBUG_LVL_DRVINTF_TRACE("\tbarMap\t0x%lX\n", pBarInfo->virtualAddr); DEBUG_LVL_DRVINTF_TRACE("\tbarPhy\t0x%lX\n", pBarInfo->busAddr); } // Enable PCI busmaster DEBUG_LVL_DRVINTF_TRACE("%s enable busmaster\n", __FUNCTION__); pci_set_master(pPciDev_p); // Enable msi DEBUG_LVL_DRVINTF_TRACE("Enable MSI\n"); result = pci_enable_msi(pPciDev_p); if (result != 0) { DEBUG_LVL_DRVINTF_TRACE("%s Could not enable MSI\n", __FUNCTION__); } // Install interrupt handler DEBUG_LVL_DRVINTF_TRACE("%s install interrupt handler\n", __FUNCTION__); result = request_irq(pPciDev_p->irq, pcieDrvIrqHandler, IRQF_SHARED, PLK_DRV_NAME, /* pPciDev_p->dev.name */ pPciDev_p); if (result != 0) { goto ExitFail; } goto Exit; ExitFail: removeOnePciDev(pPciDev_p); Exit: DEBUG_LVL_DRVINTF_TRACE("%s finished with %d\n", __FUNCTION__, result); return result; }
int bttv_input_init(struct bttv *btv) { struct card_ir *ir; struct ir_scancode_table *ir_codes = NULL; struct input_dev *input_dev; int ir_type = IR_TYPE_OTHER; int err = -ENOMEM; if (!btv->has_remote) return -ENODEV; ir = kzalloc(sizeof(*ir),GFP_KERNEL); input_dev = input_allocate_device(); if (!ir || !input_dev) goto err_out_free; /* detect & configure */ switch (btv->c.type) { case BTTV_BOARD_AVERMEDIA: case BTTV_BOARD_AVPHONE98: case BTTV_BOARD_AVERMEDIA98: ir_codes = &ir_codes_avermedia_table; ir->mask_keycode = 0xf88000; ir->mask_keydown = 0x010000; ir->polling = 50; // ms break; case BTTV_BOARD_AVDVBT_761: case BTTV_BOARD_AVDVBT_771: ir_codes = &ir_codes_avermedia_dvbt_table; ir->mask_keycode = 0x0f00c0; ir->mask_keydown = 0x000020; ir->polling = 50; // ms break; case BTTV_BOARD_PXELVWPLTVPAK: ir_codes = &ir_codes_pixelview_table; ir->mask_keycode = 0x003e00; ir->mask_keyup = 0x010000; ir->polling = 50; // ms break; case BTTV_BOARD_PV_M4900: case BTTV_BOARD_PV_BT878P_9B: case BTTV_BOARD_PV_BT878P_PLUS: ir_codes = &ir_codes_pixelview_table; ir->mask_keycode = 0x001f00; ir->mask_keyup = 0x008000; ir->polling = 50; // ms break; case BTTV_BOARD_WINFAST2000: ir_codes = &ir_codes_winfast_table; ir->mask_keycode = 0x1f8; break; case BTTV_BOARD_MAGICTVIEW061: case BTTV_BOARD_MAGICTVIEW063: ir_codes = &ir_codes_winfast_table; ir->mask_keycode = 0x0008e000; ir->mask_keydown = 0x00200000; break; case BTTV_BOARD_APAC_VIEWCOMP: ir_codes = &ir_codes_apac_viewcomp_table; ir->mask_keycode = 0x001f00; ir->mask_keyup = 0x008000; ir->polling = 50; // ms break; case BTTV_BOARD_ASKEY_CPH03X: case BTTV_BOARD_CONCEPTRONIC_CTVFMI2: case BTTV_BOARD_CONTVFMI: ir_codes = &ir_codes_pixelview_table; ir->mask_keycode = 0x001F00; ir->mask_keyup = 0x006000; ir->polling = 50; // ms break; case BTTV_BOARD_NEBULA_DIGITV: ir_codes = &ir_codes_nebula_table; btv->custom_irq = bttv_rc5_irq; ir->rc5_gpio = 1; break; case BTTV_BOARD_MACHTV_MAGICTV: ir_codes = &ir_codes_apac_viewcomp_table; ir->mask_keycode = 0x001F00; ir->mask_keyup = 0x004000; ir->polling = 50; /* ms */ break; case BTTV_BOARD_KOZUMI_KTV_01C: ir_codes = &ir_codes_pctv_sedna_table; ir->mask_keycode = 0x001f00; ir->mask_keyup = 0x006000; ir->polling = 50; /* ms */ break; case BTTV_BOARD_ENLTV_FM_2: ir_codes = &ir_codes_encore_enltv2_table; ir->mask_keycode = 0x00fd00; ir->mask_keyup = 0x000080; ir->polling = 1; /* ms */ ir->last_gpio = ir_extract_bits(bttv_gpio_read(&btv->c), ir->mask_keycode); break; } if (NULL == ir_codes) { dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n", btv->c.type); err = -ENODEV; goto err_out_free; } if (ir->rc5_gpio) { u32 gpio; /* enable remote irq */ bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4); gpio = bttv_gpio_read(&btv->c); bttv_gpio_write(&btv->c, gpio & ~(1 << 4)); bttv_gpio_write(&btv->c, gpio | (1 << 4)); } else { /* init hardware-specific stuff */ bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0); } /* init input device */ ir->dev = input_dev; snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)", btv->c.type); snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(btv->c.pci)); ir_input_init(input_dev, &ir->ir, ir_type, ir_codes); input_dev->name = ir->name; input_dev->phys = ir->phys; input_dev->id.bustype = BUS_PCI; input_dev->id.version = 1; if (btv->c.pci->subsystem_vendor) { input_dev->id.vendor = btv->c.pci->subsystem_vendor; input_dev->id.product = btv->c.pci->subsystem_device; } else { input_dev->id.vendor = btv->c.pci->vendor; input_dev->id.product = btv->c.pci->device; } input_dev->dev.parent = &btv->c.pci->dev; btv->remote = ir; bttv_ir_start(btv, ir); /* all done */ err = input_register_device(btv->remote->dev); if (err) goto err_out_stop; /* the remote isn't as bouncy as a keyboard */ ir->dev->rep[REP_DELAY] = repeat_delay; ir->dev->rep[REP_PERIOD] = repeat_period; return 0; err_out_stop: bttv_ir_stop(btv); btv->remote = NULL; err_out_free: input_free_device(input_dev); kfree(ir); return err; }
/* * We need to register our own PCI probe function (instead of the USB core's * function) in order to create a second roothub under xHCI. */ static int xhci_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { int retval; struct xhci_hcd *xhci; struct hc_driver *driver; struct usb_hcd *hcd; driver = (struct hc_driver *)id->driver_data; /* Prevent runtime suspending between USB-2 and USB-3 initialization */ pm_runtime_get_noresume(&dev->dev); /* Register the USB 2.0 roothub. * FIXME: USB core must know to register the USB 2.0 roothub first. * This is sort of silly, because we could just set the HCD driver flags * to say USB 2.0, but I'm not sure what the implications would be in * the other parts of the HCD code. */ retval = usb_hcd_pci_probe(dev, id); if (retval) goto put_runtime_pm; /* USB 2.0 roothub is stored in the PCI device now. */ hcd = dev_get_drvdata(&dev->dev); xhci = hcd_to_xhci(hcd); xhci->shared_hcd = usb_create_shared_hcd(driver, &dev->dev, pci_name(dev), hcd); if (!xhci->shared_hcd) { retval = -ENOMEM; goto dealloc_usb2_hcd; } /* Set the xHCI pointer before xhci_pci_setup() (aka hcd_driver.reset) * is called by usb_add_hcd(). */ *((struct xhci_hcd **) xhci->shared_hcd->hcd_priv) = xhci; retval = usb_add_hcd(xhci->shared_hcd, dev->irq, IRQF_SHARED); if (retval) goto put_usb3_hcd; /* Roothub already marked as USB 3.0 speed */ /* We know the LPM timeout algorithms for this host, let the USB core * enable and disable LPM for devices under the USB 3.0 roothub. */ if (xhci->quirks & XHCI_LPM_SUPPORT) hcd_to_bus(xhci->shared_hcd)->root_hub->lpm_capable = 1; /* USB-2 and USB-3 roothubs initialized, allow runtime pm suspend */ pm_runtime_put_noidle(&dev->dev); return 0; put_usb3_hcd: usb_put_hcd(xhci->shared_hcd); dealloc_usb2_hcd: usb_hcd_pci_remove(dev); put_runtime_pm: pm_runtime_put_noidle(&dev->dev); return retval; }
/** * usb_hcd_pci_probe - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * * Store this function in the HCD's struct pci_driver as probe(). */ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct hc_driver *driver; unsigned long resource, len; void __iomem *base; struct usb_hcd *hcd; int retval, region; char buf [8], *bufp = buf; if (usb_disabled()) return -ENODEV; if (!id || !(driver = (struct hc_driver *) id->driver_data)) return -EINVAL; if (pci_enable_device (dev) < 0) return -ENODEV; if (!dev->irq) { dev_err (&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); return -ENODEV; } if (driver->flags & HCD_MEMORY) { // EHCI, OHCI region = 0; resource = pci_resource_start (dev, 0); len = pci_resource_len (dev, 0); if (!request_mem_region (resource, len, driver->description)) { dev_dbg (&dev->dev, "controller already in use\n"); return -EBUSY; } base = ioremap_nocache (resource, len); if (base == NULL) { dev_dbg (&dev->dev, "error mapping memory\n"); retval = -EFAULT; clean_1: release_mem_region (resource, len); dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); return retval; } } else { // UHCI resource = len = 0; for (region = 0; region < PCI_ROM_RESOURCE; region++) { if (!(pci_resource_flags (dev, region) & IORESOURCE_IO)) continue; resource = pci_resource_start (dev, region); len = pci_resource_len (dev, region); if (request_region (resource, len, driver->description)) break; } if (region == PCI_ROM_RESOURCE) { dev_dbg (&dev->dev, "no i/o regions available\n"); return -EBUSY; } base = (void __iomem *) resource; } // driver->reset(), later on, will transfer device from // control by SMM/BIOS to control by Linux (if needed) hcd = driver->hcd_alloc (); if (hcd == NULL){ dev_dbg (&dev->dev, "hcd alloc fail\n"); retval = -ENOMEM; clean_2: if (driver->flags & HCD_MEMORY) { iounmap (base); goto clean_1; } else { release_region (resource, len); dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); return retval; } } // hcd zeroed everything hcd->regs = base; hcd->region = region; pci_set_drvdata (dev, hcd); hcd->driver = driver; hcd->description = driver->description; hcd->self.bus_name = pci_name(dev); #ifdef CONFIG_PCI_NAMES hcd->product_desc = dev->pretty_name; #else if (hcd->product_desc == NULL) hcd->product_desc = "USB Host Controller"; #endif hcd->self.controller = &dev->dev; if ((retval = hcd_buffer_create (hcd)) != 0) { clean_3: driver->hcd_free (hcd); goto clean_2; } dev_info (hcd->self.controller, "%s\n", hcd->product_desc); /* till now HC has been in an indeterminate state ... */ if (driver->reset && (retval = driver->reset (hcd)) < 0) { dev_err (hcd->self.controller, "can't reset\n"); goto clean_3; } hcd->state = USB_STATE_HALT; pci_set_master (dev); #ifndef __sparc__ sprintf (buf, "%d", dev->irq); #else bufp = __irq_itoa(dev->irq); #endif retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd); if (retval != 0) { dev_err (hcd->self.controller, "request interrupt %s failed\n", bufp); goto clean_3; } hcd->irq = dev->irq; dev_info (hcd->self.controller, "irq %s, %s %p\n", bufp, (driver->flags & HCD_MEMORY) ? "pci mem" : "io base", base); usb_bus_init (&hcd->self); hcd->self.op = &usb_hcd_operations; hcd->self.hcpriv = (void *) hcd; hcd->self.release = &hcd_pci_release; init_timer (&hcd->rh_timer); INIT_LIST_HEAD (&hcd->dev_list); usb_register_bus (&hcd->self); if ((retval = driver->start (hcd)) < 0) { dev_err (hcd->self.controller, "init error %d\n", retval); usb_hcd_pci_remove (dev); } return retval; }
/** * PCI probe entry. */ int bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid) { struct bfad_s *bfad; int error = -ENODEV, retval; /* * For single port cards - only claim function 0 */ if ((pdev->device == BFA_PCI_DEVICE_ID_FC_8G1P) && (PCI_FUNC(pdev->devfn) != 0)) return -ENODEV; BFA_TRACE(BFA_INFO, "bfad_pci_probe entry"); bfad = kzalloc(sizeof(struct bfad_s), GFP_KERNEL); if (!bfad) { error = -ENOMEM; goto out; } bfad->trcmod = kzalloc(sizeof(struct bfa_trc_mod_s), GFP_KERNEL); if (!bfad->trcmod) { printk(KERN_WARNING "Error alloc trace buffer!\n"); error = -ENOMEM; goto out_alloc_trace_failure; } /* * LOG/TRACE INIT */ bfa_trc_init(bfad->trcmod); bfa_trc(bfad, bfad_inst); bfad->logmod = &bfad->log_data; bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf); bfad_drv_log_level_set(bfad); bfad->aen = &bfad->aen_buf; if (!(bfad_load_fwimg(pdev))) { printk(KERN_WARNING "bfad_load_fwimg failure!\n"); kfree(bfad->trcmod); goto out_alloc_trace_failure; } retval = bfad_pci_init(pdev, bfad); if (retval) { printk(KERN_WARNING "bfad_pci_init failure!\n"); error = retval; goto out_pci_init_failure; } mutex_lock(&bfad_mutex); bfad->inst_no = bfad_inst++; list_add_tail(&bfad->list_entry, &bfad_list); mutex_unlock(&bfad_mutex); spin_lock_init(&bfad->bfad_lock); pci_set_drvdata(pdev, bfad); bfad->ref_count = 0; bfad->pport.bfad = bfad; bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s", "bfad_worker"); if (IS_ERR(bfad->bfad_tsk)) { printk(KERN_INFO "bfad[%d]: Kernel thread" " creation failed!\n", bfad->inst_no); goto out_kthread_create_failure; } retval = bfad_drv_init(bfad); if (retval != BFA_STATUS_OK) goto out_drv_init_failure; if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { bfad->bfad_flags |= BFAD_HAL_INIT_FAIL; printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); goto ok; } retval = bfad_start_ops(bfad); if (retval != BFA_STATUS_OK) goto out_start_ops_failure; kthread_stop(bfad->bfad_tsk); bfad->bfad_tsk = NULL; ok: return 0; out_start_ops_failure: bfad_drv_uninit(bfad); out_drv_init_failure: kthread_stop(bfad->bfad_tsk); out_kthread_create_failure: mutex_lock(&bfad_mutex); bfad_inst--; list_del(&bfad->list_entry); mutex_unlock(&bfad_mutex); bfad_pci_uninit(pdev, bfad); out_pci_init_failure: kfree(bfad->trcmod); out_alloc_trace_failure: kfree(bfad); out: return error; }
static ssize_t vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos) { char usercmd[64]; const char *pdev_name; int i, ret; bool delay = false, can_switch; bool just_mux = false; int client_id = -1; struct vga_switcheroo_client *client = NULL; if (cnt > 63) cnt = 63; if (copy_from_user(usercmd, ubuf, cnt)) return -EFAULT; mutex_lock(&vgasr_mutex); if (!vgasr_priv.active) { cnt = -EINVAL; goto out; } /* pwr off the device not in use */ if (strncmp(usercmd, "OFF", 3) == 0) { for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { if (vgasr_priv.clients[i].active) continue; if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_ON) vga_switchoff(&vgasr_priv.clients[i]); } goto out; } /* pwr on the device not in use */ if (strncmp(usercmd, "ON", 2) == 0) { for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { if (vgasr_priv.clients[i].active) continue; if (vgasr_priv.clients[i].pwr_state == VGA_SWITCHEROO_OFF) vga_switchon(&vgasr_priv.clients[i]); } goto out; } /* request a delayed switch - test can we switch now */ if (strncmp(usercmd, "DIGD", 4) == 0) { client_id = VGA_SWITCHEROO_IGD; delay = true; } if (strncmp(usercmd, "DDIS", 4) == 0) { client_id = VGA_SWITCHEROO_DIS; delay = true; } if (strncmp(usercmd, "IGD", 3) == 0) client_id = VGA_SWITCHEROO_IGD; if (strncmp(usercmd, "DIS", 3) == 0) client_id = VGA_SWITCHEROO_DIS; if (strncmp(usercmd, "MIGD", 4) == 0) { just_mux = true; client_id = VGA_SWITCHEROO_IGD; } if (strncmp(usercmd, "MDIS", 4) == 0) { just_mux = true; client_id = VGA_SWITCHEROO_DIS; } if (client_id == -1) goto out; for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { if (vgasr_priv.clients[i].id == client_id) { client = &vgasr_priv.clients[i]; break; } } vgasr_priv.delayed_switch_active = false; if (just_mux) { ret = vgasr_priv.handler->switchto(client_id); goto out; } if (client->active == true) goto out; /* okay we want a switch - test if devices are willing to switch */ can_switch = true; for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { can_switch = vgasr_priv.clients[i].can_switch(vgasr_priv.clients[i].pdev); if (can_switch == false) { printk(KERN_ERR "vga_switcheroo: client %d refused switch\n", i); break; } } if (can_switch == false && delay == false) goto out; if (can_switch == true) { pdev_name = pci_name(client->pdev); ret = vga_switchto_stage1(client); if (ret) printk(KERN_ERR "vga_switcheroo: switching failed stage 1 %d\n", ret); ret = vga_switchto_stage2(client); if (ret) printk(KERN_ERR "vga_switcheroo: switching failed stage 2 %d\n", ret); } else { printk(KERN_INFO "vga_switcheroo: setting delayed switch to client %d\n", client->id); vgasr_priv.delayed_switch_active = true; vgasr_priv.delayed_client_id = client_id; ret = vga_switchto_stage1(client); if (ret) printk(KERN_ERR "vga_switcheroo: delayed switching stage 1 failed %d\n", ret); } out: mutex_unlock(&vgasr_mutex); return cnt; }
static INT __devinit rt2860_probe( IN struct pci_dev *pci_dev, IN const struct pci_device_id *pci_id) { VOID *pAd = NULL; struct net_device *net_dev; PVOID handle; PSTRING print_name; ULONG csr_addr; INT rv = 0; RTMP_OS_NETDEV_OP_HOOK netDevHook; ULONG OpMode; DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n")); /*PCIDevInit============================================== */ /* wake up and enable device */ if ((rv = pci_enable_device(pci_dev))!= 0) { DBGPRINT(RT_DEBUG_ERROR, ("Enable PCI device failed, errno=%d!\n", rv)); return rv; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) print_name = (PSTRING)pci_name(pci_dev); #else print_name = pci_dev->slot_name; #endif /* LINUX_VERSION_CODE */ if ((rv = pci_request_regions(pci_dev, print_name)) != 0) { DBGPRINT(RT_DEBUG_ERROR, ("Request PCI resource failed, errno=%d!\n", rv)); goto err_out; } /* map physical address to virtual address for accessing register */ csr_addr = (unsigned long) ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); if (!csr_addr) { DBGPRINT(RT_DEBUG_ERROR, ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n", print_name, (ULONG)pci_resource_len(pci_dev, 0), (ULONG)pci_resource_start(pci_dev, 0))); goto err_out_free_res; } else { DBGPRINT(RT_DEBUG_TRACE, ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name, (ULONG)pci_resource_start(pci_dev, 0), (ULONG)csr_addr, pci_dev->irq)); } /* Set DMA master */ pci_set_master(pci_dev); /*RtmpDevInit============================================== */ /* Allocate RTMP_ADAPTER adapter structure */ os_alloc_mem(NULL, (UCHAR **)&handle, sizeof(struct os_cookie)); if (handle == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s(): Allocate memory for os handle failed!\n", __FUNCTION__)); goto err_out_iounmap; } memset(handle, 0, sizeof(struct os_cookie)); ((POS_COOKIE)handle)->pci_dev = pci_dev; #ifdef OS_ABL_FUNC_SUPPORT { RTMP_PCI_CONFIG PciConfig; PciConfig.ConfigVendorID = PCI_VENDOR_ID; /* get DRIVER operations */ RTMP_DRV_OPS_FUNCTION(pRtmpDrvOps, NULL, &PciConfig, NULL); } #endif /* OS_ABL_FUNC_SUPPORT */ rv = RTMPAllocAdapterBlock(handle, &pAd); /* we may need the pci_dev for allocate structure of "RTMP_ADAPTER" */ if (rv != NDIS_STATUS_SUCCESS) goto err_out_iounmap; /* Here are the RTMP_ADAPTER structure with pci-bus specific parameters. */ RTMP_DRIVER_PCI_CSR_SET(pAd, csr_addr); RTMP_DRIVER_PCIE_INIT(pAd, pci_dev); /*NetDevInit============================================== */ net_dev = RtmpPhyNetDevInit(pAd, &netDevHook); if (net_dev == NULL) goto err_out_free_radev; /* Here are the net_device structure with pci-bus specific parameters. */ net_dev->irq = pci_dev->irq; /* Interrupt IRQ number */ net_dev->base_addr = csr_addr; /* Save CSR virtual address and irq to device structure */ pci_set_drvdata(pci_dev, net_dev); /* Set driver data */ /*All done, it's time to register the net device to linux kernel. */ /* Register this device */ #ifdef RT_CFG80211_SUPPORT { /* pAd->pCfgDev = &(pci_dev->dev); */ /* pAd->CFG80211_Register = CFG80211_Register; */ /* RTMP_DRIVER_CFG80211_INIT(pAd, pci_dev); */ /* In 2.6.32, cfg80211 register must be before register_netdevice(); We can not put the register in rt28xx_open(); Or you will suffer NULL pointer in list_add of cfg80211_netdev_notifier_call(). */ CFG80211_Register(pAd, &(pci_dev->dev), net_dev); } #endif /* RT_CFG80211_SUPPORT */ RTMP_DRIVER_OP_MODE_GET(pAd, &OpMode); rv = RtmpOSNetDevAttach(OpMode, net_dev, &netDevHook); if (rv) goto err_out_free_netdev; /*#ifdef KTHREAD_SUPPORT */ #ifdef PRE_ASSIGN_MAC_ADDR UCHAR PermanentAddress[MAC_ADDR_LEN]; RTMP_DRIVER_MAC_ADDR_GET(pAd, &PermanentAddress[0]); DBGPRINT(RT_DEBUG_TRACE, ("@%s MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, PermanentAddress[0], PermanentAddress[1],PermanentAddress[2],PermanentAddress[3],PermanentAddress[4],PermanentAddress[5])); /* Set up the Mac address */ RtmpOSNetDevAddrSet(OpMode, net_dev, &PermanentAddress[0], NULL); #endif /* PRE_ASSIGN_MAC_ADDR */ wl_proc_init(); DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n")); return 0; /* probe ok */ /* --------------------------- ERROR HANDLE --------------------------- */ err_out_free_netdev: RtmpOSNetDevFree(net_dev); err_out_free_radev: /* free RTMP_ADAPTER strcuture and os_cookie*/ RTMPFreeAdapter(pAd); err_out_iounmap: iounmap((void *)(csr_addr)); release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); err_out_free_res: pci_release_regions(pci_dev); err_out: pci_disable_device(pci_dev); DBGPRINT(RT_DEBUG_ERROR, ("<=== rt2860_probe failed with rv = %d!\n", rv)); return -ENODEV; /* probe fail */ }
/** * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze * @dn device node * @dev pci device, if known * * Check for an EEH failure for the given device node. Call this * routine if the result of a read was all 0xff's and you want to * find out if this is due to an EEH slot freeze. This routine * will query firmware for the EEH status. * * Returns 0 if there has not been an EEH error; otherwise returns * a non-zero value and queues up a slot isolation event notification. * * It is safe to call this routine in an interrupt context. */ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) { int ret; int rets[3]; unsigned long flags; struct pci_dn *pdn; enum pci_channel_state state; int rc = 0; total_mmio_ffs++; if (!eeh_subsystem_enabled) return 0; if (!dn) { no_dn++; return 0; } pdn = PCI_DN(dn); /* Access to IO BARs might get this far and still not want checking. */ if (!(pdn->eeh_mode & EEH_MODE_SUPPORTED) || pdn->eeh_mode & EEH_MODE_NOCHECK) { ignored_check++; #ifdef DEBUG printk ("EEH:ignored check (%x) for %s %s\n", pdn->eeh_mode, pci_name (dev), dn->full_name); #endif return 0; } if (!pdn->eeh_config_addr && !pdn->eeh_pe_config_addr) { no_cfg_addr++; return 0; } /* If we already have a pending isolation event for this * slot, we know it's bad already, we don't need to check. * Do this checking under a lock; as multiple PCI devices * in one slot might report errors simultaneously, and we * only want one error recovery routine running. */ spin_lock_irqsave(&confirm_error_lock, flags); rc = 1; if (pdn->eeh_mode & EEH_MODE_ISOLATED) { pdn->eeh_check_count ++; if (pdn->eeh_check_count >= EEH_MAX_FAILS) { printk (KERN_ERR "EEH: Device driver ignored %d bad reads, panicing\n", pdn->eeh_check_count); dump_stack(); msleep(5000); /* re-read the slot reset state */ if (read_slot_reset_state(pdn, rets) != 0) rets[0] = -1; /* reset state unknown */ /* If we are here, then we hit an infinite loop. Stop. */ panic("EEH: MMIO halt (%d) on device:%s\n", rets[0], pci_name(dev)); } goto dn_unlock; } /* * Now test for an EEH failure. This is VERY expensive. * Note that the eeh_config_addr may be a parent device * in the case of a device behind a bridge, or it may be * function zero of a multi-function device. * In any case they must share a common PHB. */ ret = read_slot_reset_state(pdn, rets); /* If the call to firmware failed, punt */ if (ret != 0) { printk(KERN_WARNING "EEH: read_slot_reset_state() failed; rc=%d dn=%s\n", ret, dn->full_name); false_positives++; rc = 0; goto dn_unlock; } /* If EEH is not supported on this device, punt. */ if (rets[1] != 1) { printk(KERN_WARNING "EEH: event on unsupported device, rc=%d dn=%s\n", ret, dn->full_name); false_positives++; rc = 0; goto dn_unlock; } /* If not the kind of error we know about, punt. */ if (rets[0] != 2 && rets[0] != 4 && rets[0] != 5) { false_positives++; rc = 0; goto dn_unlock; } /* Note that config-io to empty slots may fail; * we recognize empty because they don't have children. */ if ((rets[0] == 5) && (dn->child == NULL)) { false_positives++; rc = 0; goto dn_unlock; } slot_resets++; /* Avoid repeated reports of this failure, including problems * with other functions on this device, and functions under * bridges. */ eeh_mark_slot (dn, EEH_MODE_ISOLATED); spin_unlock_irqrestore(&confirm_error_lock, flags); state = pci_channel_io_normal; if ((rets[0] == 2) || (rets[0] == 4)) state = pci_channel_io_frozen; if (rets[0] == 5) state = pci_channel_io_perm_failure; eeh_send_failure_event (dn, dev, state, rets[2]); /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure * out what happened. So print that out. */ if (rets[0] != 5) dump_stack(); return 1; dn_unlock: spin_unlock_irqrestore(&confirm_error_lock, flags); return rc; }
static int __devinit pasemi_edac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mem_ctl_info *mci = NULL; u32 errctl1, errcor, scrub, mcen; pci_read_config_dword(pdev, MCCFG_MCEN, &mcen); if (!(mcen & MCCFG_MCEN_MMC_EN)) return -ENODEV; /* * We should think about enabling other error detection later on */ pci_read_config_dword(pdev, MCDEBUG_ERRCTL1, &errctl1); errctl1 |= MCDEBUG_ERRCTL1_SBE_LOG_EN | MCDEBUG_ERRCTL1_MBE_LOG_EN | MCDEBUG_ERRCTL1_RFL_LOG_EN; pci_write_config_dword(pdev, MCDEBUG_ERRCTL1, errctl1); mci = edac_mc_alloc(0, PASEMI_EDAC_NR_CSROWS, PASEMI_EDAC_NR_CHANS, system_mmc_id++); if (mci == NULL) return -ENOMEM; pci_read_config_dword(pdev, MCCFG_ERRCOR, &errcor); errcor |= MCCFG_ERRCOR_RNK_FAIL_DET_EN | MCCFG_ERRCOR_ECC_GEN_EN | MCCFG_ERRCOR_ECC_CRR_EN; mci->dev = &pdev->dev; mci->mtype_cap = MEM_FLAG_DDR | MEM_FLAG_RDDR; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_EC | EDAC_FLAG_SECDED; mci->edac_cap = (errcor & MCCFG_ERRCOR_ECC_GEN_EN) ? ((errcor & MCCFG_ERRCOR_ECC_CRR_EN) ? (EDAC_FLAG_EC | EDAC_FLAG_SECDED) : EDAC_FLAG_EC) : EDAC_FLAG_NONE; mci->mod_name = MODULE_NAME; mci->dev_name = pci_name(pdev); mci->ctl_name = "pasemi,pwrficient-mc"; mci->edac_check = pasemi_edac_check; mci->ctl_page_to_phys = NULL; pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub); mci->scrub_cap = SCRUB_FLAG_HW_PROG | SCRUB_FLAG_HW_SRC; mci->scrub_mode = ((errcor & MCCFG_ERRCOR_ECC_CRR_EN) ? SCRUB_FLAG_HW_SRC : 0) | ((scrub & MCCFG_SCRUB_RGLR_SCRB_EN) ? SCRUB_FLAG_HW_PROG : 0); if (pasemi_edac_init_csrows(mci, pdev, (mci->edac_cap & EDAC_FLAG_SECDED) ? EDAC_SECDED : ((mci->edac_cap & EDAC_FLAG_EC) ? EDAC_EC : EDAC_NONE))) goto fail; /* * Clear status */ pasemi_edac_get_error_info(mci); if (edac_mc_add_mc(mci)) goto fail; /* get this far and it's successful */ return 0; fail: edac_mc_free(mci); return -ENODEV; }
static int zt5550_hc_config(struct pci_dev *pdev) { int ret; /* Since we know that no boards exist with two HC chips, treat it as an error */ if(hc_dev) { err("too many host controller devices?"); return -EBUSY; } ret = pci_enable_device(pdev); if(ret) { err("cannot enable %s\n", pci_name(pdev)); return ret; } hc_dev = pdev; dbg("hc_dev = %p", hc_dev); dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); if(!request_mem_region(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1), MY_NAME)) { err("cannot reserve MMIO region"); ret = -ENOMEM; goto exit_disable_device; } hc_registers = ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); if(!hc_registers) { err("cannot remap MMIO region %llx @ %llx", (unsigned long long)pci_resource_len(hc_dev, 1), (unsigned long long)pci_resource_start(hc_dev, 1)); ret = -ENODEV; goto exit_release_region; } csr_hc_index = hc_registers + CSR_HCINDEX; csr_hc_data = hc_registers + CSR_HCDATA; csr_int_status = hc_registers + CSR_INTSTAT; csr_int_mask = hc_registers + CSR_INTMASK; /* * Disable host control, fault and serial interrupts */ dbg("disabling host control, fault and serial interrupts"); writeb((u8) HC_INT_MASK_REG, csr_hc_index); writeb((u8) ALL_INDEXED_INTS_MASK, csr_hc_data); dbg("disabled host control, fault and serial interrupts"); /* * Disable timer0, timer1 and ENUM interrupts */ dbg("disabling timer0, timer1 and ENUM interrupts"); writeb((u8) ALL_DIRECT_INTS_MASK, csr_int_mask); dbg("disabled timer0, timer1 and ENUM interrupts"); return 0; exit_release_region: release_mem_region(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); exit_disable_device: pci_disable_device(hc_dev); return ret; }
/** * usb_hcd_pci_probe - initialize PCI-based HCDs * @dev: USB Host Controller being probed * @id: pci hotplug id connecting controller to HCD framework * Context: !in_interrupt() * * Allocates basic PCI resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. * * Store this function in the HCD's struct pci_driver as probe(). */ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct hc_driver *driver; struct usb_hcd *hcd; int retval; if (usb_disabled()) return -ENODEV; if (!id || !(driver = (struct hc_driver *) id->driver_data)) return -EINVAL; if (pci_enable_device (dev) < 0) return -ENODEV; dev->current_state = PCI_D0; dev->dev.power.power_state = PMSG_ON; if (!dev->irq) { dev_err (&dev->dev, "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", pci_name(dev)); retval = -ENODEV; goto err1; } hcd = usb_create_hcd (driver, &dev->dev, pci_name(dev)); if (!hcd) { retval = -ENOMEM; goto err1; } if (driver->flags & HCD_MEMORY) { // EHCI, OHCI hcd->rsrc_start = pci_resource_start (dev, 0); hcd->rsrc_len = pci_resource_len (dev, 0); if (!request_mem_region (hcd->rsrc_start, hcd->rsrc_len, driver->description)) { dev_dbg (&dev->dev, "controller already in use\n"); retval = -EBUSY; goto err2; } hcd->regs = ioremap_nocache (hcd->rsrc_start, hcd->rsrc_len); if (hcd->regs == NULL) { dev_dbg (&dev->dev, "error mapping memory\n"); retval = -EFAULT; goto err3; } } else { // UHCI int region; for (region = 0; region < PCI_ROM_RESOURCE; region++) { if (!(pci_resource_flags (dev, region) & IORESOURCE_IO)) continue; hcd->rsrc_start = pci_resource_start (dev, region); hcd->rsrc_len = pci_resource_len (dev, region); if (request_region (hcd->rsrc_start, hcd->rsrc_len, driver->description)) break; } if (region == PCI_ROM_RESOURCE) { dev_dbg (&dev->dev, "no i/o regions available\n"); retval = -EBUSY; goto err1; } } #ifdef CONFIG_PCI_NAMES hcd->product_desc = dev->pretty_name; #endif pci_set_master (dev); retval = usb_add_hcd (hcd, dev->irq, SA_SHIRQ); if (retval != 0) goto err4; return retval; err4: if (driver->flags & HCD_MEMORY) { iounmap (hcd->regs); err3: release_mem_region (hcd->rsrc_start, hcd->rsrc_len); } else release_region (hcd->rsrc_start, hcd->rsrc_len); err2: usb_put_hcd (hcd); err1: pci_disable_device (dev); dev_err (&dev->dev, "init %s fail, %d\n", pci_name(dev), retval); return retval; }
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; unsigned int i; int rc; struct ata_probe_ent *probe_ent; int board_id = (int) ent->driver_data; const int *bar_sizes; int pci_dev_busy = 0; u8 tmp8; if (!printed_version++) printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); rc = pci_enable_device(pdev); if (rc) return rc; rc = pci_request_regions(pdev, DRV_NAME); if (rc) { pci_dev_busy = 1; goto err_out; } if (board_id == vt6420) { pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8); if (tmp8 & SATA_2DEV) { printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n", pci_name(pdev), (int) tmp8); rc = -EIO; goto err_out_regions; } bar_sizes = &svia_bar_sizes[0]; } else { bar_sizes = &vt6421_bar_sizes[0]; } for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++) if ((pci_resource_start(pdev, i) == 0) || (pci_resource_len(pdev, i) < bar_sizes[i])) { printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n", pci_name(pdev), i, pci_resource_start(pdev, i), pci_resource_len(pdev, i)); rc = -ENODEV; goto err_out_regions; } rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); if (rc) goto err_out_regions; rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); if (rc) goto err_out_regions; if (board_id == vt6420) probe_ent = vt6420_init_probe_ent(pdev); else probe_ent = vt6421_init_probe_ent(pdev); if (!probe_ent) { printk(KERN_ERR DRV_NAME "(%s): out of memory\n", pci_name(pdev)); rc = -ENOMEM; goto err_out_regions; } svia_configure(pdev); pci_set_master(pdev); /* FIXME: check ata_device_add return value */ ata_device_add(probe_ent); kfree(probe_ent); return 0; err_out_regions: pci_release_regions(pdev); err_out: if (!pci_dev_busy) pci_disable_device(pdev); return rc; }