add PCI ROMs to sysfs
Quoted 1 line · Matthew Wilcox
BTW, what do you think to moving all the ROM code from
pci-sysfs.cto
a
Quoted 1 line
new file
rom.c? There's not much sense to the ROM accessing code
being
Quoted 1 line
mixed in with the sysfs code like this. After all, we might choose
to
Quoted 1 line
expose the ROM in some other way in the future.
After thinking about this for a while it's a good idea. New patch splits core ROM support into a new file, rom.c.
Patch applies against both current Linus bk and mm now.
If the ROM attribute on a Radeon card is empty, modprobe in the new radeonfb driver. The driver will correct a hardware bug and the ROM will appear.
=====
Jon Smirl
[email protected]
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail
Exposes PCI ROMs via sysfs. Four new routines for drivers to use when accessing ROMs: pci_map_rom, pci_map_rom_copy, pci_unmap_rom, pci_remove_rom. Handles shadow ROMs for laptops that compress actual ROMs.
arch/i386/pci/fixup.c +38 -0
@@ -255,3 +255,41 @@ }DECLARE_PCI_FIXUP_HEADER (PCI_VENDOR_ID_NVIDIA ,PCI_DEVICE_ID_NVIDIA_NFORCE2 , pci_fixup_nforce2); +/* +* Fixup to mark boot BIOS video selected by BIOS before it changes +* +* From information provided by "Jon Smirl" <[email protected]> +* +* The standard boot ROM sequence for an x86 machine uses the BIOS +* to select an initial video card for boot display. This boot video +* card will have it's BIOS copied to C0000 in system RAM. +* IORESOURCE_ROM_SHADOW is used to associate the boot video +* card with this copy. On laptops this copy has to be used since +* the main ROM may be compressed or combined with another image. +* See pci_map_rom() for use of this flag. IORESOURCE_ROM_SHADOW +* is marked here since the boot video device will be the only enabled +* video device at this point. +* +*/ static void __devinit pci_fixup_video (struct pci_dev *pdev) +{ +struct pci_dev *bridge; +struct pci_bus *bus; +u16 l; + +if ((pdev->class >>8 ) !=PCI_CLASS_DISPLAY_VGA ) +return ; + +/* Is VGA routed to us? */ + bus = pdev->bus; +while (bus) { + bridge = bus->self; +if (bridge) { +pci_read_config_word (bridge,PCI_BRIDGE_CONTROL , &l); +if (!(l &PCI_BRIDGE_CTL_VGA )) +return ; + } + bus = bus->parent; + } + pdev->resource[PCI_ROM_RESOURCE ].flags |=IORESOURCE_ROM_SHADOW ; +} +DECLARE_PCI_FIXUP_HEADER (PCI_ANY_ID ,PCI_ANY_ID , pci_fixup_video);
drivers/pci/Makefile +2 -1
@@ -3,7 +3,8 @@ # obj-y += access.o bus.o probe.o remove.o pci.o quirks.o \ - names.o pci-driver.o search.o pci-sysfs.o + names.o pci-driver.o search.o pci-sysfs.o \ + rom.o obj-$(CONFIG_PROC_FS) += proc.o ifndef CONFIG_SPARC64
drivers/pci/pci-sysfs.c +93 -1
124 lines not on this page · raw message
drivers/pci/pci.h +3 -1
@@ -2,7 +2,9 @@extern int pci_hotplug (struct device *dev,char **envp,int num_envp,char *buffer,int buffer_size); -extern void pci_create_sysfs_dev_files (struct pci_dev *pdev); +extern int pci_create_sysfs_dev_files (struct pci_dev *pdev); +extern void pci_remove_sysfs_dev_files (struct pci_dev *pdev); +extern void pci_cleanup_rom (struct pci_dev *dev); extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, unsigned long size, unsigned long align, unsigned long min, unsigned int type_mask,
drivers/pci/probe.c +1 -1
@@ -170,7 +170,7 @@if (sz && sz !=0xffffffff ) { sz =pci_size (l, sz,PCI_ROM_ADDRESS_MASK );if (sz) { - res->flags = (l &PCI_ROM_ADDRESS_ENABLE ) | + res->flags = (l &IORESOURCE_ROM_ENABLE ) |IORESOURCE_MEM |IORESOURCE_PREFETCH |IORESOURCE_READONLY |IORESOURCE_CACHEABLE ; res->start = l &PCI_ROM_ADDRESS_MASK ;
drivers/pci/remove.c +2 -0
@@ -16,6 +16,7 @@msi_remove_pci_irq_vectors (dev); +pci_cleanup_rom (dev);for (i =0 ; i <PCI_NUM_RESOURCES ; i++) {struct resource *res = dev->resource + i;if (res->parent)
@@ -26,6 +27,7 @@static void pci_destroy_dev (struct pci_dev *dev) {pci_proc_detach_device (dev); +pci_remove_sysfs_dev_files (dev);device_unregister (&dev->dev);/* Remove the device from the device lists, and prevent any further
drivers/pci/rom.c new file +226 -0
226 lines not on this page · raw message
drivers/pci/setup-res.c +1 -1
@@ -56,7 +56,7 @@if (resno <6 ) { reg =PCI_BASE_ADDRESS_0 +4 * resno; }else if (resno ==PCI_ROM_RESOURCE ) { - new |= res->flags &PCI_ROM_ADDRESS_ENABLE ; + new |= res->flags &IORESOURCE_ROM_ENABLE ; reg = dev->rom_base_reg; }else {/* Hmm, non-standard resource. */
include/linux/ioport.h +5 -0
@@ -82,6 +82,11 @@#define IORESOURCE_MEM_SHADOWABLE (1<<5)/* dup: IORESOURCE_SHADOWABLE */ #define IORESOURCE_MEM_EXPANSIONROM (1<<6) +/* PCI ROM control bits (IORESOURCE_BITS) */ +#define IORESOURCE_ROM_ENABLE (1<<0)/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ +#define IORESOURCE_ROM_SHADOW (1<<1)/* ROM is copy at C000:0 */ +#define IORESOURCE_ROM_COPY (1<<2)/* ROM is alloc'd copy, resource field overlaid */ +/* PC/ISA/whatever - the normal PC address spaces: IO and memory */ extern struct resource ioport_resource;extern struct resource iomem_resource;
include/linux/pci.h +7 -0
@@ -537,6 +537,7 @@ unsigned int is_busmaster:1; /* device is busmaster */u32 saved_config_space[16 ];/* config space saved at suspend time */ +struct bin_attribute *rom_attr;/* attribute descriptor for sysfs ROM entry */ #ifdef CONFIG_PCI_NAMES #define PCI_NAME_SIZE 96#define PCI_NAME_HALF __stringify(43)/* less than half to handle slop */
@@ -777,6 +778,12 @@int pci_dac_set_dma_mask (struct pci_dev *dev,u64 mask);int pci_set_consistent_dma_mask (struct pci_dev *dev,u64 mask);int pci_assign_resource (struct pci_dev *dev,int i); + +/* ROM control related routines */ +unsigned char *pci_map_rom (struct pci_dev *pdev,size_t *size); +unsigned char *pci_map_rom_copy (struct pci_dev *pdev,size_t *size); +void pci_unmap_rom (struct pci_dev *pdev,unsigned char *rom); +void pci_remove_rom (struct pci_dev *pdev);/* Power management related routines */ int pci_save_state (struct pci_dev *dev,u32 *buffer);