mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] add PCI ROMs to sysfs
@ 2004-07-30 21:09 Jesse Barnes
  2004-07-30 21:29 ` Greg KH
  0 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-07-30 21:09 UTC (permalink / raw)
  To: linux-kernel, linux-pci, Jon Smirl

[-- Attachment #1: Type: text/plain, Size: 918 bytes --]

Per a big thread earlier today, this patch adds a 'rom' file to sysfs in the 
same place where we currently have 'config', 'irq', etc.

Note that the ROM is *not* cached, so userspace will have to save the ROM when 
a device is first detected if the card doesn't support address cycles to ROM 
space at the same time as other memory accesses.  (I'm still open to changing 
this if people feel strongly, but as it stands, the 'rom' file is only 
slightly more dangerous than the 'config' file.)

Jon, am I missing something or is it possible for us to cache the ROM in 
userspace when it receives the hotplug event?  I saw your DRM code, and for 
the case of ROMs at a nonstandard address, we can fixup the address for 
pci_dev->resource[PCI_ROM_RESOURCE] in pci-quirks, can't we?

Thoughts?  I've tried to add cleanup code, but I'm not sure how acceptable it 
is and I don't have any way of testing it.

Thanks,
Jesse

[-- Attachment #2: pci-sysfs-rom-4.patch --]
[-- Type: text/plain, Size: 4456 bytes --]

===== 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 14:04:40 -07:00
@@ -164,6 +164,86 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+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);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+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);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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",
@@ -193,6 +273,39 @@
 	else
 		sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
 
+	/* If the device has a ROM, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct bin_attribute *rom_attr;
+		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+
+		if (!rom_attr)
+			goto out;
+
+		pdev->rom_attr = rom_attr;
+		rom_attr->attr.name = "rom";
+		rom_attr->attr.mode = S_IRUSR;
+		rom_attr->attr.owner = THIS_MODULE;
+		rom_attr->read = pci_read_rom;
+		rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+		sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+	}
+ out:
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	/* Don't need to free config entries since they're static & global */
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE) && pdev->rom_attr) {
+		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+		kfree(pdev->rom_attr);
+	}
 }
===== drivers/pci/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	2004-02-03 09:17:30 -08:00
+++ edited/drivers/pci/remove.c	2004-07-30 13:35:18 -07:00
@@ -26,6 +26,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
===== include/linux/pci.h 1.130 vs edited =====
--- 1.130/include/linux/pci.h	2004-06-30 11:21:27 -07:00
+++ edited/include/linux/pci.h	2004-07-30 13:37:09 -07:00
@@ -537,6 +537,7 @@
 	unsigned int	is_busmaster:1; /* device is busmaster */
 	
 	unsigned int 	saved_config_space[16]; /* config space saved at suspend time */
+	struct bin_attribute *rom_attr; /* ROM attribute (if ROM is present) */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:09 [PATCH] add PCI ROMs to sysfs Jesse Barnes
@ 2004-07-30 21:29 ` Greg KH
  2004-07-30 21:34   ` Jesse Barnes
  2004-07-30 21:53   ` Jon Smirl
  0 siblings, 2 replies; 58+ messages in thread
From: Greg KH @ 2004-07-30 21:29 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: linux-kernel, linux-pci, Jon Smirl

On Fri, Jul 30, 2004 at 02:09:05PM -0700, Jesse Barnes wrote:
> 
> Thoughts?  I've tried to add cleanup code, but I'm not sure how acceptable it 
> is and I don't have any way of testing it.

You don't have access to a cardbus machine?  Or how about using the
fakephp driver to "remove" pci devices?  You should be able to test this
code path with either one of those methods...

