From 987d24018dc83d27e491674c50ff2272f51eb719 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Tue, 15 Nov 2005 23:28:20 +0000 Subject: [MTD] CFI: Use 16-bit access to autoselect/read device id data Recent models of Intel/Sharp and Spansion CFI flash now have significant bits in the upper byte of device ID codes, read via what Spansion calls "autoselect" and Intel calls "read device identifier". Currently these values are truncated to the low 8 bits in the mtd data structures, as all CFI read query info has previously been read one byte at a time. Add a new method for reading 16-bit info, currently just manufacturer and device codes; datasheets hint at future uses for upper bytes in other fields. Signed-off-by: Todd Poynor Signed-off-by: Thomas Gleixner --- include/linux/mtd/cfi.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 3c9ea4b7adda..23a568910341 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -1,7 +1,7 @@ /* Common Flash Interface structures * See http://support.intel.com/design/flash/technote/index.htm - * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $ + * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $ */ #ifndef __MTD_CFI_H__ @@ -426,6 +426,22 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) } } +static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) +{ + map_word val = map_read(map, addr); + + if (map_bankwidth_is_1(map)) { + return val.x[0] & 0xff; + } else if (map_bankwidth_is_2(map)) { + return cfi16_to_cpu(val.x[0]); + } else { + /* No point in a 64-bit byteswap since that would just be + swapping the responses from different chips, and we are + only interested in one chip (a representative sample) */ + return cfi32_to_cpu(val.x[0]); + } +} + static inline void cfi_udelay(int us) { if (us >= 1000) { -- cgit v1.2.3 From 238f58d898df941aa9d1cb390fb27ff4febe8965 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 13:01:56 -0800 Subject: Support strange discontiguous PFN remappings These get created by some drivers that don't generally even want a pfn remapping at all, but would really mostly prefer to just map pages they've allocated individually instead. For now, create a helper function that turns such an incomplete PFN remapping call into a loop that does that explicit mapping. In the long run we almost certainly want to export a totally different interface for that, though. Signed-off-by: Linus Torvalds --- include/linux/mm.h | 1 + mm/memory.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 6a75a7a78bf1..74f90d7eb5ef 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -163,6 +163,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ +#define VM_INCOMPLETE 0x02000000 /* Strange partial PFN mapping marker */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS diff --git a/mm/memory.c b/mm/memory.c index 74839b3a3999..990e7dc666f8 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1146,6 +1146,95 @@ int zeromap_page_range(struct vm_area_struct *vma, return err; } +/* + * This is the old fallback for page remapping. + * + * For historical reasons, it only allows reserved pages. Only + * old drivers should use this, and they needed to mark their + * pages reserved for the old functions anyway. + */ +static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot) +{ + int retval; + pgd_t * pgd; + pud_t * pud; + pmd_t * pmd; + pte_t * pte; + spinlock_t *ptl; + + retval = -EINVAL; + if (PageAnon(page) || !PageReserved(page)) + goto out; + retval = -ENOMEM; + flush_dcache_page(page); + pgd = pgd_offset(mm, addr); + pud = pud_alloc(mm, pgd, addr); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + if (!pte) + goto out; + retval = -EBUSY; + if (!pte_none(*pte)) + goto out_unlock; + + /* Ok, finally just insert the thing.. */ + get_page(page); + inc_mm_counter(mm, file_rss); + page_add_file_rmap(page); + set_pte_at(mm, addr, pte, mk_pte(page, prot)); + + retval = 0; +out_unlock: + pte_unmap_unlock(pte, ptl); +out: + return retval; +} + +/* + * Somebody does a pfn remapping that doesn't actually work as a vma. + * + * Do it as individual pages instead, and warn about it. It's bad form, + * and very inefficient. + */ +static int incomplete_pfn_remap(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + unsigned long pfn, pgprot_t prot) +{ + static int warn = 10; + struct page *page; + int retval; + + if (!(vma->vm_flags & VM_INCOMPLETE)) { + if (warn) { + warn--; + printk("%s does an incomplete pfn remapping", current->comm); + dump_stack(); + } + } + vma->vm_flags |= VM_INCOMPLETE | VM_IO | VM_RESERVED; + + if (start < vma->vm_start || end > vma->vm_end) + return -EINVAL; + + if (!pfn_valid(pfn)) + return -EINVAL; + + retval = 0; + page = pfn_to_page(pfn); + while (start < end) { + retval = insert_page(vma->vm_mm, start, page, prot); + if (retval < 0) + break; + start += PAGE_SIZE; + page++; + } + return retval; +} + /* * maps a range of physical memory into the requested pages. the old * mappings are removed. any references to nonexistent pages results @@ -1220,6 +1309,9 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, struct mm_struct *mm = vma->vm_mm; int err; + if (addr != vma->vm_start || end != vma->vm_end) + return incomplete_pfn_remap(vma, addr, end, pfn, prot); + /* * Physically remapped pages are special. Tell the * rest of the world about it: -- cgit v1.2.3 From c9cfcddfd65735437a4cb8563d6b66a6da8a5ed6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 14:03:14 -0800 Subject: VM: add common helper function to create the page tables This logic was duplicated four times, for no good reason. Signed-off-by: Linus Torvalds --- fs/exec.c | 12 +----------- include/linux/mm.h | 2 ++ mm/fremap.c | 24 ++---------------------- mm/memory.c | 26 ++++++++++++++------------ 4 files changed, 19 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/fs/exec.c b/fs/exec.c index 1f8a9fd2c9ed..22533cce0611 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -306,9 +306,6 @@ void install_arg_page(struct vm_area_struct *vma, struct page *page, unsigned long address) { struct mm_struct *mm = vma->vm_mm; - pgd_t * pgd; - pud_t * pud; - pmd_t * pmd; pte_t * pte; spinlock_t *ptl; @@ -316,14 +313,7 @@ void install_arg_page(struct vm_area_struct *vma, goto out; flush_dcache_page(page); - pgd = pgd_offset(mm, address); - pud = pud_alloc(mm, pgd, address); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, address); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, address, &ptl); + pte = get_locked_pte(mm, address, &ptl); if (!pte) goto out; if (!pte_none(*pte)) { diff --git a/include/linux/mm.h b/include/linux/mm.h index 74f90d7eb5ef..0e73f1539d08 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -742,6 +742,8 @@ struct shrinker; extern struct shrinker *set_shrinker(int, shrinker_t); extern void remove_shrinker(struct shrinker *shrinker); +extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); + int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address); int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address); int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address); diff --git a/mm/fremap.c b/mm/fremap.c index f851775e09c2..9f381e58bf44 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -55,20 +55,10 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma, pgoff_t size; int err = -ENOMEM; pte_t *pte; - pmd_t *pmd; - pud_t *pud; - pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; @@ -110,20 +100,10 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, { int err = -ENOMEM; pte_t *pte; - pmd_t *pmd; - pud_t *pud; - pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; diff --git a/mm/memory.c b/mm/memory.c index 990e7dc666f8..74f95ae0510b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1146,6 +1146,18 @@ int zeromap_page_range(struct vm_area_struct *vma, return err; } +pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) +{ + pgd_t * pgd = pgd_offset(mm, addr); + pud_t * pud = pud_alloc(mm, pgd, addr); + if (pud) { + pmd_t * pmd = pmd_alloc(mm, pgd, addr); + if (pmd) + return pte_alloc_map_lock(mm, pmd, addr, ptl); + } + return NULL; +} + /* * This is the old fallback for page remapping. * @@ -1156,10 +1168,7 @@ int zeromap_page_range(struct vm_area_struct *vma, static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot) { int retval; - pgd_t * pgd; - pud_t * pud; - pmd_t * pmd; - pte_t * pte; + pte_t *pte; spinlock_t *ptl; retval = -EINVAL; @@ -1167,14 +1176,7 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa goto out; retval = -ENOMEM; flush_dcache_page(page); - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; retval = -EBUSY; -- cgit v1.2.3 From c219750b2e667f4f79f4d8faca5057dad793db87 Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:13:55 -0800 Subject: [ATM]: atm_pcr_goal() doesn't modify its argument's contents -- mark it as const Signed-off-by: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- include/linux/atmdev.h | 2 +- net/atm/atm_misc.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index e7d0593bb576..37e5ee485399 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -468,7 +468,7 @@ static inline void atm_dev_put(struct atm_dev *dev) int atm_charge(struct atm_vcc *vcc,int truesize); struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, gfp_t gfp_flags); -int atm_pcr_goal(struct atm_trafprm *tp); +int atm_pcr_goal(const struct atm_trafprm *tp); void vcc_release_async(struct atm_vcc *vcc, int reply); diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c index 223c7ad5bd0f..02cc7e71efea 100644 --- a/net/atm/atm_misc.c +++ b/net/atm/atm_misc.c @@ -74,11 +74,14 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, */ -int atm_pcr_goal(struct atm_trafprm *tp) +int atm_pcr_goal(const struct atm_trafprm *tp) { - if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr; - if (tp->min_pcr && !tp->pcr) return tp->min_pcr; - if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr; + if (tp->pcr && tp->pcr != ATM_MAX_PCR) + return -tp->pcr; + if (tp->min_pcr && !tp->pcr) + return tp->min_pcr; + if (tp->max_pcr != ATM_MAX_PCR) + return -tp->max_pcr; return 0; } -- cgit v1.2.3 From 5045b6d34c6a9efa4a8a1815265ca9fcf44d6a7c Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Tue, 29 Nov 2005 16:15:38 -0800 Subject: [ATM]: linux/config.h only needed for #ifdef __KERNEL__ section Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- include/linux/atmdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 37e5ee485399..8fadb073c834 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -7,7 +7,6 @@ #define LINUX_ATMDEV_H -#include #include #include #include @@ -210,6 +209,7 @@ struct atm_cirange { #ifdef __KERNEL__ +#include #include /* wait_queue_head_t */ #include /* struct timeval */ #include -- cgit v1.2.3 From 64bf69ddff7637b7ed7acf9b2a823cc0ee519439 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 29 Nov 2005 16:16:41 -0800 Subject: [ATM]: deregistration removes device from atm_devs list immediately atm_dev_deregister() removes device from atm_dev list immediately to prevent operations on a phantom device. Decision to free device based only on ->refcnt now. Remove shutdown_atm_dev() use atm_dev_deregister() instead. atm_dev_deregister() also asynchronously releases all vccs related to device. Signed-off-by: Stanislaw Gruszka Signed-off-by: Chas Williams Signed-off-by: David S. Miller --- drivers/atm/atmtcp.c | 20 ++------------------ drivers/usb/atm/usbatm.c | 4 ++-- include/linux/atmdev.h | 14 +++++++------- net/atm/common.c | 30 +++++++++++++++++++++++++++--- net/atm/common.h | 2 ++ net/atm/resources.c | 39 ++++++++++++--------------------------- 6 files changed, 52 insertions(+), 57 deletions(-) (limited to 'include/linux') diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 57f1810fdccd..fc518d85543d 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -246,10 +246,6 @@ static void atmtcp_c_close(struct atm_vcc *vcc) { struct atm_dev *atmtcp_dev; struct atmtcp_dev_data *dev_data; - struct sock *s; - struct hlist_node *node; - struct atm_vcc *walk; - int i; atmtcp_dev = (struct atm_dev *) vcc->dev_data; dev_data = PRIV(atmtcp_dev); @@ -257,20 +253,8 @@ static void atmtcp_c_close(struct atm_vcc *vcc) if (dev_data->persist) return; atmtcp_dev->dev_data = NULL; kfree(dev_data); - shutdown_atm_dev(atmtcp_dev); + atm_dev_deregister(atmtcp_dev); vcc->dev_data = NULL; - read_lock(&vcc_sklist_lock); - for(i = 0; i < VCC_HTABLE_SIZE; ++i) { - struct hlist_head *head = &vcc_hash[i]; - - sk_for_each(s, node, head) { - walk = atm_sk(s); - if (walk->dev != atmtcp_dev) - continue; - wake_up(s->sk_sleep); - } - } - read_unlock(&vcc_sklist_lock); module_put(THIS_MODULE); } @@ -450,7 +434,7 @@ static int atmtcp_remove_persistent(int itf) if (PRIV(dev)->vcc) return 0; kfree(dev_data); atm_dev_put(dev); - shutdown_atm_dev(dev); + atm_dev_deregister(dev); return 0; } diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index c466739428b2..2e6593e6c1bd 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -879,7 +879,7 @@ static int usbatm_atm_init(struct usbatm_data *instance) fail: instance->atm_dev = NULL; - shutdown_atm_dev(atm_dev); /* usbatm_atm_dev_close will eventually be called */ + atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ return ret; } @@ -1164,7 +1164,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf) /* ATM finalize */ if (instance->atm_dev) - shutdown_atm_dev(instance->atm_dev); + atm_dev_deregister(instance->atm_dev); usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ } diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 8fadb073c834..b203ea82a0a8 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -274,7 +274,7 @@ enum { enum { - ATM_DF_CLOSE, /* close device when last VCC is closed */ + ATM_DF_REMOVED, /* device was removed from atm_devs list */ }; @@ -415,7 +415,6 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, int number,unsigned long *flags); /* number == -1: pick first available */ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); -void shutdown_atm_dev(struct atm_dev *dev); void vcc_insert_socket(struct sock *sk); @@ -457,11 +456,12 @@ static inline void atm_dev_hold(struct atm_dev *dev) static inline void atm_dev_put(struct atm_dev *dev) { - atomic_dec(&dev->refcnt); - - if ((atomic_read(&dev->refcnt) == 1) && - test_bit(ATM_DF_CLOSE,&dev->flags)) - shutdown_atm_dev(dev); + if (atomic_dec_and_test(&dev->refcnt)) { + BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags)); + if (dev->ops->dev_close) + dev->ops->dev_close(dev); + kfree(dev); + } } diff --git a/net/atm/common.c b/net/atm/common.c index 9e016f404e14..6656b111cc05 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -221,6 +221,29 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) EXPORT_SYMBOL(vcc_release_async); +void atm_dev_release_vccs(struct atm_dev *dev) +{ + int i; + + write_lock_irq(&vcc_sklist_lock); + for (i = 0; i < VCC_HTABLE_SIZE; i++) { + struct hlist_head *head = &vcc_hash[i]; + struct hlist_node *node, *tmp; + struct sock *s; + struct atm_vcc *vcc; + + sk_for_each_safe(s, node, tmp, head) { + vcc = atm_sk(s); + if (vcc->dev == dev) { + vcc_release_async(vcc, -EPIPE); + sk_del_node_init(s); + } + } + } + write_unlock_irq(&vcc_sklist_lock); +} + + static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) { int max_sdu; @@ -332,12 +355,13 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi, return -EINVAL; if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) return -EPERM; - error = 0; + error = -ENODEV; if (!try_module_get(dev->ops->owner)) - return -ENODEV; + return error; vcc->dev = dev; write_lock_irq(&vcc_sklist_lock); - if ((error = find_ci(vcc, &vpi, &vci))) { + if (test_bit(ATM_DF_REMOVED, &dev->flags) || + (error = find_ci(vcc, &vpi, &vci))) { write_unlock_irq(&vcc_sklist_lock); goto fail_module_put; } diff --git a/net/atm/common.h b/net/atm/common.h index e49ed41c0e33..4887c317cefe 100644 --- a/net/atm/common.h +++ b/net/atm/common.h @@ -47,4 +47,6 @@ static inline void atm_proc_exit(void) /* SVC */ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); +void atm_dev_release_vccs(struct atm_dev *dev); + #endif diff --git a/net/atm/resources.c b/net/atm/resources.c index ad533b02b84f..c8c459fcb038 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -70,6 +70,7 @@ struct atm_dev *atm_dev_lookup(int number) return dev; } + struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, int number, unsigned long *flags) { @@ -123,37 +124,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, void atm_dev_deregister(struct atm_dev *dev) { - unsigned long warning_time; - - atm_proc_dev_deregister(dev); - + BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags)); + set_bit(ATM_DF_REMOVED, &dev->flags); + + /* + * if we remove current device from atm_devs list, new device + * with same number can appear, such we need deregister proc, + * release async all vccs and remove them from vccs list too + */ down(&atm_dev_mutex); list_del(&dev->dev_list); up(&atm_dev_mutex); - warning_time = jiffies; - while (atomic_read(&dev->refcnt) != 1) { - msleep(250); - if ((jiffies - warning_time) > 10 * HZ) { - printk(KERN_EMERG "atm_dev_deregister: waiting for " - "dev %d to become free. Usage count = %d\n", - dev->number, atomic_read(&dev->refcnt)); - warning_time = jiffies; - } - } - - kfree(dev); -} + atm_dev_release_vccs(dev); + atm_proc_dev_deregister(dev); -void shutdown_atm_dev(struct atm_dev *dev) -{ - if (atomic_read(&dev->refcnt) > 1) { - set_bit(ATM_DF_CLOSE, &dev->flags); - return; - } - if (dev->ops->dev_close) - dev->ops->dev_close(dev); - atm_dev_deregister(dev); + atm_dev_put(dev); } @@ -433,4 +419,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_dev_lookup); -EXPORT_SYMBOL(shutdown_atm_dev); -- cgit v1.2.3 From df69a60dc6afc2936d79054d30b481c1fd9720e5 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Tue, 29 Nov 2005 19:34:31 -0800 Subject: [PATCH] process events connector: uid_t gid_t size issues The uid_t and gid_t fields appear to present a 32/64-bit userspace/kernel problem for some archs. This patch addresses the problem by fixing the size to the largest size for uid_t/gid_t used in the kernel. This preserves the total size of the event structure while ensuring that the layouts of the ID change event match in 32 and 64-bit kernels and applications. Signed-off-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cn_proc.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 70ab56317380..c948f678e04e 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -86,12 +86,12 @@ struct proc_event { pid_t process_pid; pid_t process_tgid; union { - uid_t ruid; /* current->uid */ - gid_t rgid; /* current->gid */ + __u32 ruid; /* task uid */ + __u32 rgid; /* task gid */ } r; union { - uid_t euid; - gid_t egid; + __u32 euid; + __u32 egid; } e; } id; -- cgit v1.2.3 From c9d6073fb3cda856132dd544d537679f9715436c Mon Sep 17 00:00:00 2001 From: Grant Coady Date: Thu, 24 Nov 2005 20:41:06 +1100 Subject: [PATCH] pci_ids.h: remove duplicate entries G'day Albert, Andrew, commit 4fb80634d30f5e639a92b78c8f215f96a61ba8c7 Author: Albert Lee Date: Thu May 12 15:49:21 2005 -0400 duplicates symbols already appearing in pci_ids.h, appended patch removes them again :o) From: Grant Coady pci_ids: commit 4fb80634d30f5e639a92b78c8f215f96a61ba8c7 duplicated a couple existing symbols in pci_ids.h, remove them. Signed-off-by: Grant Coady Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1e737e269db9..53e3293051d4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -387,7 +387,6 @@ #define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 #define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 #define PCI_DEVICE_ID_NS_87410 0xd001 -#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 @@ -489,8 +488,6 @@ #define PCI_DEVICE_ID_AMD_8151_0 0x7454 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 -#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A - #define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 -- cgit v1.2.3 From a145dd411eb28c83ee4bb68b66f62c326c0f764e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 30 Nov 2005 09:35:19 -0800 Subject: VM: add "vm_insert_page()" function This is what a lot of drivers will actually want to use to insert individual pages into a user VMA. It doesn't have the old PageReserved restrictions of remap_pfn_range(), and it doesn't complain about partial remappings. The page you insert needs to be a nice clean kernel allocation, so you can't insert arbitrary page mappings with this, but that's not what people want. Signed-off-by: Linus Torvalds --- include/linux/mm.h | 1 + mm/memory.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 0e73f1539d08..29f02d8513f6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -956,6 +956,7 @@ struct page *vmalloc_to_page(void *addr); unsigned long vmalloc_to_pfn(void *addr); int remap_pfn_range(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t); +int vm_insert_page(struct vm_area_struct *, unsigned long addr, struct page *); struct page *follow_page(struct vm_area_struct *, unsigned long address, unsigned int foll_flags); diff --git a/mm/memory.c b/mm/memory.c index 8d10b5540c73..4b4fc3a7ea48 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1172,7 +1172,7 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa spinlock_t *ptl; retval = -EINVAL; - if (PageAnon(page) || !PageReserved(page)) + if (PageAnon(page)) goto out; retval = -ENOMEM; flush_dcache_page(page); @@ -1196,6 +1196,35 @@ out: return retval; } +/* + * This allows drivers to insert individual pages they've allocated + * into a user vma. + * + * The page has to be a nice clean _individual_ kernel allocation. + * If you allocate a compound page, you need to have marked it as + * such (__GFP_COMP), or manually just split the page up yourself + * (which is mainly an issue of doing "set_page_count(page, 1)" for + * each sub-page, and then freeing them one by one when you free + * them rather than freeing it as a compound page). + * + * NOTE! Traditionally this was done with "remap_pfn_range()" which + * took an arbitrary page protection parameter. This doesn't allow + * that. Your vma protection will have to be set up correctly, which + * means that if you want a shared writable mapping, you'd better + * ask for a shared writable mapping! + * + * The page does not need to be reserved. + */ +int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, struct page *page) +{ + if (addr < vma->vm_start || addr >= vma->vm_end) + return -EFAULT; + if (!page_count(page)) + return -EINVAL; + return insert_page(vma->vm_mm, addr, page, vma->vm_page_prot); +} +EXPORT_SYMBOL_GPL(vm_insert_page); + /* * Somebody does a pfn remapping that doesn't actually work as a vma. * @@ -1225,8 +1254,11 @@ static int incomplete_pfn_remap(struct vm_area_struct *vma, if (!pfn_valid(pfn)) return -EINVAL; - retval = 0; page = pfn_to_page(pfn); + if (!PageReserved(page)) + return -EINVAL; + + retval = 0; while (start < end) { retval = insert_page(vma->vm_mm, start, page, prot); if (retval < 0) -- cgit v1.2.3 From 346f7dbb17cb7d84317b4410df2e8f7bf2e57f44 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 30 Nov 2005 10:22:30 -0800 Subject: Revert "[PATCH] pci_ids.h: remove duplicate entries" This reverts commit c9d6073fb3cda856132dd544d537679f9715436c. It was totally bogus. Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 53e3293051d4..1e737e269db9 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -387,6 +387,7 @@ #define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 #define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 #define PCI_DEVICE_ID_NS_87410 0xd001 +#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d #define PCI_VENDOR_ID_TSENG 0x100c #define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 @@ -488,6 +489,8 @@ #define PCI_DEVICE_ID_AMD_8151_0 0x7454 #define PCI_DEVICE_ID_AMD_8131_APIC 0x7450 +#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A + #define PCI_VENDOR_ID_TRIDENT 0x1023 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 #define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 -- cgit v1.2.3 From 769e24382dd47434dfda681f360868c4acd8b6e2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 1 Dec 2005 00:51:35 -0800 Subject: [PATCH] V4L: Some funcions now static and I2C hw code for IR - Some funcions are now declared as static - Added a I2C code for InfraRed. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/cx25840/cx25840-core.c | 4 ++-- drivers/media/video/ir-kbd-i2c.c | 2 +- drivers/media/video/saa7127.c | 6 +++--- include/linux/i2c-id.h | 1 + 4 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index f6afeec499c5..539db129a9f4 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -714,7 +714,7 @@ static int cx25840_command(struct i2c_client *client, unsigned int cmd, /* ----------------------------------------------------------------------- */ -struct i2c_driver i2c_driver_cx25840; +static struct i2c_driver i2c_driver_cx25840; static int cx25840_detect_client(struct i2c_adapter *adapter, int address, int kind) @@ -807,7 +807,7 @@ static int cx25840_detach_client(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -struct i2c_driver i2c_driver_cx25840 = { +static struct i2c_driver i2c_driver_cx25840 = { .name = "cx25840", .id = I2C_DRIVERID_CX25840, diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c index 801c736e9328..124c502ea1f3 100644 --- a/drivers/media/video/ir-kbd-i2c.c +++ b/drivers/media/video/ir-kbd-i2c.c @@ -278,7 +278,7 @@ static int ir_probe(struct i2c_adapter *adap); static struct i2c_driver driver = { .name = "ir remote kbd driver", - .id = I2C_DRIVERID_EXP3, /* FIXME */ + .id = I2C_DRIVERID_I2C_IR, .flags = I2C_DF_NOTIFY, .attach_adapter = ir_probe, .detach_client = ir_detach, diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c index 843431f10e3b..3428e1ed0032 100644 --- a/drivers/media/video/saa7127.c +++ b/drivers/media/video/saa7127.c @@ -223,7 +223,7 @@ static const struct i2c_reg_value saa7127_init_config_60hz[] = { }; #define SAA7127_50HZ_DAC_CONTROL 0x02 -struct i2c_reg_value saa7127_init_config_50hz[] = { +static struct i2c_reg_value saa7127_init_config_50hz[] = { { SAA7127_REG_BURST_START, 0x21 }, /* BURST_END is also used as a chip ID in saa7127_detect_client */ { SAA7127_REG_BURST_END, 0x1d }, @@ -696,7 +696,7 @@ static int saa7127_command(struct i2c_client *client, /* ----------------------------------------------------------------------- */ -struct i2c_driver i2c_driver_saa7127; +static struct i2c_driver i2c_driver_saa7127; /* ----------------------------------------------------------------------- */ @@ -818,7 +818,7 @@ static int saa7127_detach(struct i2c_client *client) /* ----------------------------------------------------------------------- */ -struct i2c_driver i2c_driver_saa7127 = { +static struct i2c_driver i2c_driver_saa7127 = { .name = "saa7127", .id = I2C_DRIVERID_SAA7127, .flags = I2C_DF_NOTIFY, diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 1543daaa9c5e..ef3b5632e63a 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -108,6 +108,7 @@ #define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ +#define I2C_DRIVERID_I2C_IR 75 /* I2C InfraRed on Video boards */ #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */ #define I2C_DRIVERID_EXP1 0xF1 -- cgit v1.2.3