/* * Wait for last operation to complete. * This code has to spin since there is no other notification from the PCI * hardware. Since the VPD is often implemented by serial attachment to an * EEPROM, it may take many milliseconds to complete. * * Returns 0 on success, negative values indicate error. */ static int pci_vpd_wait(struct pci_dev *dev) { struct pci_vpd *vpd = dev->vpd; unsigned long timeout = jiffies + msecs_to_jiffies(125); unsigned long max_sleep = 16; u16 status; int ret; if (!vpd->busy) return 0; while (time_before(jiffies, timeout)) { ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR, &status); if (ret < 0) return ret; if ((status & PCI_VPD_ADDR_F) == vpd->flag) { vpd->busy = 0; return 0; } if (fatal_signal_pending(current)) return -EINTR; usleep_range(10, max_sleep); if (max_sleep < 1024) max_sleep *= 2; } pci_warn(dev, "VPD access failed. This is likely a firmware bug on this device. Contact the card vendor for a firmware update\n"); return -ETIMEDOUT; }
SYSCALL_DEFINE5(pciconfig_read, unsigned long, bus, unsigned long, dfn, unsigned long, off, unsigned long, len, void __user *, buf) { struct pci_dev *dev; u8 byte; u16 word; u32 dword; long err; long cfg_ret; if (!capable(CAP_SYS_ADMIN)) return -EPERM; err = -ENODEV; dev = pci_get_bus_and_slot(bus, dfn); if (!dev) goto error; switch (len) { case 1: cfg_ret = pci_user_read_config_byte(dev, off, &byte); break; case 2: cfg_ret = pci_user_read_config_word(dev, off, &word); break; case 4: cfg_ret = pci_user_read_config_dword(dev, off, &dword); break; default: err = -EINVAL; goto error; } err = -EIO; if (cfg_ret != PCIBIOS_SUCCESSFUL) goto error; switch (len) { case 1: err = put_user(byte, (unsigned char __user *)buf); break; case 2: err = put_user(word, (unsigned short __user *)buf); break; case 4: err = put_user(dword, (unsigned int __user *)buf); break; } pci_dev_put(dev); return err; error: /* ??? XFree86 doesn't even check the return value. They just look for 0xffffffff in the output, since that's what they get instead of a machine check on x86. */ switch (len) { case 1: put_user(-1, (unsigned char __user *)buf); break; case 2: put_user(-1, (unsigned short __user *)buf); break; case 4: put_user(-1, (unsigned int __user *)buf); break; } pci_dev_put(dev); return err; }
static ssize_t proc_bus_pci_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) { struct pci_dev *dev = PDE_DATA(file_inode(file)); unsigned int pos = *ppos; unsigned int cnt, size; /* * Normal users can read only the standardized portion of the * configuration space as several chips lock up when trying to read * undefined locations (think of Intel PIIX4 as a typical example). */ if (capable(CAP_SYS_ADMIN)) size = dev->cfg_size; else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) size = 128; else size = 64; if (pos >= size) return 0; if (nbytes >= size) nbytes = size; if (pos + nbytes > size) nbytes = size - pos; cnt = nbytes; if (!access_ok(VERIFY_WRITE, buf, cnt)) return -EINVAL; pci_config_pm_runtime_get(dev); if ((pos & 1) && cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; cnt--; } if ((pos & 3) && cnt > 2) { unsigned short val; pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (__le16 __user *) buf); buf += 2; pos += 2; cnt -= 2; } while (cnt >= 4) { unsigned int val; pci_user_read_config_dword(dev, pos, &val); __put_user(cpu_to_le32(val), (__le32 __user *) buf); buf += 4; pos += 4; cnt -= 4; } if (cnt >= 2) { unsigned short val; pci_user_read_config_word(dev, pos, &val); __put_user(cpu_to_le16(val), (__le16 __user *) buf); buf += 2; pos += 2; cnt -= 2; } if (cnt) { unsigned char val; pci_user_read_config_byte(dev, pos, &val); __put_user(val, buf); buf++; pos++; cnt--; } pci_config_pm_runtime_put(dev); *ppos = pos; return nbytes; }