> +void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
> +{
> +	/* Don't need to free config entries since they're static & global */

What do you mean by this?  You should still remove all files we added in
the pci_create_sysfs_dev_files() function here, not just the rom file.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:29 ` Greg KH
@ 2004-07-30 21:34   ` Jesse Barnes
  2004-07-30 21:39     ` Greg KH
                       ` (2 more replies)
  2004-07-30 21:53   ` Jon Smirl
  1 sibling, 3 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-07-30 21:34 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel, linux-pci, Jon Smirl

On Friday, July 30, 2004 2:29 pm, Greg KH wrote:
> On Fri, Jul 30, 2004 at 02:09:05PM -0700, Jesse Barnes wrote:
> > Thoughts?  I've tried to add cleanup code, but I'm not sure how
> > acceptable it is and I don't have any way of testing it.
>
> You don't have access to a cardbus machine?  Or how about using the
> fakephp driver to "remove" pci devices?  You should be able to test this
> code path with either one of those methods...

I've never tried fakephp, I'll look into it.  And I do have a laptop at home 
that I could mess around on too, though I don't think I have any devices with 
ROMs...

> > +void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
> > +{
> > +	/* Don't need to free config entries since they're static & global */
>
> What do you mean by this?  You should still remove all files we added in
> the pci_create_sysfs_dev_files() function here, not just the rom file.

What will happen if we don't?  They didn't used to be removed, and there's 
only one global copy afaict.  I'll add code to kill them at any rate.

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:34   ` Jesse Barnes
@ 2004-07-30 21:39     ` Greg KH
  2004-07-30 21:48     ` Jesse Barnes
  2004-07-30 22:15     ` Jon Smirl
  2 siblings, 0 replies; 58+ messages in thread
From: Greg KH @ 2004-07-30 21:39 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: linux-kernel, linux-pci, Jon Smirl

On Fri, Jul 30, 2004 at 02:34:50PM -0700, Jesse Barnes wrote:
> > > +void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
> > > +{
> > > +	/* Don't need to free config entries since they're static & global */
> >
> > What do you mean by this?  You should still remove all files we added in
> > the pci_create_sysfs_dev_files() function here, not just the rom file.
> 
> What will happen if we don't?

Then the driver core will clean them up, like it does today :)

But it's "not nice", and we should clean them up as we now have a
function in which we can do that, and based on changes we have planned
for the driver core in the future, it will be something that is required
to do later on.  Might as well do it now, as you are modifying the same
code...

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:34   ` Jesse Barnes
  2004-07-30 21:39     ` Greg KH
@ 2004-07-30 21:48     ` Jesse Barnes
  2004-07-30 22:15     ` Jon Smirl
  2 siblings, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-07-30 21:48 UTC (permalink / raw)
  To: linux-pci; +Cc: Greg KH, linux-kernel, Jon Smirl

[-- Attachment #1: Type: text/plain, Size: 815 bytes --]

On Friday, July 30, 2004 2:34 pm, Jesse Barnes wrote:
> On Friday, July 30, 2004 2:29 pm, Greg KH wrote:
> > On Fri, Jul 30, 2004 at 02:09:05PM -0700, Jesse Barnes wrote:
> > > Thoughts?  I've tried to add cleanup code, but I'm not sure how
> > > acceptable it is and I don't have any way of testing it.
> >
> > You don't have access to a cardbus machine?  Or how about using the
> > fakephp driver to "remove" pci devices?  You should be able to test this
> > code path with either one of those methods...
>
> I've never tried fakephp, I'll look into it.  And I do have a laptop at
> home that I could mess around on too, though I don't think I have any
> devices with ROMs...

Ok, I tested it with fakephp and things seem to work ok (no panics, all files 
are removed).

Does it look ok otherwise?

Thanks,
Jesse

[-- Attachment #2: pci-sysfs-rom-6.patch --]
[-- Type: text/plain, Size: 4569 bytes --]

===== 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 14:37:04 -07:00
@@ -164,6 +164,86 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+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);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+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);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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",
@@ -193,6 +273,43 @@
 	else
 		sysfs_create_bin_file(&pdev->dev.kobj, &pcie_config_attr);
 
+	/* If the device has a ROM, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct bin_attribute *rom_attr;
+		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+
+		pdev->rom_attr = NULL;
+		if (!rom_attr)
+			goto out;
+
+		pdev->rom_attr = rom_attr;
+		rom_attr->attr.name = "rom";
+		rom_attr->attr.mode = S_IRUSR;
+		rom_attr->attr.owner = THIS_MODULE;
+		rom_attr->read = pci_read_rom;
+		rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+		sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+	}
+ out:
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE) && pdev->rom_attr) {
+		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
+		kfree(pdev->rom_attr);
+	}
 }
===== drivers/pci/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	2004-02-03 09:17:30 -08:00
+++ edited/drivers/pci/remove.c	2004-07-30 13:35:18 -07:00
@@ -26,6 +26,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
===== include/linux/pci.h 1.130 vs edited =====
--- 1.130/include/linux/pci.h	2004-06-30 11:21:27 -07:00
+++ edited/include/linux/pci.h	2004-07-30 13:37:09 -07:00
@@ -537,6 +537,7 @@
 	unsigned int	is_busmaster:1; /* device is busmaster */
 	
 	unsigned int 	saved_config_space[16]; /* config space saved at suspend time */
+	struct bin_attribute *rom_attr; /* ROM attribute (if ROM is present) */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:29 ` Greg KH
  2004-07-30 21:34   ` Jesse Barnes
@ 2004-07-30 21:53   ` Jon Smirl
  2004-07-31 10:03     ` Vojtech Pavlik
  1 sibling, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-07-30 21:53 UTC (permalink / raw)
  To: Greg KH, Jesse Barnes; +Cc: linux-kernel, linux-pci, Jon Smirl

Here's another grungy thing I needed to do to PCI. Multi-headed video
cards don't really implement independent PCI devices even though they
look like independent devices. I've heard that this behavior is needed
for MS Windows compatibility.

I'm missing a PCI call to claim ownership for the secondary device
without also causing a second instance of my driver to be loaded.
Here's the code I'm using, what's the right way to do this?

struct pci_dev *secondary;
/* check the next function on the same card */
secondary = pci_find_slot(dev->pdev->bus->number, dev->pdev->devfn +
1);
if (secondary) {
	/* check if class is secondary video */
	if (secondary->class == 0x038000) {
		DRM_DEBUG("registering secondary video head\n");
		/* This code is need to bind the driver to the secondary device */
		/* There is no direct pci call to do this, there should be one */
		secondary->dev.driver = dev->pdev->dev.driver;
		device_bind_driver(&secondary->dev);
		/* dev->pdev->driver is not filled until after probe completes */
		secondary->driver = to_pci_driver(dev->pdev->dev.driver);
		pci_dev_get(secondary);
	}
}

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:34   ` Jesse Barnes
  2004-07-30 21:39     ` Greg KH
  2004-07-30 21:48     ` Jesse Barnes
@ 2004-07-30 22:15     ` Jon Smirl
  2004-07-31 15:59       ` Jesse Barnes
  2 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-07-30 22:15 UTC (permalink / raw)
  To: Jesse Barnes, Greg KH; +Cc: linux-kernel, linux-pci, Jon Smirl

--- Jesse Barnes <jbarnes@engr.sgi.com> wrote:
> Jon, am I missing something or is it possible for us to cache the ROM
> in userspace when it receives the hotplug event?  I saw your DRM
code,
> and for the case of ROMs at a nonstandard address, we can fixup the
> address for pci_dev->resource[PCI_ROM_RESOURCE] in pci-quirks, 
> can't we?

When I was done with the ROM I did this:
if (r->parent) {
	release_resource(r);
	r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
	r->end -= r->start;
	r->start = 0;
}
/* This will disable and set address to unassigned */
pci_write_config_dword(dev->pdev, PCI_ROM_ADDRESS, 0);
	
Then when I accessed them I did this:

/* assign the ROM an address if it doesn't have one */
if (r->parent == NULL)
	pci_assign_resource(dev->pdev, PCI_ROM_RESOURCE);

I believe I needed to do this because Xfree was enabling the ROMs
without telling the kernel. This caused the kernel resource struct to
get out of sync with the actual state of the ROM. 

If you set pci_dev->resource[PCI_ROM_RESOURCE] to C000:0 won't this
mess up pci_assign_resource()/release_resource()?

I wrote this code a while ago so I'm forgetting exactly why I did
things. There is a variation on this code in drivers/video/aty/radeon_base.c

=====
Jon Smirl
jonsmirl@yahoo.com


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 21:53   ` Jon Smirl
@ 2004-07-31 10:03     ` Vojtech Pavlik
  2004-07-31 13:28       ` Jon Smirl
  0 siblings, 1 reply; 58+ messages in thread
From: Vojtech Pavlik @ 2004-07-31 10:03 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Greg KH, Jesse Barnes, linux-kernel, linux-pci

On Fri, Jul 30, 2004 at 02:53:25PM -0700, Jon Smirl wrote:
> Here's another grungy thing I needed to do to PCI. Multi-headed video
> cards don't really implement independent PCI devices even though they
> look like independent devices. I've heard that this behavior is needed
> for MS Windows compatibility.
> 
> I'm missing a PCI call to claim ownership for the secondary device
> without also causing a second instance of my driver to be loaded.
> Here's the code I'm using, what's the right way to do this?
> 
> struct pci_dev *secondary;
> /* check the next function on the same card */
> secondary = pci_find_slot(dev->pdev->bus->number, dev->pdev->devfn +
> 1);
> if (secondary) {
> 	/* check if class is secondary video */
> 	if (secondary->class == 0x038000) {
> 		DRM_DEBUG("registering secondary video head\n");
> 		/* This code is need to bind the driver to the secondary device */
> 		/* There is no direct pci call to do this, there should be one */
> 		secondary->dev.driver = dev->pdev->dev.driver;
> 		device_bind_driver(&secondary->dev);
> 		/* dev->pdev->driver is not filled until after probe completes */
> 		secondary->driver = to_pci_driver(dev->pdev->dev.driver);
> 		pci_dev_get(secondary);
> 	}
> }

You can do that, but where is the problem with your probe function being
called twice - once for each of the devices? You should be able to sort
out which one is which rather easily.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-31 10:03     ` Vojtech Pavlik
@ 2004-07-31 13:28       ` Jon Smirl
  2004-07-31 15:42         ` Greg KH
  0 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-07-31 13:28 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Greg KH, Jesse Barnes, linux-kernel, linux-pci

--- Vojtech Pavlik <vojtech@suse.cz> wrote:
> On Fri, Jul 30, 2004 at 02:53:25PM -0700, Jon Smirl wrote:
> > Here's another grungy thing I needed to do to PCI. Multi-headed
> video
> 
> You can do that, but where is the problem with your probe function
> being
> called twice - once for each of the devices? You should be able to
> sort
> out which one is which rather easily.

I wrote this a while ago, but I believe the problem was that by
accepting two probes I get two hotplug ADD events that I can't tell
apart. This scheme avoids triggering hotplug. The other problem was
that the ADD events get started in parallel and I couldn't figure out
how to serialize them. The parallel hotplug programs got into a race to
see who could initialize the card first.

Now that I know more about hotplug I could modify the hotplug
parameters to indicate primary vs secondary and ignore the secondary
one. But this will still cause two apps to be started in parallel. 

Another solution would be to modify the kernel API somehow to let me
suppress hotplug ADD/REMOVE on the secondary device.

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail Address AutoComplete - You start. We finish.
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-31 13:28       ` Jon Smirl
@ 2004-07-31 15:42         ` Greg KH
  0 siblings, 0 replies; 58+ messages in thread
From: Greg KH @ 2004-07-31 15:42 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Vojtech Pavlik, Jesse Barnes, linux-kernel, linux-pci

On Sat, Jul 31, 2004 at 06:28:28AM -0700, Jon Smirl wrote:
> --- Vojtech Pavlik <vojtech@suse.cz> wrote:
> > On Fri, Jul 30, 2004 at 02:53:25PM -0700, Jon Smirl wrote:
> > > Here's another grungy thing I needed to do to PCI. Multi-headed
> > video
> > 
> > You can do that, but where is the problem with your probe function
> > being
> > called twice - once for each of the devices? You should be able to
> > sort
> > out which one is which rather easily.
> 
> I wrote this a while ago, but I believe the problem was that by
> accepting two probes I get two hotplug ADD events that I can't tell
> apart. This scheme avoids triggering hotplug. The other problem was
> that the ADD events get started in parallel and I couldn't figure out
> how to serialize them. The parallel hotplug programs got into a race to
> see who could initialize the card first.
> 
> Now that I know more about hotplug I could modify the hotplug
> parameters to indicate primary vs secondary and ignore the secondary
> one. But this will still cause two apps to be started in parallel. 

But as it's easy to tell which one is the secondary, just don't run the
userspace app for that device.  I don't recommend doing your "grab the
other device" hack in the driver, as it's not not a very nice thing to
do, and will probably break in the future.

> Another solution would be to modify the kernel API somehow to let me
> suppress hotplug ADD/REMOVE on the secondary device.

Well, as your driver isn't even loaded at that point in time, it's a bit
hard for it to control that :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-30 22:15     ` Jon Smirl
@ 2004-07-31 15:59       ` Jesse Barnes
  2004-08-02 17:02         ` Jesse Barnes
  0 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-07-31 15:59 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Greg KH, linux-kernel, linux-pci

On Friday, July 30, 2004 3:15 pm, Jon Smirl wrote:
> If you set pci_dev->resource[PCI_ROM_RESOURCE] to C000:0 won't this
> mess up pci_assign_resource()/release_resource()?

Yeah, you're right, that wouldn't be a good thing to do.  I guess I'll have to 
hang a different structure off of the pci_dev so we can tell the sysfs rom 
handling code where to get the rom.  Doing it that way would allow us to deal 
with cards that really need a copy made too, though the default behavior 
would be to read it directly.

How does that sound?

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-07-31 15:59       ` Jesse Barnes
@ 2004-08-02 17:02         ` Jesse Barnes
  2004-08-02 17:29           ` Jon Smirl
                             ` (3 more replies)
  0 siblings, 4 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-02 17:02 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Greg KH, linux-kernel, linux-pci

[-- Attachment #1: Type: text/plain, Size: 999 bytes --]

On Saturday, July 31, 2004 8:59 am, Jesse Barnes wrote:
> On Friday, July 30, 2004 3:15 pm, Jon Smirl wrote:
> > If you set pci_dev->resource[PCI_ROM_RESOURCE] to C000:0 won't this
> > mess up pci_assign_resource()/release_resource()?
>
> Yeah, you're right, that wouldn't be a good thing to do.  I guess I'll have
> to hang a different structure off of the pci_dev so we can tell the sysfs
> rom handling code where to get the rom.  Doing it that way would allow us
> to deal with cards that really need a copy made too, though the default
> behavior would be to read it directly.
>
> How does that sound?

Here's a new patch that implements that suggestion, though without any special 
cases for the various cards that might need the ROM copy (e.g. those with 
shared decoders or whose ROMs are in the system ROM somewhere).  How does it 
look, Greg?  It it suitable for the mainline yet?  I expect those familiar 
with the various cards to add the necessary quirks code as needed.

Thanks,
Jesse

[-- Attachment #2: pci-sysfs-rom-7.patch --]
[-- Type: text/plain, Size: 6230 bytes --]

===== 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-08-02 09:57:11 -07:00
@@ -164,6 +164,92 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+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);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+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);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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);
+	char direct_access = dev->rom_info.rom ? 0 : 1;
+
+	if (off > size)
+		return 0;
+	if (off + count > size) {
+		size -= off;
+		count = size;
+	} else {
+		size = count;
+	}
+
+	/* Enable ROM space decodes and do the reads */
+	if (direct_access)
+		pci_enable_rom(dev);
+
+	while (size > 0) {
+		unsigned char val;
+		if (direct_access)
+			val = readb(start + off);
+		else
+			val = *(dev->rom_info.rom + off);
+		buf[off - init_off] = val;
+		off++;
+		--size;
+	}
+
+	/* Disable again before continuing */
+	if (direct_access)
+		pci_disable_rom(dev);
+
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +272,50 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+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, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct bin_attribute *rom_attr;
+		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+
+		pdev->rom_info.rom_attr = NULL;
+		if (!rom_attr)
+			goto out;
+
+		pdev->rom_info.rom_attr = rom_attr;
+		rom_attr->attr.name = "rom";
+		rom_attr->attr.mode = S_IRUSR;
+		rom_attr->attr.owner = THIS_MODULE;
+		rom_attr->read = pci_read_rom;
+		rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+		sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+	}
+ out:
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pdev->rom_info.rom_attr) {
+		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_info.rom_attr);
+		kfree(pdev->rom_info.rom_attr);
+	}
 }
===== drivers/pci/pci.h 1.12 vs edited =====
--- 1.12/drivers/pci/pci.h	2004-06-04 06:23:04 -07:00
+++ edited/drivers/pci/pci.h	2004-08-02 09:41:02 -07:00
@@ -3,6 +3,7 @@
 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 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 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.65 vs edited =====
--- 1.65/drivers/pci/probe.c	2004-05-21 11:45:27 -07:00
+++ edited/drivers/pci/probe.c	2004-08-02 09:43:21 -07:00
@@ -157,6 +157,8 @@
 #endif
 		}
 	}
+
+	dev->rom_info.rom = NULL;
 	if (rom) {
 		dev->rom_base_reg = rom;
 		res = &dev->resource[PCI_ROM_RESOURCE];
===== drivers/pci/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	2004-02-03 09:17:30 -08:00
+++ edited/drivers/pci/remove.c	2004-08-02 09:41:52 -07:00
@@ -26,6 +26,9 @@
 static void pci_destroy_dev(struct pci_dev *dev)
 {
 	pci_proc_detach_device(dev);
+	/* Free the copy of the ROM if we made one */
+	kfree(dev->rom_info.rom);
+	pci_remove_sysfs_dev_files(dev);
 	device_unregister(&dev->dev);
 
 	/* Remove the device from the device lists, and prevent any further
===== include/linux/pci.h 1.130 vs edited =====
--- 1.130/include/linux/pci.h	2004-06-30 11:21:27 -07:00
+++ edited/include/linux/pci.h	2004-08-02 09:32:08 -07:00
@@ -471,6 +471,11 @@
 	pci_mmap_mem
 };
 
+struct rom_info {
+	char *rom; /* copy of the ROM if necessary */
+	struct bin_attribute *rom_attr;
+};
+
 /* This defines the direction arg to the DMA mapping routines. */
 #define PCI_DMA_BIDIRECTIONAL	0
 #define PCI_DMA_TODEVICE	1
@@ -537,6 +542,7 @@
 	unsigned int	is_busmaster:1; /* device is busmaster */
 	
 	unsigned int 	saved_config_space[16]; /* config space saved at suspend time */
+	struct rom_info rom_info; /* How and where to get the ROM info for this device */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 17:02         ` Jesse Barnes
@ 2004-08-02 17:29           ` Jon Smirl
  2004-08-02 21:00           ` Jon Smirl
                             ` (2 subsequent siblings)
  3 siblings, 0 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-02 17:29 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Greg KH, linux-kernel, linux-pci

--- Jesse Barnes <jbarnes@engr.sgi.com> wrote:
> look, Greg?  It it suitable for the mainline yet?  I expect those
> familiar  with the various cards to add the necessary quirks code
> as needed.

Radeons need this quirk for broken VBIOS's that leave the ROM decoding
disabled.

   unsigned int temp;
   temp = DRM_READ32(mmio, RADEON_MPP_TB_CONFIG);
   temp &= 0x00ffffffu;
   temp |= 0x04 << 24;
   DRM_WRITE32(mmio, RADEON_MPP_TB_CONFIG, temp);
   temp = DRM_READ32(mmio, RADEON_MPP_TB_CONFIG);

Shouldn't this go into the radeon driver so that it will work with
hotplug? Or should it go in both places, a _devinit pci_quirk and the
radeon driver?


=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 17:02         ` Jesse Barnes
  2004-08-02 17:29           ` Jon Smirl
@ 2004-08-02 21:00           ` Jon Smirl
  2004-08-02 21:05             ` Jesse Barnes
  2004-08-02 23:30           ` Alan Cox
  2004-08-04  6:08           ` Jon Smirl
  3 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-02 21:00 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Greg KH, linux-kernel, linux-pci

--- Jesse Barnes <jbarnes@engr.sgi.com> wrote:
> It it suitable for the mainline yet?  I expect those familiar with 
> the various cards to add the necessary quirks code as needed.

Is tracking the boot video device and redirecting to C000:0 going to be
a quirk, architecture specific, or what? Where does this little piece
of code need to go?

=====
Jon Smirl
jonsmirl@yahoo.com


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 21:00           ` Jon Smirl
@ 2004-08-02 21:05             ` Jesse Barnes
  2004-08-02 23:32               ` Alan Cox
  0 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-02 21:05 UTC (permalink / raw)
  To: linux-pci; +Cc: Jon Smirl, Greg KH, linux-kernel

On Monday, August 2, 2004 2:00 pm, Jon Smirl wrote:
> --- Jesse Barnes <jbarnes@engr.sgi.com> wrote:
> > It it suitable for the mainline yet?  I expect those familiar with
> > the various cards to add the necessary quirks code as needed.
>
> Is tracking the boot video device and redirecting to C000:0 going to be
> a quirk, architecture specific, or what? Where does this little piece
> of code need to go?

I think that would be a quirk.  You'd copy ROMs like that into the rom pointer 
in the pci_dev structure I guess.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 17:02         ` Jesse Barnes
  2004-08-02 17:29           ` Jon Smirl
  2004-08-02 21:00           ` Jon Smirl
@ 2004-08-02 23:30           ` Alan Cox
  2004-08-03  2:03             ` Jesse Barnes
  2004-08-04  6:08           ` Jon Smirl
  3 siblings, 1 reply; 58+ messages in thread
From: Alan Cox @ 2004-08-02 23:30 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, linux-pci

What guarantees the ROM already has an assigned PCI address ?


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 21:05             ` Jesse Barnes
@ 2004-08-02 23:32               ` Alan Cox
  0 siblings, 0 replies; 58+ messages in thread
From: Alan Cox @ 2004-08-02 23:32 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: linux-pci, Jon Smirl, Greg KH, Linux Kernel Mailing List

On Llu, 2004-08-02 at 22:05, Jesse Barnes wrote:
> > Is tracking the boot video device and redirecting to C000:0 going to be
> > a quirk, architecture specific, or what? Where does this little piece
> > of code need to go?
> 
> I think that would be a quirk.  You'd copy ROMs like that into the rom pointer 
> in the pci_dev structure I guess.

Providing that quirk is scanned at hotplug time it can go into the quirk
code which is probably simplest. It may need a tiny hook in sysfs to map
the right object but that isnt hard.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 23:30           ` Alan Cox
@ 2004-08-03  2:03             ` Jesse Barnes
  2004-08-03  2:32               ` Jon Smirl
  2004-08-03 21:19               ` Jon Smirl
  0 siblings, 2 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-03  2:03 UTC (permalink / raw)
  To: Alan Cox; +Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, linux-pci

On Monday, August 2, 2004 4:30 pm, Alan Cox wrote:
> What guarantees the ROM already has an assigned PCI address ?

Presumably the PCI core.  If that's a bad assumption, then clearly this code 
won't work as is and will need additional checks/setup code.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03  2:03             ` Jesse Barnes
@ 2004-08-03  2:32               ` Jon Smirl
  2004-08-03 17:07                 ` Jesse Barnes
  2004-08-03 21:19               ` Jon Smirl
  1 sibling, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-03  2:32 UTC (permalink / raw)
  To: Jesse Barnes, Alan Cox
  Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, linux-pci

My original version have this in it:

/* assign the ROM an address if it doesn't have one */
if (r->parent == NULL)
   pci_assign_resource(dev->pdev, PCI_ROM_RESOURCE);
                                                                       
                  
if (r->parent) {
    release_resource(r);
    r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
    r->end -= r->start;
    r->start = 0;
}

I was running this code on both 2.4/2.6 but I may have needed to do
this for 2.4. Is it consistent to have pci_assign_resource() and then
use release_resource()?

My i875P AGP controller has a ROM on it as well as my two video cards.


--- Jesse Barnes <jbarnes@engr.sgi.com> wrote:

> On Monday, August 2, 2004 4:30 pm, Alan Cox wrote:
> > What guarantees the ROM already has an assigned PCI address ?
> 
> Presumably the PCI core.  If that's a bad assumption, then clearly
> this code 
> won't work as is and will need additional checks/setup code.
> 
> Jesse
> 

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03  2:32               ` Jon Smirl
@ 2004-08-03 17:07                 ` Jesse Barnes
  0 siblings, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-03 17:07 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Alan Cox, Greg KH, Linux Kernel Mailing List, linux-pci

On Monday, August 2, 2004 7:32 pm, Jon Smirl wrote:
> My original version have this in it:
>
> /* assign the ROM an address if it doesn't have one */
> if (r->parent == NULL)
>    pci_assign_resource(dev->pdev, PCI_ROM_RESOURCE);
>
>
> if (r->parent) {
>     release_resource(r);
>     r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
>     r->end -= r->start;
>     r->start = 0;
> }
>
> I was running this code on both 2.4/2.6 but I may have needed to do
> this for 2.4. Is it consistent to have pci_assign_resource() and then
> use release_resource()?
>
> My i875P AGP controller has a ROM on it as well as my two video cards.

So it seems there's some redundancy here--some platforms will map the ROMs at 
discovery time while on others we have to map them explicitly?  Which should 
we count on?  I was assuming the former in the last patch I posted, and would 
like to keep it that way unless there's some reason not to.

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03  2:03             ` Jesse Barnes
  2004-08-03  2:32               ` Jon Smirl
@ 2004-08-03 21:19               ` Jon Smirl
  2004-08-03 21:28                 ` Jesse Barnes
  1 sibling, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-03 21:19 UTC (permalink / raw)
  To: Jesse Barnes, Alan Cox
  Cc: Jon Smirl, Greg KH, Linux Kernel Mailing List, linux-pci

This is saying that my AGP bridge chip has a ROM right?

00:01.0 PCI bridge: Intel Corp. 82875P Processor to AGP Controller (rev
02) (prog-if 00 [Normal decode])
        Flags: bus master, 66Mhz, fast devsel, latency 64
        Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
        I/O behind bridge: 0000d000-0000dfff
        Memory behind bridge: fe900000-feafffff
        Prefetchable memory behind bridge: f0000000-f7ffffff
        Expansion ROM at 0000d000 [disabled] [size=4K]
 
Each of my video controllers has one too:

01:00.0 VGA compatible controller: ATI Technologies Inc Radeon RV250 If
[Radeon 9000] (rev 01) (prog-if 00 [VGA])
        Subsystem: C.P. Technology Co. Ltd RV250 If [Radeon 9000 Pro
"Evil Commando"]
        Flags: stepping, 66Mhz, medium devsel, IRQ 177
        Memory at f4000000 (32-bit, prefetchable) [disabled]
[size=fea00000]
        I/O ports at de00 [disabled] [size=256]
        Memory at fe9e0000 (32-bit, non-prefetchable) [disabled]
[size=64K]
        Expansion ROM at 00020000 [disabled]
        Capabilities: <available only to root>
 
02:02.0 VGA compatible controller: ATI Technologies Inc Rage 128 PD/PRO
TMDS (prog-if 00 [VGA])
        Subsystem: ATI Technologies Inc Rage 128 AIW
        Flags: bus master, stepping, medium devsel, latency 64, IRQ 209
        Memory at f8000000 (32-bit, prefetchable) [size=fe800000]
        I/O ports at ce00 [size=256]
        Memory at fe7dc000 (32-bit, non-prefetchable) [size=16K]
        Expansion ROM at 00020000 [disabled]
        Capabilities: <available only to root>

Both of the video ROMs are at 00020000, won't they end up on top of
each other when enabled?

With the patch the video ROMs are in sysfs but the AGP bridge one is
not.


=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:19               ` Jon Smirl
@ 2004-08-03 21:28                 ` Jesse Barnes
  2004-08-03 21:30                   ` Jesse Barnes
  2004-08-03 21:31                   ` Martin Mares
  0 siblings, 2 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-03 21:28 UTC (permalink / raw)
  To: linux-pci; +Cc: Jon Smirl, Alan Cox, Greg KH, Linux Kernel Mailing List

On Tuesday, August 3, 2004 2:19 pm, Jon Smirl wrote:
> This is saying that my AGP bridge chip has a ROM right?
>
> 00:01.0 PCI bridge: Intel Corp. 82875P Processor to AGP Controller (rev
> 02) (prog-if 00 [Normal decode])
>         Flags: bus master, 66Mhz, fast devsel, latency 64
>         Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
>         I/O behind bridge: 0000d000-0000dfff
>         Memory behind bridge: fe900000-feafffff
>         Prefetchable memory behind bridge: f0000000-f7ffffff
>         Expansion ROM at 0000d000 [disabled] [size=4K]
>
> Each of my video controllers has one too:
>
> 01:00.0 VGA compatible controller: ATI Technologies Inc Radeon RV250 If
> [Radeon 9000] (rev 01) (prog-if 00 [VGA])
>         Subsystem: C.P. Technology Co. Ltd RV250 If [Radeon 9000 Pro
> "Evil Commando"]
>         Flags: stepping, 66Mhz, medium devsel, IRQ 177
>         Memory at f4000000 (32-bit, prefetchable) [disabled]
> [size=fea00000]
>         I/O ports at de00 [disabled] [size=256]
>         Memory at fe9e0000 (32-bit, non-prefetchable) [disabled]
> [size=64K]
>         Expansion ROM at 00020000 [disabled]
>         Capabilities: <available only to root>
>
> 02:02.0 VGA compatible controller: ATI Technologies Inc Rage 128 PD/PRO
> TMDS (prog-if 00 [VGA])
>         Subsystem: ATI Technologies Inc Rage 128 AIW
>         Flags: bus master, stepping, medium devsel, latency 64, IRQ 209
>         Memory at f8000000 (32-bit, prefetchable) [size=fe800000]
>         I/O ports at ce00 [size=256]
>         Memory at fe7dc000 (32-bit, non-prefetchable) [size=16K]
>         Expansion ROM at 00020000 [disabled]
>         Capabilities: <available only to root>
>
> Both of the video ROMs are at 00020000, won't they end up on top of
> each other when enabled?

Yeah, it doesn't look like they've been properly assigned addresses.  But then 
I've also seen lspci lie, you can check /sys/devices/.../config for the 
actual resource values.  If they're sane then things are more likely to work.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:28                 ` Jesse Barnes
@ 2004-08-03 21:30                   ` Jesse Barnes
  2004-08-03 21:31                   ` Martin Mares
  1 sibling, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-03 21:30 UTC (permalink / raw)
  To: linux-pci; +Cc: Jon Smirl, Alan Cox, Greg KH, Linux Kernel Mailing List

On Tuesday, August 3, 2004 2:28 pm, Jesse Barnes wrote:
> > Both of the video ROMs are at 00020000, won't they end up on top of
> > each other when enabled?
>
> Yeah, it doesn't look like they've been properly assigned addresses.  But
> then I've also seen lspci lie, you can check /sys/devices/.../config for
> the actual resource values.  If they're sane then things are more likely to
> work.

Oops, I mean /sys/devices/.../resource.  E.g.

jbarnes@mill:~$ cat /sys/devices/pci0002\:06/0002\:06\:0f.0/resource
0x00000000f5200000 0x00000000f53fffff 0x0000000000000200
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 0x0000000000000000
0x00000000f5100000 0x00000000f51fffff 0x0000000000007200

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:28                 ` Jesse Barnes
  2004-08-03 21:30                   ` Jesse Barnes
@ 2004-08-03 21:31                   ` Martin Mares
  2004-08-03 21:36                     ` Jon Smirl
  1 sibling, 1 reply; 58+ messages in thread
From: Martin Mares @ 2004-08-03 21:31 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: linux-pci, Jon Smirl, Alan Cox, Greg KH, Linux Kernel Mailing List

> Yeah, it doesn't look like they've been properly assigned addresses.  But then 
> I've also seen lspci lie, you can check /sys/devices/.../config for the 
> actual resource values.  If they're sane then things are more likely to work.

... or try `lspci -b', it will dump the actual registers, not the kernel's
view.

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
A jury consists of 12 persons chosen to decide who has the better lawyer.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:31                   ` Martin Mares
@ 2004-08-03 21:36                     ` Jon Smirl
  2004-08-03 21:39                       ` Martin Mares
  0 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-03 21:36 UTC (permalink / raw)
  To: Martin Mares, Jesse Barnes
  Cc: linux-pci, Jon Smirl, Alan Cox, Greg KH, Linux Kernel Mailing List

lspci -b would be great but it doesn't seem to have implemented dumping
the ROM location. It dumps everything else.

--- Martin Mares <mj@ucw.cz> wrote:

> > Yeah, it doesn't look like they've been properly assigned
> addresses.  But then 
> > I've also seen lspci lie, you can check /sys/devices/.../config for
> the 
> > actual resource values.  If they're sane then things are more
> likely to work.
> 
> ... or try `lspci -b', it will dump the actual registers, not the
> kernel's
> view.
> 
> 				Have a nice fortnight
> -- 
> Martin `MJ' Mares   <mj@ucw.cz>  
> http://atrey.karlin.mff.cuni.cz/~mj/
> Faculty of Math and Physics, Charles University, Prague, Czech Rep.,
> Earth
> A jury consists of 12 persons chosen to decide who has the better
> lawyer.
> 


=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:36                     ` Jon Smirl
@ 2004-08-03 21:39                       ` Martin Mares
  2004-08-04  6:00                         ` lspci and ROM on bridge, was: " Jon Smirl
  2004-08-05  5:05                         ` Jon Smirl
  0 siblings, 2 replies; 58+ messages in thread
From: Martin Mares @ 2004-08-03 21:39 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Jesse Barnes, linux-pci, Alan Cox, Greg KH, Linux Kernel Mailing List

> lspci -b would be great but it doesn't seem to have implemented dumping
> the ROM location. It dumps everything else.

Ah well, I see the problem -- it doesn't display disabled ROMs.

The following quick hack should cure it:

--- orig/lib/generic.c
+++ mod/lib/generic.c
@@ -160,7 +160,9 @@
       if (reg)
 	{
 	  u32 a = pci_read_long(d, reg);
+#if 0
 	  if (a & PCI_ROM_ADDRESS_ENABLE)
+#endif
 	    d->rom_base_addr = a;
 	}
     }




				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
