--- zzzz-none-000/linux-2.6.13.1/kernel/resource.c 2005-09-10 02:42:58.000000000 +0000 +++ ohio-7170-487/linux-2.6.13.1/kernel/resource.c 2007-09-11 07:58:42.000000000 +0000 @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -23,22 +24,117 @@ struct resource ioport_resource = { .name = "PCI IO", - .start = 0x0000, + .start = 0, .end = IO_SPACE_LIMIT, .flags = IORESOURCE_IO, }; - EXPORT_SYMBOL(ioport_resource); struct resource iomem_resource = { .name = "PCI mem", - .start = 0UL, - .end = ~0UL, + .start = 0, + .end = -1, .flags = IORESOURCE_MEM, }; - EXPORT_SYMBOL(iomem_resource); +#ifdef CONFIG_MIPS_UR8 +struct resource nwss_tx_queue_resource = { + .name = "NWSS Tx Queue", + .start = 0, + .end = 17, + .flags = IORESOURCE_DMA +}; +EXPORT_SYMBOL(nwss_tx_queue_resource); + +struct resource nwss_tx_completion_queue_resource = { + .name = "NWSS Tx Completion Queue", + .start = 0, + .end = 3, + .flags = IORESOURCE_DMA +}; +EXPORT_SYMBOL(nwss_tx_completion_queue_resource); + +struct resource nwss_rx_queue_resource = { + .name = "NWSS Rx Queue", + .start = 0, + .end = 7, + .flags = IORESOURCE_DMA +}; +EXPORT_SYMBOL(nwss_rx_queue_resource); + +struct resource nwss_free_buffer_queue_resource = { + .name = "NWSS Free Buffer Descriptor Queue", + .start = 0, + .end = 3, + .flags = IORESOURCE_DMA +}; +EXPORT_SYMBOL(nwss_free_buffer_queue_resource); + +struct resource nwss_free_packet_queue_resource = { + .name = "NWSS Free Packet Descriptor Queue", + .start = 0, + .end = 1, + .flags = IORESOURCE_DMA +}; +EXPORT_SYMBOL(nwss_free_packet_queue_resource); + +struct resource gpio_resource = { + .name = "gpio", + .start = 0, + .end = 40, + .flags = IORESOURCE_IO +}; +EXPORT_SYMBOL(gpio_resource); + +struct resource timer_resource = { + .name = "timer", + .start = 0, + .end = 3, + .flags = IORESOURCE_IO +}; +EXPORT_SYMBOL(timer_resource); +#endif /*--- #ifdef CONFIG_MIPS_UR8 ---*/ + +#if defined(CONFIG_ARCH_DAVINCI) +extern int alloc_gpio_resource(unsigned int start, unsigned int end, unsigned long flags); + +struct resource gpio_resource = { + .name = "gpio", + .start = 0, + .end = 63, + .flags = IORESOURCE_IO, + .alloc = alloc_gpio_resource +}; +EXPORT_SYMBOL(gpio_resource); + +struct resource timer_resource = { + .name = "timer", + .start = 0, + .end = 3, + .flags = IORESOURCE_IO +}; +EXPORT_SYMBOL(timer_resource); +#endif /*--- #if defined(CONFIG_ARCH_DAVINCI) ---*/ + +#if defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) +struct resource gpio_resource = { + .name = "gpio", + .start = 0, + .end = 31, + .flags = IORESOURCE_IO +}; +EXPORT_SYMBOL(gpio_resource); + +struct resource timer_resource = { + .name = "timer", + .start = 0, + .end = 1, + .flags = IORESOURCE_IO +}; +EXPORT_SYMBOL(timer_resource); +#endif /*--- #if defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) ---*/ + static DEFINE_RWLOCK(resource_lock); #ifdef CONFIG_PROC_FS @@ -132,22 +228,196 @@ .release = seq_release, }; +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +#if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) +static int iogpio_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &gpio_resource; + } + return res; +} + +static struct file_operations proc_gpio_operations = { + .open = iogpio_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static int iotimer_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &timer_resource; + } + return res; +} + +static struct file_operations proc_timer_operations = { + .open = iotimer_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif /*--- #if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) ---*/ + +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +#ifdef CONFIG_MIPS_UR8 +/*------------------------------------------------------------------------------------------*\ +\*------------------------------------------------------------------------------------------*/ +char *proc_nwss_names[] = { + "nwss_tx_queue", + "nwss_tx_completion_queue", + "nwss_rx_queue", + "nwss_free_buffer_queue", + "nwss_free_packet_queue", + NULL; +}; + +static int nwss_tx_queue_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &nwss_tx_queue_resource; + } + return res; +} + +static int nwss_tx_completion_queue_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &nwss_tx_completion_queue_resource; + } + return res; +} + +static int nwss_rx_queue_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &nwss_rx_queue_resource; + } + return res; +} + +static int nwss_free_buffer_queue_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &nwss_free_buffer_queue_resource; + } + return res; +} + +static int nwss_free_packet_queue_open(struct inode *inode, struct file *file) +{ + int res = seq_open(file, &resource_op); + if (!res) { + struct seq_file *m = file->private_data; + m->private = &nwss_free_packet_queue_resource; + } + return res; +} + +static struct file_operations proc_nwss_operations[] = { + { + .open = nsww_tx_queue_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + }, + { + .open = nsww_tx_completion_queue_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + }, + { + .open = nsww_rx_queue_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + }, + { + .open = nsww_free_buffer_queue_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + }, + { + .open = nsww_free_packet_queue_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + } +}; +#endif /*--- #ifdef CONFIG_MIPS_UR8 ---*/ + static int __init ioresources_init(void) { struct proc_dir_entry *entry; +#ifdef CONFIG_MIPS_UR8 + int i; +#endif + /*--------------------------------------------------------------------------------------*\ + \*--------------------------------------------------------------------------------------*/ entry = create_proc_entry("ioports", 0, NULL); if (entry) entry->proc_fops = &proc_ioports_operations; + + /*--------------------------------------------------------------------------------------*\ + \*--------------------------------------------------------------------------------------*/ entry = create_proc_entry("iomem", 0, NULL); if (entry) entry->proc_fops = &proc_iomem_operations; + +#ifdef CONFIG_MIPS_UR8 + /*--------------------------------------------------------------------------------------*\ + nwss_tx_queue_resource + nwss_tx_completion_queue_resource + nwss_rx_queue_resource + nwss_free_buffer_queue_resource + nwss_free_packet_queue_resource + \*--------------------------------------------------------------------------------------*/ + for(i = 0 ; i < sizeof() / sizeof() ; i++) { + entry = create_proc_entry(proc_nwss_names[i], 0, NULL); + if (entry) + entry->proc_fops = &proc_nwss_operations[i]; + } +#endif /*--- #ifdef CONFIG_MIPS_UR8 ---*/ +#if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) + /*--------------------------------------------------------------------------------------*\ + \*--------------------------------------------------------------------------------------*/ + entry = create_proc_entry("gpio", 0, NULL); + if (entry) + entry->proc_fops = &proc_gpio_operations; + + /*--------------------------------------------------------------------------------------*\ + \*--------------------------------------------------------------------------------------*/ + entry = create_proc_entry("hw_timer", 0, NULL); + if (entry) + entry->proc_fops = &proc_timer_operations; +#endif /*--- #if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) || defined(CONFIG_MIPS_OHIO) || defined(CONFIG_MIPS_AR7) ---*/ return 0; } __initcall(ioresources_init); #endif /* CONFIG_PROC_FS */ +static int __release_resource(struct resource *old); + /* Return the conflict entry if you can't request it */ static struct resource * __request_resource(struct resource *root, struct resource *new) { @@ -173,6 +443,14 @@ p = &tmp->sibling; if (tmp->end < start) continue; +#if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) + if(root->alloc) { + if(root->alloc(new->start, new->end, new->flags)) { + __release_resource(new); + return NULL; + } + } +#endif /*--- #if defined(CONFIG_MIPS_UR8) || defined(CONFIG_ARCH_DAVINCI) ---*/ return tmp; } } @@ -196,6 +474,13 @@ return -EINVAL; } +/** + * request_resource - request and reserve an I/O or memory resource + * @root: root resource descriptor + * @new: resource descriptor desired by caller + * + * Returns 0 for success, negative error code on error. + */ int request_resource(struct resource *root, struct resource *new) { struct resource *conflict; @@ -208,6 +493,15 @@ EXPORT_SYMBOL(request_resource); +/** + * ____request_resource - reserve a resource, with resource conflict returned + * @root: root resource descriptor + * @new: resource descriptor desired by caller + * + * Returns: + * On success, NULL is returned. + * On error, a pointer to the conflicting resource is returned. + */ struct resource *____request_resource(struct resource *root, struct resource *new) { struct resource *conflict; @@ -220,6 +514,10 @@ EXPORT_SYMBOL(____request_resource); +/** + * release_resource - release a previously reserved resource + * @old: resource pointer + */ int release_resource(struct resource *old) { int retval; @@ -232,13 +530,13 @@ EXPORT_SYMBOL(release_resource); + /* * Find empty slot in the resource tree given range and alignment. */ static int find_resource(struct resource *root, struct resource *new, - unsigned long size, - unsigned long min, unsigned long max, - unsigned long align, + unsigned long size, unsigned long min, + unsigned long max, unsigned long align, void (*alignf)(void *, struct resource *, unsigned long, unsigned long), void *alignf_data) @@ -278,13 +576,20 @@ return -EBUSY; } -/* - * Allocate empty slot in the resource tree given range and alignment. +/** + * allocate_resource - allocate empty slot in the resource tree given range & alignment + * @root: root resource descriptor + * @new: resource descriptor desired by caller + * @size: requested resource region size + * @min: minimum size to allocate + * @max: maximum size to allocate + * @align: alignment requested, in bytes + * @alignf: alignment function, optional, called if not NULL + * @alignf_data: arbitrary data to pass to the @alignf function */ int allocate_resource(struct resource *root, struct resource *new, - unsigned long size, - unsigned long min, unsigned long max, - unsigned long align, + unsigned long size, unsigned long min, + unsigned long max, unsigned long align, void (*alignf)(void *, struct resource *, unsigned long, unsigned long), void *alignf_data) @@ -308,12 +613,11 @@ * * Returns 0 on success, -EBUSY if the resource can't be inserted. * - * This function is equivalent of request_resource when no conflict + * This function is equivalent to request_resource when no conflict * happens. If a conflict happens, and the conflicting resources * entirely fit within the range of the new resource, then the new - * resource is inserted and the conflicting resources become childs of - * the new resource. Otherwise the new resource becomes the child of - * the conflicting resource + * resource is inserted and the conflicting resources become children of + * the new resource. */ int insert_resource(struct resource *parent, struct resource *new) { @@ -321,20 +625,21 @@ struct resource *first, *next; write_lock(&resource_lock); - begin: - result = 0; +begin: + result = 0; first = __request_resource(parent, new); if (!first) goto out; - + result = -EBUSY; if (first == parent) goto out; - + /* Resource fully contained by the clashing resource? Recurse into it */ if (first->start <= new->start && first->end >= new->end) { parent = first; goto begin; + } for (next = first; ; next = next->sibling) { @@ -371,12 +676,15 @@ return result; } -EXPORT_SYMBOL(insert_resource); - -/* +/** + * adjust_resource - modify a resource's start and size + * @res: resource to modify + * @start: new start value + * @size: new size + * * Given an existing resource, change its start and size to match the - * arguments. Returns -EBUSY if it can't fit. Existing children of - * the resource are assumed to be immutable. + * arguments. Returns 0 on success, -EBUSY if it can't fit. + * Existing children of the resource are assumed to be immutable. */ int adjust_resource(struct resource *res, unsigned long start, unsigned long size) { @@ -422,13 +730,23 @@ * Note how this, unlike the above, knows about * the IO flag meanings (busy etc). * - * Request-region creates a new busy region. + * request_region creates a new busy region. * - * Check-region returns non-zero if the area is already busy + * check_region returns non-zero if the area is already busy. * - * Release-region releases a matching busy region. + * release_region releases a matching busy region. + */ + +/** + * __request_region - create a new busy resource region + * @parent: parent resource descriptor + * @start: resource start address + * @n: resource region size + * @name: reserving caller's ID string */ -struct resource * __request_region(struct resource *parent, unsigned long start, unsigned long n, const char *name) +struct resource * __request_region(struct resource *parent, + unsigned long start, unsigned long n, + const char *name) { struct resource *res = kmalloc(sizeof(*res), GFP_KERNEL); @@ -462,10 +780,25 @@ } return res; } - EXPORT_SYMBOL(__request_region); -int __deprecated __check_region(struct resource *parent, unsigned long start, unsigned long n) +/** + * __check_region - check if a resource region is busy or free + * @parent: parent resource descriptor + * @start: resource start address + * @n: resource region size + * + * Returns 0 if the region is free at the moment it is checked, + * returns %-EBUSY if the region is busy. + * + * NOTE: + * This function is deprecated because its use is racy. + * Even if it returns 0, a subsequent call to request_region() + * may fail because another driver etc. just allocated the region. + * Do NOT use it. It will be removed from the kernel. + */ +int __check_region(struct resource *parent, unsigned long start, + unsigned long n) { struct resource * res; @@ -477,10 +810,18 @@ kfree(res); return 0; } - EXPORT_SYMBOL(__check_region); -void __release_region(struct resource *parent, unsigned long start, unsigned long n) +/** + * __release_region - release a previously reserved resource region + * @parent: parent resource descriptor + * @start: resource start address + * @n: resource region size + * + * The described resource region must match a currently busy region. + */ +void __release_region(struct resource *parent, unsigned long start, + unsigned long n) { struct resource **p; unsigned long end; @@ -512,9 +853,10 @@ write_unlock(&resource_lock); - printk(KERN_WARNING "Trying to free nonexistent resource <%08lx-%08lx>\n", start, end); + printk(KERN_WARNING "Trying to free nonexistent resource " + "<%016lx-%016lx>\n", (unsigned long)start, + (unsigned long)end); } - EXPORT_SYMBOL(__release_region); /*