Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 97c44836 authored by Timothy S. Nelson's avatar Timothy S. Nelson Committed by Jesse Barnes
Browse files

PCI: return error on failure to read PCI ROMs



This patch makes the ROM reading code return an error to user space if
the size of the ROM read is equal to 0.

The patch also emits a warnings if the contents of the ROM are invalid,
and documents the effects of the "enable" file on ROM reading.

Signed-off-by: default avatarTimothy S. Nelson <wayland@wayland.id.au>
Acked-by: default avatarAlex Villacis-Lasso <a_villacis@palosanto.com>
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
parent 3419c75e
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -9,6 +9,7 @@ that support it. For example, a given bus might look like this:
     |   |-- class
     |   |-- class
     |   |-- config
     |   |-- config
     |   |-- device
     |   |-- device
     |   |-- enable
     |   |-- irq
     |   |-- irq
     |   |-- local_cpus
     |   |-- local_cpus
     |   |-- resource
     |   |-- resource
@@ -32,6 +33,7 @@ files, each with their own function.
       class		   PCI class (ascii, ro)
       class		   PCI class (ascii, ro)
       config		   PCI config space (binary, rw)
       config		   PCI config space (binary, rw)
       device		   PCI device (ascii, ro)
       device		   PCI device (ascii, ro)
       enable	           Whether the device is enabled (ascii, rw)
       irq		   IRQ number (ascii, ro)
       irq		   IRQ number (ascii, ro)
       local_cpus	   nearby CPU mask (cpumask, ro)
       local_cpus	   nearby CPU mask (cpumask, ro)
       resource		   PCI resource host addresses (ascii, ro)
       resource		   PCI resource host addresses (ascii, ro)
@@ -57,10 +59,19 @@ used to do actual device programming from userspace. Note that some platforms
don't support mmapping of certain resources, so be sure to check the return
don't support mmapping of certain resources, so be sure to check the return
value from any attempted mmap.
value from any attempted mmap.


The 'enable' file provides a counter that indicates how many times the device 
has been enabled.  If the 'enable' file currently returns '4', and a '1' is
echoed into it, it will then return '5'.  Echoing a '0' into it will decrease
the count.  Even when it returns to 0, though, some of the initialisation
may not be reversed.  

The 'rom' file is special in that it provides read-only access to the device's
The 'rom' file is special in that it provides read-only access to the device's
ROM file, if available.  It's disabled by default, however, so applications
ROM file, if available.  It's disabled by default, however, so applications
should write the string "1" to the file to enable it before attempting a read
should write the string "1" to the file to enable it before attempting a read
call, and disable it following the access by writing "0" to the file.
call, and disable it following the access by writing "0" to the file.  Note
that the device must be enabled for a rom read to return data succesfully.
In the event a driver is not bound to the device, it can be enabled using the
'enable' file, documented above.


Accessing legacy resources through sysfs
Accessing legacy resources through sysfs
----------------------------------------
----------------------------------------
+1 −1
Original line number Original line Diff line number Diff line
@@ -443,7 +443,7 @@ sn_acpi_slot_fixup(struct pci_dev *dev)
		size = pci_resource_len(dev, PCI_ROM_RESOURCE);
		size = pci_resource_len(dev, PCI_ROM_RESOURCE);
		addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
		addr = ioremap(pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE],
			       size);
			       size);
		image_size = pci_get_rom_size(addr, size);
		image_size = pci_get_rom_size(dev, addr, size);
		dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
		dev->resource[PCI_ROM_RESOURCE].start = (unsigned long) addr;
		dev->resource[PCI_ROM_RESOURCE].end =
		dev->resource[PCI_ROM_RESOURCE].end =
					(unsigned long) addr + image_size - 1;
					(unsigned long) addr + image_size - 1;
+1 −1
Original line number Original line Diff line number Diff line
@@ -269,7 +269,7 @@ sn_io_slot_fixup(struct pci_dev *dev)


			rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
			rom = ioremap(pci_resource_start(dev, PCI_ROM_RESOURCE),
				      size + 1);
				      size + 1);
			image_size = pci_get_rom_size(rom, size + 1);
			image_size = pci_get_rom_size(dev, rom, size + 1);
			dev->resource[PCI_ROM_RESOURCE].end =
			dev->resource[PCI_ROM_RESOURCE].end =
				dev->resource[PCI_ROM_RESOURCE].start +
				dev->resource[PCI_ROM_RESOURCE].start +
				image_size - 1;
				image_size - 1;
+2 −2
Original line number Original line Diff line number Diff line
@@ -768,8 +768,8 @@ pci_read_rom(struct kobject *kobj, struct bin_attribute *bin_attr,
		return -EINVAL;
		return -EINVAL;
	
	
	rom = pci_map_rom(pdev, &size);	/* size starts out as PCI window size */
	rom = pci_map_rom(pdev, &size);	/* size starts out as PCI window size */
	if (!rom)
	if (!rom || !size)
		return 0;
		return -EIO;
		
		
	if (off >= size)
	if (off >= size)
		count = 0;
		count = 0;
+5 −3
Original line number Original line Diff line number Diff line
@@ -63,7 +63,7 @@ void pci_disable_rom(struct pci_dev *pdev)
 * The PCI window size could be much larger than the
 * The PCI window size could be much larger than the
 * actual image size.
 * actual image size.
 */
 */
size_t pci_get_rom_size(void __iomem *rom, size_t size)
size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size)
{
{
	void __iomem *image;
	void __iomem *image;
	int last_image;
	int last_image;
@@ -72,8 +72,10 @@ size_t pci_get_rom_size(void __iomem *rom, size_t size)
	do {
	do {
		void __iomem *pds;
		void __iomem *pds;
		/* Standard PCI ROMs start out with these bytes 55 AA */
		/* Standard PCI ROMs start out with these bytes 55 AA */
		if (readb(image) != 0x55)
		if (readb(image) != 0x55) {
			dev_err(&pdev->dev, "Invalid ROM contents\n");
			break;
			break;
		}
		if (readb(image + 1) != 0xAA)
		if (readb(image + 1) != 0xAA)
			break;
			break;
		/* get the PCI data structure and check its signature */
		/* get the PCI data structure and check its signature */
@@ -159,7 +161,7 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size)
	 * size is much larger than the actual size of the ROM.
	 * size is much larger than the actual size of the ROM.
	 * True size is important if the ROM is going to be copied.
	 * True size is important if the ROM is going to be copied.
	 */
	 */
	*size = pci_get_rom_size(rom, *size);
	*size = pci_get_rom_size(pdev, rom, *size);
	return rom;
	return rom;
}
}


Loading