A student who changes the course of history is probably taking an exam.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* lspci and ROM on bridge, was: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:39                       ` Martin Mares
@ 2004-08-04  6:00                         ` Jon Smirl
  2004-08-04 16:04                           ` Martin Mares
  2004-08-05  5:05                         ` Jon Smirl
  1 sibling, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-04  6:00 UTC (permalink / raw)
  To: Martin Mares; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

lspci shows my AGP bridge

00:01.0 PCI bridge: Intel Corp. 82875P Processor to AGP Controller (rev
02) (prog-if 00 [Normal decode])
        Flags: bus master, 66Mhz, fast devsel, latency 64
        Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
        I/O behind bridge: 0000d000-0000dfff
        Memory behind bridge: fe900000-feafffff
        Prefetchable memory behind bridge: f0000000-f7ffffff
        Expansion ROM at 0000d000 [disabled] [size=4K]
 
It shows an expansion ROM at d000. d000 is a normal address for a ROM.
But d000 also shows as I/O behind bridge.

If I list sysfs resources, the ROM is in slot 7, not 6 which is normal
for a ROM. Is this really a ROM or a bug in lspci?

[jonsmirl@smirl 0000:00:01.0]$ cat resource
0  0x0000000000000000 0x0000000000000000 0x0000000000000000
1  0x0000000000000000 0x0000000000000000 0x0000000000000000
2  0x0000000000000000 0x0000000000000000 0x0000000000000000
3  0x0000000000000000 0x0000000000000000 0x0000000000000000
4  0x0000000000000000 0x0000000000000000 0x0000000000000000
5  0x0000000000000000 0x0000000000000000 0x0000000000000000
6  0x0000000000000000 0x0000000000000000 0x0000000000000000
7  0x000000000000d000 0x000000000000dfff 0x0000000000000100
8  0x00000000fe900000 0x00000000feafffff 0x0000000000000200
9  0x00000000f0000000 0x00000000f7ffffff 0x0000000000001200
10 0x0000000000000000 0x0000000000000000 0x0000000000000000
11 0x0000000000000000 0x0000000000000000 0x0000000000000000
[jonsmirl@smirl 0000:00:01.0]$



