From aaac1064de71c495d284b981d83f70d3bd445826 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Fri, 2 May 2008 08:52:37 +0000 Subject: add initial support for 2.6.25 SVN-Revision: 11005 --- .../902-usb_use_debugfs_instead_of_sysfs.patch | 363 +++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 target/linux/adm5120/patches-2.6.25/902-usb_use_debugfs_instead_of_sysfs.patch (limited to 'target/linux/adm5120/patches-2.6.25/902-usb_use_debugfs_instead_of_sysfs.patch') diff --git a/target/linux/adm5120/patches-2.6.25/902-usb_use_debugfs_instead_of_sysfs.patch b/target/linux/adm5120/patches-2.6.25/902-usb_use_debugfs_instead_of_sysfs.patch new file mode 100644 index 0000000000..ee14a247ae --- /dev/null +++ b/target/linux/adm5120/patches-2.6.25/902-usb_use_debugfs_instead_of_sysfs.patch @@ -0,0 +1,363 @@ +Index: linux-2.6.25/drivers/usb/host/adm5120.h +=================================================================== +--- linux-2.6.25.orig/drivers/usb/host/adm5120.h ++++ linux-2.6.25/drivers/usb/host/adm5120.h +@@ -431,6 +431,13 @@ struct admhcd { + #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ + #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ + // there are also chip quirks/bugs in init logic ++ ++#ifdef DEBUG ++ struct dentry *debug_dir; ++ struct dentry *debug_async; ++ struct dentry *debug_periodic; ++ struct dentry *debug_registers; ++#endif + }; + + /* convert between an hcd pointer and the corresponding ahcd_hcd */ +Index: linux-2.6.25/drivers/usb/host/adm5120-hcd.c +=================================================================== +--- linux-2.6.25.orig/drivers/usb/host/adm5120-hcd.c ++++ linux-2.6.25/drivers/usb/host/adm5120-hcd.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -799,6 +800,14 @@ static int __init admhc_hcd_mod_init(voi + pr_info("%s: block sizes: ed %Zd td %Zd\n", hcd_name, + sizeof (struct ed), sizeof (struct td)); + ++#ifdef DEBUG ++ admhc_debug_root = debugfs_create_dir("admhc", NULL); ++ if (!admhc_debug_root) { ++ ret = -ENOENT; ++ goto error_debug; ++ } ++#endif ++ + #ifdef PLATFORM_DRIVER + ret = platform_driver_register(&PLATFORM_DRIVER); + if (ret < 0) +@@ -811,6 +820,12 @@ static int __init admhc_hcd_mod_init(voi + platform_driver_unregister(&PLATFORM_DRIVER); + error_platform: + #endif ++ ++#ifdef DEBUG ++ debugfs_remove(admhc_debug_root); ++ admhc_debug_root = NULL; ++error_debug: ++#endif + return ret; + } + module_init(admhc_hcd_mod_init); +@@ -818,6 +833,9 @@ module_init(admhc_hcd_mod_init); + static void __exit admhc_hcd_mod_exit(void) + { + platform_driver_unregister(&PLATFORM_DRIVER); ++#ifdef DEBUG ++ debugfs_remove(admhc_debug_root); ++#endif + } + module_exit(admhc_hcd_mod_exit); + +Index: linux-2.6.25/drivers/usb/host/adm5120-dbg.c +=================================================================== +--- linux-2.6.25.orig/drivers/usb/host/adm5120-dbg.c ++++ linux-2.6.25/drivers/usb/host/adm5120-dbg.c +@@ -390,6 +390,42 @@ static inline void remove_debug_files(st + + #else + ++static int debug_async_open(struct inode *, struct file *); ++static int debug_periodic_open(struct inode *, struct file *); ++static int debug_registers_open(struct inode *, struct file *); ++static int debug_async_open(struct inode *, struct file *); ++static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*); ++static int debug_close(struct inode *, struct file *); ++ ++static const struct file_operations debug_async_fops = { ++ .owner = THIS_MODULE, ++ .open = debug_async_open, ++ .read = debug_output, ++ .release = debug_close, ++}; ++static const struct file_operations debug_periodic_fops = { ++ .owner = THIS_MODULE, ++ .open = debug_periodic_open, ++ .read = debug_output, ++ .release = debug_close, ++}; ++static const struct file_operations debug_registers_fops = { ++ .owner = THIS_MODULE, ++ .open = debug_registers_open, ++ .read = debug_output, ++ .release = debug_close, ++}; ++ ++static struct dentry *admhc_debug_root; ++ ++struct debug_buffer { ++ ssize_t (*fill_func)(struct debug_buffer *); /* fill method */ ++ struct device *dev; ++ struct mutex mutex; /* protect filling of buffer */ ++ size_t count; /* number of characters filled into buffer */ ++ char *page; ++}; ++ + static ssize_t + show_list(struct admhcd *ahcd, char *buf, size_t count, struct ed *ed) + { +@@ -455,8 +491,7 @@ show_list(struct admhcd *ahcd, char *buf + return count - size; + } + +-static ssize_t +-show_async(struct device *dev, struct device_attribute *attr, char *buf) ++static ssize_t fill_async_buffer(struct debug_buffer *buf) + { + struct usb_bus *bus; + struct usb_hcd *hcd; +@@ -464,24 +499,22 @@ show_async(struct device *dev, struct de + size_t temp; + unsigned long flags; + +- bus = dev_get_drvdata(dev); ++ bus = dev_get_drvdata(buf->dev); + hcd = bus_to_hcd(bus); + ahcd = hcd_to_admhcd(hcd); + + /* display control and bulk lists together, for simplicity */ + spin_lock_irqsave(&ahcd->lock, flags); +- temp = show_list(ahcd, buf, PAGE_SIZE, ahcd->ed_head); ++ temp = show_list(ahcd, buf->page, buf->count, ahcd->ed_head); + spin_unlock_irqrestore(&ahcd->lock, flags); + + return temp; + } +-static DEVICE_ATTR(async, S_IRUGO, show_async, NULL); + + + #define DBG_SCHED_LIMIT 64 + +-static ssize_t +-show_periodic(struct device *dev, struct device_attribute *attr, char *buf) ++static ssize_t fill_periodic_buffer(struct debug_buffer *buf) + { + struct usb_bus *bus; + struct usb_hcd *hcd; +@@ -496,10 +529,10 @@ show_periodic(struct device *dev, struct + return 0; + seen_count = 0; + +- bus = dev_get_drvdata(dev); ++ bus = dev_get_drvdata(buf->dev); + hcd = bus_to_hcd(bus); + ahcd = hcd_to_admhcd(hcd); +- next = buf; ++ next = buf->page; + size = PAGE_SIZE; + + temp = scnprintf(next, size, "size = %d\n", NUM_INTS); +@@ -574,13 +607,11 @@ show_periodic(struct device *dev, struct + + return PAGE_SIZE - size; + } +-static DEVICE_ATTR(periodic, S_IRUGO, show_periodic, NULL); + + + #undef DBG_SCHED_LIMIT + +-static ssize_t +-show_registers(struct device *dev, struct device_attribute *attr, char *buf) ++static ssize_t fill_registers_buffer(struct debug_buffer *buf) + { + struct usb_bus *bus; + struct usb_hcd *hcd; +@@ -591,11 +622,11 @@ show_registers(struct device *dev, struc + char *next; + u32 rdata; + +- bus = dev_get_drvdata(dev); ++ bus = dev_get_drvdata(buf->dev); + hcd = bus_to_hcd(bus); + ahcd = hcd_to_admhcd(hcd); + regs = ahcd->regs; +- next = buf; ++ next = buf->page; + size = PAGE_SIZE; + + spin_lock_irqsave(&ahcd->lock, flags); +@@ -656,27 +687,154 @@ done: + spin_unlock_irqrestore(&ahcd->lock, flags); + return PAGE_SIZE - size; + } +-static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL); + + +-static inline void create_debug_files (struct admhcd *ahcd) ++static struct debug_buffer *alloc_buffer(struct device *dev, ++ ssize_t (*fill_func)(struct debug_buffer *)) + { +- struct device *dev = admhcd_to_hcd(ahcd)->self.dev; +- int retval; ++ struct debug_buffer *buf; + +- retval = device_create_file(dev, &dev_attr_async); +- retval = device_create_file(dev, &dev_attr_periodic); +- retval = device_create_file(dev, &dev_attr_registers); +- admhc_dbg(ahcd, "created debug files\n"); ++ buf = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); ++ ++ if (buf) { ++ buf->dev = dev; ++ buf->fill_func = fill_func; ++ mutex_init(&buf->mutex); ++ } ++ ++ return buf; ++} ++ ++static int fill_buffer(struct debug_buffer *buf) ++{ ++ int ret = 0; ++ ++ if (!buf->page) ++ buf->page = (char *)get_zeroed_page(GFP_KERNEL); ++ ++ if (!buf->page) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ ret = buf->fill_func(buf); ++ ++ if (ret >= 0) { ++ buf->count = ret; ++ ret = 0; ++ } ++ ++out: ++ return ret; ++} ++ ++static ssize_t debug_output(struct file *file, char __user *user_buf, ++ size_t len, loff_t *offset) ++{ ++ struct debug_buffer *buf = file->private_data; ++ int ret = 0; ++ ++ mutex_lock(&buf->mutex); ++ if (buf->count == 0) { ++ ret = fill_buffer(buf); ++ if (ret != 0) { ++ mutex_unlock(&buf->mutex); ++ goto out; ++ } ++ } ++ mutex_unlock(&buf->mutex); ++ ++ ret = simple_read_from_buffer(user_buf, len, offset, ++ buf->page, buf->count); ++ ++out: ++ return ret; ++} ++ ++static int debug_close(struct inode *inode, struct file *file) ++{ ++ struct debug_buffer *buf = file->private_data; ++ ++ if (buf) { ++ if (buf->page) ++ free_page((unsigned long)buf->page); ++ kfree(buf); ++ } ++ ++ return 0; + } + +-static inline void remove_debug_files (struct admhcd *ahcd) ++static int debug_async_open(struct inode *inode, struct file *file) + { +- struct device *dev = admhcd_to_hcd(ahcd)->self.dev; ++ file->private_data = alloc_buffer(inode->i_private, fill_async_buffer); ++ ++ return file->private_data ? 0 : -ENOMEM; ++} ++ ++static int debug_periodic_open(struct inode *inode, struct file *file) ++{ ++ file->private_data = alloc_buffer(inode->i_private, ++ fill_periodic_buffer); ++ ++ return file->private_data ? 0 : -ENOMEM; ++} + +- device_remove_file(dev, &dev_attr_async); +- device_remove_file(dev, &dev_attr_periodic); +- device_remove_file(dev, &dev_attr_registers); ++static int debug_registers_open(struct inode *inode, struct file *file) ++{ ++ file->private_data = alloc_buffer(inode->i_private, ++ fill_registers_buffer); ++ ++ return file->private_data ? 0 : -ENOMEM; ++} ++ ++static inline void create_debug_files(struct admhcd *ahcd) ++{ ++ struct usb_bus *bus = &admhcd_to_hcd(ahcd)->self; ++ struct device *dev = bus->dev; ++ ++ ahcd->debug_dir = debugfs_create_dir(bus->bus_name, admhc_debug_root); ++ if (!ahcd->debug_dir) ++ goto dir_error; ++ ++ ahcd->debug_async = debugfs_create_file("async", S_IRUGO, ++ ahcd->debug_dir, dev, ++ &debug_async_fops); ++ if (!ahcd->debug_async) ++ goto async_error; ++ ++ ahcd->debug_periodic = debugfs_create_file("periodic", S_IRUGO, ++ ahcd->debug_dir, dev, ++ &debug_periodic_fops); ++ if (!ahcd->debug_periodic) ++ goto periodic_error; ++ ++ ahcd->debug_registers = debugfs_create_file("registers", S_IRUGO, ++ ahcd->debug_dir, dev, ++ &debug_registers_fops); ++ if (!ahcd->debug_registers) ++ goto registers_error; ++ ++ admhc_dbg(ahcd, "created debug files\n"); ++ return; ++ ++registers_error: ++ debugfs_remove(ahcd->debug_periodic); ++periodic_error: ++ debugfs_remove(ahcd->debug_async); ++async_error: ++ debugfs_remove(ahcd->debug_dir); ++dir_error: ++ ahcd->debug_periodic = NULL; ++ ahcd->debug_async = NULL; ++ ahcd->debug_dir = NULL; ++} ++ ++static inline void remove_debug_files(struct admhcd *ahcd) ++{ ++ debugfs_remove(ahcd->debug_registers); ++ debugfs_remove(ahcd->debug_periodic); ++ debugfs_remove(ahcd->debug_async); ++ debugfs_remove(ahcd->debug_dir); + } + + #endif -- cgit v1.2.3