[PATCH] [2/3] PCI sysfs improvements

Matthew Wilcox (willy@debian.org)
Tue, 8 Apr 2003 00:43:34 +0100


[Note: This patch depends on the sysfs-bin patch]

Improve pci-sysfs:
- Add PCI config space access to sysfs.
- Prefix values in the PCI space with `0x' cos they're hex values.
- Reformat the resource file with 64-bit values.
- Present all resources in the file, don't stop at the first empty one.

Todo:
- Implement write access.
- Convert resource file into directories

diff -urpNX dontdiff linux-2.5.66/drivers/pci/pci-sysfs.c linux-2.5.66-laptop/drivers/pci/pci-sysfs.c
--- linux-2.5.66/drivers/pci/pci-sysfs.c 2003-02-24 13:05:33.000000000 -0600
+++ linux-2.5.66-laptop/drivers/pci/pci-sysfs.c 2003-04-07 14:33:12.000000000 -0500
@@ -18,12 +18,6 @@

#include "pci.h"

-#if BITS_PER_LONG == 32
-#define LONG_FORMAT "\t%08lx"
-#else
-#define LONG_FORMAT "\t%16lx"
-#endif
-
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
@@ -36,11 +30,11 @@ show_##field (struct device *dev, char *
} \
static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL);

-pci_config_attr(vendor, "%04x\n");
-pci_config_attr(device, "%04x\n");
-pci_config_attr(subsystem_vendor, "%04x\n");
-pci_config_attr(subsystem_device, "%04x\n");
-pci_config_attr(class, "%06x\n");
+pci_config_attr(vendor, "%#06x\n");
+pci_config_attr(device, "%#06x\n");
+pci_config_attr(subsystem_vendor, "%#06x\n");
+pci_config_attr(subsystem_device, "%#06x\n");
+pci_config_attr(class, "%#08x\n");
pci_config_attr(irq, "%u\n");

/* show resources */
@@ -50,9 +44,14 @@ pci_show_resources(struct device * dev,
struct pci_dev * pci_dev = to_pci_dev(dev);
char * str = buf;
int i;
+ int max = 7;
+
+ if (pci_dev->subordinate)
+ max = DEVICE_COUNT_RESOURCE;

- for (i = 0; i < DEVICE_COUNT_RESOURCE && pci_resource_start(pci_dev,i); i++) {
- str += sprintf(str,LONG_FORMAT LONG_FORMAT LONG_FORMAT "\n",
+ for (i = 0; i < max; i++) {
+
+ str += sprintf(str,"\t%#018lx\t%#018lx\t%#018lx\n",
pci_resource_start(pci_dev,i),
pci_resource_end(pci_dev,i),
pci_resource_flags(pci_dev,i));
@@ -62,6 +61,80 @@ pci_show_resources(struct device * dev,

static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL);

+static ssize_t
+pci_read_config(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 int size = 64;
+
+ printk("data %p, offset %lld, count %zd\n", buf, off, count);
+ /* Several chips lock up trying to read undefined config space */
+ if (capable(CAP_SYS_ADMIN)) {
+ size = 256;
+ } else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
+ size = 128;
+ }
+
+ printk("size = %d", size);
+
+ if (off > size)
+ return 0;
+ if (off + count > size) {
+ size -= off;
+ count = size;
+ } else {
+ size = count;
+ }
+
+ printk("data %p, offset %lld, count %zd\n", buf, off, count);
+
+ while (off & 3) {
+ unsigned char val;
+ pci_read_config_byte(dev, off, &val);
+ buf[off] = val;
+ off++;
+ if (--size == 0)
+ break;
+ }
+
+ while (size > 3) {
+ unsigned int val;
+ pci_read_config_dword(dev, off, &val);
+ buf[off] = val & 0xff;
+ buf[off + 1] = (val >> 8) & 0xff;
+ buf[off + 2] = (val >> 16) & 0xff;
+ buf[off + 3] = (val >> 24) & 0xff;
+ off += 4;
+ size -= 4;
+ }
+
+ while (size > 0) {
+ unsigned char val;
+ pci_read_config_byte(dev, off, &val);
+ buf[off] = val;
+ off++;
+ --size;
+ }
+
+ return count;
+}
+
+static ssize_t
+pci_write_config(struct kobject *kobj, char *buf, loff_t off, size_t count)
+{
+ return 0;
+}
+
+static struct bin_attribute pci_config_attr = {
+ .attr = {
+ .name = "config",
+ .mode = S_IRUGO | S_IWUSR,
+ },
+ .size = 256,
+ .read = pci_read_config,
+ .write = pci_write_config,
+};
+
void pci_create_sysfs_dev_files (struct pci_dev *pdev)
{
struct device *dev = &pdev->dev;
@@ -74,4 +147,5 @@ void pci_create_sysfs_dev_files (struct
device_create_file (dev, &dev_attr_class);
device_create_file (dev, &dev_attr_irq);
device_create_file (dev, &dev_attr_resource);
+ sysfs_create_bin_file(&dev->kobj, &pci_config_attr);
}

-- 
"It's not Hollywood.  War is real, war is primarily not about defeat or
victory, it is about death.  I've seen thousands and thousands of dead bodies.
Do you think I want to have an academic debate on this subject?" -- Robert Fisk
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/