=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Read only the mail you want - Yahoo! Mail SpamGuard.
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-02 17:02         ` Jesse Barnes
                             ` (2 preceding siblings ...)
  2004-08-02 23:30           ` Alan Cox
@ 2004-08-04  6:08           ` Jon Smirl
  2004-08-04 15:56             ` Jesse Barnes
  3 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-04  6:08 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: Greg KH, linux-kernel, linux-pci

[-- Attachment #1: Type: text/plain, Size: 858 bytes --]

This is a new version of Jesse's PCI ROM patch.

It can read ROMs on x86. Main problem was that the PCI address space is
not part of the kernel address space on the x86 so ioremap() is needed.
I added the parts about assign/release resource but I am not sure that
they are needed.

The patch obviously needs more work for the not_direct case. The quirk
to record the boot video card has not been written.

I wasted a lot of time figuring out why it wouldn't work until I
remembered that my radeon card needs a kernel quirk to fix it's ROM
enabling. Most radeon cards have this problem so if you get FFFF the
code is problem working, I just need to write the quirk to enable the ROM.

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail is new and improved - Check it out!
http://promotions.yahoo.com/new_mail

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pci-sysfs-rom-8.patch --]
[-- Type: text/x-patch; name="pci-sysfs-rom-8.patch", Size: 6830 bytes --]

===== drivers/pci/pci-sysfs.c 1.10 vs edited =====
--- 1.10/drivers/pci/pci-sysfs.c	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci-sysfs.c	Wed Aug  4 01:37:15 2004
@@ -164,6 +164,108 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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));
+	unsigned long start;
+	loff_t i, size;
+	char direct_access = dev->rom_info.rom ? 0 : 1;
+	unsigned char *rom = NULL;
+	struct resource *r = &dev->resource[PCI_ROM_RESOURCE];
+
+	if (off > size)
+		return 0;
+		
+	if (direct_access) {
+		/* assign the ROM an address if it doesn't have one */
+		if (r->parent == NULL)
+			pci_assign_resource(dev, PCI_ROM_RESOURCE);
+		/* Enable ROM space decodes and do the reads */
+		pci_enable_rom(dev);
+		start = pci_resource_start(dev, PCI_ROM_RESOURCE);
+		size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		rom = ioremap(start, size);
+		
+		printk("read_rom start %lx size %x\n", start, size);
+		printk("rom bytes %02x %02x\n", rom, rom + 1);
+	}
+	if (off + count > size) {
+		size -= off;
+		count = size;
+	} else
+		size = count;
+
+	i = 0;
+	while (size > 0) {
+		unsigned char val;
+		if (direct_access)
+			val = readb(rom + off);
+		else
+			val = *(dev->rom_info.rom + off);
+		buf[i++] = val;
+		off++;
+		--size;
+	}
+	if (direct_access) {
+		iounmap(rom);
+		/* Disable again before continuing */
+		pci_disable_rom(dev);
+		if (r->parent) {
+			release_resource(r);
+			r->end -= r->start;
+			r->start = 0;
+		}
+	}
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +288,51 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+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);
 
+printk("devfn %x len %lx start %lx\n", pdev->devfn, pci_resource_len(pdev, PCI_ROM_RESOURCE), pci_resource_start(pdev, PCI_ROM_RESOURCE));
+	/* If the device has a ROM, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct bin_attribute *rom_attr;
+		rom_attr = kmalloc(sizeof(*rom_attr), GFP_ATOMIC);
+
+		pdev->rom_info.rom_attr = NULL;
+		if (!rom_attr)
+			goto out;
+
+		pdev->rom_info.rom_attr = rom_attr;
+		rom_attr->attr.name = "rom";
+		rom_attr->attr.mode = S_IRUSR;
+		rom_attr->attr.owner = THIS_MODULE;
+		rom_attr->read = pci_read_rom;
+		rom_attr->size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+		sysfs_create_bin_file(&pdev->dev.kobj, rom_attr);
+	}
+ out:
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pdev->rom_info.rom_attr) {
+		sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_info.rom_attr);
+		kfree(pdev->rom_info.rom_attr);
+	}
 }
===== drivers/pci/pci.h 1.12 vs edited =====
--- 1.12/drivers/pci/pci.h	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci.h	Tue Aug  3 17:05:19 2004
@@ -3,6 +3,7 @@
 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 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 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.65 vs edited =====
--- 1.65/drivers/pci/probe.c	Fri May 21 14:45:27 2004
+++ edited/drivers/pci/probe.c	Tue Aug  3 17:05:19 2004
@@ -157,6 +157,8 @@
 #endif
 		}
 	}
+
+	dev->rom_info.rom = NULL;
 	if (rom) {
 		dev->rom_base_reg = rom;
 		res = &dev->resource[PCI_ROM_RESOURCE];
===== drivers/pci/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	Tue Feb  3 12:17:30 2004
+++ edited/drivers/pci/remove.c	Tue Aug  3 17:05:20 2004
@@ -26,6 +26,9 @@
 static void pci_destroy_dev(struct pci_dev *dev)
 {
 	pci_proc_detach_device(dev);
+	/* Free the copy of the ROM if we made one */
+	kfree(dev->rom_info.rom);
+	pci_remove_sysfs_dev_files(dev);
 	device_unregister(&dev->dev);
 
 	/* Remove the device from the device lists, and prevent any further
===== include/linux/pci.h 1.132 vs edited =====
--- 1.132/include/linux/pci.h	Mon Aug  2 04:00:43 2004
+++ edited/include/linux/pci.h	Tue Aug  3 17:05:21 2004
@@ -471,6 +471,11 @@
 	pci_mmap_mem
 };
 
+struct rom_info {
+	char *rom; /* copy of the ROM if necessary */
+	struct bin_attribute *rom_attr;
+};
+
 /* This defines the direction arg to the DMA mapping routines. */
 #define PCI_DMA_BIDIRECTIONAL	0
 #define PCI_DMA_TODEVICE	1
@@ -537,6 +542,7 @@
 	unsigned int	is_busmaster:1; /* device is busmaster */
 	
 	unsigned int 	saved_config_space[16]; /* config space saved at suspend time */
+	struct rom_info rom_info; /* How and where to get the ROM info for this device */
 #ifdef CONFIG_PCI_NAMES
 #define PCI_NAME_SIZE	96
 #define PCI_NAME_HALF	__stringify(43)	/* less than half to handle slop */

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-04  6:08           ` Jon Smirl
@ 2004-08-04 15:56             ` Jesse Barnes
  0 siblings, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-04 15:56 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Greg KH, linux-kernel, linux-pci

On Tuesday, August 3, 2004 11:08 pm, Jon Smirl wrote:
> This is a new version of Jesse's PCI ROM patch.
>
> It can read ROMs on x86. Main problem was that the PCI address space is
> not part of the kernel address space on the x86 so ioremap() is needed.
> I added the parts about assign/release resource but I am not sure that
> they are needed.

Ah, that would explain it.  Thanks for fixing it up.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: lspci and ROM on bridge, was: [PATCH] add PCI ROMs to sysfs
  2004-08-04  6:00                         ` lspci and ROM on bridge, was: " Jon Smirl
@ 2004-08-04 16:04                           ` Martin Mares
  0 siblings, 0 replies; 58+ messages in thread
From: Martin Mares @ 2004-08-04 16:04 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

> lspci shows my AGP bridge
> 
> 00:01.0 PCI bridge: Intel Corp. 82875P Processor to AGP Controller (rev
> 02) (prog-if 00 [Normal decode])
>         Flags: bus master, 66Mhz, fast devsel, latency 64
>         Bus: primary=00, secondary=01, subordinate=01, sec-latency=64
>         I/O behind bridge: 0000d000-0000dfff
>         Memory behind bridge: fe900000-feafffff
>         Prefetchable memory behind bridge: f0000000-f7ffffff
>         Expansion ROM at 0000d000 [disabled] [size=4K]
>  
> It shows an expansion ROM at d000. d000 is a normal address for a ROM.
> But d000 also shows as I/O behind bridge.

Was it with the `-b' option or not?

				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj@ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"#define QUESTION ((bb) || !(bb))"  -- Shakespeare

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-03 21:39                       ` Martin Mares
  2004-08-04  6:00                         ` lspci and ROM on bridge, was: " Jon Smirl
@ 2004-08-05  5:05                         ` Jon Smirl
  2004-08-05  5:41                           ` Benjamin Herrenschmidt
  2004-08-05 15:54                           ` Jesse Barnes
  1 sibling, 2 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-05  5:05 UTC (permalink / raw)
  To: Martin Mares
  Cc: Jesse Barnes, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 931 bytes --]

Version 10

implements an x86 quirk to record the boot video device. Is the
PCI_ROM_SHADOW flag a safe define? Quirk records boot video device by
looking at how the bridges route to the VGA device. It there some other
way to tell which video card is the boot one? What if there is more
than one VGA card on the PCI bus? I think the BIOS spec is to enable
the one in the lowest slot number. Can someone who own multiple PCI
video cards test this? I tested with one PCI, one AGP.

BenH, this should solve the problem of which video card owns the ROM
copy at C000:0. For the boot device this code returns the shadow copy,
else the real ROM on the card.

I did the x86 quirk, what do the quirks on ia64, ppc, x86_64 need? Can
they just copy the x86 one?

=====
Jon Smirl
jonsmirl@yahoo.com


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pci-sysfs-rom-10.patch --]
[-- Type: text/x-patch; name="pci-sysfs-rom-10.patch", Size: 7275 bytes --]

===== arch/i386/pci/fixup.c 1.19 vs edited =====
--- 1.19/arch/i386/pci/fixup.c	Thu Jun  3 10:58:17 2004
+++ edited/arch/i386/pci/fixup.c	Thu Aug  5 00:20:08 2004
@@ -237,6 +237,29 @@
 	}
 }
 
+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 |= PCI_ROM_SHADOW;
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{
 		.pass		= PCI_FIXUP_HEADER,
@@ -345,6 +368,12 @@
 		.vendor		= PCI_VENDOR_ID_NVIDIA,
 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2,
 		.hook		= pci_fixup_nforce2
+	},
+	{
+		.pass		= PCI_FIXUP_FINAL,
+		.vendor		= PCI_ANY_ID,
+		.device		= PCI_ANY_ID,
+		.hook		= pci_fixup_video
 	},
 	{ .pass = 0 }
 };
===== drivers/pci/pci-sysfs.c 1.10 vs edited =====
--- 1.10/drivers/pci/pci-sysfs.c	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci-sysfs.c	Thu Aug  5 00:45:04 2004
@@ -164,6 +164,95 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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 start;
+	size_t size;
+	unsigned char *rom;
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+
+	if (res->flags & PCI_ROM_SHADOW) {	/* PCI_ROM_SHADOW only set on x86 */
+		start = (unsigned char *)0xC0000; /* primary video rom always starts here */
+		size = 0x20000;			/* cover C000:0 through E000:0 */
+	} else {
+		/* assign the ROM an address if it doesn't have one */
+		if (res->parent == NULL)
+			pci_assign_resource(dev, PCI_ROM_RESOURCE);
+			
+		start = pci_resource_start(dev, PCI_ROM_RESOURCE);
+		size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		
+		/* Enable ROM space decodes */
+		pci_enable_rom(dev);
+	}
+	if (off >= size)
+		return 0;
+		
+	if (off + count > size)
+		count = size - off;
+	
+	rom = ioremap(start, size);
+	if (rom) {
+		memcpy_fromio(buf, rom + off, count);
+		iounmap(rom);
+	} else
+		count = 0;
+		
+	/* Disable again before continuing, leave enabled if pci=rom */
+	if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE|PCI_ROM_SHADOW)))
+		pci_disable_rom(dev);
+		
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +275,49 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+static struct bin_attribute rom_attr = {
+	.attr =	{
+		.name = "rom",
+		.mode = S_IRUSR,
+		.owner = THIS_MODULE,
+	},
+	/* .size is set individually for each device, sysfs copies it into dentry */
+	.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, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		struct resource *res = &pdev->resource[PCI_ROM_RESOURCE];
+		if (res->flags & PCI_ROM_SHADOW) {
+			rom_attr.size = 0x20000;	/* cover C000:0 through E000:0 */
+		} else
+			rom_attr.size = pci_resource_len(pdev, PCI_ROM_RESOURCE);
+		sysfs_create_bin_file(&pdev->dev.kobj, &rom_attr);
+	}
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
+}
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+		sysfs_remove_bin_file(&pdev->dev.kobj, &rom_attr);
 }
===== drivers/pci/pci.h 1.12 vs edited =====
--- 1.12/drivers/pci/pci.h	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci.h	Tue Aug  3 17:05:19 2004
@@ -3,6 +3,7 @@
 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 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 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.65 vs edited =====
--- 1.65/drivers/pci/probe.c	Fri May 21 14:45:27 2004
+++ edited/drivers/pci/probe.c	Thu Aug  5 00:10:06 2004
@@ -157,6 +157,7 @@
 #endif
 		}
 	}
+
 	if (rom) {
 		dev->rom_base_reg = rom;
 		res = &dev->resource[PCI_ROM_RESOURCE];
===== drivers/pci/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	Tue Feb  3 12:17:30 2004
+++ edited/drivers/pci/remove.c	Thu Aug  5 00:11:05 2004
@@ -26,6 +26,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
===== include/linux/pci.h 1.132 vs edited =====
--- 1.132/include/linux/pci.h	Mon Aug  2 04:00:43 2004
+++ edited/include/linux/pci.h	Thu Aug  5 00:13:54 2004
@@ -102,6 +102,8 @@
 #define PCI_SUBSYSTEM_ID	0x2e  
 #define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
+#define  PCI_ROM_SHADOW		0x02	/* resource flag, ROM is copy at C000:0 */
+#define  PCI_ROM_COPY		0x04	/* resource flag, ROM is alloc'd copy */
 #define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
 
 #define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05  5:05                         ` Jon Smirl
