===== drivers/pci/pci-sysfs.c 1.14 vs edited ===== --- 1.14/drivers/pci/pci-sysfs.c 2004-12-21 11:28:57 -08:00 +++ edited/drivers/pci/pci-sysfs.c 2004-12-21 14:03:35 -08:00 @@ -179,6 +179,76 @@ return count; } +#ifdef HAVE_PCI_LEGACY +/** + * pci_read_legacy_io - read byte(s) from legacy I/O port space + * @kobj: kobject corresponding to file to read from + * @buf: buffer to store results + * @off: offset into legacy I/O port space + * @count: number of bytes to read + * + * Reads 1, 2, or 4 bytes from legacy I/O port space using an arch specific + * callback routine (pci_legacy_read). + */ +ssize_t +pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct pci_bus *bus = to_pci_bus(container_of(kobj, + struct class_device, + kobj)); + + /* Only support 1, 2 or 4 byte accesses */ + if (count != 1 && count != 2 && count != 4) + return -EINVAL; + + return pci_legacy_read(bus, off, (u32 *)buf, count); +} + +/** + * pci_write_legacy_io - write byte(s) to legacy I/O port space + * @kobj: kobject corresponding to file to read from + * @buf: buffer containing value to be written + * @off: offset into legacy I/O port space + * @count: number of bytes to write + * + * Writes 1, 2, or 4 bytes from legacy I/O port space using an arch specific + * callback routine (pci_legacy_write). + */ +ssize_t +pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count) +{ + struct pci_bus *bus = to_pci_bus(container_of(kobj, + struct class_device, + kobj)); + /* Only support 1, 2 or 4 byte accesses */ + if (count != 1 && count != 2 && count != 4) + return -EINVAL; + + return pci_legacy_write(bus, off, *(u32 *)buf, count); +} + +/** + * pci_mmap_legacy_mem - map legacy PCI memory into user memory space + * @kobj: kobject corresponding to device to be mapped + * @attr: struct bin_attribute for this file + * @vma: struct vm_area_struct passed to mmap + * + * Uses an arch specific callback, pci_mmap_legacy_page_range, to mmap + * legacy memory space (first meg of bus space) into application virtual + * memory space. + */ +int +pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, + struct vm_area_struct *vma) +{ + struct pci_bus *bus = to_pci_bus(container_of(kobj, + struct class_device, + kobj)); + + return pci_mmap_legacy_page_range(bus, vma); +} +#endif /* HAVE_PCI_LEGACY */ + #ifdef HAVE_PCI_MMAP /** * pci_mmap_resource - map a PCI resource into user memory space ===== drivers/pci/probe.c 1.72 vs edited ===== --- 1.72/drivers/pci/probe.c 2004-11-11 12:53:33 -08:00 +++ edited/drivers/pci/probe.c 2004-12-21 13:58:10 -08:00 @@ -764,6 +764,42 @@ return max; } +#ifdef HAVE_PCI_LEGACY +/** + * pci_create_legacy_files - create legacy I/O port and memory files + * @b: bus to create files under + * + * Some platforms allow access to legacy I/O port and ISA memory space on + * a per-bus basis. This routine creates the files and ties them into + * their associated read, write and mmap files from pci-sysfs.c + */ +static void pci_create_legacy_files(struct pci_bus *b) +{ + b->legacy_io = kmalloc(sizeof(struct bin_attribute) * 2, + GFP_ATOMIC); + if (b->legacy_io) { + b->legacy_io->attr.name = "legacy_io"; + b->legacy_io->size = 0xffff; + b->legacy_io->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_io->attr.owner = THIS_MODULE; + b->legacy_io->read = pci_read_legacy_io; + b->legacy_io->write = pci_write_legacy_io; + class_device_create_bin_file(&b->class_dev, b->legacy_io); + + /* Allocated above after the legacy_io struct */ + b->legacy_mem = b->legacy_io + 1; + b->legacy_mem->attr.name = "legacy_mem"; + b->legacy_mem->size = 1024*1024; + b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR; + b->legacy_mem->attr.owner = THIS_MODULE; + b->legacy_mem->mmap = pci_mmap_legacy_mem; + class_device_create_bin_file(&b->class_dev, b->legacy_mem); + } +} +#else /* !HAVE_PCI_LEGACY */ +static inline void pci_create_legacy_files(struct pci_bus *bus) { return; } +#endif /* HAVE_PCI_LEGACY */ + struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { int error; @@ -807,6 +843,9 @@ error = class_device_create_file(&b->class_dev, &class_device_attr_cpuaffinity); if (error) goto class_dev_create_file_err; + + /* Create legacy_io and legacy_mem files for this bus */ + pci_create_legacy_files(b); error = sysfs_create_link(&b->class_dev.kobj, &b->bridge->kobj, "bridge"); if (error) ===== include/linux/pci.h 1.143 vs edited ===== --- 1.143/include/linux/pci.h 2004-12-21 11:21:50 -08:00 +++ edited/include/linux/pci.h 2004-12-21 12:32:38 -08:00 @@ -594,6 +594,8 @@ unsigned short pad2; struct device *bridge; struct class_device class_dev; + struct bin_attribute *legacy_io; /* legacy I/O for this bus */ + struct bin_attribute *legacy_mem; /* legacy mem */ }; #define pci_bus_b(n) list_entry(n, struct pci_bus, node)