/*===========================================================================* * atl2_probe * *===========================================================================*/ static int atl2_probe(int skip) { /* Find a matching PCI device. */ u16_t vid, did; char *dname; int r, devind; pci_init(); r = pci_first_dev(&devind, &vid, &did); if (r <= 0) return -1; while (skip--) { r = pci_next_dev(&devind, &vid, &did); if (r <= 0) return -1; } dname = pci_dev_name(vid, did); ATL2_DEBUG(("ATL2: found %s (%x/%x) at %s\n", dname ? dname : "<unknown>", vid, did, pci_slot_name(devind))); pci_reserve(devind); return devind; }
/*===========================================================================* * root_pci * *===========================================================================*/ static void root_pci(void) { /* Print information about PCI devices present in the system. */ u16_t vid, did; u8_t bcr, scr, pifr; char *slot_name, *dev_name; int r, devind; static int first = TRUE; /* This should be taken care of behind the scenes by the PCI lib. */ if (first) { pci_init(); first = FALSE; } /* Iterate over all devices, printing info for each of them. */ r = pci_first_dev(&devind, &vid, &did); while (r == 1) { slot_name = pci_slot_name(devind); dev_name = pci_dev_name(vid, did); bcr = pci_attr_r8(devind, PCI_BCR); scr = pci_attr_r8(devind, PCI_SCR); pifr = pci_attr_r8(devind, PCI_PIFR); buf_printf("%s %x/%x/%x %04X:%04X %s\n", slot_name ? slot_name : "-", bcr, scr, pifr, vid, did, dev_name ? dev_name : ""); r = pci_next_dev(&devind, &vid, &did); } }
static int rename_slot(struct pci_slot *slot, const char *name) { int result = 0; char *slot_name; if (strcmp(pci_slot_name(slot), name) == 0) return result; slot_name = make_slot_name(name); if (!slot_name) return -ENOMEM; result = kobject_rename(&slot->kobj, slot_name); kfree(slot_name); return result; }
static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; struct pci_slot *slot = to_pci_slot(kobj); dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n", slot->number, pci_slot_name(slot)); down_read(&pci_bus_sem); list_for_each_entry(dev, &slot->bus->devices, bus_list) if (PCI_SLOT(dev->devfn) == slot->number) dev->slot = NULL; up_read(&pci_bus_sem); list_del(&slot->list); kfree(slot); }
/*===========================================================================* * e1000_probe * *===========================================================================*/ PRIVATE int e1000_probe(e1000_t *e, int skip) { int i, r, devind; u16_t vid, did; u32_t status[2]; u32_t gfpreg, sector_base_addr; char *dname; E1000_DEBUG(3, ("%s: probe()\n", e->name)); /* * Attempt to iterate the PCI bus. Start at the beginning. */ if ((r = pci_first_dev(&devind, &vid, &did)) == 0) { return FALSE; } /* Loop devices on the PCI bus. */ for(;;) { for (i = 0; pcitab_e1000[i] != 0; i++) { if (vid != 0x8086) continue; if (did != pcitab_e1000[i]) continue; else break; } if (pcitab_e1000[i] != 0) { if (!skip) break; skip--; } if (!(r = pci_next_dev(&devind, &vid, &did))) { return FALSE; } } /* * Successfully detected an Intel Pro/1000 on the PCI bus. */ e->status |= E1000_DETECTED; e->eeprom_read = eeprom_eerd; /* * Set card specific properties. */ switch (did) { case E1000_DEV_ID_ICH10_R_BM_LF: e->eeprom_read = eeprom_ich; break; case E1000_DEV_ID_82574L: case E1000_DEV_ID_82541GI_LF: e->eeprom_done_bit = (1 << 1); e->eeprom_addr_off = 2; break; default: e->eeprom_done_bit = (1 << 4); e->eeprom_addr_off = 8; break; } /* Inform the user about the new card. */ if (!(dname = pci_dev_name(vid, did))) { dname = "Intel Pro/1000 Gigabit Ethernet Card"; } E1000_DEBUG(1, ("%s: %s (%04x/%04x/%02x) at %s\n", e->name, dname, vid, did, e->revision, pci_slot_name(devind))); /* Reserve PCI resources found. */ if ((r = pci_reserve_ok(devind)) != OK) { panic("failed to reserve PCI device: %d", r); } /* Read PCI configuration. */ e->irq = pci_attr_r8(devind, PCI_ILR); e->regs = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR), 0x20000); /* Verify mapped registers. */ if (e->regs == (u8_t *) -1) { panic("failed to map hardware registers from PCI"); } /* Optionally map flash memory. */ if (did != E1000_DEV_ID_82540EM && did != E1000_DEV_ID_82540EP && pci_attr_r32(devind, PCI_BAR_2)) { if((e->flash = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR_2), 0x10000)) == MAP_FAILED) { if((e->flash = vm_map_phys(SELF, (void *) pci_attr_r32(devind, PCI_BAR_2), 0x1000)) == MAP_FAILED) { panic("e1000: couldn't map in flash."); } } gfpreg = E1000_READ_FLASH_REG(e, ICH_FLASH_GFPREG); /* * sector_base_addr is a "sector"-aligned address (4096 bytes) */ sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK; /* flash_base_addr is byte-aligned */ e->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT; } /* * Output debug information. */ status[0] = e1000_reg_read(e, E1000_REG_STATUS); E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status[0] & 3 ? "up" : "down", status[0] & 1 ? "full" : "half")); return TRUE; }
/* * Find a matching device. Return TRUE on success. */ static int e1000_probe(e1000_t * e, int skip) { int r, devind, ioflag; u16_t vid, did, cr; u32_t status; u32_t base, size; char *dname; E1000_DEBUG(3, ("%s: probe()\n", e->name)); /* Initialize communication to the PCI driver. */ pci_init(); /* Attempt to iterate the PCI bus. Start at the beginning. */ if ((r = pci_first_dev(&devind, &vid, &did)) == 0) return FALSE; /* Loop devices on the PCI bus. */ while (skip--) { E1000_DEBUG(3, ("%s: probe() devind %d vid 0x%x did 0x%x\n", e->name, devind, vid, did)); if (!(r = pci_next_dev(&devind, &vid, &did))) return FALSE; } /* We found a matching card. Set card-specific properties. */ e->eeprom_read = eeprom_eerd; switch (did) { case E1000_DEV_ID_ICH10_D_BM_LM: case E1000_DEV_ID_ICH10_R_BM_LF: e->eeprom_read = eeprom_ich; break; case E1000_DEV_ID_82540EM: case E1000_DEV_ID_82545EM: case E1000_DEV_ID_82540EP_LP: e->eeprom_done_bit = (1 << 4); e->eeprom_addr_off = 8; break; default: e->eeprom_done_bit = (1 << 1); e->eeprom_addr_off = 2; break; } /* Inform the user about the new card. */ if (!(dname = pci_dev_name(vid, did))) dname = "Intel Pro/1000 Gigabit Ethernet Card"; E1000_DEBUG(1, ("%s: %s (%04x/%04x) at %s\n", e->name, dname, vid, did, pci_slot_name(devind))); /* Reserve PCI resources found. */ pci_reserve(devind); /* Read PCI configuration. */ e->irq = pci_attr_r8(devind, PCI_ILR); if ((r = pci_get_bar(devind, PCI_BAR, &base, &size, &ioflag)) != OK) panic("failed to get PCI BAR: %d", r); if (ioflag) panic("PCI BAR is not for memory"); if ((e->regs = vm_map_phys(SELF, (void *)base, size)) == MAP_FAILED) panic("failed to map hardware registers from PCI"); /* Enable DMA bus mastering if necessary. */ cr = pci_attr_r16(devind, PCI_CR); if (!(cr & PCI_CR_MAST_EN)) pci_attr_w16(devind, PCI_CR, cr | PCI_CR_MAST_EN); /* Optionally map flash memory. */ e1000_map_flash(e, devind, did); /* Output debug information. */ status = e1000_reg_read(e, E1000_REG_STATUS); E1000_DEBUG(3, ("%s: MEM at %p, IRQ %d\n", e->name, e->regs, e->irq)); E1000_DEBUG(3, ("%s: link %s, %s duplex\n", e->name, status & 3 ? "up" : "down", status & 1 ? "full" : "half")); return TRUE; }
/** * pci_create_slot - create or increment refcount for physical PCI slot * @parent: struct pci_bus of parent bridge * @slot_nr: PCI_SLOT(pci_dev->devfn) or -1 for placeholder * @name: user visible string presented in /sys/bus/pci/slots/<name> * @hotplug: set if caller is hotplug driver, NULL otherwise * * PCI slots have first class attributes such as address, speed, width, * and a &struct pci_slot is used to manage them. This interface will * either return a new &struct pci_slot to the caller, or if the pci_slot * already exists, its refcount will be incremented. * * Slots are uniquely identified by a @pci_bus, @slot_nr tuple. * * There are known platforms with broken firmware that assign the same * name to multiple slots. Workaround these broken platforms by renaming * the slots on behalf of the caller. If firmware assigns name N to * multiple slots: * * The first slot is assigned N * The second slot is assigned N-1 * The third slot is assigned N-2 * etc. * * Placeholder slots: * In most cases, @pci_bus, @slot_nr will be sufficient to uniquely identify * a slot. There is one notable exception - pSeries (rpaphp), where the * @slot_nr cannot be determined until a device is actually inserted into * the slot. In this scenario, the caller may pass -1 for @slot_nr. * * The following semantics are imposed when the caller passes @slot_nr == * -1. First, we no longer check for an existing %struct pci_slot, as there * may be many slots with @slot_nr of -1. The other change in semantics is * user-visible, which is the 'address' parameter presented in sysfs will * consist solely of a dddd:bb tuple, where dddd is the PCI domain of the * %struct pci_bus and bb is the bus number. In other words, the devfn of * the 'placeholder' slot will not be displayed. */ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, const char *name, struct hotplug_slot *hotplug) { struct pci_dev *dev; struct pci_slot *slot; int err = 0; char *slot_name = NULL; mutex_lock(&pci_slot_mutex); if (slot_nr == -1) goto placeholder; /* * Hotplug drivers are allowed to rename an existing slot, * but only if not already claimed. */ slot = get_slot(parent, slot_nr); if (slot) { if (hotplug) { if ((err = slot->hotplug ? -EBUSY : 0) || (err = rename_slot(slot, name))) { kobject_put(&slot->kobj); slot = NULL; goto err; } } goto out; } placeholder: slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) { err = -ENOMEM; goto err; } slot->bus = parent; slot->number = slot_nr; slot->kobj.kset = pci_slots_kset; slot_name = make_slot_name(name); if (!slot_name) { err = -ENOMEM; goto err; } err = kobject_init_and_add(&slot->kobj, &pci_slot_ktype, NULL, "%s", slot_name); if (err) goto err; INIT_LIST_HEAD(&slot->list); list_add(&slot->list, &parent->slots); down_read(&pci_bus_sem); list_for_each_entry(dev, &parent->devices, bus_list) if (PCI_SLOT(dev->devfn) == slot_nr) dev->slot = slot; up_read(&pci_bus_sem); dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n", slot_nr, pci_slot_name(slot)); out: kfree(slot_name); mutex_unlock(&pci_slot_mutex); return slot; err: kfree(slot); slot = ERR_PTR(err); goto out; }