@ 2004-08-05  5:41                           ` Benjamin Herrenschmidt
  2004-08-05 11:53                             ` Jon Smirl
  2004-08-05 15:54                           ` Jesse Barnes
  1 sibling, 1 reply; 58+ messages in thread
From: Benjamin Herrenschmidt @ 2004-08-05  5:41 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Martin Mares, Jesse Barnes, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec

On Thu, 2004-08-05 at 15:05, Jon Smirl wrote:
> Version 10
> 
> implements an x86 quirk to record the boot video device. Is the
> PCI_ROM_SHADOW flag a safe define? Quirk records boot video device by
> looking at how the bridges route to the VGA device. It there some other
> way to tell which video card is the boot one? What if there is more
> than one VGA card on the PCI bus? I think the BIOS spec is to enable
> the one in the lowest slot number. Can someone who own multiple PCI
> video cards test this? I tested with one PCI, one AGP.
> 
> BenH, this should solve the problem of which video card owns the ROM
> copy at C000:0. For the boot device this code returns the shadow copy,
> else the real ROM on the card.

Looks ok for me. It would be nice though if the code returning the
shadow copy could be "hooked" by the driver, that way, the radeon
kernel driver can force-enable the ROM decoding... or do you want
to use pci quirks for that too ?

> I did the x86 quirk, what do the quirks on ia64, ppc, x86_64 need? Can
> they just copy the x86 one?

Probably... can't we have arch-independant quirks ? Especially with the
new quirk section stuff David just posted, we can have quirks pretty much
anywhere...

Ben.



^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05  5:41                           ` Benjamin Herrenschmidt
@ 2004-08-05 11:53                             ` Jon Smirl
  0 siblings, 0 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-05 11:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Martin Mares, Jesse Barnes, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec

--- Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> Looks ok for me. It would be nice though if the code returning the
> shadow copy could be "hooked" by the driver, that way, the radeon
> kernel driver can force-enable the ROM decoding... or do you want
> to use pci quirks for that too ?

My current plan is for the radeon driver to keep the code for enabling
the ROM. Otherwise we have to build all of the radeon PCI IDs somewhere
else into the kernel. In my system if you dump if without the driver
loaded it is FFFF, load the driver and you see it. First thing the
driver does is fix the ROM so that it is visible to the hotplug event.

> > I did the x86 quirk, what do the quirks on ia64, ppc, x86_64 need?
> Can
> > they just copy the x86 one?
> 
> Probably... can't we have arch-independant quirks ? Especially with
> the new quirk section stuff David just posted, we can have quirks
> pretty much anywhere...

But isn't this architecture specific? The Mac doesn't shadow ROMs at
0xC0000 does it? How does it shadow ROMs?

I may change the API a little today and expose a map/unmap ROM function
to make things easier for the driver to get the right copy. Adding
those calls will let me add a pci_map_rom_copy, which the driver can
use to trigger the copy for ROMs that aren't fully decoded.

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05  5:05                         ` Jon Smirl
  2004-08-05  5:41                           ` Benjamin Herrenschmidt
@ 2004-08-05 15:54                           ` Jesse Barnes
  2004-08-05 16:25                             ` Jesse Barnes
  1 sibling, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-05 15:54 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

On Wednesday, August 4, 2004 10:05 pm, Jon Smirl wrote:
> Version 10

For some reason this version doesn't work on ia64.  It just returns bytes 
containing 0 when I try to dump the ROM.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05 15:54                           ` Jesse Barnes
@ 2004-08-05 16:25                             ` Jesse Barnes
  2004-08-05 20:45                               ` Jon Smirl
  0 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-05 16:25 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

On Thursday, August 5, 2004 8:54 am, Jesse Barnes wrote:
> On Wednesday, August 4, 2004 10:05 pm, Jon Smirl wrote:
> > Version 10
>
> For some reason this version doesn't work on ia64.  It just returns bytes
> containing 0 when I try to dump the ROM.

pci_assign_resource is mucking with the values in 
pci_dev->resource[PCI_ROM_RESOURCE].  If I remove the call to 
pci_assign_resource, things work for me.  Is that call really necessary?  
Don't we just need ioremap?

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05 16:25                             ` Jesse Barnes
@ 2004-08-05 20:45                               ` Jon Smirl
  2004-08-05 21:12                                 ` Jesse Barnes
  0 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-05 20:45 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

--- Jesse Barnes <jbarnes@engr.sgi.com> wrote:
> pci_assign_resource is mucking with the values in 
> pci_dev->resource[PCI_ROM_RESOURCE].  If I remove the call to 
> pci_assign_resource, things work for me.  Is that call really
> necessary?  
> Don't we just need ioremap?

/* assign the ROM an address if it doesn't have one */
if (res->parent == NULL)
	pci_assign_resource(dev, PCI_ROM_RESOURCE);

It is protected by the (res->parent == NULL). Looking at the code in
kernel/resource.c this is the correct check to see if the resource does
not have an address assigned. If (res->parent != NULL) then it is
supposed to muck with the addresses.

If you follow the code path of pci_assign_resource() it will program
the ROM to appear at the newly assigned address in
pci_update_resource(). I'd check these code paths and see if they are
64 bit broken. This process does work on ia32.

If you can read the ROM without a resource assigned it is just luck
that everything is still in the same place as boot. If you start
hotpluging the original ROM address could get used by another card
since is is not actively assigned.

I didn't check the error code from pci_assign_resource(). If it can't
match the PREFETCH type it will fail. That may be what is happening.
I'll add a check.




=====
Jon Smirl
jonsmirl@yahoo.com


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05 20:45                               ` Jon Smirl
@ 2004-08-05 21:12                                 ` Jesse Barnes
  2004-08-06 21:14                                   ` Jon Smirl
  0 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-05 21:12 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

On Thursday, August 5, 2004 1:45 pm, Jon Smirl wrote:
> If you follow the code path of pci_assign_resource() it will program
> the ROM to appear at the newly assigned address in
> pci_update_resource(). I'd check these code paths and see if they are
> 64 bit broken. This process does work on ia32.

I think just my platform is broken (i.e. pci_assign_resource doesn't do the 
right thing on sn2).  I'll take a look.

> If you can read the ROM without a resource assigned it is just luck
> that everything is still in the same place as boot. If you start
> hotpluging the original ROM address could get used by another card
> since is is not actively assigned.

Right.

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-05 21:12                                 ` Jesse Barnes
@ 2004-08-06 21:14                                   ` Jon Smirl
  2004-08-06 22:33                                     ` Jesse Barnes
  2004-08-11 17:04                                     ` Jesse Barnes
  0 siblings, 2 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-06 21:14 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 1781 bytes --]

Version 11

I removed the call to pci_alloc_resource(). The sysfs attribute code
builds the attributes before the pci subsystem is fully initialized.
Specifically before arch pcibios_init() has been called. If
pci_alloc_resource() is called for the ROM before pcibios_init() the
kernel's resource maps have not been built yet. This will result in the
ROM being located on top of the framebuffer; as soon as it is enabled
the system will lock. Right now the code relies on the BIOS getting
things set up right. If we can figure out how to initialize the sysfs
attributes after pcibios_init() then I can put the alloc call back.

Changes the API to make it useful from a device driver:

pci_map_rom - map the rom and provide virtual address, transparently
return shadow/copy if needed. Normal drivers call this

pci_map_rom_copy - same as pci_map_rom except the ROM will copied,
future reads of ROM will use copy. Hardware with minimal decoding calls
this

pci_unmap_rom - release the ioremap if there is one

If the ROM code finds the 55 AA signature at the start of the ROM it
will use the len/512 from the third byte for the length. The PCI window
is often much larger than the ROM really is so this saves a lot of
memory for copied ROMs.

I added two new defines in pci.h
#define  PCI_ROM_SHADOW 0x02 /* resource flag, ROM is copy at C000:0 */
#define  PCI_ROM_COPY   0x04 /* resource flag, ROM is alloc'd copy */
I don't think these conflict with anything, please check to make sure.

Please check the code out and give it some testing. It will probably
needs some adjustment for other platforms.

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Read only the mail you want - Yahoo! Mail SpamGuard.
http://promotions.yahoo.com/new_mail 

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pci-sysfs-rom-11.patch --]
[-- Type: text/x-patch; name="pci-sysfs-rom-11.patch", Size: 10553 bytes --]

===== arch/i386/pci/fixup.c 1.19 vs edited =====
--- 1.19/arch/i386/pci/fixup.c	Thu Jun  3 10:58:17 2004
+++ edited/arch/i386/pci/fixup.c	Thu Aug  5 00:20:08 2004
@@ -237,6 +237,29 @@
 	}
 }
 
+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 |= PCI_ROM_SHADOW;
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{
 		.pass		= PCI_FIXUP_HEADER,
@@ -345,6 +368,12 @@
 		.vendor		= PCI_VENDOR_ID_NVIDIA,
 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2,
 		.hook		= pci_fixup_nforce2
+	},
+	{
+		.pass		= PCI_FIXUP_FINAL,
+		.vendor		= PCI_ANY_ID,
+		.device		= PCI_ANY_ID,
+		.hook		= pci_fixup_video
 	},
 	{ .pass = 0 }
 };
===== drivers/pci/pci-sysfs.c 1.10 vs edited =====
--- 1.10/drivers/pci/pci-sysfs.c	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci-sysfs.c	Fri Aug  6 16:38:00 2004
@@ -5,6 +5,7 @@
  * (C) Copyright 2002-2004 IBM Corp.
  * (C) Copyright 2003 Matthew Wilcox
  * (C) Copyright 2003 Hewlett-Packard
+ * (C) Copyright 2004 Jon Smirl
  *
  * File attributes for PCI devices
  *
@@ -164,6 +165,176 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_map_rom - map a PCI ROM to kernel space
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+unsigned char *
+pci_map_rom(struct pci_dev *dev, size_t *size) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+	loff_t start;
+	unsigned char *rom;
+	
+	if (res->flags & PCI_ROM_SHADOW) {	/* PCI_ROM_SHADOW only set on x86 */
+		start = (loff_t)0xC0000; 	/* primary video rom always starts here */
+		*size = 0x20000;		/* cover C000:0 through E000:0 */
+	} else if (res->flags & PCI_ROM_COPY) {
+		*size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		return (unsigned char *)pci_resource_start(dev, PCI_ROM_RESOURCE);
+	} else {
+		start = pci_resource_start(dev, PCI_ROM_RESOURCE);
+		*size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		if (*size == 0)
+			return NULL;
+		
+		/* Enable ROM space decodes */
+		pci_enable_rom(dev);
+	}
+	
+	rom = ioremap(start, *size);
+	if (!rom) {
+		/* restore enable if ioremap fails */
+		if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE | PCI_ROM_SHADOW | PCI_ROM_COPY)))
+			pci_disable_rom(dev);
+		return NULL;
+	}		
+	/* Standard PCI ROMs start out with these three bytes 55 AA size/512 */
+	if ((*rom == 0x55) && (*(rom + 1) == 0xAA))
+		*size = *(rom + 2) * 512;	/* return true ROM size, not PCI window size */
+		
+	return rom;
+}
+
+/**
+ * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+unsigned char *
+pci_map_rom_copy(struct pci_dev *dev, size_t *size) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+	unsigned char *rom;
+	
+	rom = pci_map_rom(dev, size);
+	if (!rom)
+		return NULL;
+		
+	if (res->flags & (PCI_ROM_COPY | PCI_ROM_SHADOW))
+		return rom;
+		
+	res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
+	if (!res->start) 
+		return rom;
+
+	res->end = res->start + *size; 
+	memcpy((void*)res->start, rom, *size);
+	pci_unmap_rom(dev, rom);
+	res->flags |= PCI_ROM_COPY;
+	
+	return (unsigned char *)res->start;
+}
+
+/**
+ * pci_unmap_rom - unmap the ROM from kernel space
+ * @dev: pointer to pci device struct
+ * @rom: virtual address of the previous mapping
+ *
+ * Remove a mapping of a previously mapped ROM
+ */
+void 
+pci_unmap_rom(struct pci_dev *dev, unsigned char *rom) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+
+	if (res->flags & PCI_ROM_COPY)
+		return;
+		
+	iounmap(rom);
+		
+	/* Disable again before continuing, leave enabled if pci=rom */
+	if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE | PCI_ROM_SHADOW)))
+		pci_disable_rom(dev);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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));
+	unsigned char *rom;
+	size_t size;
+	
+	rom = pci_map_rom(dev, &size);	/* size starts out as PCI window size */
+	if (!rom)
+		return 0;
+		
+	if (off >= size)
+		count = 0;
+	else {
+		if (off + count > size)
+			count = size - off;
+		
+		memcpy_fromio(buf, rom + off, count);
+	}
+	pci_unmap_rom(dev, rom);
+		
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +357,53 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+static struct bin_attribute rom_attr = {
+	.attr =	{
+		.name = "rom",
+		.mode = S_IRUSR,
+		.owner = THIS_MODULE,
+	},
+	/* .size is set individually for each device, sysfs copies it into dentry */
+	.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, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		unsigned char *rom;
+		rom = pci_map_rom(pdev, &rom_attr.size);
+		if (rom) {
+			pci_unmap_rom(pdev, rom);
+			sysfs_create_bin_file(&pdev->dev.kobj, &rom_attr);
+		}
+	}
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
 }
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+		sysfs_remove_bin_file(&pdev->dev.kobj, &rom_attr);
+}
+
+EXPORT_SYMBOL(pci_map_rom);
+EXPORT_SYMBOL(pci_map_rom_copy);
+EXPORT_SYMBOL(pci_unmap_rom);
===== drivers/pci/pci.h 1.12 vs edited =====
--- 1.12/drivers/pci/pci.h	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci.h	Tue Aug  3 17:05:19 2004
@@ -3,6 +3,7 @@
 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 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 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/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	Tue Feb  3 12:17:30 2004
+++ edited/drivers/pci/remove.c	Fri Aug  6 15:36:18 2004
@@ -12,12 +12,22 @@
 
 static void pci_free_resources(struct pci_dev *dev)
 {
+	struct resource *res;
 	int i;
 
  	msi_remove_pci_irq_vectors(dev);
 
+	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+		res = &dev->resource[PCI_ROM_RESOURCE];
+		if (res->flags & PCI_ROM_COPY) {
+			kfree((void*)res->start);
+			res->flags &= !PCI_ROM_COPY;
+			res->start = 0;
+			res->end = 0;
+		}
+	}
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *res = dev->resource + i;
+		res = dev->resource + i;
 		if (res->parent)
 			release_resource(res);
 	}
@@ -26,6 +36,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
===== include/linux/pci.h 1.132 vs edited =====
--- 1.132/include/linux/pci.h	Mon Aug  2 04:00:43 2004
+++ edited/include/linux/pci.h	Fri Aug  6 00:34:27 2004
@@ -102,6 +102,8 @@
 #define PCI_SUBSYSTEM_ID	0x2e  
 #define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
+#define  PCI_ROM_SHADOW		0x02	/* resource flag, ROM is copy at C000:0 */
+#define  PCI_ROM_COPY		0x04	/* resource flag, ROM is alloc'd copy */
 #define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
 
 #define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
@@ -777,6 +779,9 @@
 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);
