===== drivers/pci/pci-sysfs.c 1.10 vs edited ===== --- 1.10/drivers/pci/pci-sysfs.c 2004-06-04 06:23:04 -07:00 +++ edited/drivers/pci/pci-sysfs.c 2004-07-30 11:47:26 -07:00 @@ -164,6 +164,60 @@ return count; } +static void +pci_enable_rom(struct pci_dev *dev) +{ + u32 rom_addr; + + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_addr); + rom_addr |= PCI_ROM_ADDRESS_ENABLE; + pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_addr); +} + +static void +pci_disable_rom(struct pci_dev *dev) +{ + u32 rom_addr; + + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_addr); + rom_addr &= ~PCI_ROM_ADDRESS_ENABLE; + pci_write_config_dword(dev, PCI_ROM_ADDRESS, rom_addr); +} + +static ssize_t +pci_read_rom(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct pci_dev *dev = to_pci_dev(container_of(kobj,struct device,kobj)); + loff_t init_off = off; + unsigned long start = pci_resource_start(dev, PCI_ROM_RESOURCE); + int size = pci_resource_len(dev, PCI_ROM_RESOURCE); + + if (off > size) + return 0; + if (off + count > size) { + size -= off; + count = size; + } else { + size = count; + } + + /* Enable ROM space decodes and do the reads */ + pci_enable_rom(dev); + + while (size > 0) { + unsigned char val; + val = readb(start + off); + buf[off - init_off] = val; + off++; + --size; + } + + /* Disable again before continuing */ + pci_disable_rom(dev); + + return count; +} + static struct bin_attribute pci_config_attr = { .attr = { .name = "config", @@ -186,12 +240,27 @@ .write = pci_write_config, }; +static struct bin_attribute pci_rom_attr = { + .attr = { + .name = "rom", + .mode = S_IRUSR, + .owner = THIS_MODULE, + }, + .read = pci_read_rom, +}; + void pci_create_sysfs_dev_files (struct pci_dev *pdev) { if (pdev->cfg_size < 4096) sysfs_create_bin_file(&pdev->dev.kobj, &pci_config_attr); else sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr); + + /* If the device has a ROM, map it */ + if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { + pci_rom_attr.size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + sysfs_create_bin_file(&pdev->dev.kobj, &pci_rom_attr); + } /* add platform-specific attributes */ pcibios_add_platform_entries(pdev);