+unsigned char *pci_map_rom(struct pci_dev *dev, size_t *size);
+unsigned char *pci_map_rom_copy(struct pci_dev *dev, size_t *size);
+void pci_unmap_rom(struct pci_dev *dev, unsigned char *rom);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev, u32 *buffer);

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-06 21:14                                   ` Jon Smirl
@ 2004-08-06 22:33                                     ` Jesse Barnes
  2004-08-11 17:04                                     ` Jesse Barnes
  1 sibling, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-06 22:33 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> attributes after pcibios_init() then I can put the alloc call back.

I've fixed (well, hacked) the sn2 code such that your original check for 
res->parent will work correctly for me too, so it sounds like we're covered 
there.

> Please check the code out and give it some testing. It will probably
> needs some adjustment for other platforms.

Thanks, will do (though probably not until next week, I'm about to head out 
for the weekend).

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-06 21:14                                   ` Jon Smirl
  2004-08-06 22:33                                     ` Jesse Barnes
@ 2004-08-11 17:04                                     ` Jesse Barnes
  2004-08-11 17:28                                       ` Greg KH
  1 sibling, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-11 17:04 UTC (permalink / raw)
  To: Jon Smirl
  Cc: greg, Martin Mares, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec,
	Benjamin Herrenschmidt

On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> Please check the code out and give it some testing. It will probably
> needs some adjustment for other platforms.

Jon, this works on my machine too.  Greg, if it looks ok can you pull it in?  
And can you add:

 * (C) Copyright 2004 Silicon Graphics, Inc.
 *       Jesse Barnes <jbarnes@sgi.com>

to pci-sysfs.c if you do?

Greg was a little worried that your comment
	/* .size is set individually for each device, sysfs copies it into dentry */
might not be correct.  If not, you can reuse the code from my 
pci-sysfs-rom-7.patch if you want, otherwise it's probably fine aside from a 
bunch of trailing whitespace in the file.  I added the following to my .emacs 
to make it obvious so that I could kill it when I saw it:
(defun linux-c-mode ()
  "C mode with Linux kernel defaults"
  (interactive)
  (c-mode)
  (c-set-style "K&R")
  (setq c-basic-offset 8)
  (setq indent-tabs-mode t)
  (setq show-trailing-whitespace t))

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 17:04                                     ` Jesse Barnes
@ 2004-08-11 17:28                                       ` Greg KH
  2004-08-11 18:02                                         ` Jesse Barnes
                                                           ` (2 more replies)
  0 siblings, 3 replies; 58+ messages in thread
From: Greg KH @ 2004-08-11 17:28 UTC (permalink / raw)
  To: Jesse Barnes
  Cc: Jon Smirl, Martin Mares, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec,
	Benjamin Herrenschmidt

On Wed, Aug 11, 2004 at 10:04:02AM -0700, Jesse Barnes wrote:
> On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> > Please check the code out and give it some testing. It will probably
> > needs some adjustment for other platforms.
> 
> Jon, this works on my machine too.  Greg, if it looks ok can you pull it in?  
> And can you add:
> 
>  * (C) Copyright 2004 Silicon Graphics, Inc.
>  *       Jesse Barnes <jbarnes@sgi.com>
> 
> to pci-sysfs.c if you do?

Care to send me a new patch?  Oh, and that copyright line needs to look
like:
* Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>

to make it legal, or so my lawyers say :)

> Greg was a little worried that your comment
> 	/* .size is set individually for each device, sysfs copies it into dentry */
> might not be correct.

I looked at the code, and he's right.  But it's pretty scary that it
works correctly so I'd prefer to do it the way your patch did it (create
a new attribute for every entry.)

thnaks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 17:28                                       ` Greg KH
@ 2004-08-11 18:02                                         ` Jesse Barnes
  2004-08-11 18:12                                           ` Greg KH
  2004-08-11 19:24                                         ` Jon Smirl
  2004-08-12  0:45                                         ` Jon Smirl
  2 siblings, 1 reply; 58+ messages in thread
From: Jesse Barnes @ 2004-08-11 18:02 UTC (permalink / raw)
  To: Greg KH
  Cc: Jon Smirl, Martin Mares, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec,
	Benjamin Herrenschmidt

On Wednesday, August 11, 2004 10:28 am, Greg KH wrote:
> On Wed, Aug 11, 2004 at 10:04:02AM -0700, Jesse Barnes wrote:
> > On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> > > Please check the code out and give it some testing. It will probably
> > > needs some adjustment for other platforms.
> >
> > Jon, this works on my machine too.  Greg, if it looks ok can you pull it
> > in? And can you add:
> >
> >  * (C) Copyright 2004 Silicon Graphics, Inc.
> >  *       Jesse Barnes <jbarnes@sgi.com>
> >
> > to pci-sysfs.c if you do?
>
> Care to send me a new patch?  Oh, and that copyright line needs to look
> like:
> * Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
>
> to make it legal, or so my lawyers say :)

But I'm not the copyright holder, Silicon Graphics is, I just wanted people to 
know who to harass if something breaks :).

> > Greg was a little worried that your comment
> > 	/* .size is set individually for each device, sysfs copies it into
> > dentry */ might not be correct.
>
> I looked at the code, and he's right.  But it's pretty scary that it
> works correctly so I'd prefer to do it the way your patch did it (create
> a new attribute for every entry.)

Ok.  Jon?

Thanks,
Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 18:02                                         ` Jesse Barnes
@ 2004-08-11 18:12                                           ` Greg KH
  2004-08-12  1:28                                             ` Marcelo Tosatti
  2004-08-12  2:25                                             ` Miles Bader
  0 siblings, 2 replies; 58+ messages in thread
From: Greg KH @ 2004-08-11 18:12 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: linux-pci, Linux Kernel Mailing List

On Wed, Aug 11, 2004 at 11:02:10AM -0700, Jesse Barnes wrote:
> On Wednesday, August 11, 2004 10:28 am, Greg KH wrote:
> > On Wed, Aug 11, 2004 at 10:04:02AM -0700, Jesse Barnes wrote:
> > > On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> > > > Please check the code out and give it some testing. It will probably
> > > > needs some adjustment for other platforms.
> > >
> > > Jon, this works on my machine too.  Greg, if it looks ok can you pull it
> > > in? And can you add:
> > >
> > >  * (C) Copyright 2004 Silicon Graphics, Inc.
> > >  *       Jesse Barnes <jbarnes@sgi.com>
> > >
> > > to pci-sysfs.c if you do?
> >
> > Care to send me a new patch?  Oh, and that copyright line needs to look
> > like:
> > * Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
> >
> > to make it legal, or so my lawyers say :)
> 
> But I'm not the copyright holder, Silicon Graphics is, I just wanted people to 
> know who to harass if something breaks :).

That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
really matters, from what I have been told to do.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 17:28                                       ` Greg KH
  2004-08-11 18:02                                         ` Jesse Barnes
@ 2004-08-11 19:24                                         ` Jon Smirl
  2004-08-11 19:44                                           ` Jesse Barnes
  2004-08-11 20:11                                           ` Alan Cox
  2004-08-12  0:45                                         ` Jon Smirl
  2 siblings, 2 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-11 19:24 UTC (permalink / raw)
  To: Greg KH, Jesse Barnes, Benjamin Herrenschmidt
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

[-- Attachment #1: Type: text/plain, Size: 2262 bytes --]

I can put together a new patch later tonight that reverts to the old
size scheme. It was more complicated since you need to allocate each
attribute.

I'll attach a newer version that incorporates a little feedback about
creating a function to remove the attribute for devices that don't want
to expose the ROM.

Alan Cox had concerns about copying the ROMs for those devices that
don't implement full address decoding. I'm using kmalloc for 40-60KB.
Would vmalloc be a better choice? Very few drivers will use the copy
option, mostly old hardware.

BenH said he would check it out on ppc but I haven't heard from him
yet.

Jesse, did you notice that the quirk for tracking the boot video device
is x86 only? I believe this needs to run on ia64 and x86_64 too. How do
we want to do that? It will do the wrong thing on architectures that
don't shadow video ROMs to C0000.

 
--- Greg KH <greg@kroah.com> wrote:

> On Wed, Aug 11, 2004 at 10:04:02AM -0700, Jesse Barnes wrote:
> > On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> > > Please check the code out and give it some testing. It will
> probably
> > > needs some adjustment for other platforms.
> > 
> > Jon, this works on my machine too.  Greg, if it looks ok can you
> pull it in?  
> > And can you add:
> > 
> >  * (C) Copyright 2004 Silicon Graphics, Inc.
> >  *       Jesse Barnes <jbarnes@sgi.com>
> > 
> > to pci-sysfs.c if you do?

I'll add this

> Care to send me a new patch?  Oh, and that copyright line needs to
> look
> like:
> * Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes
> <jbarnes@sgi.com>
> 
> to make it legal, or so my lawyers say :)
> 
> > Greg was a little worried that your comment
> > 	/* .size is set individually for each device, sysfs copies it into
> dentry */
> > might not be correct.
> 
> I looked at the code, and he's right.  But it's pretty scary that it
> works correctly so I'd prefer to do it the way your patch did it
> (create
> a new attribute for every entry.)

I can revert back to the old code. The new scheme was just so much
simpler.

> 
> thanks,
> 
> greg k-h
> 

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: pci-sysfs-rom-13.patch --]
[-- Type: text/x-patch; name="pci-sysfs-rom-13.patch", Size: 11116 bytes --]

===== arch/i386/pci/fixup.c 1.19 vs edited =====
--- 1.19/arch/i386/pci/fixup.c	Thu Jun  3 10:58:17 2004
+++ edited/arch/i386/pci/fixup.c	Thu Aug  5 00:20:08 2004
@@ -237,6 +237,29 @@
 	}
 }
 
+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 |= PCI_ROM_SHADOW;
+}
+
 struct pci_fixup pcibios_fixups[] = {
 	{
 		.pass		= PCI_FIXUP_HEADER,
@@ -345,6 +368,12 @@
 		.vendor		= PCI_VENDOR_ID_NVIDIA,
 		.device		= PCI_DEVICE_ID_NVIDIA_NFORCE2,
 		.hook		= pci_fixup_nforce2
+	},
+	{
+		.pass		= PCI_FIXUP_FINAL,
+		.vendor		= PCI_ANY_ID,
+		.device		= PCI_ANY_ID,
+		.hook		= pci_fixup_video
 	},
 	{ .pass = 0 }
 };
===== drivers/pci/pci-sysfs.c 1.10 vs edited =====
--- 1.10/drivers/pci/pci-sysfs.c	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci-sysfs.c	Sat Aug  7 13:37:14 2004
@@ -5,6 +5,7 @@
  * (C) Copyright 2002-2004 IBM Corp.
  * (C) Copyright 2003 Matthew Wilcox
  * (C) Copyright 2003 Hewlett-Packard
+ * (C) Copyright 2004 Jon Smirl
  *
  * File attributes for PCI devices
  *
@@ -164,6 +165,193 @@
 	return count;
 }
 
+/**
+ * pci_enable_rom - enable ROM decoding for a PCI device
+ * @dev: PCI device to enable
+ *
+ * Enable ROM decoding on @dev.  This involves simply turning on the last
+ * bit of the PCI ROM BAR.  Note that some cards may share address decoders
+ * between the ROM and other resources, so enabling it may disable access
+ * to MMIO registers or other card memory.
+ */
+static void
+pci_enable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr |= PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_disable_rom - disable ROM decoding for a PCI device
+ * @dev: PCI device to disable
+ *
+ * Disable ROM decoding on a PCI device by turning off the last bit in the
+ * ROM BAR.
+ */
+static void
+pci_disable_rom(struct pci_dev *dev)
+{
+	u32 rom_addr;
+	pci_read_config_dword(dev, dev->rom_base_reg, &rom_addr);
+	rom_addr &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_dword(dev, dev->rom_base_reg, rom_addr);
+}
+
+/**
+ * pci_map_rom - map a PCI ROM to kernel space
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+unsigned char *
+pci_map_rom(struct pci_dev *dev, size_t *size) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+	loff_t start;
+	unsigned char *rom;
+	
+	if (res->flags & PCI_ROM_SHADOW) {	/* PCI_ROM_SHADOW only set on x86 */
+		start = (loff_t)0xC0000; 	/* primary video rom always starts here */
+		*size = 0x20000;		/* cover C000:0 through E000:0 */
+	} else if (res->flags & PCI_ROM_COPY) {
+		*size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		return (unsigned char *)pci_resource_start(dev, PCI_ROM_RESOURCE);
+	} else {
+		start = pci_resource_start(dev, PCI_ROM_RESOURCE);
+		*size = pci_resource_len(dev, PCI_ROM_RESOURCE);
+		if (*size == 0)
+			return NULL;
+		
+		/* Enable ROM space decodes */
+		pci_enable_rom(dev);
+	}
+	
+	rom = ioremap(start, *size);
+	if (!rom) {
+		/* restore enable if ioremap fails */
+		if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE | PCI_ROM_SHADOW | PCI_ROM_COPY)))
+			pci_disable_rom(dev);
+		return NULL;
+	}		
+	/* Standard PCI ROMs start out with these three bytes 55 AA size/512 */
+	if ((*rom == 0x55) && (*(rom + 1) == 0xAA))
+		*size = *(rom + 2) * 512;	/* return true ROM size, not PCI window size */
+		
+	return rom;
+}
+
+/**
+ * pci_map_rom_copy - map a PCI ROM to kernel space, create a copy
+ * @dev: pointer to pci device struct
+ * @size: pointer to receive size of pci window over ROM
+ * @return: kernel virtual pointer to image of ROM
+ *
+ * Map a PCI ROM into kernel space. If ROM is boot video ROM,
+ * the shadow BIOS copy will be returned instead of the 
+ * actual ROM.
+ */
+unsigned char *
+pci_map_rom_copy(struct pci_dev *dev, size_t *size) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+	unsigned char *rom;
+	
+	rom = pci_map_rom(dev, size);
+	if (!rom)
+		return NULL;
+		
+	if (res->flags & (PCI_ROM_COPY | PCI_ROM_SHADOW))
+		return rom;
+		
+	res->start = (unsigned long)kmalloc(*size, GFP_KERNEL);
+	if (!res->start) 
+		return rom;
+
+	res->end = res->start + *size; 
+	memcpy((void*)res->start, rom, *size);
+	pci_unmap_rom(dev, rom);
+	res->flags |= PCI_ROM_COPY;
+	
+	return (unsigned char *)res->start;
+}
+
+/**
+ * pci_unmap_rom - unmap the ROM from kernel space
+ * @dev: pointer to pci device struct
+ * @rom: virtual address of the previous mapping
+ *
+ * Remove a mapping of a previously mapped ROM
+ */
+void 
+pci_unmap_rom(struct pci_dev *dev, unsigned char *rom) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+
+	if (res->flags & PCI_ROM_COPY)
+		return;
+		
+	iounmap(rom);
+		
+	/* Disable again before continuing, leave enabled if pci=rom */
+	if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE | PCI_ROM_SHADOW)))
+		pci_disable_rom(dev);
+}
+
+static struct bin_attribute rom_attr;
+
+/**
+ * pci_remove_rom - disable the ROM and remove it's sysfs attribute
+ * @dev: pointer to pci device struct
+ *
+ */
+void 
+pci_remove_rom(struct pci_dev *dev) {
+	struct resource *res = &dev->resource[PCI_ROM_RESOURCE];
+	
+	if (pci_resource_len(dev, PCI_ROM_RESOURCE))
+		sysfs_remove_bin_file(&dev->dev.kobj, &rom_attr);
+	if (!(res->flags & (PCI_ROM_ADDRESS_ENABLE | PCI_ROM_SHADOW | PCI_ROM_COPY)))
+		pci_disable_rom(dev);
+}
+
+/**
+ * pci_read_rom - read a PCI ROM
+ * @kobj: kernel object handle
+ * @buf: where to put the data we read from the ROM
+ * @off: file offset
+ * @count: number of bytes to read
+ *
+ * Put @count bytes starting at @off into @buf from the ROM in the PCI
+ * device corresponding to @kobj.
+ */
+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));
+	unsigned char *rom;
+	size_t size;
+	
+	rom = pci_map_rom(dev, &size);	/* size starts out as PCI window size */
+	if (!rom)
+		return 0;
+		
+	if (off >= size)
+		count = 0;
+	else {
+		if (off + count > size)
+			count = size - off;
+		
+		memcpy_fromio(buf, rom + off, count);
+	}
+	pci_unmap_rom(dev, rom);
+		
+	return count;
+}
+
 static struct bin_attribute pci_config_attr = {
 	.attr =	{
 		.name = "config",
@@ -186,13 +374,53 @@
 	.write = pci_write_config,
 };
 
-void pci_create_sysfs_dev_files (struct pci_dev *pdev)
+static struct bin_attribute rom_attr = {
+	.attr =	{
+		.name = "rom",
+		.mode = S_IRUSR,
+		.owner = THIS_MODULE,
+	},
+	/* .size is set individually for each device, sysfs copies it into dentry */
+	.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, try to expose it in sysfs. */
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) {
+		unsigned char *rom;
+		rom = pci_map_rom(pdev, &rom_attr.size);
+		if (rom) {
+			pci_unmap_rom(pdev, rom);
+			sysfs_create_bin_file(&pdev->dev.kobj, &rom_attr);
+		}
+	}
 	/* add platform-specific attributes */
 	pcibios_add_platform_entries(pdev);
 }
+
+/**
+ * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
+ * @pdev: device whose entries we should free
+ *
+ * Cleanup when @pdev is removed from sysfs.
+ */
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
+{
+	if (pdev->cfg_size < 4096)
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
+	else
+		sysfs_remove_bin_file(&pdev->dev.kobj, &pcie_config_attr);
+
+	if (pci_resource_len(pdev, PCI_ROM_RESOURCE))
+		sysfs_remove_bin_file(&pdev->dev.kobj, &rom_attr);
+}
+
+EXPORT_SYMBOL(pci_map_rom);
+EXPORT_SYMBOL(pci_map_rom_copy);
+EXPORT_SYMBOL(pci_unmap_rom);
===== drivers/pci/pci.h 1.12 vs edited =====
--- 1.12/drivers/pci/pci.h	Fri Jun  4 09:23:04 2004
+++ edited/drivers/pci/pci.h	Tue Aug  3 17:05:19 2004
@@ -3,6 +3,7 @@
 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 void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
 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/remove.c 1.3 vs edited =====
--- 1.3/drivers/pci/remove.c	Tue Feb  3 12:17:30 2004
+++ edited/drivers/pci/remove.c	Fri Aug  6 15:36:18 2004
@@ -12,12 +12,22 @@
 
 static void pci_free_resources(struct pci_dev *dev)
 {
+	struct resource *res;
 	int i;
 
  	msi_remove_pci_irq_vectors(dev);
 
+	if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL) {
+		res = &dev->resource[PCI_ROM_RESOURCE];
+		if (res->flags & PCI_ROM_COPY) {
+			kfree((void*)res->start);
+			res->flags &= !PCI_ROM_COPY;
+			res->start = 0;
+			res->end = 0;
+		}
+	}
 	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-		struct resource *res = dev->resource + i;
+		res = dev->resource + i;
 		if (res->parent)
 			release_resource(res);
 	}
@@ -26,6 +36,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
===== include/linux/pci.h 1.132 vs edited =====
--- 1.132/include/linux/pci.h	Mon Aug  2 04:00:43 2004
+++ edited/include/linux/pci.h	Sat Aug  7 13:33:34 2004
@@ -102,6 +102,8 @@
 #define PCI_SUBSYSTEM_ID	0x2e  
 #define PCI_ROM_ADDRESS		0x30	/* Bits 31..11 are address, 10..1 reserved */
 #define  PCI_ROM_ADDRESS_ENABLE	0x01
+#define  PCI_ROM_SHADOW		0x02	/* resource flag, ROM is copy at C000:0 */
+#define  PCI_ROM_COPY		0x04	/* resource flag, ROM is alloc'd copy */
 #define PCI_ROM_ADDRESS_MASK	(~0x7ffUL)
 
 #define PCI_CAPABILITY_LIST	0x34	/* Offset of first capability list entry */
@@ -777,6 +779,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 *dev, size_t *size);
+unsigned char *pci_map_rom_copy(struct pci_dev *dev, size_t *size);
+void pci_unmap_rom(struct pci_dev *dev, unsigned char *rom);
+void pci_remove_rom(struct pci_dev *dev);
 
 /* Power management related routines */
 int pci_save_state(struct pci_dev *dev, u32 *buffer);

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 19:24                                         ` Jon Smirl
@ 2004-08-11 19:44                                           ` Jesse Barnes
  2004-08-11 20:11                                           ` Alan Cox
  1 sibling, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-11 19:44 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Greg KH, Benjamin Herrenschmidt, Martin Mares, linux-pci,
	Alan Cox, Linux Kernel Mailing List, Petr Vandrovec

On Wednesday, August 11, 2004 12:24 pm, Jon Smirl wrote:
> Jesse, did you notice that the quirk for tracking the boot video device
> is x86 only? I believe this needs to run on ia64 and x86_64 too. How do
> we want to do that? It will do the wrong thing on architectures that
> don't shadow video ROMs to C0000.

Yeah, but I don't know of any ia64 platforms that need the quirk.  All of them 
that I'm aware of use add-on boards.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 19:24                                         ` Jon Smirl
  2004-08-11 19:44                                           ` Jesse Barnes
@ 2004-08-11 20:11                                           ` Alan Cox
  2004-08-11 23:31                                             ` Jon Smirl
  1 sibling, 1 reply; 58+ messages in thread
From: Alan Cox @ 2004-08-11 20:11 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Greg KH, Jesse Barnes, Benjamin Herrenschmidt, Martin Mares,
	linux-pci, Linux Kernel Mailing List, Petr Vandrovec

On Mer, 2004-08-11 at 20:24, Jon Smirl wrote:
> Alan Cox had concerns about copying the ROMs for those devices that
> don't implement full address decoding. I'm using kmalloc for 40-60KB.
> Would vmalloc be a better choice? Very few drivers will use the copy
> option, mostly old hardware.

As I said before you don't need to allocate big chunks of kernel memory
for this because you don't want to store ROM copies in kernel, you just
disallow mmap in such a case and let the user use read().

I am opposed to anything that keeps ROM copies in the kernel.


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 20:11                                           ` Alan Cox
@ 2004-08-11 23:31                                             ` Jon Smirl
  2004-08-12 11:51                                               ` Alan Cox
  0 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-11 23:31 UTC (permalink / raw)
  To: Alan Cox
  Cc: Greg KH, Jesse Barnes, Benjamin Herrenschmidt, Martin Mares,
	linux-pci, Linux Kernel Mailing List, Petr Vandrovec

--- Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:
> On Mer, 2004-08-11 at 20:24, Jon Smirl wrote:
> > Alan Cox had concerns about copying the ROMs for those devices that
> > don't implement full address decoding. I'm using kmalloc for
> 40-60KB.
> > Would vmalloc be a better choice? Very few drivers will use the
> copy
> > option, mostly old hardware.
> 
> As I said before you don't need to allocate big chunks of kernel
> memory for this because you don't want to store ROM copies in kernel,
> you just disallow mmap in such a case and let the user use read().
> 
> I am opposed to anything that keeps ROM copies in the kernel.
> 

How are we supposed to implement this without a copy? Once the device
driver is loaded there is never a safe way access the ROM again because
an interrupt or another CPU might use the PCI decoders to access the
other hardware and disrupt the ROM read. You have to copy the ROM when
the driver says it is safe.

I provided two calls for the driver to pick from: 1) make an in kernel
copy of the ROM and leave it visible from sysfs or 2) remove the sysfs
attribute. 

Another possible scheme could have a user space daemon that copies the
ROMs out of the kernel at boot and then holds them for later access by
other apps, but that would break the ROM attribute in sysfs model. 

Still another scheme would be to make the drivers for this class of
card implement a lock around PCI address decoder use. That would get
complex with interrupt routines.

How much trouble do we want to go to handling a case that only applies
to very few cards? I believe old QLogic disk controllers have this
problem, are there others? I'm not aware of any video cards with this
problem. 99%+ of PCI ROMs don't need the copy.

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - 50x more storage than other providers!
http://promotions.yahoo.com/new_mail

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 17:28                                       ` Greg KH
  2004-08-11 18:02                                         ` Jesse Barnes
  2004-08-11 19:24                                         ` Jon Smirl
@ 2004-08-12  0:45                                         ` Jon Smirl
  2004-08-12  4:37                                           ` Greg KH
  2 siblings, 1 reply; 58+ messages in thread
From: Jon Smirl @ 2004-08-12  0:45 UTC (permalink / raw)
  To: Greg KH, Jesse Barnes
  Cc: Martin Mares, linux-pci, Alan Cox, Linux Kernel Mailing List,
	Petr Vandrovec, Benjamin Herrenschmidt

I have to add a pointer to struct pci_dev to track the attribute copy
with the size in it. Would you rather have me add the pointer or or
change the sysfs rules to state that a copy of the length is made?

--- Greg KH <greg@kroah.com> wrote:
> > Greg was a little worried that your comment
> > 	/* .size is set individually for each device, sysfs copies it into
> dentry */
> > might not be correct.
> 
> I looked at the code, and he's right.  But it's pretty scary that it
> works correctly so I'd prefer to do it the way your patch did it
> (create
> a new attribute for every entry.)
> 
> thnaks,
> 
> greg k-h
> 


=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 18:12                                           ` Greg KH
@ 2004-08-12  1:28                                             ` Marcelo Tosatti
  2004-08-12 14:38                                               ` Jesse Barnes
  2004-08-12 17:29                                               ` Greg KH
  2004-08-12  2:25                                             ` Miles Bader
  1 sibling, 2 replies; 58+ messages in thread
From: Marcelo Tosatti @ 2004-08-12  1:28 UTC (permalink / raw)
  To: Greg KH; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

On Wed, Aug 11, 2004 at 11:12:36AM -0700, Greg KH wrote:
> On Wed, Aug 11, 2004 at 11:02:10AM -0700, Jesse Barnes wrote:
> > On Wednesday, August 11, 2004 10:28 am, Greg KH wrote:
> > > On Wed, Aug 11, 2004 at 10:04:02AM -0700, Jesse Barnes wrote:
> > > > On Friday, August 6, 2004 2:14 pm, Jon Smirl wrote:
> > > > > Please check the code out and give it some testing. It will probably
> > > > > needs some adjustment for other platforms.
> > > >
> > > > Jon, this works on my machine too.  Greg, if it looks ok can you pull it
> > > > in? And can you add:
> > > >
> > > >  * (C) Copyright 2004 Silicon Graphics, Inc.
> > > >  *       Jesse Barnes <jbarnes@sgi.com>
> > > >
> > > > to pci-sysfs.c if you do?
> > >
> > > Care to send me a new patch?  Oh, and that copyright line needs to look
> > > like:
> > > * Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
> > >
> > > to make it legal, or so my lawyers say :)
> > 
> > But I'm not the copyright holder, Silicon Graphics is, I just wanted people to 
> > know who to harass if something breaks :).
> 
> That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
> really matters, from what I have been told to do.

Greg,

That made me curious, what is the rationale behind 

(C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com> 

works and the previous suggested

(C) Copyright 2004 Silicon Graphics, Inc. 
	Jesse Barnes <jbarnes@sgi.com> 

doesnt? 

I know its a bit offtopic, but still, if you know the reason, would be
great to hear :) Bet others will also like to hear that. 

Thanks!





^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 18:12                                           ` Greg KH
  2004-08-12  1:28                                             ` Marcelo Tosatti
@ 2004-08-12  2:25                                             ` Miles Bader
  2004-08-12  4:38                                               ` Greg KH
  1 sibling, 1 reply; 58+ messages in thread
From: Miles Bader @ 2004-08-12  2:25 UTC (permalink / raw)
  To: Greg KH; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

Greg KH <greg@kroah.com> writes:
> That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
> really matters, from what I have been told to do.

Is that true now?  It used to be said (including by some people who I
trust on such matters) that the ascii graphic "(c)" -- as opposed to a
real c-in-a-circle character -- was _not_ officially recognized as
meaning "Copyright", and so one needed the actual word "Copyright", or a
real c-in-a-circle, for such notices to have some meaning.  However the
word "Copyright" alone is apparently enough.

-Miles
-- 
Somebody has to do something, and it's just incredibly pathetic that it
has to be us.  -- Jerry Garcia

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  0:45                                         ` Jon Smirl
@ 2004-08-12  4:37                                           ` Greg KH
  0 siblings, 0 replies; 58+ messages in thread
From: Greg KH @ 2004-08-12  4:37 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Jesse Barnes, Martin Mares, linux-pci, Alan Cox,
	Linux Kernel Mailing List, Petr Vandrovec,
	Benjamin Herrenschmidt

On Wed, Aug 11, 2004 at 05:45:25PM -0700, Jon Smirl wrote:
> I have to add a pointer to struct pci_dev to track the attribute copy
> with the size in it. Would you rather have me add the pointer or or
> change the sysfs rules to state that a copy of the length is made?

Adding a pointer is fine for now.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  2:25                                             ` Miles Bader
@ 2004-08-12  4:38                                               ` Greg KH
  2004-08-12  9:18                                                 ` Geert Uytterhoeven
  2004-08-12 22:01                                                 ` Matthew Wilcox
  0 siblings, 2 replies; 58+ messages in thread
From: Greg KH @ 2004-08-12  4:38 UTC (permalink / raw)
  To: Miles Bader; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

On Thu, Aug 12, 2004 at 11:25:27AM +0900, Miles Bader wrote:
> Greg KH <greg@kroah.com> writes:
> > That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
> > really matters, from what I have been told to do.
> 
> Is that true now?

That's what the copyright lawyers at a certian three letter company
said is needed, and for some reason I tend to believe what they say :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  4:38                                               ` Greg KH
@ 2004-08-12  9:18                                                 ` Geert Uytterhoeven
  2004-08-12 22:01                                                 ` Matthew Wilcox
  1 sibling, 0 replies; 58+ messages in thread
From: Geert Uytterhoeven @ 2004-08-12  9:18 UTC (permalink / raw)
  To: Greg KH; +Cc: Miles Bader, Jesse Barnes, linux-pci, Linux Kernel Mailing List

On Wed, 11 Aug 2004, Greg KH wrote:
> On Thu, Aug 12, 2004 at 11:25:27AM +0900, Miles Bader wrote:
> > Greg KH <greg@kroah.com> writes:
> > > That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
> > > really matters, from what I have been told to do.
> >
> > Is that true now?
>
> That's what the copyright lawyers at a certian three letter company
> said is needed, and for some reason I tend to believe what they say :)

You mean the copyright lawyers at a certian three letter company in a certain
three letter country?

IIRC, according to copyright laws in the other part of the world, everything
you write is always copyrighted by you, whether `©' or `(c)' or `copyright' are
present or not.

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-11 23:31                                             ` Jon Smirl
@ 2004-08-12 11:51                                               ` Alan Cox
  2004-08-12 20:28                                                 ` Jon Smirl
  0 siblings, 1 reply; 58+ messages in thread
From: Alan Cox @ 2004-08-12 11:51 UTC (permalink / raw)
  To: Jon Smirl
  Cc: Greg KH, Jesse Barnes, Benjamin Herrenschmidt, Martin Mares,
	linux-pci, Linux Kernel Mailing List, Petr Vandrovec

On Iau, 2004-08-12 at 00:31, Jon Smirl wrote:
> How are we supposed to implement this without a copy? Once the device
> driver is loaded there is never a safe way access the ROM again because
> an interrupt or another CPU might use the PCI decoders to access the
> other hardware and disrupt the ROM read. You have to copy the ROM when
> the driver says it is safe.

It's never safe essentially. The only way you can make it safe for this
case is to put the knowledge in the device driver for that specific card
rather than sysfs.

> Still another scheme would be to make the drivers for this class of
> card implement a lock around PCI address decoder use. That would get
> complex with interrupt routines.

That would be impossible in fact because of DMA and SMM activity.

> How much trouble do we want to go to handling a case that only applies
> to very few cards? I believe old QLogic disk controllers have this
> problem, are there others? I'm not aware of any video cards with this
> problem. 99%+ of PCI ROMs don't need the copy.

It would be better to just to blacklist those corner cases


^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  1:28                                             ` Marcelo Tosatti
@ 2004-08-12 14:38                                               ` Jesse Barnes
  2004-08-12 17:29                                               ` Greg KH
  1 sibling, 0 replies; 58+ messages in thread
From: Jesse Barnes @ 2004-08-12 14:38 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Greg KH, linux-pci, Linux Kernel Mailing List

On Wednesday, August 11, 2004 6:28 pm, Marcelo Tosatti wrote:
> That made me curious, what is the rationale behind
>
> (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
>
> works and the previous suggested
>
> (C) Copyright 2004 Silicon Graphics, Inc.
> 	Jesse Barnes <jbarnes@sgi.com>
>
> doesnt?
>
> I know its a bit offtopic, but still, if you know the reason, would be
> great to hear :) Bet others will also like to hear that.

My thought was that the second one doesn't list me as the copyright holder, 
only the author, which is just what I wanted.  To me, the first one seems to 
indicate that the copyright is shared between myself and the entity that owns 
it, which is incorrect.

Jesse

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  1:28                                             ` Marcelo Tosatti
  2004-08-12 14:38                                               ` Jesse Barnes
@ 2004-08-12 17:29                                               ` Greg KH
  1 sibling, 0 replies; 58+ messages in thread
From: Greg KH @ 2004-08-12 17:29 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: Jesse Barnes, linux-pci, Linux Kernel Mailing List

On Wed, Aug 11, 2004 at 10:28:43PM -0300, Marcelo Tosatti wrote:
> > > > > Jon, this works on my machine too.  Greg, if it looks ok can you pull it
> > > > > in? And can you add:
> > > > >
> > > > >  * (C) Copyright 2004 Silicon Graphics, Inc.
> > > > >  *       Jesse Barnes <jbarnes@sgi.com>
> > > > >
> > > > > to pci-sysfs.c if you do?
> > > >
> > > > Care to send me a new patch?  Oh, and that copyright line needs to look
> > > > like:
> > > > * Copyright (c) 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com>
> > > >
> > > > to make it legal, or so my lawyers say :)
> > > 
> > > But I'm not the copyright holder, Silicon Graphics is, I just wanted people to 
> > > know who to harass if something breaks :).
> > 
> > That's fine.  It's the "Copyright (c) 2004" order and exact "(c)" that
> > really matters, from what I have been told to do.
> 
> Greg,
> 
> That made me curious, what is the rationale behind 
> 
> (C) Copyright 2004 Silicon Graphics, Inc. Jesse Barnes <jbarnes@sgi.com> 
> 
> works and the previous suggested
> 
> (C) Copyright 2004 Silicon Graphics, Inc. 
> 	Jesse Barnes <jbarnes@sgi.com> 
> 
> doesnt? 
> 
> I know its a bit offtopic, but still, if you know the reason, would be
> great to hear :) Bet others will also like to hear that. 

Ok, this is as per some copyright lawyers who know US Copyright law, and
how to defend it in court.  To make it legally binding in the US, so you
can file for a copyright in the proper government agencies (which is
necessary if you want to be able defend your copyright in court in an
easier manner, it's not necessary but it sure helps.) you need the
phrase to look like:
	Copyright (c) <DATE> <COMPANY_NAME>

Note that this is different from the above description of putting a
"(C)" and then the word "Copyright".

Now I have no idea if this is the same for all countries, I only know
what I was told to do.

Hope this helps, and I really don't want to start a big "copyright"
thread, as I'm not a lawyer, I only have to deal with them on a constant
basis :)

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12 11:51                                               ` Alan Cox
@ 2004-08-12 20:28                                                 ` Jon Smirl
  0 siblings, 0 replies; 58+ messages in thread
From: Jon Smirl @ 2004-08-12 20:28 UTC (permalink / raw)
  To: Alan Cox
  Cc: Greg KH, Jesse Barnes, Benjamin Herrenschmidt, Martin Mares,
	linux-pci, Linux Kernel Mailing List, Petr Vandrovec

--- Alan Cox <alan@lxorguk.ukuu.org.uk> wrote:

> On Iau, 2004-08-12 at 00:31, Jon Smirl wrote:
> > How are we supposed to implement this without a copy? Once the
> device
> > driver is loaded there is never a safe way access the ROM again
> because
> > an interrupt or another CPU might use the PCI decoders to access
> the
> > other hardware and disrupt the ROM read. You have to copy the ROM
> when
> > the driver says it is safe.
> 
> It's never safe essentially. The only way you can make it safe for
> this
> case is to put the knowledge in the device driver for that specific
> card
> rather than sysfs.

I added these two calls to the pci API just for the case of partially
decoded hardware. The device driver for the hardware needs to make
these calls.

unsigned char *pci_map_rom_copy(struct pci_dev *dev, size_t *size);

Call this one from the driver when it is safe to read the ROM. It will
copy it and then provide a virtual address so that you can read it. The
copy is stored in the kernel so that the sysfs attribute will work
right.

void pci_remove_rom(struct pci_dev *dev);

Call this one from the driver to simply remove the ROM attribute.

Before the driver is loaded we have to assume that it safe to read the
ROM normally and the sysfs attribute will directly access the ROM.


unsigned char *pci_map_rom(struct pci_dev *dev, size_t *size);

For normal hardware that implements full decoding use this call. It
will automatically sort out the need to use the real ROM or a shadow
copy.

void pci_unmap_rom(struct pci_dev *dev, unsigned char *rom);

When you are done with a mapping use this

Normal ROMs do not make copies. The only time a copy happens is when a
device driver for a partially decoded device calls pci_map_rom_copy().

=====
Jon Smirl
jonsmirl@yahoo.com


		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail 

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] add PCI ROMs to sysfs
  2004-08-12  4:38                                               ` Greg KH
  2004-08-12  9:18                                                 ` Geert Uytterhoeven
@ 2004-08-12 22:01                                                 ` Matthew Wilcox
  1 sibling, 0 replies; 58+ messages in thread
From: Matthew Wilcox @ 2004-08-12 22:01 UTC (permalink / raw)
  To: Greg KH; +Cc: Miles Bader, Jesse Barnes, linux-pci, Linux Kernel Mailing List

On Wed, Aug 11, 2004 at 09:38:18PM -0700, Greg KH wrote:
> That's what the copyright lawyers at a certian three letter company
> said is needed, and for some reason I tend to believe what they say :)

On the other hand, you could believe what the US government tells you ...
http://www.copyright.gov/circs/circ1.html#noc

In particular, the (c) has no relevance; the important bit is the word
"Copyright":

   1. The symbol © (the letter C in a circle), or the word "Copyright,"
   or the abbreviation "Copr."; and

-- 
"Next the statesmen will invent cheap lies, putting the blame upon 
the nation that is attacked, and every man will be glad of those
conscience-soothing falsities, and will diligently study them, and refuse
to examine any refutations of them; and thus he will by and by convince 
himself that the war is just, and will thank God for the better sleep 
he enjoys after this process of grotesque self-deception." -- Mark Twain

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2004-08-12 22:03 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-30 21:09 [PATCH] add PCI ROMs to sysfs Jesse Barnes
2004-07-30 21:29 ` Greg KH
2004-07-30 21:34   ` Jesse Barnes
2004-07-30 21:39     ` Greg KH
2004-07-30 21:48     ` Jesse Barnes
2004-07-30 22:15     ` Jon Smirl
2004-07-31 15:59       ` Jesse Barnes
2004-08-02 17:02         ` Jesse Barnes
2004-08-02 17:29           ` Jon Smirl
2004-08-02 21:00           ` Jon Smirl
2004-08-02 21:05             ` Jesse Barnes
2004-08-02 23:32               ` Alan Cox
2004-08-02 23:30           ` Alan Cox
2004-08-03  2:03             ` Jesse Barnes
2004-08-03  2:32               ` Jon Smirl
2004-08-03 17:07                 ` Jesse Barnes
2004-08-03 21:19               ` Jon Smirl
2004-08-03 21:28                 ` Jesse Barnes
2004-08-03 21:30                   ` Jesse Barnes
2004-08-03 21:31                   ` Martin Mares
2004-08-03 21:36                     ` Jon Smirl
2004-08-03 21:39                       ` Martin Mares
2004-08-04  6:00                         ` lspci and ROM on bridge, was: " Jon Smirl
2004-08-04 16:04                           ` Martin Mares
2004-08-05  5:05                         ` Jon Smirl
2004-08-05  5:41                           ` Benjamin Herrenschmidt
2004-08-05 11:53                             ` Jon Smirl
2004-08-05 15:54                           ` Jesse Barnes
2004-08-05 16:25                             ` Jesse Barnes
2004-08-05 20:45                               ` Jon Smirl
2004-08-05 21:12                                 ` Jesse Barnes
2004-08-06 21:14                                   ` Jon Smirl
2004-08-06 22:33                                     ` Jesse Barnes
2004-08-11 17:04                                     ` Jesse Barnes
2004-08-11 17:28                                       ` Greg KH
2004-08-11 18:02                                         ` Jesse Barnes
2004-08-11 18:12                                           ` Greg KH
2004-08-12  1:28                                             ` Marcelo Tosatti
2004-08-12 14:38                                               ` Jesse Barnes
2004-08-12 17:29                                               ` Greg KH
2004-08-12  2:25                                             ` Miles Bader
2004-08-12  4:38                                               ` Greg KH
2004-08-12  9:18                                                 ` Geert Uytterhoeven
2004-08-12 22:01                                                 ` Matthew Wilcox
2004-08-11 19:24                                         ` Jon Smirl
2004-08-11 19:44                                           ` Jesse Barnes
2004-08-11 20:11                                           ` Alan Cox
2004-08-11 23:31                                             ` Jon Smirl
2004-08-12 11:51                                               ` Alan Cox
2004-08-12 20:28                                                 ` Jon Smirl
2004-08-12  0:45                                         ` Jon Smirl
2004-08-12  4:37                                           ` Greg KH
2004-08-04  6:08           ` Jon Smirl
2004-08-04 15:56             ` Jesse Barnes
2004-07-30 21:53   ` Jon Smirl
2004-07-31 10:03     ` Vojtech Pavlik
2004-07-31 13:28       ` Jon Smirl
2004-07-31 15:42         ` Greg KH

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®