From bd8fbdee6562ee526f3c2582a3b373ef195015dd Mon Sep 17 00:00:00 2001 From: Rui Sousa Date: Wed, 3 Sep 2008 17:53:07 +0200 Subject: lockdep: fix compilation when CONFIG_TRACE_IRQFLAGS_SUPPORT is not set This patch fixes compilation if CONFIG_TRACE_IRQFLAGS_SUPPORT is ever disabled (which is currently not allowed by Kconfig). Alternatively we could just remove the option altogether and the associated code paths. Since the compilation error has been in the tree for at least two years and no one noticed it, I guess we don't really have the need for CONFIG_TRACE_IRQFLAGS_SUPPORT=n. Boot tested on x86 UP. Signed-off-by: Rui Sousa Signed-off-by: Ingo Molnar --- include/linux/irqflags.h | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index 74bde13224c..f2993512b3b 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -52,10 +52,10 @@ # define start_critical_timings() do { } while (0) #endif -#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT - #include +#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT + #define local_irq_enable() \ do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0) #define local_irq_disable() \ @@ -84,21 +84,20 @@ * The local_irq_*() APIs are equal to the raw_local_irq*() * if !TRACE_IRQFLAGS. */ -# define raw_local_irq_disable() local_irq_disable() -# define raw_local_irq_enable() local_irq_enable() -# define raw_local_irq_save(flags) \ +#define local_irq_disable() raw_local_irq_disable() +#define local_irq_enable() raw_local_irq_enable() +#define local_irq_save(flags) \ do { \ typecheck(unsigned long, flags); \ - local_irq_save(flags); \ + raw_local_irq_save(flags); \ } while (0) -# define raw_local_irq_restore(flags) \ +# define local_irq_restore(flags) \ do { \ typecheck(unsigned long, flags); \ - local_irq_restore(flags); \ + raw_local_irq_restore(flags); \ } while (0) #endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ -#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT #define safe_halt() \ do { \ trace_hardirqs_on(); \ @@ -124,6 +123,5 @@ typecheck(unsigned long, flags); \ raw_irqs_disabled_flags(flags); \ }) -#endif /* CONFIG_X86 */ #endif -- cgit v1.2.3 From 8c56250f48347750c82ab18d98d647dcf99ca674 Mon Sep 17 00:00:00 2001 From: Rui Sousa Date: Thu, 4 Sep 2008 19:47:53 +0200 Subject: lockdep, UML: fix compilation when CONFIG_TRACE_IRQFLAGS_SUPPORT is not set Hiroshi Shimamoto reported: > > !TRACE_IRQFLAGS_SUPPORT mode of build for future work, it can be > > restored via a simple revert. > > Hi, it seems that this patch breaks uml build. > > kernel/printk.c: In function 'vprintk': > kernel/printk.c:674: error: implicit declaration of function > 'raw_local_irq_save' kernel/printk.c:772: error: implicit declaration of > function 'raw_local_irq_restore' With the patch bellow it compiles (make ARCH=um with a x86 host), but I'm really out of my league on this one... Reported-by: Hiroshi Shimamoto Signed-off-by: Ingo Molnar --- include/asm-um/system-generic.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h index 5bcfa35e7a2..f1ea4da34fa 100644 --- a/include/asm-um/system-generic.h +++ b/include/asm-um/system-generic.h @@ -4,15 +4,15 @@ #include "asm/arch/system.h" #undef switch_to -#undef local_irq_save -#undef local_irq_restore -#undef local_irq_disable -#undef local_irq_enable -#undef local_save_flags -#undef local_irq_restore -#undef local_irq_enable -#undef local_irq_disable -#undef local_irq_save +#undef raw_local_irq_save +#undef raw_local_irq_restore +#undef raw_local_irq_disable +#undef raw_local_irq_enable +#undef raw_local_save_flags +#undef raw_local_irq_restore +#undef raw_local_irq_enable +#undef raw_local_irq_disable +#undef raw_local_irq_save #undef irqs_disabled extern void *switch_to(void *prev, void *next, void *last); @@ -23,21 +23,21 @@ extern int get_signals(void); extern void block_signals(void); extern void unblock_signals(void); -#define local_save_flags(flags) do { typecheck(unsigned long, flags); \ +#define raw_local_save_flags(flags) do { typecheck(unsigned long, flags); \ (flags) = get_signals(); } while(0) -#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \ +#define raw_local_irq_restore(flags) do { typecheck(unsigned long, flags); \ set_signals(flags); } while(0) -#define local_irq_save(flags) do { local_save_flags(flags); \ - local_irq_disable(); } while(0) +#define raw_local_irq_save(flags) do { raw_local_save_flags(flags); \ + raw_local_irq_disable(); } while(0) -#define local_irq_enable() unblock_signals() -#define local_irq_disable() block_signals() +#define raw_local_irq_enable() unblock_signals() +#define raw_local_irq_disable() block_signals() #define irqs_disabled() \ ({ \ unsigned long flags; \ - local_save_flags(flags); \ + raw_local_save_flags(flags); \ (flags == 0); \ }) -- cgit v1.2.3 From ab7476cf76e560f0efda2a631a70aabe93009025 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Fri, 15 Aug 2008 15:29:38 -0700 Subject: debug: add notifier chain debugging, v2 - unbreak ia64 (and powerpc) where function pointers dont point at code but at data (reported by Tony Luck) [ mingo@elte.hu: various cleanups ] Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2651f805ba6..4e1366b552a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -187,6 +187,9 @@ extern unsigned long long memparse(char *ptr, char **retptr); extern int core_kernel_text(unsigned long addr); extern int __kernel_text_address(unsigned long addr); extern int kernel_text_address(unsigned long addr); +extern int func_ptr_is_kernel_text(void *ptr); +extern void *dereference_function_descriptor(void *ptr); + struct pid; extern struct pid *session_of_pgrp(struct pid *pgrp); -- cgit v1.2.3 From 76b189e91845eab3a9d52bb97f971d312d25652d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 10 Sep 2008 09:57:35 +0200 Subject: lockdep: add might_lock() / might_lock_read() useful to establish a lock dependency in case the actual dependency is rare or hard to trigger. Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 331e5f1c2d8..0aa657aa8a1 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -480,4 +480,22 @@ static inline void print_irqtrace_events(struct task_struct *curr) # define lock_map_release(l) do { } while (0) #endif +#ifdef CONFIG_PROVE_LOCKING +# define might_lock(lock) \ +do { \ + typecheck(struct lockdep_map *, &(lock)->dep_map); \ + lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_); \ + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ +} while (0) +# define might_lock_read(lock) \ +do { \ + typecheck(struct lockdep_map *, &(lock)->dep_map); \ + lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_); \ + lock_release(&(lock)->dep_map, 0, _THIS_IP_); \ +} while (0) +#else +# define might_lock(lock) do { } while (0) +# define might_lock_read(lock) do { } while (0) +#endif + #endif /* __LINUX_LOCKDEP_H */ -- cgit v1.2.3 From c10d38dda1774ed4540380333cabd229eff37094 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 10 Sep 2008 13:37:17 +0200 Subject: x86: some lock annotations for user copy paths copy_to/from_user and all its variants (except the atomic ones) can take a page fault and perform non-trivial work like taking mmap_sem and entering the filesyste/pagecache. Unfortunately, this often escapes lockdep because a common pattern is to use it to read in some arguments just set up from userspace, or write data back to a hot buffer. In those cases, it will be unlikely for page reclaim to get a window in to cause copy_*_user to fault. With the new might_lock primitives, add some annotations to x86. I don't know if I caught all possible faulting points (it's a bit of a maze, and I didn't really look at 32-bit). But this is a starting point. Boots and runs OK so far. Signed-off-by: Nick Piggin Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/asm-x86/uaccess.h | 14 ++++++++++++++ include/asm-x86/uaccess_32.h | 10 ++++++++-- include/asm-x86/uaccess_64.h | 12 ++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 5f702d1d521..ad29752a171 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -157,6 +159,9 @@ extern int __get_user_bad(void); int __ret_gu; \ unsigned long __val_gu; \ __chk_user_ptr(ptr); \ + might_sleep(); \ + if (current->mm) \ + might_lock_read(¤t->mm->mmap_sem); \ switch (sizeof(*(ptr))) { \ case 1: \ __get_user_x(1, __ret_gu, __val_gu, ptr); \ @@ -241,6 +246,9 @@ extern void __put_user_8(void); int __ret_pu; \ __typeof__(*(ptr)) __pu_val; \ __chk_user_ptr(ptr); \ + might_sleep(); \ + if (current->mm) \ + might_lock_read(¤t->mm->mmap_sem); \ __pu_val = x; \ switch (sizeof(*(ptr))) { \ case 1: \ @@ -265,6 +273,9 @@ extern void __put_user_8(void); #define __put_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ + might_sleep(); \ + if (current->mm) \ + might_lock_read(¤t->mm->mmap_sem); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ @@ -317,6 +328,9 @@ do { \ #define __get_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ + might_sleep(); \ + if (current->mm) \ + might_lock_read(¤t->mm->mmap_sem); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index 6fdef39a0bc..d725e2d703f 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -82,8 +82,10 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) static __always_inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) { - might_sleep(); - return __copy_to_user_inatomic(to, from, n); + might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); + return __copy_to_user_inatomic(to, from, n); } static __always_inline unsigned long @@ -138,6 +140,8 @@ static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); if (__builtin_constant_p(n)) { unsigned long ret; @@ -160,6 +164,8 @@ static __always_inline unsigned long __copy_from_user_nocache(void *to, const void __user *from, unsigned long n) { might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); if (__builtin_constant_p(n)) { unsigned long ret; diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 515d4dce96b..40a7205fe57 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -28,6 +28,10 @@ static __always_inline __must_check int __copy_from_user(void *dst, const void __user *src, unsigned size) { int ret = 0; + + might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); if (!__builtin_constant_p(size)) return copy_user_generic(dst, (__force void *)src, size); switch (size) { @@ -70,6 +74,10 @@ static __always_inline __must_check int __copy_to_user(void __user *dst, const void *src, unsigned size) { int ret = 0; + + might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, src, size); switch (size) { @@ -112,6 +120,10 @@ static __always_inline __must_check int __copy_in_user(void __user *dst, const void __user *src, unsigned size) { int ret = 0; + + might_sleep(); + if (current->mm) + might_lock_read(¤t->mm->mmap_sem); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, (__force void *)src, size); -- cgit v1.2.3 From 3ee1afa308f2a38e5d1e2ad3752ad7abcf480da1 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 10 Sep 2008 13:37:17 +0200 Subject: x86: some lock annotations for user copy paths, v2 - introduce might_fault() - handle the atomic user copy paths correctly [ mingo@elte.hu: move might_sleep() outside of in_atomic(). ] Signed-off-by: Nick Piggin Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/asm-x86/uaccess.h | 18 ++++-------------- include/asm-x86/uaccess_32.h | 12 +++--------- include/asm-x86/uaccess_64.h | 12 +++--------- include/linux/kernel.h | 9 +++++++++ 4 files changed, 19 insertions(+), 32 deletions(-) (limited to 'include') diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index ad29752a171..39f8420c75d 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -8,8 +8,6 @@ #include #include #include -#include -#include #include #include @@ -159,9 +157,7 @@ extern int __get_user_bad(void); int __ret_gu; \ unsigned long __val_gu; \ __chk_user_ptr(ptr); \ - might_sleep(); \ - if (current->mm) \ - might_lock_read(¤t->mm->mmap_sem); \ + might_fault(); \ switch (sizeof(*(ptr))) { \ case 1: \ __get_user_x(1, __ret_gu, __val_gu, ptr); \ @@ -246,9 +242,7 @@ extern void __put_user_8(void); int __ret_pu; \ __typeof__(*(ptr)) __pu_val; \ __chk_user_ptr(ptr); \ - might_sleep(); \ - if (current->mm) \ - might_lock_read(¤t->mm->mmap_sem); \ + might_fault(); \ __pu_val = x; \ switch (sizeof(*(ptr))) { \ case 1: \ @@ -273,9 +267,7 @@ extern void __put_user_8(void); #define __put_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ - might_sleep(); \ - if (current->mm) \ - might_lock_read(¤t->mm->mmap_sem); \ + might_fault(); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ @@ -328,9 +320,7 @@ do { \ #define __get_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ - might_sleep(); \ - if (current->mm) \ - might_lock_read(¤t->mm->mmap_sem); \ + might_fault(); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ diff --git a/include/asm-x86/uaccess_32.h b/include/asm-x86/uaccess_32.h index d725e2d703f..d10e842ec3e 100644 --- a/include/asm-x86/uaccess_32.h +++ b/include/asm-x86/uaccess_32.h @@ -82,9 +82,7 @@ __copy_to_user_inatomic(void __user *to, const void *from, unsigned long n) static __always_inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n) { - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); return __copy_to_user_inatomic(to, from, n); } @@ -139,9 +137,7 @@ __copy_from_user_inatomic(void *to, const void __user *from, unsigned long n) static __always_inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) { - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); if (__builtin_constant_p(n)) { unsigned long ret; @@ -163,9 +159,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n) static __always_inline unsigned long __copy_from_user_nocache(void *to, const void __user *from, unsigned long n) { - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); if (__builtin_constant_p(n)) { unsigned long ret; diff --git a/include/asm-x86/uaccess_64.h b/include/asm-x86/uaccess_64.h index 40a7205fe57..13fd56fbc3a 100644 --- a/include/asm-x86/uaccess_64.h +++ b/include/asm-x86/uaccess_64.h @@ -29,9 +29,7 @@ int __copy_from_user(void *dst, const void __user *src, unsigned size) { int ret = 0; - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); if (!__builtin_constant_p(size)) return copy_user_generic(dst, (__force void *)src, size); switch (size) { @@ -75,9 +73,7 @@ int __copy_to_user(void __user *dst, const void *src, unsigned size) { int ret = 0; - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, src, size); switch (size) { @@ -121,9 +117,7 @@ int __copy_in_user(void __user *dst, const void __user *src, unsigned size) { int ret = 0; - might_sleep(); - if (current->mm) - might_lock_read(¤t->mm->mmap_sem); + might_fault(); if (!__builtin_constant_p(size)) return copy_user_generic((__force void *)dst, (__force void *)src, size); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2651f805ba6..e580ec09576 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -140,6 +140,15 @@ extern int _cond_resched(void); (__x < 0) ? -__x : __x; \ }) +#ifdef CONFIG_PROVE_LOCKING +void might_fault(void); +#else +static inline void might_fault(void) +{ + might_sleep(); +} +#endif + extern struct atomic_notifier_head panic_notifier_list; extern long (*panic_blink)(long time); NORET_TYPE void panic(const char * fmt, ...) -- cgit v1.2.3 From 1d18ef489509314506328b9e464dd47c24c1d68f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 11 Sep 2008 20:53:21 +0200 Subject: x86: some lock annotations for user copy paths, v3 - add annotation back to clear_user() - change probe_kernel_address() to _inatomic*() method Signed-off-by: Ingo Molnar --- include/asm-x86/uaccess.h | 2 -- include/linux/uaccess.h | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'include') diff --git a/include/asm-x86/uaccess.h b/include/asm-x86/uaccess.h index 39f8420c75d..dc8edb5c465 100644 --- a/include/asm-x86/uaccess.h +++ b/include/asm-x86/uaccess.h @@ -267,7 +267,6 @@ extern void __put_user_8(void); #define __put_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ - might_fault(); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ @@ -320,7 +319,6 @@ do { \ #define __get_user_size(x, ptr, size, retval, errret) \ do { \ retval = 0; \ - might_fault(); \ __chk_user_ptr(ptr); \ switch (size) { \ case 1: \ diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index fec6decfb98..2062293e57e 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -78,7 +78,7 @@ static inline unsigned long __copy_from_user_nocache(void *to, \ set_fs(KERNEL_DS); \ pagefault_disable(); \ - ret = __get_user(retval, (__force typeof(retval) __user *)(addr)); \ + ret = __copy_from_user_inatomic((__force typeof(retval) __user *)(addr), &(retval), sizeof(retval)); \ pagefault_enable(); \ set_fs(old_fs); \ ret; \ -- cgit v1.2.3 From 53b9d87f41a3d8838210ad7cdef02d814817ce85 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 11 Sep 2008 17:02:58 -0700 Subject: lock debug: sit tight when we are already in a panic in: > http://bugzilla.kernel.org/show_bug.cgi?id=11543 The panic code called the kexec code which called mutex_trylock() which called spin_lock_mutex() which then stupidly went and blurted a load of debug stuff because of in_interrupt(). Keep the lock debug code from escallating an already crappy situation. Signed-off-by: Ingo Molnar --- include/linux/debug_locks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h index 4aaa4afb1cb..096476f1fb3 100644 --- a/include/linux/debug_locks.h +++ b/include/linux/debug_locks.h @@ -17,7 +17,7 @@ extern int debug_locks_off(void); ({ \ int __ret = 0; \ \ - if (unlikely(c)) { \ + if (!oops_in_progress && unlikely(c)) { \ if (debug_locks_off() && !debug_locks_silent) \ WARN_ON(1); \ __ret = 1; \ -- cgit v1.2.3 From 30742d5c2277c325fb0e9d2d817d55a19995fe8f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Sep 2008 14:43:39 +0200 Subject: Revert "lockdep: fix compilation when CONFIG_TRACE_IRQFLAGS_SUPPORT is not set" This reverts commit bd8fbdee6562ee526f3c2582a3b373ef195015dd. This broke the powerpc build - more fixes are needed before we can undo this revert. --- include/linux/irqflags.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h index f2993512b3b..74bde13224c 100644 --- a/include/linux/irqflags.h +++ b/include/linux/irqflags.h @@ -52,10 +52,10 @@ # define start_critical_timings() do { } while (0) #endif -#include - #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT +#include + #define local_irq_enable() \ do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0) #define local_irq_disable() \ @@ -84,20 +84,21 @@ * The local_irq_*() APIs are equal to the raw_local_irq*() * if !TRACE_IRQFLAGS. */ -#define local_irq_disable() raw_local_irq_disable() -#define local_irq_enable() raw_local_irq_enable() -#define local_irq_save(flags) \ +# define raw_local_irq_disable() local_irq_disable() +# define raw_local_irq_enable() local_irq_enable() +# define raw_local_irq_save(flags) \ do { \ typecheck(unsigned long, flags); \ - raw_local_irq_save(flags); \ + local_irq_save(flags); \ } while (0) -# define local_irq_restore(flags) \ +# define raw_local_irq_restore(flags) \ do { \ typecheck(unsigned long, flags); \ - raw_local_irq_restore(flags); \ + local_irq_restore(flags); \ } while (0) #endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ +#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT #define safe_halt() \ do { \ trace_hardirqs_on(); \ @@ -123,5 +124,6 @@ typecheck(unsigned long, flags); \ raw_irqs_disabled_flags(flags); \ }) +#endif /* CONFIG_X86 */ #endif -- cgit v1.2.3 From fb71e45338453698bd7460f7e8f171ea0304d218 Mon Sep 17 00:00:00 2001 From: Hiroshi Shimamoto Date: Mon, 15 Sep 2008 18:04:26 -0700 Subject: uaccess: fix parameters inversion for __copy_from_user_inatomic() The following patch changes to use __copy_from_user_inatomic(), but the passing parameters incorrect: x86: some lock annotations for user copy paths, v3 This fixes the netfilter crash reported by Steven Noonan. Reported-by: Steven Noonan Signed-off-by: Hiroshi Shimamoto Tested-by: Steven Noonan Signed-off-by: Ingo Molnar --- include/linux/uaccess.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 2062293e57e..6b58367d145 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -78,7 +78,7 @@ static inline unsigned long __copy_from_user_nocache(void *to, \ set_fs(KERNEL_DS); \ pagefault_disable(); \ - ret = __copy_from_user_inatomic((__force typeof(retval) __user *)(addr), &(retval), sizeof(retval)); \ + ret = __copy_from_user_inatomic(&(retval), (__force typeof(retval) __user *)(addr), sizeof(retval)); \ pagefault_enable(); \ set_fs(old_fs); \ ret; \ -- cgit v1.2.3 From 38d47c1b7075bd7ec3881141bb3629da58f88dab Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 26 Sep 2008 19:32:20 +0200 Subject: futex: rely on get_user_pages() for shared futexes On the way of getting rid of the mmap_sem requirement for shared futexes, start by relying on get_user_pages(). Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Signed-off-by: Ingo Molnar --- include/linux/futex.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/futex.h b/include/linux/futex.h index 586ab56a3ec..8f627b9ae2b 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -164,6 +164,8 @@ union futex_key { } both; }; +#define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = NULL } } + #ifdef CONFIG_FUTEX extern void exit_robust_list(struct task_struct *curr); extern void exit_pi_state_list(struct task_struct *curr); -- cgit v1.2.3 From c7e78cff6b7518212247fb20b1dc6411540dc9af Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 16 Oct 2008 23:17:09 +0200 Subject: lockstat: contend with points We currently only provide points that have to wait on contention, also lists the points we have to wait for. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 0aa657aa8a1..fc9f8e88123 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -73,6 +73,8 @@ struct lock_class_key { struct lockdep_subclass_key subkeys[MAX_LOCKDEP_SUBCLASSES]; }; +#define LOCKSTAT_POINTS 4 + /* * The lock-class itself: */ @@ -119,7 +121,8 @@ struct lock_class { int name_version; #ifdef CONFIG_LOCK_STAT - unsigned long contention_point[4]; + unsigned long contention_point[LOCKSTAT_POINTS]; + unsigned long contending_point[LOCKSTAT_POINTS]; #endif }; @@ -144,6 +147,7 @@ enum bounce_type { struct lock_class_stats { unsigned long contention_point[4]; + unsigned long contending_point[4]; struct lock_time read_waittime; struct lock_time write_waittime; struct lock_time read_holdtime; @@ -165,6 +169,7 @@ struct lockdep_map { const char *name; #ifdef CONFIG_LOCK_STAT int cpu; + unsigned long ip; #endif }; @@ -355,7 +360,7 @@ struct lock_class_key { }; #ifdef CONFIG_LOCK_STAT extern void lock_contended(struct lockdep_map *lock, unsigned long ip); -extern void lock_acquired(struct lockdep_map *lock); +extern void lock_acquired(struct lockdep_map *lock, unsigned long ip); #define LOCK_CONTENDED(_lock, try, lock) \ do { \ @@ -363,13 +368,13 @@ do { \ lock_contended(&(_lock)->dep_map, _RET_IP_); \ lock(_lock); \ } \ - lock_acquired(&(_lock)->dep_map); \ + lock_acquired(&(_lock)->dep_map, _RET_IP_); \ } while (0) #else /* CONFIG_LOCK_STAT */ #define lock_contended(lockdep_map, ip) do {} while (0) -#define lock_acquired(lockdep_map) do {} while (0) +#define lock_acquired(lockdep_map, ip) do {} while (0) #define LOCK_CONTENDED(_lock, try, lock) \ lock(_lock) -- cgit v1.2.3 From 2cb1599f9b2ecdd7a9e59feeee647eb258966839 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 30 Oct 2008 17:32:23 +1100 Subject: Inode: Allow external initialisers To allow XFS to combine the XFS and linux inodes into a single structure, we need to drive inode lookup from the XFS inode cache, not the generic inode cache. This means that we need initialise a struct inode from a context outside alloc_inode() as it is no longer used by XFS. Factor and export the struct inode initialisation code from alloc_inode() to inode_init_always() as a counterpart to inode_init_once(). i.e. we have to call this init function for each inode instantiation (always), as opposed inode_init_once() which is only called on slab object instantiation (once). Signed-off-by: Dave Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b248d61430..04abead4b02 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1881,6 +1881,7 @@ extern loff_t default_llseek(struct file *file, loff_t offset, int origin); extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin); +extern struct inode * inode_init_always(struct super_block *, struct inode *); extern void inode_init_once(struct inode *); extern void iput(struct inode *); extern struct inode * igrab(struct inode *); -- cgit v1.2.3 From 8290c35f87304a6b73d4fd17b03580b4f7425de8 Mon Sep 17 00:00:00 2001 From: David Chinner Date: Thu, 30 Oct 2008 17:35:24 +1100 Subject: Inode: Allow external list initialisation To allow XFS to combine the XFS and linux inodes into a single structure, we need to drive inode lookup from the XFS inode cache, not the generic inode cache. This means that we need initialise a struct inode from a context outside alloc_inode() as it is no longer used by XFS. After inode allocation and initialisation, we need to add the inode to the superblock list, the in-use list, hash it and do some accounting. This all needs to be done with the inode_lock held and there are already several places in fs/inode.c that do this list manipulation. Factor out the common code, add a locking wrapper and export the function so ti can be called from XFS. Signed-off-by: Dave Chinner Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 04abead4b02..1deedf235d5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1883,6 +1883,7 @@ extern loff_t vfs_llseek(struct file *file, loff_t offset, int origin); extern struct inode * inode_init_always(struct super_block *, struct inode *); extern void inode_init_once(struct inode *); +extern void inode_add_to_lists(struct super_block *, struct inode *); extern void iput(struct inode *); extern struct inode * igrab(struct inode *); extern ino_t iunique(struct super_block *, ino_t); -- cgit v1.2.3 From 180ee700ddfcc882d90410d979a4b3a804380ed2 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:32 +0000 Subject: [ARM] S3C: Move regs-watchdog.h to arch/arm/plat-s3c/include/plat Move regs-watchdog.h to arch/arm/plat-s3c/include/plat ready to clean out the old include directories Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/regs-watchdog.h | 41 -------------------------------- 1 file changed, 41 deletions(-) delete mode 100644 include/asm-arm/plat-s3c/regs-watchdog.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c/regs-watchdog.h b/include/asm-arm/plat-s3c/regs-watchdog.h deleted file mode 100644 index 4938492470f..00000000000 --- a/include/asm-arm/plat-s3c/regs-watchdog.h +++ /dev/null @@ -1,41 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-watchdog.h - * - * Copyright (c) 2003 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 Watchdog timer control -*/ - - -#ifndef __ASM_ARCH_REGS_WATCHDOG_H -#define __ASM_ARCH_REGS_WATCHDOG_H - -#define S3C_WDOGREG(x) ((x) + S3C_VA_WATCHDOG) - -#define S3C2410_WTCON S3C_WDOGREG(0x00) -#define S3C2410_WTDAT S3C_WDOGREG(0x04) -#define S3C2410_WTCNT S3C_WDOGREG(0x08) - -/* the watchdog can either generate a reset pulse, or an - * interrupt. - */ - -#define S3C2410_WTCON_RSTEN (0x01) -#define S3C2410_WTCON_INTEN (1<<2) -#define S3C2410_WTCON_ENABLE (1<<5) - -#define S3C2410_WTCON_DIV16 (0<<3) -#define S3C2410_WTCON_DIV32 (1<<3) -#define S3C2410_WTCON_DIV64 (2<<3) -#define S3C2410_WTCON_DIV128 (3<<3) - -#define S3C2410_WTCON_PRESCALE(x) ((x) << 8) -#define S3C2410_WTCON_PRESCALE_MASK (0xff00) - -#endif /* __ASM_ARCH_REGS_WATCHDOG_H */ - - -- cgit v1.2.3 From 9498cb79463c9b2abb243a4b0c2ce3ac1853d5b0 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:33 +0000 Subject: [ARM] S3C: Move i2c headers to arch/arm/plat-s3c/include/plat. Move the i2c headers to arch/arm/plat-s3c/include/plat ready to clean out the old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/iic.h | 33 ---------------------- include/asm-arm/plat-s3c/regs-iic.h | 56 ------------------------------------- 2 files changed, 89 deletions(-) delete mode 100644 include/asm-arm/plat-s3c/iic.h delete mode 100644 include/asm-arm/plat-s3c/regs-iic.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c/iic.h b/include/asm-arm/plat-s3c/iic.h deleted file mode 100644 index 5106acaa1d0..00000000000 --- a/include/asm-arm/plat-s3c/iic.h +++ /dev/null @@ -1,33 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/iic.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks - * - * S3C2410 - I2C Controller platfrom_device info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_IIC_H -#define __ASM_ARCH_IIC_H __FILE__ - -#define S3C_IICFLG_FILTER (1<<0) /* enable s3c2440 filter */ - -/* Notes: - * 1) All frequencies are expressed in Hz - * 2) A value of zero is `do not care` -*/ - -struct s3c2410_platform_i2c { - int bus_num; /* bus number to use */ - unsigned int flags; - unsigned int slave_addr; /* slave address for controller */ - unsigned long bus_freq; /* standard bus frequency */ - unsigned long max_freq; /* max frequency for the bus */ - unsigned long min_freq; /* min frequency for the bus */ - unsigned int sda_delay; /* pclks (s3c2440 only) */ -}; - -#endif /* __ASM_ARCH_IIC_H */ diff --git a/include/asm-arm/plat-s3c/regs-iic.h b/include/asm-arm/plat-s3c/regs-iic.h deleted file mode 100644 index 2f7c17de8ac..00000000000 --- a/include/asm-arm/plat-s3c/regs-iic.h +++ /dev/null @@ -1,56 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-iic.h - * - * Copyright (c) 2004 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 I2C Controller -*/ - -#ifndef __ASM_ARCH_REGS_IIC_H -#define __ASM_ARCH_REGS_IIC_H __FILE__ - -/* see s3c2410x user guide, v1.1, section 9 (p447) for more info */ - -#define S3C2410_IICREG(x) (x) - -#define S3C2410_IICCON S3C2410_IICREG(0x00) -#define S3C2410_IICSTAT S3C2410_IICREG(0x04) -#define S3C2410_IICADD S3C2410_IICREG(0x08) -#define S3C2410_IICDS S3C2410_IICREG(0x0C) -#define S3C2440_IICLC S3C2410_IICREG(0x10) - -#define S3C2410_IICCON_ACKEN (1<<7) -#define S3C2410_IICCON_TXDIV_16 (0<<6) -#define S3C2410_IICCON_TXDIV_512 (1<<6) -#define S3C2410_IICCON_IRQEN (1<<5) -#define S3C2410_IICCON_IRQPEND (1<<4) -#define S3C2410_IICCON_SCALE(x) ((x)&15) -#define S3C2410_IICCON_SCALEMASK (0xf) - -#define S3C2410_IICSTAT_MASTER_RX (2<<6) -#define S3C2410_IICSTAT_MASTER_TX (3<<6) -#define S3C2410_IICSTAT_SLAVE_RX (0<<6) -#define S3C2410_IICSTAT_SLAVE_TX (1<<6) -#define S3C2410_IICSTAT_MODEMASK (3<<6) - -#define S3C2410_IICSTAT_START (1<<5) -#define S3C2410_IICSTAT_BUSBUSY (1<<5) -#define S3C2410_IICSTAT_TXRXEN (1<<4) -#define S3C2410_IICSTAT_ARBITR (1<<3) -#define S3C2410_IICSTAT_ASSLAVE (1<<2) -#define S3C2410_IICSTAT_ADDR0 (1<<1) -#define S3C2410_IICSTAT_LASTBIT (1<<0) - -#define S3C2410_IICLC_SDA_DELAY0 (0 << 0) -#define S3C2410_IICLC_SDA_DELAY5 (1 << 0) -#define S3C2410_IICLC_SDA_DELAY10 (2 << 0) -#define S3C2410_IICLC_SDA_DELAY15 (3 << 0) -#define S3C2410_IICLC_SDA_DELAY_MASK (3 << 0) - -#define S3C2410_IICLC_FILTER_ON (1<<2) - -#endif /* __ASM_ARCH_REGS_IIC_H */ -- cgit v1.2.3 From e2cd00cfebd9a25e0e09712b0116ef18edc2cd98 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:34 +0000 Subject: [ARM] S3C: Move regs-rtc.h to arch/arm/plat-s3c/include/plat Move regs-rtc.h to arch/arm/plat-s3c/include/plat ready to clean out old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/regs-rtc.h | 61 ------------------------------------- 1 file changed, 61 deletions(-) delete mode 100644 include/asm-arm/plat-s3c/regs-rtc.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c/regs-rtc.h b/include/asm-arm/plat-s3c/regs-rtc.h deleted file mode 100644 index d5837cf8e40..00000000000 --- a/include/asm-arm/plat-s3c/regs-rtc.h +++ /dev/null @@ -1,61 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-rtc.h - * - * Copyright (c) 2003 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 Internal RTC register definition -*/ - -#ifndef __ASM_ARCH_REGS_RTC_H -#define __ASM_ARCH_REGS_RTC_H __FILE__ - -#define S3C2410_RTCREG(x) (x) - -#define S3C2410_RTCCON S3C2410_RTCREG(0x40) -#define S3C2410_RTCCON_RTCEN (1<<0) -#define S3C2410_RTCCON_CLKSEL (1<<1) -#define S3C2410_RTCCON_CNTSEL (1<<2) -#define S3C2410_RTCCON_CLKRST (1<<3) - -#define S3C2410_TICNT S3C2410_RTCREG(0x44) -#define S3C2410_TICNT_ENABLE (1<<7) - -#define S3C2410_RTCALM S3C2410_RTCREG(0x50) -#define S3C2410_RTCALM_ALMEN (1<<6) -#define S3C2410_RTCALM_YEAREN (1<<5) -#define S3C2410_RTCALM_MONEN (1<<4) -#define S3C2410_RTCALM_DAYEN (1<<3) -#define S3C2410_RTCALM_HOUREN (1<<2) -#define S3C2410_RTCALM_MINEN (1<<1) -#define S3C2410_RTCALM_SECEN (1<<0) - -#define S3C2410_RTCALM_ALL \ - S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\ - S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\ - S3C2410_RTCALM_SECEN - - -#define S3C2410_ALMSEC S3C2410_RTCREG(0x54) -#define S3C2410_ALMMIN S3C2410_RTCREG(0x58) -#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c) - -#define S3C2410_ALMDATE S3C2410_RTCREG(0x60) -#define S3C2410_ALMMON S3C2410_RTCREG(0x64) -#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68) - -#define S3C2410_RTCRST S3C2410_RTCREG(0x6c) - -#define S3C2410_RTCSEC S3C2410_RTCREG(0x70) -#define S3C2410_RTCMIN S3C2410_RTCREG(0x74) -#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78) -#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c) -#define S3C2410_RTCDAY S3C2410_RTCREG(0x80) -#define S3C2410_RTCMON S3C2410_RTCREG(0x84) -#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88) - - -#endif /* __ASM_ARCH_REGS_RTC_H */ -- cgit v1.2.3 From 7926b5a325f06745a1bed75bfb4ef814d0ae9d99 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:35 +0000 Subject: [ARM] S3C: Move nand headers to arch/arm/plat-s3c/include/plat Move nand headers to arch/arm/plat-s3c/include/plat ready to clean out the old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/nand.h | 50 -------------- include/asm-arm/plat-s3c/regs-nand.h | 123 ----------------------------------- 2 files changed, 173 deletions(-) delete mode 100644 include/asm-arm/plat-s3c/nand.h delete mode 100644 include/asm-arm/plat-s3c/regs-nand.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c/nand.h b/include/asm-arm/plat-s3c/nand.h deleted file mode 100644 index f4dcd14af05..00000000000 --- a/include/asm-arm/plat-s3c/nand.h +++ /dev/null @@ -1,50 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/nand.h - * - * Copyright (c) 2004 Simtec Electronics - * Ben Dooks - * - * S3C2410 - NAND device controller platfrom_device info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -/* struct s3c2410_nand_set - * - * define an set of one or more nand chips registered with an unique mtd - * - * nr_chips = number of chips in this set - * nr_partitions = number of partitions pointed to be partitoons (or zero) - * name = name of set (optional) - * nr_map = map for low-layer logical to physical chip numbers (option) - * partitions = mtd partition list -*/ - -struct s3c2410_nand_set { - unsigned int disable_ecc : 1; - - int nr_chips; - int nr_partitions; - char *name; - int *nr_map; - struct mtd_partition *partitions; - struct nand_ecclayout *ecc_layout; -}; - -struct s3c2410_platform_nand { - /* timing information for controller, all times in nanoseconds */ - - int tacls; /* time for active CLE/ALE to nWE/nOE */ - int twrph0; /* active time for nWE/nOE */ - int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */ - - unsigned int ignore_unset_ecc : 1; - - int nr_sets; - struct s3c2410_nand_set *sets; - - void (*select_chip)(struct s3c2410_nand_set *, - int chip); -}; - diff --git a/include/asm-arm/plat-s3c/regs-nand.h b/include/asm-arm/plat-s3c/regs-nand.h deleted file mode 100644 index b2caa4bca27..00000000000 --- a/include/asm-arm/plat-s3c/regs-nand.h +++ /dev/null @@ -1,123 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-nand.h - * - * Copyright (c) 2004,2005 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 NAND register definitions -*/ - -#ifndef __ASM_ARM_REGS_NAND -#define __ASM_ARM_REGS_NAND - - -#define S3C2410_NFREG(x) (x) - -#define S3C2410_NFCONF S3C2410_NFREG(0x00) -#define S3C2410_NFCMD S3C2410_NFREG(0x04) -#define S3C2410_NFADDR S3C2410_NFREG(0x08) -#define S3C2410_NFDATA S3C2410_NFREG(0x0C) -#define S3C2410_NFSTAT S3C2410_NFREG(0x10) -#define S3C2410_NFECC S3C2410_NFREG(0x14) - -#define S3C2440_NFCONT S3C2410_NFREG(0x04) -#define S3C2440_NFCMD S3C2410_NFREG(0x08) -#define S3C2440_NFADDR S3C2410_NFREG(0x0C) -#define S3C2440_NFDATA S3C2410_NFREG(0x10) -#define S3C2440_NFECCD0 S3C2410_NFREG(0x14) -#define S3C2440_NFECCD1 S3C2410_NFREG(0x18) -#define S3C2440_NFECCD S3C2410_NFREG(0x1C) -#define S3C2440_NFSTAT S3C2410_NFREG(0x20) -#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24) -#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28) -#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) -#define S3C2440_NFMECC1 S3C2410_NFREG(0x30) -#define S3C2440_NFSECC S3C2410_NFREG(0x34) -#define S3C2440_NFSBLK S3C2410_NFREG(0x38) -#define S3C2440_NFEBLK S3C2410_NFREG(0x3C) - -#define S3C2412_NFSBLK S3C2410_NFREG(0x20) -#define S3C2412_NFEBLK S3C2410_NFREG(0x24) -#define S3C2412_NFSTAT S3C2410_NFREG(0x28) -#define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C) -#define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30) -#define S3C2412_NFMECC0 S3C2410_NFREG(0x34) -#define S3C2412_NFMECC1 S3C2410_NFREG(0x38) -#define S3C2412_NFSECC S3C2410_NFREG(0x3C) - -#define S3C2410_NFCONF_EN (1<<15) -#define S3C2410_NFCONF_512BYTE (1<<14) -#define S3C2410_NFCONF_4STEP (1<<13) -#define S3C2410_NFCONF_INITECC (1<<12) -#define S3C2410_NFCONF_nFCE (1<<11) -#define S3C2410_NFCONF_TACLS(x) ((x)<<8) -#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) -#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) - -#define S3C2410_NFSTAT_BUSY (1<<0) - -#define S3C2440_NFCONF_BUSWIDTH_8 (0<<0) -#define S3C2440_NFCONF_BUSWIDTH_16 (1<<0) -#define S3C2440_NFCONF_ADVFLASH (1<<3) -#define S3C2440_NFCONF_TACLS(x) ((x)<<12) -#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) -#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4) - -#define S3C2440_NFCONT_LOCKTIGHT (1<<13) -#define S3C2440_NFCONT_SOFTLOCK (1<<12) -#define S3C2440_NFCONT_ILLEGALACC_EN (1<<10) -#define S3C2440_NFCONT_RNBINT_EN (1<<9) -#define S3C2440_NFCONT_RN_FALLING (1<<8) -#define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6) -#define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5) -#define S3C2440_NFCONT_INITECC (1<<4) -#define S3C2440_NFCONT_nFCE (1<<1) -#define S3C2440_NFCONT_ENABLE (1<<0) - -#define S3C2440_NFSTAT_READY (1<<0) -#define S3C2440_NFSTAT_nCE (1<<1) -#define S3C2440_NFSTAT_RnB_CHANGE (1<<2) -#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3) - -#define S3C2412_NFCONF_NANDBOOT (1<<31) -#define S3C2412_NFCONF_ECCCLKCON (1<<30) -#define S3C2412_NFCONF_ECC_MLC (1<<24) -#define S3C2412_NFCONF_TACLS_MASK (7<<12) /* 1 extra bit of Tacls */ - -#define S3C2412_NFCONT_ECC4_DIRWR (1<<18) -#define S3C2412_NFCONT_LOCKTIGHT (1<<17) -#define S3C2412_NFCONT_SOFTLOCK (1<<16) -#define S3C2412_NFCONT_ECC4_ENCINT (1<<13) -#define S3C2412_NFCONT_ECC4_DECINT (1<<12) -#define S3C2412_NFCONT_MAIN_ECC_LOCK (1<<7) -#define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5) -#define S3C2412_NFCONT_nFCE1 (1<<2) -#define S3C2412_NFCONT_nFCE0 (1<<1) - -#define S3C2412_NFSTAT_ECC_ENCDONE (1<<7) -#define S3C2412_NFSTAT_ECC_DECDONE (1<<6) -#define S3C2412_NFSTAT_ILLEGAL_ACCESS (1<<5) -#define S3C2412_NFSTAT_RnB_CHANGE (1<<4) -#define S3C2412_NFSTAT_nFCE1 (1<<3) -#define S3C2412_NFSTAT_nFCE0 (1<<2) -#define S3C2412_NFSTAT_Res1 (1<<1) -#define S3C2412_NFSTAT_READY (1<<0) - -#define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf) -#define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7) -#define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff) -#define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7) -#define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3) -#define S3C2412_NFECCERR_NONE (0) -#define S3C2412_NFECCERR_1BIT (1) -#define S3C2412_NFECCERR_MULTIBIT (2) -#define S3C2412_NFECCERR_ECCAREA (3) - - - -#endif /* __ASM_ARM_REGS_NAND */ - -- cgit v1.2.3 From f74c95c20bad8e183e41283475f68a3e7b247af4 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:36 +0000 Subject: [ARM] S3C: Move regs-ac97.h to arch/arm/plat-s3c/include/plat. Move regs-ac97.h to arch/arm/plat-s3c/include/plat ready to clean out old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c/regs-ac97.h | 67 ------------------------------------ 1 file changed, 67 deletions(-) delete mode 100644 include/asm-arm/plat-s3c/regs-ac97.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c/regs-ac97.h b/include/asm-arm/plat-s3c/regs-ac97.h deleted file mode 100644 index c3878f7acb8..00000000000 --- a/include/asm-arm/plat-s3c/regs-ac97.h +++ /dev/null @@ -1,67 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-ac97.h - * - * Copyright (c) 2006 Simtec Electronics - * http://www.simtec.co.uk/products/SWLINUX/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2440 AC97 Controller -*/ - -#ifndef __ASM_ARCH_REGS_AC97_H -#define __ASM_ARCH_REGS_AC97_H __FILE__ - -#define S3C_AC97_GLBCTRL (0x00) - -#define S3C_AC97_GLBCTRL_CODECREADYIE (1<<22) -#define S3C_AC97_GLBCTRL_PCMOUTURIE (1<<21) -#define S3C_AC97_GLBCTRL_PCMINORIE (1<<20) -#define S3C_AC97_GLBCTRL_MICINORIE (1<<19) -#define S3C_AC97_GLBCTRL_PCMOUTTIE (1<<18) -#define S3C_AC97_GLBCTRL_PCMINTIE (1<<17) -#define S3C_AC97_GLBCTRL_MICINTIE (1<<16) -#define S3C_AC97_GLBCTRL_PCMOUTTM_OFF (0<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_PIO (1<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_DMA (2<<12) -#define S3C_AC97_GLBCTRL_PCMOUTTM_MASK (3<<12) -#define S3C_AC97_GLBCTRL_PCMINTM_OFF (0<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_PIO (1<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_DMA (2<<10) -#define S3C_AC97_GLBCTRL_PCMINTM_MASK (3<<10) -#define S3C_AC97_GLBCTRL_MICINTM_OFF (0<<8) -#define S3C_AC97_GLBCTRL_MICINTM_PIO (1<<8) -#define S3C_AC97_GLBCTRL_MICINTM_DMA (2<<8) -#define S3C_AC97_GLBCTRL_MICINTM_MASK (3<<8) -#define S3C_AC97_GLBCTRL_TRANSFERDATAENABLE (1<<3) -#define S3C_AC97_GLBCTRL_ACLINKON (1<<2) -#define S3C_AC97_GLBCTRL_WARMRESET (1<<1) -#define S3C_AC97_GLBCTRL_COLDRESET (1<<0) - -#define S3C_AC97_GLBSTAT (0x04) - -#define S3C_AC97_GLBSTAT_CODECREADY (1<<22) -#define S3C_AC97_GLBSTAT_PCMOUTUR (1<<21) -#define S3C_AC97_GLBSTAT_PCMINORI (1<<20) -#define S3C_AC97_GLBSTAT_MICINORI (1<<19) -#define S3C_AC97_GLBSTAT_PCMOUTTI (1<<18) -#define S3C_AC97_GLBSTAT_PCMINTI (1<<17) -#define S3C_AC97_GLBSTAT_MICINTI (1<<16) -#define S3C_AC97_GLBSTAT_MAINSTATE_IDLE (0<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_INIT (1<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_READY (2<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE (3<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_LP (4<<0) -#define S3C_AC97_GLBSTAT_MAINSTATE_WARM (5<<0) - -#define S3C_AC97_CODEC_CMD (0x08) - -#define S3C_AC97_CODEC_CMD_READ (1<<23) - -#define S3C_AC97_STAT (0x0c) -#define S3C_AC97_PCM_ADDR (0x10) -#define S3C_AC97_PCM_DATA (0x18) -#define S3C_AC97_MIC_DATA (0x1C) - -#endif /* __ASM_ARCH_REGS_AC97_H */ -- cgit v1.2.3 From 57bd4b91a6cfc5bad4c5d829ef85293ea63643ea Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:37 +0000 Subject: [ARM] S3C24XX: Movev udc headers to arch/arm/plat-s3c24xx/include/plat Move the udc headers to the proper home in arch/arm/plat-s3c24xx/include/plat ready to clean out the old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c24xx/regs-udc.h | 153 -------------------------------- include/asm-arm/plat-s3c24xx/udc.h | 36 -------- 2 files changed, 189 deletions(-) delete mode 100644 include/asm-arm/plat-s3c24xx/regs-udc.h delete mode 100644 include/asm-arm/plat-s3c24xx/udc.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c24xx/regs-udc.h b/include/asm-arm/plat-s3c24xx/regs-udc.h deleted file mode 100644 index f0dd4a41b37..00000000000 --- a/include/asm-arm/plat-s3c24xx/regs-udc.h +++ /dev/null @@ -1,153 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-udc.h - * - * Copyright (C) 2004 Herbert Poetzl - * - * This include file is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. -*/ - -#ifndef __ASM_ARCH_REGS_UDC_H -#define __ASM_ARCH_REGS_UDC_H - -#define S3C2410_USBDREG(x) (x) - -#define S3C2410_UDC_FUNC_ADDR_REG S3C2410_USBDREG(0x0140) -#define S3C2410_UDC_PWR_REG S3C2410_USBDREG(0x0144) -#define S3C2410_UDC_EP_INT_REG S3C2410_USBDREG(0x0148) - -#define S3C2410_UDC_USB_INT_REG S3C2410_USBDREG(0x0158) -#define S3C2410_UDC_EP_INT_EN_REG S3C2410_USBDREG(0x015c) - -#define S3C2410_UDC_USB_INT_EN_REG S3C2410_USBDREG(0x016c) - -#define S3C2410_UDC_FRAME_NUM1_REG S3C2410_USBDREG(0x0170) -#define S3C2410_UDC_FRAME_NUM2_REG S3C2410_USBDREG(0x0174) - -#define S3C2410_UDC_EP0_FIFO_REG S3C2410_USBDREG(0x01c0) -#define S3C2410_UDC_EP1_FIFO_REG S3C2410_USBDREG(0x01c4) -#define S3C2410_UDC_EP2_FIFO_REG S3C2410_USBDREG(0x01c8) -#define S3C2410_UDC_EP3_FIFO_REG S3C2410_USBDREG(0x01cc) -#define S3C2410_UDC_EP4_FIFO_REG S3C2410_USBDREG(0x01d0) - -#define S3C2410_UDC_EP1_DMA_CON S3C2410_USBDREG(0x0200) -#define S3C2410_UDC_EP1_DMA_UNIT S3C2410_USBDREG(0x0204) -#define S3C2410_UDC_EP1_DMA_FIFO S3C2410_USBDREG(0x0208) -#define S3C2410_UDC_EP1_DMA_TTC_L S3C2410_USBDREG(0x020c) -#define S3C2410_UDC_EP1_DMA_TTC_M S3C2410_USBDREG(0x0210) -#define S3C2410_UDC_EP1_DMA_TTC_H S3C2410_USBDREG(0x0214) - -#define S3C2410_UDC_EP2_DMA_CON S3C2410_USBDREG(0x0218) -#define S3C2410_UDC_EP2_DMA_UNIT S3C2410_USBDREG(0x021c) -#define S3C2410_UDC_EP2_DMA_FIFO S3C2410_USBDREG(0x0220) -#define S3C2410_UDC_EP2_DMA_TTC_L S3C2410_USBDREG(0x0224) -#define S3C2410_UDC_EP2_DMA_TTC_M S3C2410_USBDREG(0x0228) -#define S3C2410_UDC_EP2_DMA_TTC_H S3C2410_USBDREG(0x022c) - -#define S3C2410_UDC_EP3_DMA_CON S3C2410_USBDREG(0x0240) -#define S3C2410_UDC_EP3_DMA_UNIT S3C2410_USBDREG(0x0244) -#define S3C2410_UDC_EP3_DMA_FIFO S3C2410_USBDREG(0x0248) -#define S3C2410_UDC_EP3_DMA_TTC_L S3C2410_USBDREG(0x024c) -#define S3C2410_UDC_EP3_DMA_TTC_M S3C2410_USBDREG(0x0250) -#define S3C2410_UDC_EP3_DMA_TTC_H S3C2410_USBDREG(0x0254) - -#define S3C2410_UDC_EP4_DMA_CON S3C2410_USBDREG(0x0258) -#define S3C2410_UDC_EP4_DMA_UNIT S3C2410_USBDREG(0x025c) -#define S3C2410_UDC_EP4_DMA_FIFO S3C2410_USBDREG(0x0260) -#define S3C2410_UDC_EP4_DMA_TTC_L S3C2410_USBDREG(0x0264) -#define S3C2410_UDC_EP4_DMA_TTC_M S3C2410_USBDREG(0x0268) -#define S3C2410_UDC_EP4_DMA_TTC_H S3C2410_USBDREG(0x026c) - -#define S3C2410_UDC_INDEX_REG S3C2410_USBDREG(0x0178) - -/* indexed registers */ - -#define S3C2410_UDC_MAXP_REG S3C2410_USBDREG(0x0180) - -#define S3C2410_UDC_EP0_CSR_REG S3C2410_USBDREG(0x0184) - -#define S3C2410_UDC_IN_CSR1_REG S3C2410_USBDREG(0x0184) -#define S3C2410_UDC_IN_CSR2_REG S3C2410_USBDREG(0x0188) - -#define S3C2410_UDC_OUT_CSR1_REG S3C2410_USBDREG(0x0190) -#define S3C2410_UDC_OUT_CSR2_REG S3C2410_USBDREG(0x0194) -#define S3C2410_UDC_OUT_FIFO_CNT1_REG S3C2410_USBDREG(0x0198) -#define S3C2410_UDC_OUT_FIFO_CNT2_REG S3C2410_USBDREG(0x019c) - -#define S3C2410_UDC_FUNCADDR_UPDATE (1<<7) - -#define S3C2410_UDC_PWR_ISOUP (1<<7) // R/W -#define S3C2410_UDC_PWR_RESET (1<<3) // R -#define S3C2410_UDC_PWR_RESUME (1<<2) // R/W -#define S3C2410_UDC_PWR_SUSPEND (1<<1) // R -#define S3C2410_UDC_PWR_ENSUSPEND (1<<0) // R/W - -#define S3C2410_UDC_PWR_DEFAULT 0x00 - -#define S3C2410_UDC_INT_EP4 (1<<4) // R/W (clear only) -#define S3C2410_UDC_INT_EP3 (1<<3) // R/W (clear only) -#define S3C2410_UDC_INT_EP2 (1<<2) // R/W (clear only) -#define S3C2410_UDC_INT_EP1 (1<<1) // R/W (clear only) -#define S3C2410_UDC_INT_EP0 (1<<0) // R/W (clear only) - -#define S3C2410_UDC_USBINT_RESET (1<<2) // R/W (clear only) -#define S3C2410_UDC_USBINT_RESUME (1<<1) // R/W (clear only) -#define S3C2410_UDC_USBINT_SUSPEND (1<<0) // R/W (clear only) - -#define S3C2410_UDC_INTE_EP4 (1<<4) // R/W -#define S3C2410_UDC_INTE_EP3 (1<<3) // R/W -#define S3C2410_UDC_INTE_EP2 (1<<2) // R/W -#define S3C2410_UDC_INTE_EP1 (1<<1) // R/W -#define S3C2410_UDC_INTE_EP0 (1<<0) // R/W - -#define S3C2410_UDC_USBINTE_RESET (1<<2) // R/W -#define S3C2410_UDC_USBINTE_SUSPEND (1<<0) // R/W - - -#define S3C2410_UDC_INDEX_EP0 (0x00) -#define S3C2410_UDC_INDEX_EP1 (0x01) // ?? -#define S3C2410_UDC_INDEX_EP2 (0x02) // ?? -#define S3C2410_UDC_INDEX_EP3 (0x03) // ?? -#define S3C2410_UDC_INDEX_EP4 (0x04) // ?? - -#define S3C2410_UDC_ICSR1_CLRDT (1<<6) // R/W -#define S3C2410_UDC_ICSR1_SENTSTL (1<<5) // R/W (clear only) -#define S3C2410_UDC_ICSR1_SENDSTL (1<<4) // R/W -#define S3C2410_UDC_ICSR1_FFLUSH (1<<3) // W (set only) -#define S3C2410_UDC_ICSR1_UNDRUN (1<<2) // R/W (clear only) -#define S3C2410_UDC_ICSR1_PKTRDY (1<<0) // R/W (set only) - -#define S3C2410_UDC_ICSR2_AUTOSET (1<<7) // R/W -#define S3C2410_UDC_ICSR2_ISO (1<<6) // R/W -#define S3C2410_UDC_ICSR2_MODEIN (1<<5) // R/W -#define S3C2410_UDC_ICSR2_DMAIEN (1<<4) // R/W - -#define S3C2410_UDC_OCSR1_CLRDT (1<<7) // R/W -#define S3C2410_UDC_OCSR1_SENTSTL (1<<6) // R/W (clear only) -#define S3C2410_UDC_OCSR1_SENDSTL (1<<5) // R/W -#define S3C2410_UDC_OCSR1_FFLUSH (1<<4) // R/W -#define S3C2410_UDC_OCSR1_DERROR (1<<3) // R -#define S3C2410_UDC_OCSR1_OVRRUN (1<<2) // R/W (clear only) -#define S3C2410_UDC_OCSR1_PKTRDY (1<<0) // R/W (clear only) - -#define S3C2410_UDC_OCSR2_AUTOCLR (1<<7) // R/W -#define S3C2410_UDC_OCSR2_ISO (1<<6) // R/W -#define S3C2410_UDC_OCSR2_DMAIEN (1<<5) // R/W - -#define S3C2410_UDC_EP0_CSR_OPKRDY (1<<0) -#define S3C2410_UDC_EP0_CSR_IPKRDY (1<<1) -#define S3C2410_UDC_EP0_CSR_SENTSTL (1<<2) -#define S3C2410_UDC_EP0_CSR_DE (1<<3) -#define S3C2410_UDC_EP0_CSR_SE (1<<4) -#define S3C2410_UDC_EP0_CSR_SENDSTL (1<<5) -#define S3C2410_UDC_EP0_CSR_SOPKTRDY (1<<6) -#define S3C2410_UDC_EP0_CSR_SSE (1<<7) - -#define S3C2410_UDC_MAXP_8 (1<<0) -#define S3C2410_UDC_MAXP_16 (1<<1) -#define S3C2410_UDC_MAXP_32 (1<<2) -#define S3C2410_UDC_MAXP_64 (1<<3) - - -#endif diff --git a/include/asm-arm/plat-s3c24xx/udc.h b/include/asm-arm/plat-s3c24xx/udc.h deleted file mode 100644 index 546bb4008f4..00000000000 --- a/include/asm-arm/plat-s3c24xx/udc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/udc.h - * - * Copyright (c) 2005 Arnaud Patard - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * - * Changelog: - * 14-Mar-2005 RTP Created file - * 02-Aug-2005 RTP File rename - * 07-Sep-2005 BJD Minor cleanups, changed cmd to enum - * 18-Jan-2007 HMW Add per-platform vbus_draw function -*/ - -#ifndef __ASM_ARM_ARCH_UDC_H -#define __ASM_ARM_ARCH_UDC_H - -enum s3c2410_udc_cmd_e { - S3C2410_UDC_P_ENABLE = 1, /* Pull-up enable */ - S3C2410_UDC_P_DISABLE = 2, /* Pull-up disable */ - S3C2410_UDC_P_RESET = 3, /* UDC reset, in case of */ -}; - -struct s3c2410_udc_mach_info { - void (*udc_command)(enum s3c2410_udc_cmd_e); - void (*vbus_draw)(unsigned int ma); - unsigned int vbus_pin; - unsigned char vbus_pin_inverted; -}; - -extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *); - -#endif /* __ASM_ARM_ARCH_UDC_H */ -- cgit v1.2.3 From 13622708725990b01fbc6d59d54d93820a726d7c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:38 +0000 Subject: [ARM] S3C: Move plat/regs-spi.h to arch/arm/plat-s3c/include/plat. Move plat/regs-spi.h to arch/arm/plat-s3c/include/plat ready ready to clean out old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c24xx/regs-spi.h | 82 --------------------------------- 1 file changed, 82 deletions(-) delete mode 100644 include/asm-arm/plat-s3c24xx/regs-spi.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c24xx/regs-spi.h b/include/asm-arm/plat-s3c24xx/regs-spi.h deleted file mode 100644 index 2b35479ee35..00000000000 --- a/include/asm-arm/plat-s3c24xx/regs-spi.h +++ /dev/null @@ -1,82 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/regs-spi.h - * - * Copyright (c) 2004 Fetron GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * S3C2410 SPI register definition -*/ - -#ifndef __ASM_ARCH_REGS_SPI_H -#define __ASM_ARCH_REGS_SPI_H - -#define S3C2410_SPI1 (0x20) -#define S3C2412_SPI1 (0x100) - -#define S3C2410_SPCON (0x00) - -#define S3C2412_SPCON_RXFIFO_RB2 (0<<14) -#define S3C2412_SPCON_RXFIFO_RB4 (1<<14) -#define S3C2412_SPCON_RXFIFO_RB12 (2<<14) -#define S3C2412_SPCON_RXFIFO_RB14 (3<<14) -#define S3C2412_SPCON_TXFIFO_RB2 (0<<12) -#define S3C2412_SPCON_TXFIFO_RB4 (1<<12) -#define S3C2412_SPCON_TXFIFO_RB12 (2<<12) -#define S3C2412_SPCON_TXFIFO_RB14 (3<<12) -#define S3C2412_SPCON_RXFIFO_RESET (1<<11) /* RxFIFO reset */ -#define S3C2412_SPCON_TXFIFO_RESET (1<<10) /* TxFIFO reset */ -#define S3C2412_SPCON_RXFIFO_EN (1<<9) /* RxFIFO Enable */ -#define S3C2412_SPCON_TXFIFO_EN (1<<8) /* TxFIFO Enable */ - -#define S3C2412_SPCON_DIRC_RX (1<<7) - -#define S3C2410_SPCON_SMOD_DMA (2<<5) /* DMA mode */ -#define S3C2410_SPCON_SMOD_INT (1<<5) /* interrupt mode */ -#define S3C2410_SPCON_SMOD_POLL (0<<5) /* polling mode */ -#define S3C2410_SPCON_ENSCK (1<<4) /* Enable SCK */ -#define S3C2410_SPCON_MSTR (1<<3) /* Master/Slave select - 0: slave, 1: master */ -#define S3C2410_SPCON_CPOL_HIGH (1<<2) /* Clock polarity select */ -#define S3C2410_SPCON_CPOL_LOW (0<<2) /* Clock polarity select */ - -#define S3C2410_SPCON_CPHA_FMTB (1<<1) /* Clock Phase Select */ -#define S3C2410_SPCON_CPHA_FMTA (0<<1) /* Clock Phase Select */ - -#define S3C2410_SPCON_TAGD (1<<0) /* Tx auto garbage data mode */ - - -#define S3C2410_SPSTA (0x04) - -#define S3C2412_SPSTA_RXFIFO_AE (1<<11) -#define S3C2412_SPSTA_TXFIFO_AE (1<<10) -#define S3C2412_SPSTA_RXFIFO_ERROR (1<<9) -#define S3C2412_SPSTA_TXFIFO_ERROR (1<<8) -#define S3C2412_SPSTA_RXFIFO_FIFO (1<<7) -#define S3C2412_SPSTA_RXFIFO_EMPTY (1<<6) -#define S3C2412_SPSTA_TXFIFO_NFULL (1<<5) -#define S3C2412_SPSTA_TXFIFO_EMPTY (1<<4) - -#define S3C2410_SPSTA_DCOL (1<<2) /* Data Collision Error */ -#define S3C2410_SPSTA_MULD (1<<1) /* Multi Master Error */ -#define S3C2410_SPSTA_READY (1<<0) /* Data Tx/Rx ready */ -#define S3C2412_SPSTA_READY_ORG (1<<3) - -#define S3C2410_SPPIN (0x08) - -#define S3C2410_SPPIN_ENMUL (1<<2) /* Multi Master Error detect */ -#define S3C2410_SPPIN_RESERVED (1<<1) -#define S3C2400_SPPIN_nCS (1<<1) /* SPI Card Select */ -#define S3C2410_SPPIN_KEEP (1<<0) /* Master Out keep */ - -#define S3C2410_SPPRE (0x0C) -#define S3C2410_SPTDAT (0x10) -#define S3C2410_SPRDAT (0x14) - -#define S3C2412_TXFIFO (0x18) -#define S3C2412_RXFIFO (0x18) -#define S3C2412_SPFIC (0x24) - - -#endif /* __ASM_ARCH_REGS_SPI_H */ -- cgit v1.2.3 From e3bd9ec5d8bfc90f9e1bd995677829e57a404061 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Thu, 30 Oct 2008 10:14:39 +0000 Subject: [ARM] S3C24XX: Move mci.h to arch/arm/plat-s3c24xx/include/plat Move mci.h to new position in arch/arm/plat-s3c24xx/include/plat ready to clean out old include directories. Signed-off-by: Ben Dooks --- include/asm-arm/plat-s3c24xx/mci.h | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 include/asm-arm/plat-s3c24xx/mci.h (limited to 'include') diff --git a/include/asm-arm/plat-s3c24xx/mci.h b/include/asm-arm/plat-s3c24xx/mci.h deleted file mode 100644 index 2d0852ac3b2..00000000000 --- a/include/asm-arm/plat-s3c24xx/mci.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _ARCH_MCI_H -#define _ARCH_MCI_H - -struct s3c24xx_mci_pdata { - unsigned int wprotect_invert : 1; - unsigned int detect_invert : 1; /* set => detect active high. */ - - unsigned int gpio_detect; - unsigned int gpio_wprotect; - unsigned long ocr_avail; - void (*set_power)(unsigned char power_mode, - unsigned short vdd); -}; - -#endif /* _ARCH_NCI_H */ -- cgit v1.2.3 From d98d38f2014ab79f28c126ff175d034891f7aefc Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 29 Oct 2008 14:24:09 -0700 Subject: mutex: improve header comment to be actually informative about the API Impact: improve documentation It's nice to say that mutex_trylock follows the spin_trylock convention. It's a lot nicer if the comment also says which that is... make it so. Signed-off-by: Arjan van de Ven Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton --- include/linux/mutex.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/mutex.h b/include/linux/mutex.h index bc6da10ceee..7a0e5c4f807 100644 --- a/include/linux/mutex.h +++ b/include/linux/mutex.h @@ -144,6 +144,8 @@ extern int __must_check mutex_lock_killable(struct mutex *lock); /* * NOTE: mutex_trylock() follows the spin_trylock() convention, * not the down_trylock() convention! + * + * Returns 1 if the mutex has been acquired successfully, and 0 on contention. */ extern int mutex_trylock(struct mutex *lock); extern void mutex_unlock(struct mutex *lock); -- cgit v1.2.3 From 29cbda77a67cf263d636feea65d3bbc9c7de2e24 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Mon, 3 Nov 2008 09:16:39 -0800 Subject: rcu: increase RCU stall-check timeouts Impact: increase timeout of debug check feature Increase RCU stall period timeouts to reduce the likelyhood of false positives. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 5f89b62e698..301dda829e3 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -41,7 +41,7 @@ #include #ifdef CONFIG_RCU_CPU_STALL_DETECTOR -#define RCU_SECONDS_TILL_STALL_CHECK ( 3 * HZ) /* for rcp->jiffies_stall */ +#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ) /* for rcp->jiffies_stall */ #define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rcp->jiffies_stall */ #endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ -- cgit v1.2.3 From e25cf3db560e803292946ef23a30c69e341ce56f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 17 Oct 2008 15:55:07 +0200 Subject: lockdep: include/linux/lockdep.h - fix warning in net/bluetooth/af_bluetooth.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix this warning: net/bluetooth/af_bluetooth.c:60: warning: ‘bt_key_strings’ defined but not used net/bluetooth/af_bluetooth.c:71: warning: ‘bt_slock_key_strings’ defined but not used this is a lockdep macro problem in the !LOCKDEP case. We cannot convert it to an inline because the macro works on multiple types, but we can mark the parameter used. [ also clean up a misaligned tab in sock_lock_init_class_and_name() ] [ also remove #ifdefs from around af_family_clock_key strings - which were certainly added to get rid of the ugly build warnings. ] Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 5 +++-- include/net/sock.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index fc9f8e88123..8956daf64ab 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -336,10 +336,11 @@ static inline void lockdep_on(void) # define lock_set_subclass(l, s, i) do { } while (0) # define lockdep_init() do { } while (0) # define lockdep_info() do { } while (0) -# define lockdep_init_map(lock, name, key, sub) do { (void)(key); } while (0) +# define lockdep_init_map(lock, name, key, sub) \ + do { (void)(name); (void)(key); } while (0) # define lockdep_set_class(lock, key) do { (void)(key); } while (0) # define lockdep_set_class_and_name(lock, key, name) \ - do { (void)(key); } while (0) + do { (void)(key); (void)(name); } while (0) #define lockdep_set_class_and_subclass(lock, key, sub) \ do { (void)(key); } while (0) #define lockdep_set_subclass(lock, sub) do { } while (0) diff --git a/include/net/sock.h b/include/net/sock.h index c04f9e18ea2..2f47107f6d0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -815,7 +815,7 @@ static inline void sk_wmem_free_skb(struct sock *sk, struct sk_buff *skb) */ #define sock_lock_init_class_and_name(sk, sname, skey, name, key) \ do { \ - sk->sk_lock.owned = 0; \ + sk->sk_lock.owned = 0; \ init_waitqueue_head(&sk->sk_lock.wq); \ spin_lock_init(&(sk)->sk_lock.slock); \ debug_check_no_locks_freed((void *)&(sk)->sk_lock, \ -- cgit v1.2.3 From e262a7ba31f0cd4dae225e6d2e9037e5ac6108e8 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Sun, 23 Nov 2008 14:34:43 +0000 Subject: irq.h: remove padding from irq_desc on 64bits Impact: reduce struct irq_desc size struct irq_desc: reorder to remove padding on 64bits shrinks irq_desc to 128 bytes which saves data space & cache lines On a generic x86_64/SMP build this reduces the reported data size by 64k. Signed-off-by: Richard Kennedy Signed-off-by: Ingo Molnar --- include/linux/irq.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index d058c57be02..838a977885e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -142,8 +142,8 @@ struct irq_chip { * @depth: disable-depth, for nested irq_disable() calls * @wake_depth: enable depth, for multiple set_irq_wake() callers * @irq_count: stats field to detect stalled irqs - * @irqs_unhandled: stats field for spurious unhandled interrupts * @last_unhandled: aging timer for unhandled count + * @irqs_unhandled: stats field for spurious unhandled interrupts * @lock: locking for SMP * @affinity: IRQ affinity on SMP * @cpu: cpu index useful for balancing @@ -165,8 +165,8 @@ struct irq_desc { unsigned int depth; /* nested irq disables */ unsigned int wake_depth; /* nested wake enables */ unsigned int irq_count; /* For detecting broken IRQs */ - unsigned int irqs_unhandled; unsigned long last_unhandled; /* Aging timer for unhandled count */ + unsigned int irqs_unhandled; spinlock_t lock; #ifdef CONFIG_SMP cpumask_t affinity; -- cgit v1.2.3 From 1acdac104668a0834cfa267de9946fac7764d486 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 20 Nov 2008 10:02:53 -0800 Subject: futex: make clock selectable for FUTEX_WAIT_BITSET FUTEX_WAIT_BITSET could be used instead of FUTEX_WAIT by setting the bit set to FUTEX_BITSET_MATCH_ANY, but FUTEX_WAIT uses CLOCK_REALTIME while FUTEX_WAIT_BITSET uses CLOCK_MONOTONIC. Add a flag to select CLOCK_REALTIME for FUTEX_WAIT_BITSET so glibc can replace the FUTEX_WAIT logic which needs to do gettimeofday() calls before and after the syscall to convert the absolute timeout to a relative timeout for FUTEX_WAIT. Signed-off-by: Thomas Gleixner Cc: Ulrich Drepper --- include/linux/futex.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/futex.h b/include/linux/futex.h index 8f627b9ae2b..3bf5bb5a34f 100644 --- a/include/linux/futex.h +++ b/include/linux/futex.h @@ -25,7 +25,8 @@ union ktime; #define FUTEX_WAKE_BITSET 10 #define FUTEX_PRIVATE_FLAG 128 -#define FUTEX_CMD_MASK ~FUTEX_PRIVATE_FLAG +#define FUTEX_CLOCK_REALTIME 256 +#define FUTEX_CMD_MASK ~(FUTEX_PRIVATE_FLAG | FUTEX_CLOCK_REALTIME) #define FUTEX_WAIT_PRIVATE (FUTEX_WAIT | FUTEX_PRIVATE_FLAG) #define FUTEX_WAKE_PRIVATE (FUTEX_WAKE | FUTEX_PRIVATE_FLAG) -- cgit v1.2.3 From ca109491f612aab5c8152207631c0444f63da97f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 25 Nov 2008 12:43:51 +0100 Subject: hrtimer: removing all ur callback modes Impact: cleanup, move all hrtimer processing into hardirq context This is an attempt at removing some of the hrtimer complexity by reducing the number of callback modes to 1. This means that all hrtimer callback functions will be ran from HARD-irq context. I went through all the 30 odd hrtimer callback functions in the kernel and saw only one that I'm not quite sure of, which is the one in net/can/bcm.c - hence I'm CC-ing the folks responsible for that code. Furthermore, the hrtimer core now calls callbacks directly with IRQs disabled in case you try to enqueue an expired timer. If this timer is a periodic timer (which should use hrtimer_forward() to advance its time) then it might be possible to end up in an inf. recursive loop due to the fact that hrtimer_forward() doesn't round up to the next timer granularity, and therefore keeps on calling the callback - obviously this needs a fix. Aside from that, this seems to compile and actually boot on my dual core test box - although I'm sure there are some bugs in, me not hitting any makes me certain :-) Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/hrtimer.h | 34 ++-------------------------------- include/linux/interrupt.h | 3 --- 2 files changed, 2 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 3eba43878dc..bd37078c2d7 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -42,26 +42,6 @@ enum hrtimer_restart { HRTIMER_RESTART, /* Timer must be restarted */ }; -/* - * hrtimer callback modes: - * - * HRTIMER_CB_SOFTIRQ: Callback must run in softirq context - * HRTIMER_CB_IRQSAFE_PERCPU: Callback must run in hardirq context - * Special mode for tick emulation and - * scheduler timer. Such timers are per - * cpu and not allowed to be migrated on - * cpu unplug. - * HRTIMER_CB_IRQSAFE_UNLOCKED: Callback should run in hardirq context - * with timer->base lock unlocked - * used for timers which call wakeup to - * avoid lock order problems with rq->lock - */ -enum hrtimer_cb_mode { - HRTIMER_CB_SOFTIRQ, - HRTIMER_CB_IRQSAFE_PERCPU, - HRTIMER_CB_IRQSAFE_UNLOCKED, -}; - /* * Values to track state of the timer * @@ -70,7 +50,6 @@ enum hrtimer_cb_mode { * 0x00 inactive * 0x01 enqueued into rbtree * 0x02 callback function running - * 0x04 callback pending (high resolution mode) * * Special cases: * 0x03 callback function running and enqueued @@ -92,8 +71,7 @@ enum hrtimer_cb_mode { #define HRTIMER_STATE_INACTIVE 0x00 #define HRTIMER_STATE_ENQUEUED 0x01 #define HRTIMER_STATE_CALLBACK 0x02 -#define HRTIMER_STATE_PENDING 0x04 -#define HRTIMER_STATE_MIGRATE 0x08 +#define HRTIMER_STATE_MIGRATE 0x04 /** * struct hrtimer - the basic hrtimer structure @@ -109,8 +87,6 @@ enum hrtimer_cb_mode { * @function: timer expiry callback function * @base: pointer to the timer base (per cpu and per clock) * @state: state information (See bit values above) - * @cb_mode: high resolution timer feature to select the callback execution - * mode * @cb_entry: list head to enqueue an expired timer into the callback list * @start_site: timer statistics field to store the site where the timer * was started @@ -129,7 +105,6 @@ struct hrtimer { struct hrtimer_clock_base *base; unsigned long state; struct list_head cb_entry; - enum hrtimer_cb_mode cb_mode; #ifdef CONFIG_TIMER_STATS int start_pid; void *start_site; @@ -188,15 +163,11 @@ struct hrtimer_clock_base { * @check_clocks: Indictator, when set evaluate time source and clock * event devices whether high resolution mode can be * activated. - * @cb_pending: Expired timers are moved from the rbtree to this - * list in the timer interrupt. The list is processed - * in the softirq. * @nr_events: Total number of timer interrupt events */ struct hrtimer_cpu_base { spinlock_t lock; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; - struct list_head cb_pending; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t expires_next; int hres_active; @@ -404,8 +375,7 @@ static inline int hrtimer_active(const struct hrtimer *timer) */ static inline int hrtimer_is_queued(struct hrtimer *timer) { - return timer->state & - (HRTIMER_STATE_ENQUEUED | HRTIMER_STATE_PENDING); + return timer->state & HRTIMER_STATE_ENQUEUED; } /* diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index f58a0cf8929..d6210a97a8c 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -251,9 +251,6 @@ enum BLOCK_SOFTIRQ, TASKLET_SOFTIRQ, SCHED_SOFTIRQ, -#ifdef CONFIG_HIGH_RES_TIMERS - HRTIMER_SOFTIRQ, -#endif RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ NR_SOFTIRQS -- cgit v1.2.3 From ce71e27c6fdc43c29f36d307b9100bde70c947fc Mon Sep 17 00:00:00 2001 From: Eduard - Gabriel Munteanu Date: Tue, 19 Aug 2008 20:43:25 +0300 Subject: SLUB: Replace __builtin_return_address(0) with _RET_IP_. This patch replaces __builtin_return_address(0) with _RET_IP_, since a previous patch moved _RET_IP_ and _THIS_IP_ to include/linux/kernel.h and they're widely available now. This makes for shorter and easier to read code. [penberg@cs.helsinki.fi: remove _RET_IP_ casts to void pointer] Signed-off-by: Eduard - Gabriel Munteanu Signed-off-by: Pekka Enberg --- include/linux/slab.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/slab.h b/include/linux/slab.h index 000da12b5cf..c97ed28559e 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -253,9 +253,9 @@ static inline void *kmem_cache_alloc_node(struct kmem_cache *cachep, * request comes from. */ #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) -extern void *__kmalloc_track_caller(size_t, gfp_t, void*); +extern void *__kmalloc_track_caller(size_t, gfp_t, unsigned long); #define kmalloc_track_caller(size, flags) \ - __kmalloc_track_caller(size, flags, __builtin_return_address(0)) + __kmalloc_track_caller(size, flags, _RET_IP_) #else #define kmalloc_track_caller(size, flags) \ __kmalloc(size, flags) @@ -271,10 +271,10 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, void*); * allocation request comes from. */ #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_SLUB) -extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); +extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, unsigned long); #define kmalloc_node_track_caller(size, flags, node) \ __kmalloc_node_track_caller(size, flags, node, \ - __builtin_return_address(0)) + _RET_IP_) #else #define kmalloc_node_track_caller(size, flags, node) \ __kmalloc_node(size, flags, node) -- cgit v1.2.3 From 8b752e3ef6e3f5cde87afc649dd51d92b1e549c1 Mon Sep 17 00:00:00 2001 From: Liming Wang Date: Fri, 28 Nov 2008 09:52:40 +0800 Subject: softirq: remove useless function __local_bh_enable Impact: remove unused code __local_bh_enable has been replaced with _local_bh_enable. As comments says "it always nests inside local_bh_enable() sections" has not been valid now. Also there is no reason to use __local_bh_enable anywhere, so we can remove this useless function. Signed-off-by: Liming Wang Signed-off-by: Ingo Molnar --- include/linux/bottom_half.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/bottom_half.h b/include/linux/bottom_half.h index 777dbf695d4..27b1bcffe40 100644 --- a/include/linux/bottom_half.h +++ b/include/linux/bottom_half.h @@ -2,7 +2,6 @@ #define _LINUX_BH_H extern void local_bh_disable(void); -extern void __local_bh_enable(void); extern void _local_bh_enable(void); extern void local_bh_enable(void); extern void local_bh_enable_ip(unsigned long ip); -- cgit v1.2.3 From ec5679e513305f1411753e5f5489935bd638af23 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 28 Nov 2008 17:56:14 +0100 Subject: debug warnings: eliminate warn_on_slowpath() Impact: cleanup, eliminate code now that warn_on_slowpath() uses warn_slowpath(...,NULL), we can eliminate warn_on_slowpath() altogether and use warn_slowpath(). Signed-off-by: Ingo Molnar --- include/asm-generic/bug.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 12c07c1866b..b8ba6941f58 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -33,15 +33,14 @@ struct bug_entry { #ifndef __WARN #ifndef __ASSEMBLY__ -extern void warn_on_slowpath(const char *file, const int line); extern void warn_slowpath(const char *file, const int line, const char *fmt, ...) __attribute__((format(printf, 3, 4))); #define WANT_WARN_ON_SLOWPATH #endif -#define __WARN() warn_on_slowpath(__FILE__, __LINE__) -#define __WARN_printf(arg...) warn_slowpath(__FILE__, __LINE__, arg) +#define __WARN() warn_slowpath(__FILE__, __LINE__, NULL) +#define __WARN_printf(arg...) warn_slowpath(__FILE__, __LINE__, arg) #else -#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) +#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) #endif #ifndef WARN_ON -- cgit v1.2.3 From 00ef9f7348dfd2fc223ec42aceb30836e86b367f Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 4 Dec 2008 09:00:17 +0100 Subject: lockdep: change a held lock's class Impact: introduce new lockdep API Allow to change a held lock's class. Basically the same as the existing code to change a subclass therefore reuse all that. The XFS code will be able to use this to annotate their inode locking. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 8956daf64ab..37a0361f468 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -314,8 +314,15 @@ extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass, extern void lock_release(struct lockdep_map *lock, int nested, unsigned long ip); -extern void lock_set_subclass(struct lockdep_map *lock, unsigned int subclass, - unsigned long ip); +extern void lock_set_class(struct lockdep_map *lock, const char *name, + struct lock_class_key *key, unsigned int subclass, + unsigned long ip); + +static inline void lock_set_subclass(struct lockdep_map *lock, + unsigned int subclass, unsigned long ip) +{ + lock_set_class(lock, lock->name, lock->key, subclass, ip); +} # define INIT_LOCKDEP .lockdep_recursion = 0, @@ -333,6 +340,7 @@ static inline void lockdep_on(void) # define lock_acquire(l, s, t, r, c, n, i) do { } while (0) # define lock_release(l, n, i) do { } while (0) +# define lock_set_class(l, n, k, s, i) do { } while (0) # define lock_set_subclass(l, s, i) do { } while (0) # define lockdep_init() do { } while (0) # define lockdep_info() do { } while (0) -- cgit v1.2.3 From c9bb6003dd096ad190e1594a7d835ae1c39fae8f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 29 Oct 2008 23:46:09 -0700 Subject: of: Fix comment, sparc no longer uses of_device objects on special busses. It only uses of_platform_bus_type. Signed-off-by: David S. Miller --- include/linux/of_platform.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index a8efcfeea73..3d327b67d7e 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -26,8 +26,7 @@ extern struct bus_type of_platform_bus_type; /* * An of_platform_driver driver is attached to a basic of_device on - * the "platform bus" (of_platform_bus_type) (or ISA, EBUS and SBUS - * busses on sparc). + * the "platform bus" (of_platform_bus_type). */ struct of_platform_driver { -- cgit v1.2.3 From 0b8f1efad30bd58f89961b82dfe68b9edf8fd2ac Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 5 Dec 2008 18:58:31 -0800 Subject: sparse irq_desc[] array: core kernel and x86 changes Impact: new feature Problem on distro kernels: irq_desc[NR_IRQS] takes megabytes of RAM with NR_CPUS set to large values. The goal is to be able to scale up to much larger NR_IRQS value without impacting the (important) common case. To solve this, we generalize irq_desc[NR_IRQS] to an (optional) array of irq_desc pointers. When CONFIG_SPARSE_IRQ=y is used, we use kzalloc_node to get irq_desc, this also makes the IRQ descriptors NUMA-local (to the site that calls request_irq()). This gets rid of the irq_cfg[] static array on x86 as well: irq_cfg now uses desc->chip_data for x86 to store irq_cfg. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 2 ++ include/linux/irq.h | 54 ++++++++++++++++++++++++++++++++++++++++++++- include/linux/irqnr.h | 14 +++--------- include/linux/kernel_stat.h | 14 +++++++++++- include/linux/random.h | 51 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 122 insertions(+), 13 deletions(-) (limited to 'include') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index f58a0cf8929..79e915e7e8a 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -18,6 +18,8 @@ #include #include +extern int nr_irqs; + /* * These correspond to the IORESOURCE_IRQ_* defines in * linux/ioport.h to select the interrupt line behaviour. When diff --git a/include/linux/irq.h b/include/linux/irq.h index 3dddfa703eb..63b00439d4d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -129,6 +129,8 @@ struct irq_chip { const char *typename; }; +struct timer_rand_state; +struct irq_2_iommu; /** * struct irq_desc - interrupt descriptor * @irq: interrupt number for this descriptor @@ -154,6 +156,13 @@ struct irq_chip { */ struct irq_desc { unsigned int irq; +#ifdef CONFIG_SPARSE_IRQ + struct timer_rand_state *timer_rand_state; + unsigned int *kstat_irqs; +# ifdef CONFIG_INTR_REMAP + struct irq_2_iommu *irq_2_iommu; +# endif +#endif irq_flow_handler_t handle_irq; struct irq_chip *chip; struct msi_desc *msi_desc; @@ -181,14 +190,52 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; +extern void early_irq_init(void); +extern void arch_early_irq_init(void); +extern void arch_init_chip_data(struct irq_desc *desc, int cpu); +extern void arch_init_copy_chip_data(struct irq_desc *old_desc, + struct irq_desc *desc, int cpu); +extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc); + +#ifndef CONFIG_SPARSE_IRQ extern struct irq_desc irq_desc[NR_IRQS]; static inline struct irq_desc *irq_to_desc(unsigned int irq) { - return (irq < nr_irqs) ? irq_desc + irq : NULL; + return (irq < NR_IRQS) ? irq_desc + irq : NULL; +} +static inline struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) +{ + return irq_to_desc(irq); } +#ifdef CONFIG_GENERIC_HARDIRQS +# define for_each_irq_desc(irq, desc) \ + for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) +# define for_each_irq_desc_reverse(irq, desc) \ + for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \ + irq >= 0; irq--, desc--) +#endif + +#else + +extern struct irq_desc *irq_to_desc(unsigned int irq); +extern struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu); +extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu); + +# define for_each_irq_desc(irq, desc) \ + for (irq = 0, desc = irq_to_desc(irq); irq < nr_irqs; irq++, desc = irq_to_desc(irq)) +# define for_each_irq_desc_reverse(irq, desc) \ + for (irq = nr_irqs - 1, desc = irq_to_desc(irq); irq >= 0; irq--, desc = irq_to_desc(irq)) + +#define kstat_irqs_this_cpu(DESC) \ + ((DESC)->kstat_irqs[smp_processor_id()]) +#define kstat_incr_irqs_this_cpu(irqno, DESC) \ + ((DESC)->kstat_irqs[smp_processor_id()]++) + +#endif + /* * Migration helpers for obsolete names, they will go away: */ @@ -380,6 +427,11 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); #define get_irq_data(irq) (irq_to_desc(irq)->handler_data) #define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc) +#define get_irq_desc_chip(desc) ((desc)->chip) +#define get_irq_desc_chip_data(desc) ((desc)->chip_data) +#define get_irq_desc_data(desc) ((desc)->handler_data) +#define get_irq_desc_msi(desc) ((desc)->msi_desc) + #endif /* CONFIG_GENERIC_HARDIRQS */ #endif /* !CONFIG_S390 */ diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h index 452c280c811..7a299e989f8 100644 --- a/include/linux/irqnr.h +++ b/include/linux/irqnr.h @@ -7,18 +7,10 @@ # define for_each_irq_desc(irq, desc) \ for (irq = 0; irq < nr_irqs; irq++) -#else -extern int nr_irqs; -# define for_each_irq_desc(irq, desc) \ - for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) - -# define for_each_irq_desc_reverse(irq, desc) \ - for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \ - irq >= 0; irq--, desc--) +static inline early_sparse_irq_init(void) +{ +} #endif -#define for_each_irq_nr(irq) \ - for (irq = 0; irq < nr_irqs; irq++) - #endif diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 4a145caeee0..4ee4b3d2316 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,7 +28,9 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; - unsigned int irqs[NR_IRQS]; +#ifndef CONFIG_SPARSE_IRQ + unsigned int irqs[NR_IRQS]; +#endif }; DECLARE_PER_CPU(struct kernel_stat, kstat); @@ -39,6 +41,10 @@ DECLARE_PER_CPU(struct kernel_stat, kstat); extern unsigned long long nr_context_switches(void); +#ifndef CONFIG_SPARSE_IRQ +#define kstat_irqs_this_cpu(irq) \ + (kstat_this_cpu.irqs[irq]) + struct irq_desc; static inline void kstat_incr_irqs_this_cpu(unsigned int irq, @@ -46,11 +52,17 @@ static inline void kstat_incr_irqs_this_cpu(unsigned int irq, { kstat_this_cpu.irqs[irq]++; } +#endif + +#ifndef CONFIG_SPARSE_IRQ static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) { return kstat_cpu(cpu).irqs[irq]; } +#else +extern unsigned int kstat_irqs_cpu(unsigned int irq, int cpu); +#endif /* * Number of interrupts per specific IRQ source, since bootup diff --git a/include/linux/random.h b/include/linux/random.h index 36f125c0c60..ad9daa2374d 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -44,6 +44,57 @@ struct rand_pool_info { extern void rand_initialize_irq(int irq); +struct timer_rand_state; +#ifndef CONFIG_SPARSE_IRQ + +extern struct timer_rand_state *irq_timer_state[]; + +extern int nr_irqs; +static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + if (irq >= nr_irqs) + return NULL; + + return irq_timer_state[irq]; +} + +static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) +{ + if (irq >= nr_irqs) + return; + + irq_timer_state[irq] = state; +} + +#else + +#include +static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + if (!desc) + return NULL; + + return desc->timer_rand_state; +} + +static inline void set_timer_rand_state(unsigned int irq, struct timer_rand_state *state) +{ + struct irq_desc *desc; + + desc = irq_to_desc(irq); + + if (!desc) + return; + + desc->timer_rand_state = state; +} +#endif + + extern void add_input_randomness(unsigned int type, unsigned int code, unsigned int value); extern void add_interrupt_randomness(int irq); -- cgit v1.2.3 From 3145e941fcfe2548fa2270afb1a05bab3a6bc418 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 5 Dec 2008 18:58:34 -0800 Subject: x86, MSI: pass irq_cfg and irq_desc Impact: simplify code Pass irq_desc and cfg around, instead of raw IRQ numbers - this way we dont have to look it up again and again. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/msi.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/msi.h b/include/linux/msi.h index 8f293922720..d2b8a1e8ca1 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -10,8 +10,11 @@ struct msi_msg { }; /* Helper functions */ +struct irq_desc; extern void mask_msi_irq(unsigned int irq); extern void unmask_msi_irq(unsigned int irq); +extern void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); +extern void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg); extern void read_msi_msg(unsigned int irq, struct msi_msg *msg); extern void write_msi_msg(unsigned int irq, struct msi_msg *msg); -- cgit v1.2.3 From 240d367b4e6c6e3c5075e034db14dba60a6f5fa7 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 8 Dec 2008 14:06:17 -0800 Subject: sparseirq: fix Alpha build failure Impact: build fix on Alpha -tip testing found this build failure on the Alpha defconfig: /home/mingo/tip/fs/proc/stat.c: In function 'show_stat': /home/mingo/tip/fs/proc/stat.c:48: error: implicit declaration of function 'for_each_irq_desc' /home/mingo/tip/fs/proc/stat.c:48: error: expected ';' before '{' token can not use irq_desc() in stat.c on older architectures. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 9 --------- include/linux/irqnr.h | 19 ++++++++++++++++--- 2 files changed, 16 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index 63b00439d4d..b5749db3e5a 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -198,7 +198,6 @@ extern void arch_init_copy_chip_data(struct irq_desc *old_desc, extern void arch_free_chip_data(struct irq_desc *old_desc, struct irq_desc *desc); #ifndef CONFIG_SPARSE_IRQ - extern struct irq_desc irq_desc[NR_IRQS]; static inline struct irq_desc *irq_to_desc(unsigned int irq) @@ -210,14 +209,6 @@ static inline struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu) return irq_to_desc(irq); } -#ifdef CONFIG_GENERIC_HARDIRQS -# define for_each_irq_desc(irq, desc) \ - for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) -# define for_each_irq_desc_reverse(irq, desc) \ - for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \ - irq >= 0; irq--, desc--) -#endif - #else extern struct irq_desc *irq_to_desc(unsigned int irq); diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h index 7a299e989f8..13754f81358 100644 --- a/include/linux/irqnr.h +++ b/include/linux/irqnr.h @@ -8,9 +8,22 @@ # define for_each_irq_desc(irq, desc) \ for (irq = 0; irq < nr_irqs; irq++) -static inline early_sparse_irq_init(void) -{ -} +# define for_each_irq_desc_reverse(irq, desc) \ + for (irq = nr_irqs - 1; irq >= 0; irq--) +#else +#ifndef CONFIG_SPARSE_IRQ + +struct irq_desc; +extern int nr_irqs; +# define for_each_irq_desc(irq, desc) \ + for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) +# define for_each_irq_desc_reverse(irq, desc) \ + for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \ + irq >= 0; irq--, desc--) #endif +#endif + +#define for_each_irq_nr(irq) \ + for (irq = 0; irq < nr_irqs; irq++) #endif -- cgit v1.2.3 From 58494487581cb143a0d763e3056a894d5009d60a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 26 Nov 2008 12:02:53 +0100 Subject: oprofile: update comment for oprofile_add_sample() The cpu argument is no longer part of the parameter list. Signed-off-by: Robert Richter --- include/linux/oprofile.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index 5231861f357..1ce9fe572e5 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -86,8 +86,7 @@ int oprofile_arch_init(struct oprofile_operations * ops); void oprofile_arch_exit(void); /** - * Add a sample. This may be called from any context. Pass - * smp_processor_id() as cpu. + * Add a sample. This may be called from any context. */ void oprofile_add_sample(struct pt_regs * const regs, unsigned long event); -- cgit v1.2.3 From e09373f22e76cc048ca5fe10a9ff9012f5d64309 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Wed, 26 Nov 2008 14:04:19 +0100 Subject: ring_buffer: add remaining cpu functions to ring_buffer.h These functions are not yet in ring_buffer.h though they seems to be part of the API. Cc: Steven Rostedt Signed-off-by: Robert Richter --- include/linux/ring_buffer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index e097c2e6b6d..de9d8c12e5e 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -116,6 +116,8 @@ void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu); unsigned long ring_buffer_entries(struct ring_buffer *buffer); unsigned long ring_buffer_overruns(struct ring_buffer *buffer); +unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu); +unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu); u64 ring_buffer_time_stamp(int cpu); void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); -- cgit v1.2.3 From 4d4be482a4d78ca906f45e99fd9fdb91e907f5ad Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 9 Dec 2008 04:47:33 -0500 Subject: [XFS] add a FMODE flag to make XFS invisible I/O less hacky XFS has a mode called invisble I/O that doesn't update any of the timestamps. It's used for HSM-style applications and exposed through the nasty open by handle ioctl. Instead of doing directly assignment of file operations that set an internal flag for it add a new FMODE_NOCMTIME flag that we can check in the normal file operations. (addition of the generic VFS flag has been ACKed by Al as an interims solution) Signed-off-by: Christoph Hellwig Signed-off-by: Lachlan McIlroy --- include/linux/fs.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/fs.h b/include/linux/fs.h index 51bd9370d43..965b9ba3865 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -81,6 +81,14 @@ extern int dir_notify_enable; #define FMODE_WRITE_IOCTL ((__force fmode_t)128) #define FMODE_NDELAY_NOW ((__force fmode_t)256) +/* + * Don't update ctime and mtime. + * + * Currently a special hack for the XFS open_by_handle ioctl, but we'll + * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon. + */ +#define FMODE_NOCMTIME ((__force fmode_t)2048) + #define RW_MASK 1 #define RWA_MASK 2 #define READ 0 -- cgit v1.2.3 From 0ebb26e7a4e2c5337502e98b2221e037fda911b9 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 12 Dec 2008 11:26:39 +0100 Subject: sparse irqs: handle !GENIRQ platforms Impact: build fix fix: In file included from /home/mingo/tip/arch/m68k/amiga/amiints.c:39: /home/mingo/tip/include/linux/interrupt.h:21: error: expected identifier or '(' /home/mingo/tip/arch/m68k/amiga/amiints.c: In function 'amiga_init_IRQ': Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 4 ++-- include/linux/irqnr.h | 11 ++++++++++- include/linux/random.h | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 79e915e7e8a..777f89e00b4 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -14,12 +14,12 @@ #include #include #include +#include + #include #include #include -extern int nr_irqs; - /* * These correspond to the IORESOURCE_IRQ_* defines in * linux/ioport.h to select the interrupt line behaviour. When diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h index 13754f81358..95d2b74641f 100644 --- a/include/linux/irqnr.h +++ b/include/linux/irqnr.h @@ -1,6 +1,11 @@ #ifndef _LINUX_IRQNR_H #define _LINUX_IRQNR_H +/* + * Generic irq_desc iterators: + */ +#ifdef __KERNEL__ + #ifndef CONFIG_GENERIC_HARDIRQS #include # define nr_irqs NR_IRQS @@ -11,10 +16,12 @@ # define for_each_irq_desc_reverse(irq, desc) \ for (irq = nr_irqs - 1; irq >= 0; irq--) #else + +extern int nr_irqs; + #ifndef CONFIG_SPARSE_IRQ struct irq_desc; -extern int nr_irqs; # define for_each_irq_desc(irq, desc) \ for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc++) # define for_each_irq_desc_reverse(irq, desc) \ @@ -26,4 +33,6 @@ extern int nr_irqs; #define for_each_irq_nr(irq) \ for (irq = 0; irq < nr_irqs; irq++) +#endif /* __KERNEL__ */ + #endif diff --git a/include/linux/random.h b/include/linux/random.h index ad9daa2374d..adbf3bd3c6b 100644 --- a/include/linux/random.h +++ b/include/linux/random.h @@ -8,6 +8,7 @@ #define _LINUX_RANDOM_H #include +#include /* ioctl()'s for the random number generator */ @@ -49,7 +50,6 @@ struct timer_rand_state; extern struct timer_rand_state *irq_timer_state[]; -extern int nr_irqs; static inline struct timer_rand_state *get_timer_rand_state(unsigned int irq) { if (irq >= nr_irqs) -- cgit v1.2.3 From 30cb367ea2be76bf71dbd275f38d0fd3b6f4142b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 12 Dec 2008 12:19:57 +0100 Subject: sparse irqs: add irqnr.h to the user headers list Impact: fix build error /home/mingo/tip/usr/include/linux/random.h:11: included file 'linux/irqnr.h' is not exported Signed-off-by: Ingo Molnar --- include/linux/Kbuild | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index e531783e5d7..95ac82340c3 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -313,6 +313,7 @@ unifdef-y += ptrace.h unifdef-y += qnx4_fs.h unifdef-y += quota.h unifdef-y += random.h +unifdef-y += irqnr.h unifdef-y += reboot.h unifdef-y += reiserfs_fs.h unifdef-y += reiserfs_xattr.h -- cgit v1.2.3 From 27af4245b6ce99e08c6a7c38825383bf51119cc9 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 1 Dec 2008 14:18:13 -0800 Subject: posix-timers: use "struct pid*" instead of "struct task_struct*" Impact: restructure, clean up code k_itimer holds the ref to the ->it_process until sys_timer_delete(). This allows to pin up to RLIMIT_SIGPENDING dead task_struct's. Change the code to use "struct pid *" instead. The patch doesn't kill ->it_process, it places ->it_pid into the union. ->it_process is still used by do_cpu_nanosleep() as before. It would be trivial to change the nanosleep code as well, but since it uses it_process in a special way I think it is better to keep this field for grep. The patch bloats the kernel by 104 bytes and it also adds the new pointer, ->it_signal, to k_itimer. It is used by lock_timer() to verify that the found timer was not created by another process. It is not clear why do we use the global database (and thus the global idr_lock) for posix timers. We still need the signal_struct->posix_timers which contains all useable timers, perhaps it is better to use some form of per-process array instead. Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/posix-timers.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index a7c72135554..4f71bf4e628 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -45,7 +45,11 @@ struct k_itimer { int it_requeue_pending; /* waiting to requeue this timer */ #define REQUEUE_PENDING 1 int it_sigev_notify; /* notify word of sigevent struct */ - struct task_struct *it_process; /* process to send signal to */ + struct signal_struct *it_signal; + union { + struct pid *it_pid; /* pid of process to send signal to */ + struct task_struct *it_process; /* for clock_nanosleep */ + }; struct sigqueue *sigq; /* signal queue entry. */ union { struct { -- cgit v1.2.3 From c29541b24fb2c6301021637229ae5347c877330a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 1 Dec 2008 14:18:11 -0800 Subject: linux/timex.h: cleanup for userspace Impact: fix user-space exported use Move all the kernel-specific defines and includes into the __KERNEL__ section so that they don't get leaked into userspace. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Mike Frysinger Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/timex.h | 73 ++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/include/linux/timex.h b/include/linux/timex.h index 9007313b5b7..998a55d80ac 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -53,46 +53,10 @@ #ifndef _LINUX_TIMEX_H #define _LINUX_TIMEX_H -#include #include -#include - #define NTP_API 4 /* NTP API version */ -/* - * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen - * for a slightly underdamped convergence characteristic. SHIFT_KH - * establishes the damping of the FLL and is chosen by wisdom and black - * art. - * - * MAXTC establishes the maximum time constant of the PLL. With the - * SHIFT_KG and SHIFT_KF values given and a time constant range from - * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, - * respectively. - */ -#define SHIFT_PLL 4 /* PLL frequency factor (shift) */ -#define SHIFT_FLL 2 /* FLL frequency factor (shift) */ -#define MAXTC 10 /* maximum time constant (shift) */ - -/* - * SHIFT_USEC defines the scaling (shift) of the time_freq and - * time_tolerance variables, which represent the current frequency - * offset and maximum frequency tolerance. - */ -#define SHIFT_USEC 16 /* frequency offset scale (shift) */ -#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) -#define PPM_SCALE_INV_SHIFT 19 -#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \ - PPM_SCALE + 1) - -#define MAXPHASE 500000000l /* max phase error (ns) */ -#define MAXFREQ 500000 /* max frequency error (ns/s) */ -#define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT) -#define MINSEC 256 /* min interval between updates (s) */ -#define MAXSEC 2048 /* max interval between updates (s) */ -#define NTP_PHASE_LIMIT ((MAXPHASE / NSEC_PER_USEC) << 5) /* beyond max. dispersion */ - /* * syscall interface - used (mainly by NTP daemon) * to discipline kernel clock oscillator @@ -199,8 +163,45 @@ struct timex { #define TIME_BAD TIME_ERROR /* bw compat */ #ifdef __KERNEL__ +#include +#include +#include + #include +/* + * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen + * for a slightly underdamped convergence characteristic. SHIFT_KH + * establishes the damping of the FLL and is chosen by wisdom and black + * art. + * + * MAXTC establishes the maximum time constant of the PLL. With the + * SHIFT_KG and SHIFT_KF values given and a time constant range from + * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours, + * respectively. + */ +#define SHIFT_PLL 4 /* PLL frequency factor (shift) */ +#define SHIFT_FLL 2 /* FLL frequency factor (shift) */ +#define MAXTC 10 /* maximum time constant (shift) */ + +/* + * SHIFT_USEC defines the scaling (shift) of the time_freq and + * time_tolerance variables, which represent the current frequency + * offset and maximum frequency tolerance. + */ +#define SHIFT_USEC 16 /* frequency offset scale (shift) */ +#define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) +#define PPM_SCALE_INV_SHIFT 19 +#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \ + PPM_SCALE + 1) + +#define MAXPHASE 500000000l /* max phase error (ns) */ +#define MAXFREQ 500000 /* max frequency error (ns/s) */ +#define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT) +#define MINSEC 256 /* min interval between updates (s) */ +#define MAXSEC 2048 /* max interval between updates (s) */ +#define NTP_PHASE_LIMIT ((MAXPHASE / NSEC_PER_USEC) << 5) /* beyond max. dispersion */ + /* * kernel variables * Note: maximum error = NTP synch distance = dispersion + delay / 2; -- cgit v1.2.3 From b690ace50be7d10d77cb7a6d5ef1bd9de649852f Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 21 Oct 2008 14:07:03 +0100 Subject: [ARM] S3C6400: serial support for S3C6400 and S3C6410 SoCs Add support to the Samsung serial driver for the S3C6400 and S3C6410 serial ports. Signed-off-by: Ben Dooks --- include/linux/serial_core.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 4e4f1277f3b..feb3b939ec4 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -158,6 +158,8 @@ /* SH-SCI */ #define PORT_SCIFA 83 +#define PORT_S3C6400 84 + #ifdef __KERNEL__ #include -- cgit v1.2.3 From 8c5df16bec8a60bb8589fc232b9e26cac0ed4b2c Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 16 Dec 2008 12:17:26 -0800 Subject: swiotlb: allow architectures to override swiotlb pool allocation Impact: generalize swiotlb allocation code Architectures may need to allocate memory specially for use with the swiotlb. Create the weak function swiotlb_alloc_boot() and swiotlb_alloc() defaulting to the current behaviour. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ian Campbell Signed-off-by: Ingo Molnar --- include/linux/swiotlb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index b18ec5533e8..b8c5fc766a5 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -10,6 +10,9 @@ struct scatterlist; extern void swiotlb_init(void); +extern void *swiotlb_alloc_boot(size_t bytes, unsigned long nslabs); +extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); + extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); -- cgit v1.2.3 From 0016fdee927f7aa0f428494bcf11ae60c7470a02 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 16 Dec 2008 12:17:27 -0800 Subject: swiotlb: move some definitions to header Impact: cleanup Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/swiotlb.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index b8c5fc766a5..58b996a642f 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -7,6 +7,20 @@ struct device; struct dma_attrs; struct scatterlist; +/* + * Maximum allowable number of contiguous slabs to map, + * must be a power of 2. What is the appropriate value ? + * The complexity of {map,unmap}_single is linearly dependent on this value. + */ +#define IO_TLB_SEGSIZE 128 + + +/* + * log of the size of each IO TLB slab. The number of slabs is command line + * controllable. + */ +#define IO_TLB_SHIFT 11 + extern void swiotlb_init(void); -- cgit v1.2.3 From 48a1b10aff588833b73994704c47bbd0deb73e9c Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 11 Dec 2008 00:15:01 -0800 Subject: x86, sparseirq: move irq_desc according to smp_affinity, v7 Impact: improve NUMA handling by migrating irq_desc on smp_affinity changes if CONFIG_NUMA_MIGRATE_IRQ_DESC is set: - make irq_desc to go with affinity aka irq_desc moving etc - call move_irq_desc in irq_complete_move() - legacy irq_desc is not moved, because they are allocated via static array for logical apic mode, need to add move_desc_in_progress_in_same_domain, otherwise it will not be moved ==> also could need two phases to get irq_desc moved. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index b5749db3e5a..36a01574678 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -227,6 +227,16 @@ extern struct irq_desc *move_irq_desc(struct irq_desc *old_desc, int cpu); #endif +static inline struct irq_desc * +irq_remap_to_desc(unsigned int irq, struct irq_desc *desc) +{ +#ifdef CONFIG_NUMA_MIGRATE_IRQ_DESC + return irq_to_desc(irq); +#else + return desc; +#endif +} + /* * Migration helpers for obsolete names, they will go away: */ -- cgit v1.2.3 From e08e1f7adba522378e8d2ae941bf25443866136d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 16 Dec 2008 12:17:30 -0800 Subject: swiotlb: allow architectures to override phys<->bus<->phys conversions Impact: generalize phys<->bus<->phys conversions in the swiotlb code Architectures may need to override these conversions. Implement a __weak hook point containing the default implementation. Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/swiotlb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 58b996a642f..694f1839cbc 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -27,6 +27,9 @@ swiotlb_init(void); extern void *swiotlb_alloc_boot(size_t bytes, unsigned long nslabs); extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); +extern dma_addr_t swiotlb_phys_to_bus(phys_addr_t address); +extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address); + extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); -- cgit v1.2.3 From b81ea27b2329bf44b30c427800954f845896d476 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 16 Dec 2008 12:17:31 -0800 Subject: swiotlb: add arch hook to force mapping Impact: generalize the sw-IOTLB range checks Some architectures require special rules to determine whether a range needs mapping or not. This adds a weak function for architectures to override. Signed-off-by: Ian Campbell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/swiotlb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h index 694f1839cbc..325af1de035 100644 --- a/include/linux/swiotlb.h +++ b/include/linux/swiotlb.h @@ -30,6 +30,8 @@ extern void *swiotlb_alloc(unsigned order, unsigned long nslabs); extern dma_addr_t swiotlb_phys_to_bus(phys_addr_t address); extern phys_addr_t swiotlb_bus_to_phys(dma_addr_t address); +extern int swiotlb_arch_range_needs_mapping(void *ptr, size_t size); + extern void *swiotlb_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t flags); -- cgit v1.2.3 From 74c8a6130486bed224e960790f4aa72dd09c061e Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Wed, 17 Dec 2008 19:40:33 +0900 Subject: locking, irq: enclose irq_desc_lock_class in CONFIG_LOCKDEP Impact: simplify code commit "08678b0: generic: sparse irqs: use irq_desc() [...]" introduced the irq_desc_lock_class variable. But it is used only if CONFIG_SPARSE_IRQ=Y or CONFIG_TRACE_IRQFLAGS=Y. Otherwise, following warnings happen: CC kernel/irq/handle.o kernel/irq/handle.c:26: warning: 'irq_desc_lock_class' defined but not used Actually, current early_init_irq_lock_class has a bit strange and messy ifdef. In addition, it is not valueable. 1. this function is protected by !CONFIG_SPARSE_IRQ, but that is not necessary. if CONFIG_SPARSE_IRQ=Y, desc of all irq number are initialized by NULL at first - then this function calling is safe. 2. this function protected by CONFIG_TRACE_IRQFLAGS too. but it is not necessary either, because lockdep_set_class() doesn't have bad side effect even if CONFIG_TRACE_IRQFLAGS=n. This patch bloat kernel size a bit on CONFIG_TRACE_IRQFLAGS=n and CONFIG_SPARSE_IRQ=Y - but that's ok. early_init_irq_lock_class() is not a fastpatch at all. To avoid messy ifdefs is more important than a few bytes diet. Signed-off-by: KOSAKI Motohiro Signed-off-by: Ingo Molnar --- include/linux/lockdep.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 29aec6e1002..9dba554c802 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -377,7 +377,7 @@ do { \ #endif /* CONFIG_LOCK_STAT */ -#if defined(CONFIG_TRACE_IRQFLAGS) && defined(CONFIG_GENERIC_HARDIRQS) +#ifdef CONFIG_GENERIC_HARDIRQS extern void early_init_irq_lock_class(void); #else static inline void early_init_irq_lock_class(void) -- cgit v1.2.3 From 64db4cfff99c04cd5f550357edcc8780f96b54a2 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 18 Dec 2008 21:55:32 +0100 Subject: "Tree RCU": scalable classic RCU implementation This patch fixes a long-standing performance bug in classic RCU that results in massive internal-to-RCU lock contention on systems with more than a few hundred CPUs. Although this patch creates a separate flavor of RCU for ease of review and patch maintenance, it is intended to replace classic RCU. This patch still handles stress better than does mainline, so I am still calling it ready for inclusion. This patch is against the -tip tree. Nevertheless, experience on an actual 1000+ CPU machine would still be most welcome. Most of the changes noted below were found while creating an rcutiny (which should permit ejecting the current rcuclassic) and while doing detailed line-by-line documentation. Updates from v9 (http://lkml.org/lkml/2008/12/2/334): o Fixes from remainder of line-by-line code walkthrough, including comment spelling, initialization, undesirable narrowing due to type conversion, removing redundant memory barriers, removing redundant local-variable initialization, and removing redundant local variables. I do not believe that any of these fixes address the CPU-hotplug issues that Andi Kleen was seeing, but please do give it a whirl in case the machine is smarter than I am. A writeup from the walkthrough may be found at the following URL, in case you are suffering from terminal insomnia or masochism: http://www.kernel.org/pub/linux/kernel/people/paulmck/tmp/rcutree-walkthrough.2008.12.16a.pdf o Made rcutree tracing use seq_file, as suggested some time ago by Lai Jiangshan. o Added a .csv variant of the rcudata debugfs trace file, to allow people having thousands of CPUs to drop the data into a spreadsheet. Tested with oocalc and gnumeric. Updated documentation to suit. Updates from v8 (http://lkml.org/lkml/2008/11/15/139): o Fix a theoretical race between grace-period initialization and force_quiescent_state() that could occur if more than three jiffies were required to carry out the grace-period initialization. Which it might, if you had enough CPUs. o Apply Ingo's printk-standardization patch. o Substitute local variables for repeated accesses to global variables. o Fix comment misspellings and redundant (but harmless) increments of ->n_rcu_pending (this latter after having explicitly added it). o Apply checkpatch fixes. Updates from v7 (http://lkml.org/lkml/2008/10/10/291): o Fixed a number of problems noted by Gautham Shenoy, including the cpu-stall-detection bug that he was having difficulty convincing me was real. ;-) o Changed cpu-stall detection to wait for ten seconds rather than three in order to reduce false positive, as suggested by Ingo Molnar. o Produced a design document (http://lwn.net/Articles/305782/). The act of writing this document uncovered a number of both theoretical and "here and now" bugs as noted below. o Fix dynticks_nesting accounting confusion, simplify WARN_ON() condition, fix kerneldoc comments, and add memory barriers in dynticks interface functions. o Add more data to tracing. o Remove unused "rcu_barrier" field from rcu_data structure. o Count calls to rcu_pending() from scheduling-clock interrupt to use as a surrogate timebase should jiffies stop counting. o Fix a theoretical race between force_quiescent_state() and grace-period initialization. Yes, initialization does have to go on for some jiffies for this race to occur, but given enough CPUs... Updates from v6 (http://lkml.org/lkml/2008/9/23/448): o Fix a number of checkpatch.pl complaints. o Apply review comments from Ingo Molnar and Lai Jiangshan on the stall-detection code. o Fix several bugs in !CONFIG_SMP builds. o Fix a misspelled config-parameter name so that RCU now announces at boot time if stall detection is configured. o Run tests on numerous combinations of configurations parameters, which after the fixes above, now build and run correctly. Updates from v5 (http://lkml.org/lkml/2008/9/15/92, bad subject line): o Fix a compiler error in the !CONFIG_FANOUT_EXACT case (blew a changeset some time ago, and finally got around to retesting this option). o Fix some tracing bugs in rcupreempt that caused incorrect totals to be printed. o I now test with a more brutal random-selection online/offline script (attached). Probably more brutal than it needs to be on the people reading it as well, but so it goes. o A number of optimizations and usability improvements: o Make rcu_pending() ignore the grace-period timeout when there is no grace period in progress. o Make force_quiescent_state() avoid going for a global lock in the case where there is no grace period in progress. o Rearrange struct fields to improve struct layout. o Make call_rcu() initiate a grace period if RCU was idle, rather than waiting for the next scheduling clock interrupt. o Invoke rcu_irq_enter() and rcu_irq_exit() only when idle, as suggested by Andi Kleen. I still don't completely trust this change, and might back it out. o Make CONFIG_RCU_TRACE be the single config variable manipulated for all forms of RCU, instead of the prior confusion. o Document tracing files and formats for both rcupreempt and rcutree. Updates from v4 for those missing v5 given its bad subject line: o Separated dynticks interface so that NMIs and irqs call separate functions, greatly simplifying it. In particular, this code no longer requires a proof of correctness. ;-) o Separated dynticks state out into its own per-CPU structure, avoiding the duplicated accounting. o The case where a dynticks-idle CPU runs an irq handler that invokes call_rcu() is now correctly handled, forcing that CPU out of dynticks-idle mode. o Review comments have been applied (thank you all!!!). For but one example, fixed the dynticks-ordering issue that Manfred pointed out, saving me much debugging. ;-) o Adjusted rcuclassic and rcupreempt to handle dynticks changes. Attached is an updated patch to Classic RCU that applies a hierarchy, greatly reducing the contention on the top-level lock for large machines. This passes 10-hour concurrent rcutorture and online-offline testing on 128-CPU ppc64 without dynticks enabled, and exposes some timekeeping bugs in presence of dynticks (exciting working on a system where "sleep 1" hangs until interrupted...), which were fixed in the 2.6.27 kernel. It is getting more reliable than mainline by some measures, so the next version will be against -tip for inclusion. See also Manfred Spraul's recent patches (or his earlier work from 2004 at http://marc.info/?l=linux-kernel&m=108546384711797&w=2). We will converge onto a common patch in the fullness of time, but are currently exploring different regions of the design space. That said, I have already gratefully stolen quite a few of Manfred's ideas. This patch provides CONFIG_RCU_FANOUT, which controls the bushiness of the RCU hierarchy. Defaults to 32 on 32-bit machines and 64 on 64-bit machines. If CONFIG_NR_CPUS is less than CONFIG_RCU_FANOUT, there is no hierarchy. By default, the RCU initialization code will adjust CONFIG_RCU_FANOUT to balance the hierarchy, so strongly NUMA architectures may choose to set CONFIG_RCU_FANOUT_EXACT to disable this balancing, allowing the hierarchy to be exactly aligned to the underlying hardware. Up to two levels of hierarchy are permitted (in addition to the root node), allowing up to 16,384 CPUs on 32-bit systems and up to 262,144 CPUs on 64-bit systems. I just know that I am going to regret saying this, but this seems more than sufficient for the foreseeable future. (Some architectures might wish to set CONFIG_RCU_FANOUT=4, which would limit such architectures to 64 CPUs. If this becomes a real problem, additional levels can be added, but I doubt that it will make a significant difference on real hardware.) In the common case, a given CPU will manipulate its private rcu_data structure and the rcu_node structure that it shares with its immediate neighbors. This can reduce both lock and memory contention by multiple orders of magnitude, which should eliminate the need for the strange manipulations that are reported to be required when running Linux on very large systems. Some shortcomings: o More bugs will probably surface as a result of an ongoing line-by-line code inspection. Patches will be provided as required. o There are probably hangs, rcutorture failures, &c. Seems quite stable on a 128-CPU machine, but that is kind of small compared to 4096 CPUs. However, seems to do better than mainline. Patches will be provided as required. o The memory footprint of this version is several KB larger than rcuclassic. A separate UP-only rcutiny patch will be provided, which will reduce the memory footprint significantly, even compared to the old rcuclassic. One such patch passes light testing, and has a memory footprint smaller even than rcuclassic. Initial reaction from various embedded guys was "it is not worth it", so am putting it aside. Credits: o Manfred Spraul for ideas, review comments, and bugs spotted, as well as some good friendly competition. ;-) o Josh Triplett, Ingo Molnar, Peter Zijlstra, Mathieu Desnoyers, Lai Jiangshan, Andi Kleen, Andy Whitcroft, and Andrew Morton for reviews and comments. o Thomas Gleixner for much-needed help with some timer issues (see patches below). o Jon M. Tollefson, Tim Pepper, Andrew Theurer, Jose R. Santos, Andy Whitcroft, Darrick Wong, Nishanth Aravamudan, Anton Blanchard, Dave Kleikamp, and Nathan Lynch for keeping machines alive despite my heavy abuse^Wtesting. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/hardirq.h | 14 +- include/linux/rcupdate.h | 10 +- include/linux/rcutree.h | 329 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 344 insertions(+), 9 deletions(-) create mode 100644 include/linux/rcutree.h (limited to 'include') diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index 181006cc94a..9b70b923169 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h @@ -118,13 +118,17 @@ static inline void account_system_vtime(struct task_struct *tsk) } #endif -#if defined(CONFIG_PREEMPT_RCU) && defined(CONFIG_NO_HZ) +#if defined(CONFIG_NO_HZ) && !defined(CONFIG_CLASSIC_RCU) extern void rcu_irq_enter(void); extern void rcu_irq_exit(void); +extern void rcu_nmi_enter(void); +extern void rcu_nmi_exit(void); #else # define rcu_irq_enter() do { } while (0) # define rcu_irq_exit() do { } while (0) -#endif /* CONFIG_PREEMPT_RCU */ +# define rcu_nmi_enter() do { } while (0) +# define rcu_nmi_exit() do { } while (0) +#endif /* #if defined(CONFIG_NO_HZ) && !defined(CONFIG_CLASSIC_RCU) */ /* * It is safe to do non-atomic ops on ->hardirq_context, @@ -134,7 +138,6 @@ extern void rcu_irq_exit(void); */ #define __irq_enter() \ do { \ - rcu_irq_enter(); \ account_system_vtime(current); \ add_preempt_count(HARDIRQ_OFFSET); \ trace_hardirq_enter(); \ @@ -153,7 +156,6 @@ extern void irq_enter(void); trace_hardirq_exit(); \ account_system_vtime(current); \ sub_preempt_count(HARDIRQ_OFFSET); \ - rcu_irq_exit(); \ } while (0) /* @@ -161,7 +163,7 @@ extern void irq_enter(void); */ extern void irq_exit(void); -#define nmi_enter() do { lockdep_off(); __irq_enter(); } while (0) -#define nmi_exit() do { __irq_exit(); lockdep_on(); } while (0) +#define nmi_enter() do { lockdep_off(); rcu_nmi_enter(); __irq_enter(); } while (0) +#define nmi_exit() do { __irq_exit(); rcu_nmi_exit(); lockdep_on(); } while (0) #endif /* LINUX_HARDIRQ_H */ diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 86f1f5e43e3..bfd289aff57 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -52,11 +52,15 @@ struct rcu_head { void (*func)(struct rcu_head *head); }; -#ifdef CONFIG_CLASSIC_RCU +#if defined(CONFIG_CLASSIC_RCU) #include -#else /* #ifdef CONFIG_CLASSIC_RCU */ +#elif defined(CONFIG_TREE_RCU) +#include +#elif defined(CONFIG_PREEMPT_RCU) #include -#endif /* #else #ifdef CONFIG_CLASSIC_RCU */ +#else +#error "Unknown RCU implementation specified to kernel configuration" +#endif /* #else #if defined(CONFIG_CLASSIC_RCU) */ #define RCU_HEAD_INIT { .next = NULL, .func = NULL } #define RCU_HEAD(head) struct rcu_head head = RCU_HEAD_INIT diff --git a/include/linux/rcutree.h b/include/linux/rcutree.h new file mode 100644 index 00000000000..d4368b7975c --- /dev/null +++ b/include/linux/rcutree.h @@ -0,0 +1,329 @@ +/* + * Read-Copy Update mechanism for mutual exclusion (tree-based version) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright IBM Corporation, 2008 + * + * Author: Dipankar Sarma + * Paul E. McKenney Hierarchical algorithm + * + * Based on the original work by Paul McKenney + * and inputs from Rusty Russell, Andrea Arcangeli and Andi Kleen. + * + * For detailed explanation of Read-Copy Update mechanism see - + * Documentation/RCU + */ + +#ifndef __LINUX_RCUTREE_H +#define __LINUX_RCUTREE_H + +#include +#include +#include +#include +#include +#include + +/* + * Define shape of hierarchy based on NR_CPUS and CONFIG_RCU_FANOUT. + * In theory, it should be possible to add more levels straightforwardly. + * In practice, this has not been tested, so there is probably some + * bug somewhere. + */ +#define MAX_RCU_LVLS 3 +#define RCU_FANOUT (CONFIG_RCU_FANOUT) +#define RCU_FANOUT_SQ (RCU_FANOUT * RCU_FANOUT) +#define RCU_FANOUT_CUBE (RCU_FANOUT_SQ * RCU_FANOUT) + +#if NR_CPUS <= RCU_FANOUT +# define NUM_RCU_LVLS 1 +# define NUM_RCU_LVL_0 1 +# define NUM_RCU_LVL_1 (NR_CPUS) +# define NUM_RCU_LVL_2 0 +# define NUM_RCU_LVL_3 0 +#elif NR_CPUS <= RCU_FANOUT_SQ +# define NUM_RCU_LVLS 2 +# define NUM_RCU_LVL_0 1 +# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT - 1) / RCU_FANOUT) +# define NUM_RCU_LVL_2 (NR_CPUS) +# define NUM_RCU_LVL_3 0 +#elif NR_CPUS <= RCU_FANOUT_CUBE +# define NUM_RCU_LVLS 3 +# define NUM_RCU_LVL_0 1 +# define NUM_RCU_LVL_1 (((NR_CPUS) + RCU_FANOUT_SQ - 1) / RCU_FANOUT_SQ) +# define NUM_RCU_LVL_2 (((NR_CPUS) + (RCU_FANOUT) - 1) / (RCU_FANOUT)) +# define NUM_RCU_LVL_3 NR_CPUS +#else +# error "CONFIG_RCU_FANOUT insufficient for NR_CPUS" +#endif /* #if (NR_CPUS) <= RCU_FANOUT */ + +#define RCU_SUM (NUM_RCU_LVL_0 + NUM_RCU_LVL_1 + NUM_RCU_LVL_2 + NUM_RCU_LVL_3) +#define NUM_RCU_NODES (RCU_SUM - NR_CPUS) + +/* + * Dynticks per-CPU state. + */ +struct rcu_dynticks { + int dynticks_nesting; /* Track nesting level, sort of. */ + int dynticks; /* Even value for dynticks-idle, else odd. */ + int dynticks_nmi; /* Even value for either dynticks-idle or */ + /* not in nmi handler, else odd. So this */ + /* remains even for nmi from irq handler. */ +}; + +/* + * Definition for node within the RCU grace-period-detection hierarchy. + */ +struct rcu_node { + spinlock_t lock; + unsigned long qsmask; /* CPUs or groups that need to switch in */ + /* order for current grace period to proceed.*/ + unsigned long qsmaskinit; + /* Per-GP initialization for qsmask. */ + unsigned long grpmask; /* Mask to apply to parent qsmask. */ + int grplo; /* lowest-numbered CPU or group here. */ + int grphi; /* highest-numbered CPU or group here. */ + u8 grpnum; /* CPU/group number for next level up. */ + u8 level; /* root is at level 0. */ + struct rcu_node *parent; +} ____cacheline_internodealigned_in_smp; + +/* Index values for nxttail array in struct rcu_data. */ +#define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ +#define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ +#define RCU_NEXT_READY_TAIL 2 /* Also RCU_NEXT head. */ +#define RCU_NEXT_TAIL 3 +#define RCU_NEXT_SIZE 4 + +/* Per-CPU data for read-copy update. */ +struct rcu_data { + /* 1) quiescent-state and grace-period handling : */ + long completed; /* Track rsp->completed gp number */ + /* in order to detect GP end. */ + long gpnum; /* Highest gp number that this CPU */ + /* is aware of having started. */ + long passed_quiesc_completed; + /* Value of completed at time of qs. */ + bool passed_quiesc; /* User-mode/idle loop etc. */ + bool qs_pending; /* Core waits for quiesc state. */ + bool beenonline; /* CPU online at least once. */ + struct rcu_node *mynode; /* This CPU's leaf of hierarchy */ + unsigned long grpmask; /* Mask to apply to leaf qsmask. */ + + /* 2) batch handling */ + /* + * If nxtlist is not NULL, it is partitioned as follows. + * Any of the partitions might be empty, in which case the + * pointer to that partition will be equal to the pointer for + * the following partition. When the list is empty, all of + * the nxttail elements point to nxtlist, which is NULL. + * + * [*nxttail[RCU_NEXT_READY_TAIL], NULL = *nxttail[RCU_NEXT_TAIL]): + * Entries that might have arrived after current GP ended + * [*nxttail[RCU_WAIT_TAIL], *nxttail[RCU_NEXT_READY_TAIL]): + * Entries known to have arrived before current GP ended + * [*nxttail[RCU_DONE_TAIL], *nxttail[RCU_WAIT_TAIL]): + * Entries that batch # <= ->completed - 1: waiting for current GP + * [nxtlist, *nxttail[RCU_DONE_TAIL]): + * Entries that batch # <= ->completed + * The grace period for these entries has completed, and + * the other grace-period-completed entries may be moved + * here temporarily in rcu_process_callbacks(). + */ + struct rcu_head *nxtlist; + struct rcu_head **nxttail[RCU_NEXT_SIZE]; + long qlen; /* # of queued callbacks */ + long blimit; /* Upper limit on a processed batch */ + +#ifdef CONFIG_NO_HZ + /* 3) dynticks interface. */ + struct rcu_dynticks *dynticks; /* Shared per-CPU dynticks state. */ + int dynticks_snap; /* Per-GP tracking for dynticks. */ + int dynticks_nmi_snap; /* Per-GP tracking for dynticks_nmi. */ +#endif /* #ifdef CONFIG_NO_HZ */ + + /* 4) reasons this CPU needed to be kicked by force_quiescent_state */ +#ifdef CONFIG_NO_HZ + unsigned long dynticks_fqs; /* Kicked due to dynticks idle. */ +#endif /* #ifdef CONFIG_NO_HZ */ + unsigned long offline_fqs; /* Kicked due to being offline. */ + unsigned long resched_ipi; /* Sent a resched IPI. */ + + /* 5) state to allow this CPU to force_quiescent_state on others */ + long n_rcu_pending; /* rcu_pending() calls since boot. */ + long n_rcu_pending_force_qs; /* when to force quiescent states. */ + + int cpu; +}; + +/* Values for signaled field in struct rcu_state. */ +#define RCU_GP_INIT 0 /* Grace period being initialized. */ +#define RCU_SAVE_DYNTICK 1 /* Need to scan dyntick state. */ +#define RCU_FORCE_QS 2 /* Need to force quiescent state. */ +#ifdef CONFIG_NO_HZ +#define RCU_SIGNAL_INIT RCU_SAVE_DYNTICK +#else /* #ifdef CONFIG_NO_HZ */ +#define RCU_SIGNAL_INIT RCU_FORCE_QS +#endif /* #else #ifdef CONFIG_NO_HZ */ + +#define RCU_JIFFIES_TILL_FORCE_QS 3 /* for rsp->jiffies_force_qs */ +#ifdef CONFIG_RCU_CPU_STALL_DETECTOR +#define RCU_SECONDS_TILL_STALL_CHECK (10 * HZ) /* for rsp->jiffies_stall */ +#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rsp->jiffies_stall */ +#define RCU_STALL_RAT_DELAY 2 /* Allow other CPUs time */ + /* to take at least one */ + /* scheduling clock irq */ + /* before ratting on them. */ + +#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ + +/* + * RCU global state, including node hierarchy. This hierarchy is + * represented in "heap" form in a dense array. The root (first level) + * of the hierarchy is in ->node[0] (referenced by ->level[0]), the second + * level in ->node[1] through ->node[m] (->node[1] referenced by ->level[1]), + * and the third level in ->node[m+1] and following (->node[m+1] referenced + * by ->level[2]). The number of levels is determined by the number of + * CPUs and by CONFIG_RCU_FANOUT. Small systems will have a "hierarchy" + * consisting of a single rcu_node. + */ +struct rcu_state { + struct rcu_node node[NUM_RCU_NODES]; /* Hierarchy. */ + struct rcu_node *level[NUM_RCU_LVLS]; /* Hierarchy levels. */ + u32 levelcnt[MAX_RCU_LVLS + 1]; /* # nodes in each level. */ + u8 levelspread[NUM_RCU_LVLS]; /* kids/node in each level. */ + struct rcu_data *rda[NR_CPUS]; /* array of rdp pointers. */ + + /* The following fields are guarded by the root rcu_node's lock. */ + + u8 signaled ____cacheline_internodealigned_in_smp; + /* Force QS state. */ + long gpnum; /* Current gp number. */ + long completed; /* # of last completed gp. */ + spinlock_t onofflock; /* exclude on/offline and */ + /* starting new GP. */ + spinlock_t fqslock; /* Only one task forcing */ + /* quiescent states. */ + unsigned long jiffies_force_qs; /* Time at which to invoke */ + /* force_quiescent_state(). */ + unsigned long n_force_qs; /* Number of calls to */ + /* force_quiescent_state(). */ + unsigned long n_force_qs_lh; /* ~Number of calls leaving */ + /* due to lock unavailable. */ + unsigned long n_force_qs_ngp; /* Number of calls leaving */ + /* due to no GP active. */ +#ifdef CONFIG_RCU_CPU_STALL_DETECTOR + unsigned long gp_start; /* Time at which GP started, */ + /* but in jiffies. */ + unsigned long jiffies_stall; /* Time at which to check */ + /* for CPU stalls. */ +#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ +#ifdef CONFIG_NO_HZ + long dynticks_completed; /* Value of completed @ snap. */ +#endif /* #ifdef CONFIG_NO_HZ */ +}; + +extern struct rcu_state rcu_state; +DECLARE_PER_CPU(struct rcu_data, rcu_data); + +extern struct rcu_state rcu_bh_state; +DECLARE_PER_CPU(struct rcu_data, rcu_bh_data); + +/* + * Increment the quiescent state counter. + * The counter is a bit degenerated: We do not need to know + * how many quiescent states passed, just if there was at least + * one since the start of the grace period. Thus just a flag. + */ +static inline void rcu_qsctr_inc(int cpu) +{ + struct rcu_data *rdp = &per_cpu(rcu_data, cpu); + rdp->passed_quiesc = 1; + rdp->passed_quiesc_completed = rdp->completed; +} +static inline void rcu_bh_qsctr_inc(int cpu) +{ + struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu); + rdp->passed_quiesc = 1; + rdp->passed_quiesc_completed = rdp->completed; +} + +extern int rcu_pending(int cpu); +extern int rcu_needs_cpu(int cpu); + +#ifdef CONFIG_DEBUG_LOCK_ALLOC +extern struct lockdep_map rcu_lock_map; +# define rcu_read_acquire() \ + lock_acquire(&rcu_lock_map, 0, 0, 2, 1, NULL, _THIS_IP_) +# define rcu_read_release() lock_release(&rcu_lock_map, 1, _THIS_IP_) +#else +# define rcu_read_acquire() do { } while (0) +# define rcu_read_release() do { } while (0) +#endif + +static inline void __rcu_read_lock(void) +{ + preempt_disable(); + __acquire(RCU); + rcu_read_acquire(); +} +static inline void __rcu_read_unlock(void) +{ + rcu_read_release(); + __release(RCU); + preempt_enable(); +} +static inline void __rcu_read_lock_bh(void) +{ + local_bh_disable(); + __acquire(RCU_BH); + rcu_read_acquire(); +} +static inline void __rcu_read_unlock_bh(void) +{ + rcu_read_release(); + __release(RCU_BH); + local_bh_enable(); +} + +#define __synchronize_sched() synchronize_rcu() + +#define call_rcu_sched(head, func) call_rcu(head, func) + +static inline void rcu_init_sched(void) +{ +} + +extern void __rcu_init(void); +extern void rcu_check_callbacks(int cpu, int user); +extern void rcu_restart_cpu(int cpu); + +extern long rcu_batches_completed(void); +extern long rcu_batches_completed_bh(void); + +#ifdef CONFIG_NO_HZ +void rcu_enter_nohz(void); +void rcu_exit_nohz(void); +#else /* CONFIG_NO_HZ */ +static inline void rcu_enter_nohz(void) +{ +} +static inline void rcu_exit_nohz(void) +{ +} +#endif /* CONFIG_NO_HZ */ + +#endif /* __LINUX_RCUTREE_H */ -- cgit v1.2.3 From 078a55db075bf4dcc03115dc94875b3dd83f69d4 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 18 Dec 2008 16:57:52 -0800 Subject: sparseirq: add kernel-doc notation for new member in irq_desc, -v2 Signed-off-by: Yinghai Lu Acked-by: Randy Dunlap Signed-off-by: Ingo Molnar --- include/linux/irq.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/irq.h b/include/linux/irq.h index 36a01574678..7fa7f30fccb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -134,6 +134,9 @@ struct irq_2_iommu; /** * struct irq_desc - interrupt descriptor * @irq: interrupt number for this descriptor + * @timer_rand_state: pointer to timer rand state struct + * @kstat_irqs: irq stats per cpu + * @irq_2_iommu: iommu with this irq * @handle_irq: highlevel irq-events handler [if NULL, __do_IRQ()] * @chip: low level interrupt hardware access * @msi_desc: MSI descriptor -- cgit v1.2.3 From 88a9fe8cae3bb52e82489447f45e8d7ba1409ca8 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 23 Dec 2008 15:21:31 -0500 Subject: SUNRPC: Remove the last remnant of the BKL... Somehow, this escaped the previous purge. There should be no need to keep any extra locks in the XDR callbacks. The NFS client XDR code only writes into private objects, whereas all reads of shared objects are confined to fields that do not change, such as filehandles... Ditto for lockd, the NFSv2/v3 client mount code, and rpcbind. The nfsd XDR code may require the BKL, but since it does a synchronous RPC call from a thread that already holds the lock, that issue is moot. Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xdr.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'include') diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index e4057d729f0..49e1eb45446 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -36,21 +36,6 @@ struct xdr_netobj { */ typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj); -/* - * We're still requiring the BKL in the xdr code until it's been - * more carefully audited, at which point this wrapper will become - * unnecessary. - */ -static inline int rpc_call_xdrproc(kxdrproc_t xdrproc, void *rqstp, __be32 *data, void *obj) -{ - int ret; - - lock_kernel(); - ret = xdrproc(rqstp, data, obj); - unlock_kernel(); - return ret; -} - /* * Basic structure for transmission/reception of a client XDR message. * Features a header (for a linear buffer containing RPC headers -- cgit v1.2.3 From 146ec944bbd31d241a44a00518b054fb01921d22 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 23 Dec 2008 15:21:34 -0500 Subject: NFS: Move declaration of nfs_mount() to fs/nfs/internal.h Clean up: The nfs_mount() function is not to be used outside of the NFS client. Move its public declaration to fs/nfs/internal.h. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 4eaa8347a0d..f11077285a6 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -532,12 +532,6 @@ static inline void nfs3_forget_cached_acls(struct inode *inode) } #endif /* CONFIG_NFS_V3_ACL */ -/* - * linux/fs/mount_clnt.c - */ -extern int nfs_mount(struct sockaddr *, size_t, char *, char *, - int, int, struct nfs_fh *); - /* * inline functions */ -- cgit v1.2.3 From d740351bf0960e89ce1aef45cfe00167cb0f9e5b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 23 Dec 2008 15:21:37 -0500 Subject: NFS: add "[no]resvport" mount option The standard default security setting for NFS is AUTH_SYS. An NFS client connects to NFS servers via a privileged source port and a fixed standard destination port (2049). The client sends raw uid and gid numbers to identify users making NFS requests, and the server assumes an appropriate authority on the client has vetted these values because the source port is privileged. On Linux, by default in-kernel RPC services use a privileged port in the range between 650 and 1023 to avoid using source ports of well- known IP services. Using such a small range limits the number of NFS mount points and the number of unique NFS servers to which a client can connect concurrently. An NFS client can use unprivileged source ports to expand the range of source port numbers, allowing more concurrent server connections and more NFS mount points. Servers must explicitly allow NFS connections from unprivileged ports for this to work. In the past, bumping the value of the sunrpc.max_resvport sysctl on the client would permit the NFS client to use unprivileged ports. Bumping this setting also changes the maximum port number used by other in-kernel RPC services, some of which still required a port number less than 1023. This is exacerbated by the way source port numbers are chosen by the Linux RPC client, which starts at the top of the range and works downwards. It means that bumping the maximum means all RPC services requesting a source port will likely get an unprivileged port instead of a privileged one. Changing this setting effects all NFS mount points on a client. A sysadmin could not selectively choose which mount points would use non-privileged ports and which could not. Lastly, this mechanism of expanding the limit on the number of NFS mount points was entirely undocumented. To address the need for the NFS client to use a large range of source ports without interfering with the activity of other in-kernel RPC services, we introduce a new NFS mount option. This option explicitly tells only the NFS client to use a non-privileged source port when communicating with the NFS server for one specific mount point. This new mount option is called "resvport," like the similar NFS mount option on FreeBSD and Mac OS X. A sister patch for nfs-utils will be submitted that documents this new option in nfs(5). The default setting for this new mount option requires the NFS client to use a privileged port, as before. Explicitly specifying the "noresvport" mount option allows the NFS client to use an unprivileged source port for this mount point when connecting to the NFS server port. This mount option is supported only for text-based NFS mounts. [ Sidebar: it is widely known that security mechanisms based on the use of privileged source ports are ineffective. However, the NFS client can combine the use of unprivileged ports with the use of secure authentication mechanisms, such as Kerberos. This allows a large number of connections and mount points while ensuring a useful level of security. Eventually we may change the default setting for this option depending on the security flavor used for the mount. For example, if the mount is using only AUTH_SYS, then the default setting will be "resvport;" if the mount is using a strong security flavor such as krb5, the default setting will be "noresvport." ] Signed-off-by: Chuck Lever [Trond.Myklebust@netapp.com: Fixed a bug whereby nfs4_init_client() was being called with incorrect arguments.] Signed-off-by: Trond Myklebust --- include/linux/nfs_mount.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h index 6549a06ac16..4499016e6d0 100644 --- a/include/linux/nfs_mount.h +++ b/include/linux/nfs_mount.h @@ -45,7 +45,7 @@ struct nfs_mount_data { char context[NFS_MAX_CONTEXT_LEN + 1]; /* 6 */ }; -/* bits in the flags field */ +/* bits in the flags field visible to user space */ #define NFS_MOUNT_SOFT 0x0001 /* 1 */ #define NFS_MOUNT_INTR 0x0002 /* 1 */ /* now unused, but ABI */ @@ -68,5 +68,6 @@ struct nfs_mount_data { /* The following are for internal use only */ #define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000 #define NFS_MOUNT_LOOKUP_CACHE_NONE 0x20000 +#define NFS_MOUNT_NORESVPORT 0x40000 #endif -- cgit v1.2.3 From 0cb2659b818eca99235e17c04291cfa9985c14f7 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 23 Dec 2008 15:21:38 -0500 Subject: NLM: allow lockd requests from an unprivileged port If the admin has specified the "noresvport" option for an NFS mount point, the kernel's NFS client uses an unprivileged source port for the main NFS transport. The kernel's lockd client should use an unprivileged port in this case as well. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/lockd/bind.h | 1 + include/linux/lockd/lockd.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index e5872dc994c..fbc48f89852 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -41,6 +41,7 @@ struct nlmclnt_initdata { size_t addrlen; unsigned short protocol; u32 nfs_version; + int noresvport; }; /* diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index b56d5aa9b19..23da3fa69ef 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -49,6 +49,7 @@ struct nlm_host { unsigned short h_proto; /* transport proto */ unsigned short h_reclaiming : 1, h_server : 1, /* server side, not client side */ + h_noresvport : 1, h_inuse : 1; wait_queue_head_t h_gracewait; /* wait while reclaiming */ struct rw_semaphore h_rwsem; /* Reboot recovery lock */ @@ -220,7 +221,8 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const size_t salen, const unsigned short protocol, const u32 version, - const char *hostname); + const char *hostname, + int noresvport); struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, const char *hostname, const size_t hostname_len); -- cgit v1.2.3 From 95d35cb4c473c754824967c0b069bbeb7efa4847 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 23 Dec 2008 15:21:45 -0500 Subject: NFSv4: Remove nfs_client->cl_sem Now that we're using the flags to indicate state that needs to be recovered, as well as having implemented proper refcounting and spinlocking on the state and open_owners, we can get rid of nfs_client->cl_sem. The only remaining case that was dubious was the file locking, and that case is now covered by the nfsi->rwsem. Signed-off-by: Trond Myklebust --- include/linux/nfs_fs_sb.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 4e477ae5869..9bb81aec91c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -42,12 +42,6 @@ struct nfs_client { struct rb_root cl_openowner_id; struct rb_root cl_lockowner_id; - /* - * The following rwsem ensures exclusive access to the server - * while we recover the state following a lease expiration. - */ - struct rw_semaphore cl_sem; - struct list_head cl_delegations; struct rb_root cl_state_owners; spinlock_t cl_lock; -- cgit v1.2.3 From bd7bf9d540c001055fba796ebf146d90e4dd2eb2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 23 Dec 2008 15:21:53 -0500 Subject: NFSv4: Convert delegation->type field to fmode_t Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 2 +- include/linux/nfs_xdr.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index f11077285a6..8d71d7b7c78 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -180,7 +180,7 @@ struct nfs_inode { /* NFSv4 state */ struct list_head open_states; struct nfs_delegation *delegation; - int delegation_state; + fmode_t delegation_state; struct rw_semaphore rwsem; #endif /* CONFIG_NFS_V4*/ struct inode vfs_inode; diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index c1c31acb8a2..32c1a0ecdbf 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -126,7 +126,7 @@ struct nfs_openargs { struct iattr * attrs; /* UNCHECKED, GUARDED */ nfs4_verifier verifier; /* EXCLUSIVE */ nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */ - int delegation_type; /* CLAIM_PREVIOUS */ + fmode_t delegation_type; /* CLAIM_PREVIOUS */ } u; const struct qstr * name; const struct nfs_server *server; /* Needed for ID mapping */ @@ -143,7 +143,7 @@ struct nfs_openres { struct nfs_fattr * dir_attr; struct nfs_seqid * seqid; const struct nfs_server *server; - int delegation_type; + fmode_t delegation_type; nfs4_stateid delegation; __u32 do_recall; __u64 maxsize; -- cgit v1.2.3 From dc0b027dfadfcb8a5504f7d8052754bf8d501ab9 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 23 Dec 2008 15:21:56 -0500 Subject: NFSv4: Convert the open and close ops to use fmode Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 4 ++-- include/linux/nfs_xdr.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 8d71d7b7c78..b8d9c6dd4f6 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -83,7 +83,7 @@ struct nfs_open_context { struct rpc_cred *cred; struct nfs4_state *state; fl_owner_t lockowner; - int mode; + fmode_t mode; unsigned long flags; #define NFS_CONTEXT_ERROR_WRITE (0) @@ -342,7 +342,7 @@ extern int nfs_setattr(struct dentry *, struct iattr *); extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr); extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx); extern void put_nfs_open_context(struct nfs_open_context *ctx); -extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, int mode); +extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode); extern u64 nfs_compat_user_ino64(u64 fileid); extern void nfs_fattr_init(struct nfs_fattr *fattr); diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 32c1a0ecdbf..a550b528319 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -120,6 +120,7 @@ struct nfs_openargs { const struct nfs_fh * fh; struct nfs_seqid * seqid; int open_flags; + fmode_t fmode; __u64 clientid; __u64 id; union { @@ -171,7 +172,7 @@ struct nfs_closeargs { struct nfs_fh * fh; nfs4_stateid * stateid; struct nfs_seqid * seqid; - int open_flags; + fmode_t fmode; const u32 * bitmask; }; -- cgit v1.2.3 From 64672d55d93c26fb4035fd1a84a803cbc09cb058 Mon Sep 17 00:00:00 2001 From: Peter Staubach Date: Tue, 23 Dec 2008 15:21:56 -0500 Subject: optimize attribute timeouts for "noac" and "actimeo=0" Hi. I've been looking at a bugzilla which describes a problem where a customer was advised to use either the "noac" or "actimeo=0" mount options to solve a consistency problem that they were seeing in the file attributes. It turned out that this solution did not work reliably for them because sometimes, the local attribute cache was believed to be valid and not timed out. (With an attribute cache timeout of 0, the cache should always appear to be timed out.) In looking at this situation, it appears to me that the problem is that the attribute cache timeout code has an off-by-one error in it. It is assuming that the cache is valid in the region, [read_cache_jiffies, read_cache_jiffies + attrtimeo]. The cache should be considered valid only in the region, [read_cache_jiffies, read_cache_jiffies + attrtimeo). With this change, the options, "noac" and "actimeo=0", work as originally expected. This problem was previously addressed by special casing the attrtimeo == 0 case. However, since the problem is only an off- by-one error, the cleaner solution is address the off-by-one error and thus, not require the special case. Thanx... ps Signed-off-by: Peter Staubach Signed-off-by: Trond Myklebust --- include/linux/jiffies.h | 10 ++++++++++ include/linux/nfs_fs.h | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index abb6ac639e8..1a9cf78bfce 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h @@ -115,10 +115,20 @@ static inline u64 get_jiffies_64(void) ((long)(a) - (long)(b) >= 0)) #define time_before_eq(a,b) time_after_eq(b,a) +/* + * Calculate whether a is in the range of [b, c]. + */ #define time_in_range(a,b,c) \ (time_after_eq(a,b) && \ time_before_eq(a,c)) +/* + * Calculate whether a is in the range of [b, c). + */ +#define time_in_range_open(a,b,c) \ + (time_after_eq(a,b) && \ + time_before(a,c)) + /* Same as above, but does so with platform independent 64bit types. * These must be used when utilizing jiffies_64 (i.e. return value of * get_jiffies_64() */ diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index b8d9c6dd4f6..db867b04ac3 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -130,7 +130,10 @@ struct nfs_inode { * * We need to revalidate the cached attrs for this inode if * - * jiffies - read_cache_jiffies > attrtimeo + * jiffies - read_cache_jiffies >= attrtimeo + * + * Please note the comparison is greater than or equal + * so that zero timeout values can be specified. */ unsigned long read_cache_jiffies; unsigned long attrtimeo; -- cgit v1.2.3 From c977a2ef40a38c45537ad03823d0a004f06373f0 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Tue, 23 Dec 2008 16:06:13 -0500 Subject: sunrpc: get rid of rpc_rqst.rq_bufsize rq_bufsize is not used. Signed-off-by: Mike Sager Signed-off-by: Benny Halevy Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprt.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 4d80a118d53..11fc71d50c1 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h @@ -76,8 +76,7 @@ struct rpc_rqst { struct list_head rq_list; __u32 * rq_buffer; /* XDR encode buffer */ - size_t rq_bufsize, - rq_callsize, + size_t rq_callsize, rq_rcvsize; struct xdr_buf rq_private_buf; /* The receive buffer -- cgit v1.2.3 From c381060869317b3c84430d4f54965d409cbfe65f Mon Sep 17 00:00:00 2001 From: "\\\"J. Bruce Fields\\" Date: Tue, 23 Dec 2008 16:08:32 -0500 Subject: rpc: add an rpc_pipe_open method We want to transition to a new gssd upcall which is text-based and more easily extensible. To simplify upgrades, as well as testing and debugging, it will help if we can upgrade gssd (to a version which understands the new upcall) without having to choose at boot (or module-load) time whether we want the new or the old upcall. We will do this by providing two different pipes: one named, as currently, after the mechanism (normally "krb5"), and supporting the old upcall. One named "gssd" and supporting the new upcall version. We allow gssd to indicate which version it supports by its choice of which pipe to open. As we have no interest in supporting *simultaneous* use of both versions, we'll forbid opening both pipes at the same time. So, add a new pipe_open callback to the rpc_pipefs api, which the gss code can use to track which pipes have been open, and to refuse opens of incompatible pipes. We only need this to be called on the first open of a given pipe. Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- include/linux/sunrpc/rpc_pipe_fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h index 51b977a4ca2..cea764c2359 100644 --- a/include/linux/sunrpc/rpc_pipe_fs.h +++ b/include/linux/sunrpc/rpc_pipe_fs.h @@ -15,6 +15,7 @@ struct rpc_pipe_ops { ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char __user *, size_t); ssize_t (*downcall)(struct file *, const char __user *, size_t); void (*release_pipe)(struct inode *); + int (*open_pipe)(struct inode *); void (*destroy_msg)(struct rpc_pipe_msg *); }; -- cgit v1.2.3 From 68e76ad0baf8f5d5060377c2423ee6eed5c63057 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 23 Dec 2008 16:17:15 -0500 Subject: nfsd: pass client principal name in rsc downcall Two principals are involved in krb5 authentication: the target, who we authenticate *to* (normally the name of the server, like nfs/server.citi.umich.edu@CITI.UMICH.EDU), and the source, we we authenticate *as* (normally a user, like bfields@UMICH.EDU) In the case of NFSv4 callbacks, the target of the callback should be the source of the client's setclientid call, and the source should be the nfs server's own principal. Therefore we allow svcgssd to pass down the name of the principal that just authenticated, so that on setclientid we can store that principal name with the new client, to be used later on callbacks. Signed-off-by: Olga Kornievskaia Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- include/linux/nfsd/state.h | 1 + include/linux/sunrpc/svcauth_gss.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index d0fe2e37845..ce7cbf4b7c9 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h @@ -124,6 +124,7 @@ struct nfs4_client { nfs4_verifier cl_verifier; /* generated by client */ time_t cl_time; /* time of last lease renewal */ __be32 cl_addr; /* client ipaddress */ + char *cl_principal; /* setclientid principal name */ struct svc_cred cl_cred; /* setclientid principal */ clientid_t cl_clientid; /* generated by server */ nfs4_verifier cl_confirm; /* generated by server */ diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h index c9165d9771a..ca7d725861f 100644 --- a/include/linux/sunrpc/svcauth_gss.h +++ b/include/linux/sunrpc/svcauth_gss.h @@ -20,6 +20,7 @@ int gss_svc_init(void); void gss_svc_shutdown(void); int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name); u32 svcauth_gss_flavor(struct auth_domain *dom); +char *svc_gss_principal(struct svc_rqst *); #endif /* __KERNEL__ */ #endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */ -- cgit v1.2.3 From 608207e8884e083ad8b8d33eda868da70f0d63e8 Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 23 Dec 2008 16:17:40 -0500 Subject: rpc: pass target name down to rpc level on callbacks The rpc client needs to know the principal that the setclientid was done as, so it can tell gssd who to authenticate to. Signed-off-by: Olga Kornievskaia Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- include/linux/sunrpc/clnt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 6f0ee1b84a4..c39a21040dc 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -58,6 +58,7 @@ struct rpc_clnt { struct rpc_timeout cl_timeout_default; struct rpc_program * cl_program; char cl_inline_name[32]; + char *cl_principal; /* target to authenticate to */ }; /* @@ -108,6 +109,7 @@ struct rpc_create_args { u32 version; rpc_authflavor_t authflavor; unsigned long flags; + char *client_name; }; /* Values for "flags" field */ -- cgit v1.2.3 From 61054b14d545e257b9415d5ca0cd5f43762b4d0c Mon Sep 17 00:00:00 2001 From: Olga Kornievskaia Date: Tue, 23 Dec 2008 16:19:00 -0500 Subject: nfsd: support callbacks with gss flavors This patch adds server-side support for callbacks other than AUTH_SYS. Signed-off-by: Olga Kornievskaia Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- include/linux/nfsd/state.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index ce7cbf4b7c9..128298c0362 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h @@ -124,6 +124,7 @@ struct nfs4_client { nfs4_verifier cl_verifier; /* generated by client */ time_t cl_time; /* time of last lease renewal */ __be32 cl_addr; /* client ipaddress */ + u32 cl_flavor; /* setclientid pseudoflavor */ char *cl_principal; /* setclientid principal name */ struct svc_cred cl_cred; /* setclientid principal */ clientid_t cl_clientid; /* generated by server */ -- cgit v1.2.3 From 1eca4365be25c540650693e941bc06a66cf38f94 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 3 Nov 2008 20:03:17 +0900 Subject: libata: beef up iterators There currently are the following looping constructs. * __ata_port_for_each_link() for all available links * ata_port_for_each_link() for edge links * ata_link_for_each_dev() for all devices * ata_link_for_each_dev_reverse() for all devices in reverse order Now there's a need for looping construct which is similar to __ata_port_for_each_link() but iterates over PMP links before the host link. Instead of adding another one with long name, do the following cleanup. * Implement and export ata_link_next() and ata_dev_next() which take @mode parameter and can be used to build custom loop. * Implement ata_for_each_link() and ata_for_each_dev() which take looping mode explicitly. The following iteration modes are implemented. * ATA_LITER_EDGE : loop over edge links * ATA_LITER_HOST_FIRST : loop over all links, host link first * ATA_LITER_PMP_FIRST : loop over all links, PMP links first * ATA_DITER_ENABLED : loop over enabled devices * ATA_DITER_ENABLED_REVERSE : loop over enabled devices in reverse order * ATA_DITER_ALL : loop over all devices * ATA_DITER_ALL_REVERSE : loop over all devices in reverse order This change removes exlicit device enabledness checks from many loops and makes it clear which ones are iterated over in which direction. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 76 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index ed3f26eb5df..3b2a0c6444e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1285,26 +1285,62 @@ static inline int ata_link_active(struct ata_link *link) return ata_tag_valid(link->active_tag) || link->sactive; } -extern struct ata_link *__ata_port_next_link(struct ata_port *ap, - struct ata_link *link, - bool dev_only); - -#define __ata_port_for_each_link(link, ap) \ - for ((link) = __ata_port_next_link((ap), NULL, false); (link); \ - (link) = __ata_port_next_link((ap), (link), false)) - -#define ata_port_for_each_link(link, ap) \ - for ((link) = __ata_port_next_link((ap), NULL, true); (link); \ - (link) = __ata_port_next_link((ap), (link), true)) - -#define ata_link_for_each_dev(dev, link) \ - for ((dev) = (link)->device; \ - (dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \ - (dev)++) - -#define ata_link_for_each_dev_reverse(dev, link) \ - for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \ - (dev) >= (link)->device || ((dev) = NULL); (dev)--) +/* + * Iterators + * + * ATA_LITER_* constants are used to select link iteration mode and + * ATA_DITER_* device iteration mode. + * + * For a custom iteration directly using ata_{link|dev}_next(), if + * @link or @dev, respectively, is NULL, the first element is + * returned. @dev and @link can be any valid device or link and the + * next element according to the iteration mode will be returned. + * After the last element, NULL is returned. + */ +enum ata_link_iter_mode { + ATA_LITER_EDGE, /* if present, PMP links only; otherwise, + * host link. no slave link */ + ATA_LITER_HOST_FIRST, /* host link followed by PMP or slave links */ + ATA_LITER_PMP_FIRST, /* PMP links followed by host link, + * slave link still comes after host link */ +}; + +enum ata_dev_iter_mode { + ATA_DITER_ENABLED, + ATA_DITER_ENABLED_REVERSE, + ATA_DITER_ALL, + ATA_DITER_ALL_REVERSE, +}; + +extern struct ata_link *ata_link_next(struct ata_link *link, + struct ata_port *ap, + enum ata_link_iter_mode mode); + +extern struct ata_device *ata_dev_next(struct ata_device *dev, + struct ata_link *link, + enum ata_dev_iter_mode mode); + +/* + * Shortcut notation for iterations + * + * ata_for_each_link() iterates over each link of @ap according to + * @mode. @link points to the current link in the loop. @link is + * NULL after loop termination. ata_for_each_dev() works the same way + * except that it iterates over each device of @link. + * + * Note that the mode prefixes ATA_{L|D}ITER_ shouldn't need to be + * specified when using the following shorthand notations. Only the + * mode itself (EDGE, HOST_FIRST, ENABLED, etc...) should be + * specified. This not only increases brevity but also makes it + * impossible to use ATA_LITER_* for device iteration or vice-versa. + */ +#define ata_for_each_link(link, ap, mode) \ + for ((link) = ata_link_next(NULL, (ap), ATA_LITER_##mode); (link); \ + (link) = ata_link_next((link), (ap), ATA_LITER_##mode)) + +#define ata_for_each_dev(dev, link, mode) \ + for ((dev) = ata_dev_next(NULL, (link), ATA_DITER_##mode); (dev); \ + (dev) = ata_dev_next((dev), (link), ATA_DITER_##mode)) /** * ata_ncq_enabled - Test whether NCQ is enabled -- cgit v1.2.3 From ece180d1cfe5fa751eaa85bf796cf28b2150af15 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 3 Nov 2008 20:04:37 +0900 Subject: libata: perform port detach in EH ata_port_detach() first made sure EH saw ATA_PFLAG_UNLOADING and then assumed EH context belongs to it and performed detach operation itself. However, UNLOADING doesn't disable all of EH and this could lead to problems including triggering WARN_ON()'s in EH path. This patch makes port detach behave more like other EH actions such that ata_port_detach() requests EH to detach and waits for completion. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/libata.h b/include/linux/libata.h index 3b2a0c6444e..3449de597ef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -213,10 +213,11 @@ enum { ATA_PFLAG_FROZEN = (1 << 2), /* port is frozen */ ATA_PFLAG_RECOVERED = (1 << 3), /* recovery action performed */ ATA_PFLAG_LOADING = (1 << 4), /* boot/loading probe */ - ATA_PFLAG_UNLOADING = (1 << 5), /* module is unloading */ ATA_PFLAG_SCSI_HOTPLUG = (1 << 6), /* SCSI hotplug scheduled */ ATA_PFLAG_INITIALIZING = (1 << 7), /* being initialized, don't touch */ ATA_PFLAG_RESETTING = (1 << 8), /* reset in progress */ + ATA_PFLAG_UNLOADING = (1 << 9), /* driver is being unloaded */ + ATA_PFLAG_UNLOADED = (1 << 10), /* driver is unloaded */ ATA_PFLAG_SUSPENDED = (1 << 17), /* port is suspended (power) */ ATA_PFLAG_PM_PENDING = (1 << 18), /* PM operation pending */ -- cgit v1.2.3 From 88e740f1654bf28565edd528a060695c1f2b5ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Luis=20V=C3=A1zquez=20Cao?= Date: Mon, 27 Oct 2008 18:44:46 +0900 Subject: block: add queue flag for paravirt frontend drivers As is the case with SSD devices, we do not want to idle in AS/CFQ when the block device is a paravirt front-end driver. This patch adds a flag (QUEUE_FLAG_VIRT) which should be used by front-end drivers such as virtio_blk and xen-blkfront to indicate a paravirtualized device. Signed-off-by: Fernando Luis Vazquez Cao Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 031a315c050..482e9600f7a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -449,6 +449,7 @@ struct request_queue #define QUEUE_FLAG_FAIL_IO 12 /* fake timeout */ #define QUEUE_FLAG_STACKABLE 13 /* supports request stacking */ #define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ +#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ static inline int queue_is_locked(struct request_queue *q) { -- cgit v1.2.3 From 08bafc0341f2f7920e9045bc32c40299cac8c21b Mon Sep 17 00:00:00 2001 From: Keith Mannthey Date: Tue, 25 Nov 2008 10:24:35 +0100 Subject: block: Supress Buffer I/O errors when SCSI REQ_QUIET flag set Allow the scsi request REQ_QUIET flag to be propagated to the buffer file system layer. The basic ideas is to pass the flag from the scsi request to the bio (block IO) and then to the buffer layer. The buffer layer can then suppress needless printks. This patch declutters the kernel log by removed the 40-50 (per lun) buffer io error messages seen during a boot in my multipath setup . It is a good chance any real errors will be missed in the "noise" it the logs without this patch. During boot I see blocks of messages like " __ratelimit: 211 callbacks suppressed Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242847 Buffer I/O error on device sdm, logical block 1 Buffer I/O error on device sdm, logical block 5242878 Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242879 Buffer I/O error on device sdm, logical block 5242872 " in my logs. My disk environment is multipath fiber channel using the SCSI_DH_RDAC code and multipathd. This topology includes an "active" and "ghost" path for each lun. IO's to the "ghost" path will never complete and the SCSI layer, via the scsi device handler rdac code, quick returns the IOs to theses paths and sets the REQ_QUIET scsi flag to suppress the scsi layer messages. I am wanting to extend the QUIET behavior to include the buffer file system layer to deal with these errors as well. I have been running this patch for a while now on several boxes without issue. A few runs of bonnie++ show no noticeable difference in performance in my setup. Thanks for John Stultz for the quiet_error finalization. Submitted-by: Keith Mannthey Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + include/linux/buffer_head.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index 6a642098e5c..cf132bfbbac 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -117,6 +117,7 @@ struct bio { #define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */ #define BIO_NULL_MAPPED 9 /* contains invalid user pages */ #define BIO_FS_INTEGRITY 10 /* fs owns integrity data, not block layer */ +#define BIO_QUIET 11 /* Make BIO Quiet */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /* diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index 3ce64b90118..8605f8a74df 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -35,6 +35,7 @@ enum bh_state_bits { BH_Ordered, /* ordered write */ BH_Eopnotsupp, /* operation not supported (barrier) */ BH_Unwritten, /* Buffer is allocated on disk but not written */ + BH_Quiet, /* Buffer Error Prinks to be quiet */ BH_PrivateStart,/* not a state bit, but the first bit available * for private allocation by other entities -- cgit v1.2.3 From 64d01dc9e1927e6535627d73f2336c75d1dd3fe2 Mon Sep 17 00:00:00 2001 From: Cheng Renquan Date: Wed, 3 Dec 2008 12:41:39 +0100 Subject: block: use cancel_work_sync() instead of kblockd_flush_work() After many improvements on kblockd_flush_work, it is now identical to cancel_work_sync, so a direct call to cancel_work_sync is suggested. The only difference is that cancel_work_sync is a GPL symbol, so no non-GPL modules anymore. Signed-off-by: Cheng Renquan Cc: Jens Axboe Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 482e9600f7a..e9bb73ff1d6 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -978,7 +978,6 @@ static inline void put_dev_sector(Sector p) struct work_struct; int kblockd_schedule_work(struct request_queue *q, struct work_struct *work); -void kblockd_flush_work(struct work_struct *work); #define MODULE_ALIAS_BLOCKDEV(major,minor) \ MODULE_ALIAS("block-major-" __stringify(major) "-" __stringify(minor)) -- cgit v1.2.3 From ba744d5e290055d171c68067259fcc1e2721f542 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Wed, 3 Dec 2008 12:41:40 +0100 Subject: block: reorder struct bio to remove padding on 64bit Remove 8 bytes of padding from struct bio which also removes 16 bytes from struct bio_pair to make it 248 bytes. bio_pair then fits into one fewer cache lines & into a smaller slab. Signed-off-by: Richard Kennedy Signed-off-by: Jens Axboe --- include/linux/bio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index cf132bfbbac..3ed714eb54d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -90,10 +90,11 @@ struct bio { unsigned int bi_comp_cpu; /* completion CPU */ + atomic_t bi_cnt; /* pin count */ + struct bio_vec *bi_io_vec; /* the actual vec list */ bio_end_io_t *bi_end_io; - atomic_t bi_cnt; /* pin count */ void *bi_private; #if defined(CONFIG_BLK_DEV_INTEGRITY) -- cgit v1.2.3 From 313e42999dbc0f234ca5909a236f78f082cb43b1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 28 Nov 2008 13:32:02 +0900 Subject: block: reorganize QUEUE_ORDERED_* constants Separate out ordering type (drain,) and action masks (preflush, postflush, fua) from visible ordering mode selectors (QUEUE_ORDERED_*). Ordering types are now named QUEUE_ORDERED_BY_* while action masks are named QUEUE_ORDERED_DO_*. This change is necessary to add QUEUE_ORDERED_DO_BAR and make it optional to improve empty barrier implementation. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e9bb73ff1d6..5c92b443239 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -523,22 +523,29 @@ enum { * TAG_FLUSH : ordering by tag w/ pre and post flushes * TAG_FUA : ordering by tag w/ pre flush and FUA write */ - QUEUE_ORDERED_NONE = 0x00, - QUEUE_ORDERED_DRAIN = 0x01, - QUEUE_ORDERED_TAG = 0x02, - - QUEUE_ORDERED_PREFLUSH = 0x10, - QUEUE_ORDERED_POSTFLUSH = 0x20, - QUEUE_ORDERED_FUA = 0x40, - - QUEUE_ORDERED_DRAIN_FLUSH = QUEUE_ORDERED_DRAIN | - QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH, - QUEUE_ORDERED_DRAIN_FUA = QUEUE_ORDERED_DRAIN | - QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA, - QUEUE_ORDERED_TAG_FLUSH = QUEUE_ORDERED_TAG | - QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_POSTFLUSH, - QUEUE_ORDERED_TAG_FUA = QUEUE_ORDERED_TAG | - QUEUE_ORDERED_PREFLUSH | QUEUE_ORDERED_FUA, + QUEUE_ORDERED_BY_DRAIN = 0x01, + QUEUE_ORDERED_BY_TAG = 0x02, + QUEUE_ORDERED_DO_PREFLUSH = 0x10, + QUEUE_ORDERED_DO_POSTFLUSH = 0x40, + QUEUE_ORDERED_DO_FUA = 0x80, + + QUEUE_ORDERED_NONE = 0x00, + + QUEUE_ORDERED_DRAIN = QUEUE_ORDERED_BY_DRAIN, + QUEUE_ORDERED_DRAIN_FLUSH = QUEUE_ORDERED_DRAIN | + QUEUE_ORDERED_DO_PREFLUSH | + QUEUE_ORDERED_DO_POSTFLUSH, + QUEUE_ORDERED_DRAIN_FUA = QUEUE_ORDERED_DRAIN | + QUEUE_ORDERED_DO_PREFLUSH | + QUEUE_ORDERED_DO_FUA, + + QUEUE_ORDERED_TAG = QUEUE_ORDERED_BY_TAG, + QUEUE_ORDERED_TAG_FLUSH = QUEUE_ORDERED_TAG | + QUEUE_ORDERED_DO_PREFLUSH | + QUEUE_ORDERED_DO_POSTFLUSH, + QUEUE_ORDERED_TAG_FUA = QUEUE_ORDERED_TAG | + QUEUE_ORDERED_DO_PREFLUSH | + QUEUE_ORDERED_DO_FUA, /* * Ordered operation sequence -- cgit v1.2.3 From f671620e7d895af221bdfeda751d54fa55ed9546 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 28 Nov 2008 13:32:04 +0900 Subject: block: make every barrier action optional In all barrier sequences, the barrier write itself was always assumed to be issued and thus didn't have corresponding control flag. This patch adds QUEUE_ORDERED_DO_BAR and unify action mask handling in start_ordered() such that any barrier action can be skipped. This patch doesn't introduce any visible behavior changes. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 5c92b443239..b044267009e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -526,12 +526,14 @@ enum { QUEUE_ORDERED_BY_DRAIN = 0x01, QUEUE_ORDERED_BY_TAG = 0x02, QUEUE_ORDERED_DO_PREFLUSH = 0x10, + QUEUE_ORDERED_DO_BAR = 0x20, QUEUE_ORDERED_DO_POSTFLUSH = 0x40, QUEUE_ORDERED_DO_FUA = 0x80, QUEUE_ORDERED_NONE = 0x00, - QUEUE_ORDERED_DRAIN = QUEUE_ORDERED_BY_DRAIN, + QUEUE_ORDERED_DRAIN = QUEUE_ORDERED_BY_DRAIN | + QUEUE_ORDERED_DO_BAR, QUEUE_ORDERED_DRAIN_FLUSH = QUEUE_ORDERED_DRAIN | QUEUE_ORDERED_DO_PREFLUSH | QUEUE_ORDERED_DO_POSTFLUSH, @@ -539,7 +541,8 @@ enum { QUEUE_ORDERED_DO_PREFLUSH | QUEUE_ORDERED_DO_FUA, - QUEUE_ORDERED_TAG = QUEUE_ORDERED_BY_TAG, + QUEUE_ORDERED_TAG = QUEUE_ORDERED_BY_TAG | + QUEUE_ORDERED_DO_BAR, QUEUE_ORDERED_TAG_FLUSH = QUEUE_ORDERED_TAG | QUEUE_ORDERED_DO_PREFLUSH | QUEUE_ORDERED_DO_POSTFLUSH, -- cgit v1.2.3 From 8f11b3e99a1136fcbb67316c3260f085299c0bff Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 28 Nov 2008 13:32:05 +0900 Subject: block: make barrier completion more robust Barrier completion had the following assumptions. * start_ordered() couldn't finish the whole sequence properly. If all actions are to be skipped, q->ordseq is set correctly but the actual completion was never triggered thus hanging the barrier request. * Drain completion in elv_complete_request() assumed that there's always at least one request in the queue when drain completes. Both assumptions are true but these assumptions need to be removed to improve empty barrier implementation. This patch makes the following changes. * Make start_ordered() use blk_ordered_complete_seq() to mark skipped steps complete and notify __elv_next_request() that it should fetch the next request if the whole barrier has completed inside start_ordered(). * Make drain completion path in elv_complete_request() check whether the queue is empty. Empty queue also indicates drain completion. * While at it, convert 0/1 return from blk_do_ordered() to false/true. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b044267009e..3c7078e0129 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -866,10 +866,10 @@ extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *); extern void blk_queue_rq_timeout(struct request_queue *, unsigned int); extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); extern int blk_queue_ordered(struct request_queue *, unsigned, prepare_flush_fn *); -extern int blk_do_ordered(struct request_queue *, struct request **); +extern bool blk_do_ordered(struct request_queue *, struct request **); extern unsigned blk_ordered_cur_seq(struct request_queue *); extern unsigned blk_ordered_req_seq(struct request *); -extern void blk_ordered_complete_seq(struct request_queue *, unsigned, int); +extern bool blk_ordered_complete_seq(struct request_queue *, unsigned, int); extern int blk_rq_map_sg(struct request_queue *, struct request *, struct scatterlist *); extern void blk_dump_rq_flags(struct request *, char *); -- cgit v1.2.3 From 58eea927d2de43dc6f03d1ba2c46e55854b31540 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 28 Nov 2008 13:32:06 +0900 Subject: block: simplify empty barrier implementation Empty barrier required special handling in __elv_next_request() to complete it without letting the low level driver see it. With previous changes, barrier code is now flexible enough to skip the BAR step using the same barrier sequence selection mechanism. Drop the special handling and mask off q->ordered from start_ordered(). Remove blk_empty_barrier() test which now has no user. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3c7078e0129..41bbadfd17f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -596,7 +596,6 @@ enum { #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) #define blk_discard_rq(rq) ((rq)->cmd_flags & REQ_DISCARD) #define blk_bidi_rq(rq) ((rq)->next_rq != NULL) -#define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors) /* rq->queuelist of dequeued request must be list_empty() */ #define blk_queued_rq(rq) (!list_empty(&(rq)->queuelist)) -- cgit v1.2.3 From 7ff9345ffac56743b5001561bc2dc1e041b79149 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Dec 2008 11:53:43 +0100 Subject: bio: only mempool back the largest bio_vec slab cache We only very rarely need the mempool backing, so it makes sense to get rid of all but one of the mempool in a bio_set. So keep the largest bio_vec count mempool so we can always honor the largest allocation, and "upgrade" callers that fail. Signed-off-by: Jens Axboe --- include/linux/bio.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index 3ed714eb54d..d76e4bf22f2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -397,13 +397,14 @@ static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu) */ #define BIO_POOL_SIZE 2 #define BIOVEC_NR_POOLS 6 +#define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1) struct bio_set { mempool_t *bio_pool; #if defined(CONFIG_BLK_DEV_INTEGRITY) mempool_t *bio_integrity_pool; #endif - mempool_t *bvec_pools[BIOVEC_NR_POOLS]; + mempool_t *bvec_pool; }; struct biovec_slab { -- cgit v1.2.3 From 1b4344986926da324b5cd10b683e5a1a5e1b7db3 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 22 Oct 2008 20:32:58 +0200 Subject: bio: move the slab pointer inside the bio_set In preparation for adding differently sized bios. Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index d76e4bf22f2..9340098d75d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -400,6 +400,7 @@ static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu) #define BIOVEC_MAX_IDX (BIOVEC_NR_POOLS - 1) struct bio_set { + struct kmem_cache *bio_slab; mempool_t *bio_pool; #if defined(CONFIG_BLK_DEV_INTEGRITY) mempool_t *bio_integrity_pool; -- cgit v1.2.3 From bb799ca0202a360fa74d5f17039b9100caebdde7 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 10 Dec 2008 15:35:05 +0100 Subject: bio: allow individual slabs in the bio_set Instead of having a global bio slab cache, add a reference to one in each bio_set that is created. This allows for personalized slabs in each bio_set, so that they can have bios of different sizes. This means we can personalize the bios we return. File systems may want to embed the bio inside another structure, to avoid allocation more items (and stuffing them in ->bi_private) after the get a bio. Or we may want to embed a number of bio_vecs directly at the end of a bio, to avoid doing two allocations to return a bio. This is now possible. Signed-off-by: Jens Axboe --- include/linux/bio.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index 9340098d75d..4b80d3537f9 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -334,7 +334,7 @@ struct bio_pair { extern struct bio_pair *bio_split(struct bio *bi, int first_sectors); extern void bio_pair_release(struct bio_pair *dbio); -extern struct bio_set *bioset_create(int, int); +extern struct bio_set *bioset_create(unsigned int, unsigned int); extern void bioset_free(struct bio_set *); extern struct bio *bio_alloc(gfp_t, int); @@ -379,6 +379,7 @@ extern struct bio *bio_copy_user_iov(struct request_queue *, extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *); +extern void bvec_free_bs(struct bio_set *, struct bio_vec *, unsigned int); extern unsigned int bvec_nr_vecs(unsigned short idx); /* @@ -401,6 +402,8 @@ static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu) struct bio_set { struct kmem_cache *bio_slab; + unsigned int front_pad; + mempool_t *bio_pool; #if defined(CONFIG_BLK_DEV_INTEGRITY) mempool_t *bio_integrity_pool; @@ -415,6 +418,7 @@ struct biovec_slab { }; extern struct bio_set *fs_bio_set; +extern struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] __read_mostly; /* * a small number of entries is fine, not going to be performance critical. -- cgit v1.2.3 From 392ddc32982a5c661dd90dd49a3cb37f1c68b782 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 23 Dec 2008 12:42:54 +0100 Subject: bio: add support for inlining a number of bio_vecs inside the bio When we go and allocate a bio for IO, we actually do two allocations. One for the bio itself, and one for the bi_io_vec that holds the actual pages we are interested in. This feature inlines a definable amount of io vecs inside the bio itself, so we eliminate the bio_vec array allocation for IO's up to a certain size. It defaults to 4 vecs, which is typically 16k of IO. Signed-off-by: Jens Axboe --- include/linux/bio.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') diff --git a/include/linux/bio.h b/include/linux/bio.h index 4b80d3537f9..18462c5b8ff 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -102,6 +102,13 @@ struct bio { #endif bio_destructor_t *bi_destructor; /* destructor */ + + /* + * We can inline a number of vecs at the end of the bio, to avoid + * double allocations for a small number of bio_vecs. This member + * MUST obviously be kept at the very end of the bio. + */ + struct bio_vec bi_inline_vecs[0]; }; /* @@ -213,6 +220,11 @@ static inline void *bio_data(struct bio *bio) return NULL; } +static inline int bio_has_allocated_vec(struct bio *bio) +{ + return bio->bi_io_vec && bio->bi_io_vec != bio->bi_inline_vecs; +} + /* * will die */ -- cgit v1.2.3 From abf137dd7712132ee56d5b3143c2ff61a72a5faa Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 9 Dec 2008 08:11:22 +0100 Subject: aio: make the lookup_ioctx() lockless The mm->ioctx_list is currently protected by a reader-writer lock, so we always grab that lock on the read side for doing ioctx lookups. As the workload is extremely reader biased, turn this into an rcu hlist so we can make lookup_ioctx() lockless. Get rid of the rwlock and use a spinlock for providing update side exclusion. There's usually only 1 entry on this list, so it doesn't make sense to look into fancier data structures. Reviewed-by: Jeff Moyer Signed-off-by: Jens Axboe --- include/linux/aio.h | 5 ++++- include/linux/mm_types.h | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/aio.h b/include/linux/aio.h index f6b8cf99b59..b16a957030f 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -183,7 +184,7 @@ struct kioctx { /* This needs improving */ unsigned long user_id; - struct kioctx *next; + struct hlist_node list; wait_queue_head_t wait; @@ -199,6 +200,8 @@ struct kioctx { struct aio_ring_info ring_info; struct delayed_work wq; + + struct rcu_head rcu_head; }; /* prototypes */ diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index fe825471d5a..9cfc9b627fd 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -232,8 +232,9 @@ struct mm_struct { struct core_state *core_state; /* coredumping support */ /* aio bits */ - rwlock_t ioctx_list_lock; /* aio lock */ - struct kioctx *ioctx_list; + spinlock_t ioctx_lock; + struct hlist_head ioctx_list; + #ifdef CONFIG_MM_OWNER /* * "owner" points to a task that is regarded as the canonical -- cgit v1.2.3 From b374d18a4bfce705e4a99ae9f501b53e86ecb283 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 31 Oct 2008 10:05:07 +0100 Subject: block: get rid of elevator_t typedef Just use struct elevator_queue everywhere instead. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 3 +-- include/linux/elevator.h | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 41bbadfd17f..7035cec583b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -26,7 +26,6 @@ struct scsi_ioctl_command; struct request_queue; struct elevator_queue; -typedef struct elevator_queue elevator_t; struct request_pm_state; struct blk_trace; struct request; @@ -313,7 +312,7 @@ struct request_queue */ struct list_head queue_head; struct request *last_merge; - elevator_t *elevator; + struct elevator_queue *elevator; /* * the queue request freelist, one for reads and one for writes diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 92f6f634e3e..7a204256b15 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -28,7 +28,7 @@ typedef void (elevator_activate_req_fn) (struct request_queue *, struct request typedef void (elevator_deactivate_req_fn) (struct request_queue *, struct request *); typedef void *(elevator_init_fn) (struct request_queue *); -typedef void (elevator_exit_fn) (elevator_t *); +typedef void (elevator_exit_fn) (struct elevator_queue *); struct elevator_ops { @@ -62,8 +62,8 @@ struct elevator_ops struct elv_fs_entry { struct attribute attr; - ssize_t (*show)(elevator_t *, char *); - ssize_t (*store)(elevator_t *, const char *, size_t); + ssize_t (*show)(struct elevator_queue *, char *); + ssize_t (*store)(struct elevator_queue *, const char *, size_t); }; /* @@ -130,7 +130,7 @@ extern ssize_t elv_iosched_show(struct request_queue *, char *); extern ssize_t elv_iosched_store(struct request_queue *, const char *, size_t); extern int elevator_init(struct request_queue *, char *); -extern void elevator_exit(elevator_t *); +extern void elevator_exit(struct elevator_queue *); extern int elv_rq_merge_ok(struct request *, struct bio *); /* -- cgit v1.2.3 From a6f23657d3072bde6844055bbc2290e497f33fbc Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 24 Oct 2008 12:52:42 +0200 Subject: block: add one-hit cache for disk partition lookup disk_map_sector_rcu() returns a partition from a sector offset, which we use for IO statistics on a per-partition basis. The lookup itself is an O(N) list lookup, where N is the number of partitions. This actually hurts performance quite a bit, even on the lower end partitions. On higher numbered partitions, it can get pretty bad. Solve this by adding a one-hit cache for partition lookup. This makes the lookup O(1) for the case where we do most IO to one partition. Even for mixed partition workloads, amortized cost is pretty close to O(1) since the natural IO batching makes the one-hit cache last for lots of IOs. Signed-off-by: Jens Axboe --- include/linux/genhd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3df7742ce24..16948eaecae 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -126,6 +126,7 @@ struct blk_scsi_cmd_filter { struct disk_part_tbl { struct rcu_head rcu_head; int len; + struct hd_struct *last_lookup; struct hd_struct *part[]; }; -- cgit v1.2.3 From b3a6ffe16b5cc48abe7db8d04882dc45280eb693 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 12 Dec 2008 09:51:16 +0100 Subject: Get rid of CONFIG_LSF We have two seperate config entries for large devices/files. One is CONFIG_LBD that guards just the devices, the other is CONFIG_LSF that handles large files. This doesn't make a lot of sense, you typically want both or none. So get rid of CONFIG_LSF and change CONFIG_LBD wording to indicate that it covers both. Acked-by: Jean Delvare Signed-off-by: Jens Axboe --- include/linux/types.h | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/linux/types.h b/include/linux/types.h index 1d98330b1f2..121f349cb7e 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -135,19 +135,14 @@ typedef __s64 int64_t; * * Linux always considers sectors to be 512 bytes long independently * of the devices real block size. + * + * blkcnt_t is the type of the inode's block count. */ #ifdef CONFIG_LBD typedef u64 sector_t; -#else -typedef unsigned long sector_t; -#endif - -/* - * The type of the inode's block count. - */ -#ifdef CONFIG_LSF typedef u64 blkcnt_t; #else +typedef unsigned long sector_t; typedef unsigned long blkcnt_t; #endif -- cgit v1.2.3 From e7f7ab45ebcb54fd5f814ea15ea079e079662f67 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 28 Nov 2008 13:43:47 +1000 Subject: drm: cleanup exit path for module unload The current sub-module unload exit path is a mess, it tries to abuse the idr. Just keep a list of devices per driver struct and free them in-order on rmmod. Signed-off-by: Dave Airlie --- include/drm/drmP.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d5e8e5c8954..08b8539e7b3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -737,6 +737,8 @@ struct drm_driver { int num_ioctls; struct file_operations fops; struct pci_driver pci_driver; + /* List of devices hanging off this driver */ + struct list_head device_list; }; #define DRM_MINOR_UNASSIGNED 0 @@ -759,6 +761,7 @@ struct drm_minor { * may contain multiple heads. */ struct drm_device { + struct list_head driver_item; /**< list of devices per driver */ char *unique; /**< Unique identifier: e.g., busid */ int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ -- cgit v1.2.3 From 7c1c2871a6a3a114853ec6836e9035ac1c0c7f7a Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 28 Nov 2008 14:22:24 +1000 Subject: drm: move to kref per-master structures. This is step one towards having multiple masters sharing a drm device in order to get fast-user-switching to work. It splits out the information associated with the drm master into a separate kref counted structure, and allocates this when a master opens the device node. It also allows the current master to abdicate (say while VT switched), and a new master to take over the hardware. It moves the Intel and radeon drivers to using the sarea from within the new master structures. Signed-off-by: Dave Airlie --- include/drm/drm.h | 3 +++ include/drm/drmP.h | 64 ++++++++++++++++++++++++++++++++++++------------- include/drm/drm_sarea.h | 6 ++--- 3 files changed, 54 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/drm/drm.h b/include/drm/drm.h index f46ba4b57da..3fb173c5af3 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -634,6 +634,9 @@ struct drm_gem_open { #define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) #define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) +#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e) +#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f) + #define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) #define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) #define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 08b8539e7b3..4c6e8298b42 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -238,11 +238,11 @@ struct drm_device; */ #define LOCK_TEST_WITH_RETURN( dev, file_priv ) \ do { \ - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \ - dev->lock.file_priv != file_priv ) { \ + if (!_DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock) || \ + file_priv->master->lock.file_priv != file_priv) { \ DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\ - __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\ - dev->lock.file_priv, file_priv ); \ + __func__, _DRM_LOCK_IS_HELD(file_priv->master->lock.hw_lock->lock),\ + file_priv->master->lock.file_priv, file_priv); \ return -EINVAL; \ } \ } while (0) @@ -379,21 +379,25 @@ struct drm_buf_entry { /** File private data */ struct drm_file { int authenticated; - int master; pid_t pid; uid_t uid; drm_magic_t magic; unsigned long ioctl_count; struct list_head lhead; struct drm_minor *minor; - int remove_auth_on_close; unsigned long lock_count; + /** Mapping of mm object handles to object pointers. */ struct idr object_idr; /** Lock for synchronization of access to object_idr. */ spinlock_t table_lock; + struct file *filp; void *driver_priv; + + int is_master; /* this file private is a master for a minor */ + struct drm_master *master; /* master this node is currently associated with + N.B. not always minor->master */ }; /** Wait queue */ @@ -523,6 +527,7 @@ struct drm_map_list { struct drm_hash_item hash; struct drm_map *map; /**< mapping */ uint64_t user_token; + struct drm_master *master; }; typedef struct drm_map drm_local_map_t; @@ -612,6 +617,30 @@ struct drm_gem_object { void *driver_private; }; +/* per-master structure */ +struct drm_master { + + struct kref refcount; /* refcount for this master */ + + struct list_head head; /**< each minor contains a list of masters */ + struct drm_minor *minor; /**< link back to minor we are a master for */ + + char *unique; /**< Unique identifier: e.g., busid */ + int unique_len; /**< Length of unique field */ + + int blocked; /**< Blocked due to VC switch? */ + + /** \name Authentication */ + /*@{ */ + struct drm_open_hash magiclist; + struct list_head magicfree; + /*@} */ + + struct drm_lock_data lock; /**< Information on hardware lock */ + + void *driver_priv; /**< Private structure for driver to use */ +}; + /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -712,6 +741,10 @@ struct drm_driver { void (*set_version) (struct drm_device *dev, struct drm_set_version *sv); + /* Master routines */ + int (*master_create)(struct drm_device *dev, struct drm_master *master); + void (*master_destroy)(struct drm_device *dev, struct drm_master *master); + int (*proc_init)(struct drm_minor *minor); void (*proc_cleanup)(struct drm_minor *minor); @@ -754,6 +787,8 @@ struct drm_minor { struct device kdev; /**< Linux device */ struct drm_device *dev; struct proc_dir_entry *dev_root; /**< proc directory entry */ + struct drm_master *master; /* currently active master for this node */ + struct list_head master_list; }; /** @@ -762,13 +797,9 @@ struct drm_minor { */ struct drm_device { struct list_head driver_item; /**< list of devices per driver */ - char *unique; /**< Unique identifier: e.g., busid */ - int unique_len; /**< Length of unique field */ char *devname; /**< For /proc/interrupts */ int if_version; /**< Highest interface version set */ - int blocked; /**< Blocked due to VC switch? */ - /** \name Locks */ /*@{ */ spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ @@ -791,12 +822,7 @@ struct drm_device { atomic_t counts[15]; /*@} */ - /** \name Authentication */ - /*@{ */ struct list_head filelist; - struct drm_open_hash magiclist; /**< magic hash table */ - struct list_head magicfree; - /*@} */ /** \name Memory management */ /*@{ */ @@ -813,7 +839,6 @@ struct drm_device { struct idr ctx_idr; struct list_head vmalist; /**< List of vmas (for debugging) */ - struct drm_lock_data lock; /**< Information on hardware lock */ /*@} */ /** \name DMA queues (contexts) */ @@ -1192,6 +1217,13 @@ extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle); extern void drm_agp_chipset_flush(struct drm_device *dev); /* Stub support (drm_stub.h) */ +extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data, + struct drm_file *file_priv); +struct drm_master *drm_master_create(struct drm_minor *minor); +extern struct drm_master *drm_master_get(struct drm_master *master); +extern void drm_master_put(struct drm_master **master); extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, struct drm_driver *driver); extern int drm_put_dev(struct drm_device *dev); diff --git a/include/drm/drm_sarea.h b/include/drm/drm_sarea.h index 480037331e4..ee5389d22c6 100644 --- a/include/drm/drm_sarea.h +++ b/include/drm/drm_sarea.h @@ -36,12 +36,12 @@ /* SAREA area needs to be at least a page */ #if defined(__alpha__) -#define SAREA_MAX 0x2000 +#define SAREA_MAX 0x2000U #elif defined(__ia64__) -#define SAREA_MAX 0x10000 /* 64kB */ +#define SAREA_MAX 0x10000U /* 64kB */ #else /* Intel 830M driver needs at least 8k SAREA */ -#define SAREA_MAX 0x2000 +#define SAREA_MAX 0x2000U #endif /** Maximum number of drawables in the SAREA */ -- cgit v1.2.3 From 1147c9cdd0f60f09a98702a9f865176af18a989f Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Tue, 2 Dec 2008 13:38:47 +1000 Subject: drm: fix leak of uninitialized data to userspace ...so drm_getunique() is trying to copy some uninitialized data to userspace. The ECX register contains the number of words that are left to copy -- so there are 5 * 4 = 20 bytes left. The offset of the first uninitialized byte (counting from the start of the string) is also 20 (i.e. 0xf65d2294&((1 << 5)-1) == 20). So somebody tried to copy 40 bytes when the string was only 19 long. In drm_set_busid() we have this code: dev->unique_len = 40; dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER); ... len = snprintf(dev->unique, dev->unique_len, pci:%04x:%02x:%02x.%d", ...so it seems that dev->unique is never updated to reflect the actual length of the string. The remaining bytes (20 in this case) are random uninitialized bytes that are copied into userspace. This patch fixes the problem by setting dev->unique_len after the snprintf(). airlied- I've had to fix this up to store the alloced size so we have it for drm_free later. Reported-by: Sitsofe Wheeler Signed-off-by: Vegard Nossum Signed-off-by: Dave Airlie --- include/drm/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 4c6e8298b42..c9cc618dbcf 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -627,6 +627,7 @@ struct drm_master { char *unique; /**< Unique identifier: e.g., busid */ int unique_len; /**< Length of unique field */ + int unique_size; /**< amount allocated */ int blocked; /**< Blocked due to VC switch? */ -- cgit v1.2.3 From a2c0a97b784f837300f7b0869c82ab712c600952 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 5 Nov 2008 10:31:53 -0800 Subject: drm: GEM mmap support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add core support for mapping of GEM objects. Drivers should provide a vm_operations_struct if they want to support page faulting of objects. The code for handling GEM object offsets was taken from TTM, which was written by Thomas Hellström. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drm.h | 1 + include/drm/drmP.h | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'include') diff --git a/include/drm/drm.h b/include/drm/drm.h index 3fb173c5af3..3a66252456b 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -173,6 +173,7 @@ enum drm_map_type { _DRM_AGP = 3, /**< AGP/GART */ _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ + _DRM_GEM = 6, /**< GEM object */ }; /** diff --git a/include/drm/drmP.h b/include/drm/drmP.h index c9cc618dbcf..ae42a6a5c24 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -528,6 +528,7 @@ struct drm_map_list { struct drm_map *map; /**< mapping */ uint64_t user_token; struct drm_master *master; + struct drm_mm_node *file_offset_node; /**< fake offset */ }; typedef struct drm_map drm_local_map_t; @@ -567,6 +568,14 @@ struct drm_ati_pcigart_info { int table_size; }; +/** + * GEM specific mm private for tracking GEM objects + */ +struct drm_gem_mm { + struct drm_mm offset_manager; /**< Offset mgmt for buffer objects */ + struct drm_open_hash offset_hash; /**< User token hash table for maps */ +}; + /** * This structure defines the drm_mm memory object, which will be used by the * DRM for its buffer objects. @@ -584,6 +593,9 @@ struct drm_gem_object { /** File representing the shmem storage */ struct file *filp; + /* Mapping info for this object */ + struct drm_map_list map_list; + /** * Size of the object, in bytes. Immutable over the object's * lifetime. @@ -758,6 +770,9 @@ struct drm_driver { int (*gem_init_object) (struct drm_gem_object *obj); void (*gem_free_object) (struct drm_gem_object *obj); + /* Driver private ops for this object */ + struct vm_operations_struct *gem_vm_ops; + int major; int minor; int patchlevel; @@ -910,6 +925,8 @@ struct drm_device { struct drm_sg_mem *sg; /**< Scatter gather memory */ int num_crtcs; /**< Number of CRTCs on this device */ void *dev_private; /**< device private data */ + void *mm_private; + struct address_space *dev_mapping; struct drm_sigdata sigdata; /**< For block_all_signals */ sigset_t sigmask; @@ -1026,6 +1043,8 @@ extern int drm_release(struct inode *inode, struct file *filp); /* Mapping support (drm_vm.h) */ extern int drm_mmap(struct file *filp, struct vm_area_struct *vma); +extern int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma); +extern void drm_vm_open_locked(struct vm_area_struct *vma); extern unsigned long drm_core_get_map_ofs(struct drm_map * map); extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev); extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait); @@ -1287,10 +1306,12 @@ extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size); /* Graphics Execution Manager library functions (drm_gem.c) */ int drm_gem_init(struct drm_device *dev); +void drm_gem_destroy(struct drm_device *dev); void drm_gem_object_free(struct kref *kref); struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, size_t size); void drm_gem_object_handle_free(struct kref *kref); +int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); static inline void drm_gem_object_reference(struct drm_gem_object *obj) -- cgit v1.2.3 From de151cf67ce52ed2d88083daa5e60c7858947329 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Wed, 12 Nov 2008 10:03:55 -0800 Subject: drm/i915: add GEM GTT mapping support Use the new core GEM object mapping code to allow GTT mapping of GEM objects on i915. The fault handler will make sure a fence register is allocated too, if the object in question is tiled. Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/i915_drm.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 152b34da927..3f663ecc3db 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -160,6 +160,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_SET_TILING 0x21 #define DRM_I915_GEM_GET_TILING 0x22 #define DRM_I915_GEM_GET_APERTURE 0x23 +#define DRM_I915_GEM_MMAP_GTT 0x24 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -187,6 +188,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread) #define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite) #define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap) +#define DRM_IOCTL_I915_GEM_MMAP_GTT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP_GTT, struct drm_i915_gem_mmap_gtt) #define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain) #define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish) #define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling) @@ -382,6 +384,18 @@ struct drm_i915_gem_mmap { uint64_t addr_ptr; }; +struct drm_i915_gem_mmap_gtt { + /** Handle for the object being mapped. */ + uint32_t handle; + uint32_t pad; + /** + * Fake offset to use for subsequent mmap call + * + * This is a fixed-size type for 32/64 compatibility. + */ + uint64_t offset; +}; + struct drm_i915_gem_set_domain { /** Handle for the object */ uint32_t handle; -- cgit v1.2.3 From f453ba0460742ad027ae0c4c7d61e62817b3e7ef Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 7 Nov 2008 14:05:41 -0800 Subject: DRM: add mode setting support Add mode setting support to the DRM layer. This is a fairly big chunk of work that allows DRM drivers to provide full output control and configuration capabilities to userspace. It was motivated by several factors: - the fb layer's APIs aren't suited for anything but simple configurations - coordination between the fb layer, DRM layer, and various userspace drivers is poor to non-existent (radeonfb excepted) - user level mode setting drivers makes displaying panic & oops messages more difficult - suspend/resume of graphics state is possible in many more configurations with kernel level support This commit just adds the core DRM part of the mode setting APIs. Driver specific commits using these new structure and APIs will follow. Co-authors: Jesse Barnes , Jakob Bornecrantz Contributors: Alan Hourihane , Maarten Maathuis Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/Kbuild | 2 +- include/drm/drm.h | 21 ++ include/drm/drmP.h | 18 ++ include/drm/drm_crtc.h | 737 ++++++++++++++++++++++++++++++++++++++++++ include/drm/drm_crtc_helper.h | 121 +++++++ include/drm/drm_edid.h | 202 ++++++++++++ include/drm/drm_mode.h | 278 ++++++++++++++++ include/linux/console.h | 4 + 8 files changed, 1382 insertions(+), 1 deletion(-) create mode 100644 include/drm/drm_crtc.h create mode 100644 include/drm/drm_crtc_helper.h create mode 100644 include/drm/drm_edid.h create mode 100644 include/drm/drm_mode.h (limited to 'include') diff --git a/include/drm/Kbuild b/include/drm/Kbuild index 82b6983b7fb..b940fdfa3b2 100644 --- a/include/drm/Kbuild +++ b/include/drm/Kbuild @@ -1,4 +1,4 @@ -unifdef-y += drm.h drm_sarea.h +unifdef-y += drm.h drm_sarea.h drm_mode.h unifdef-y += i810_drm.h unifdef-y += i830_drm.h unifdef-y += i915_drm.h diff --git a/include/drm/drm.h b/include/drm/drm.h index 3a66252456b..76ce6fe300b 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -599,6 +599,8 @@ struct drm_gem_open { uint64_t size; }; +#include "drm_mode.h" + #define DRM_IOCTL_BASE 'd' #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type) @@ -668,6 +670,25 @@ struct drm_gem_open { #define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw) +#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res) +#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc) +#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor) +#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut) +#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder) +#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector) +#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd) +#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd) + +#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property) +#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property) +#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob) +#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) +#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) +#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd) + /** * Device specific ioctls should only be in their respective headers * The device specific ioctl range is from 0x40 to 0x99. diff --git a/include/drm/drmP.h b/include/drm/drmP.h index ae42a6a5c24..7802c80f2b2 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -105,6 +105,7 @@ struct drm_device; #define DRIVER_FB_DMA 0x400 #define DRIVER_IRQ_VBL2 0x800 #define DRIVER_GEM 0x1000 +#define DRIVER_MODESET 0x2000 /***********************************************************************/ /** \name Begin the DRM... */ @@ -276,6 +277,7 @@ typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd, #define DRM_AUTH 0x1 #define DRM_MASTER 0x2 #define DRM_ROOT_ONLY 0x4 +#define DRM_CONTROL_ALLOW 0x8 struct drm_ioctl_desc { unsigned int cmd; @@ -398,6 +400,7 @@ struct drm_file { int is_master; /* this file private is a master for a minor */ struct drm_master *master; /* master this node is currently associated with N.B. not always minor->master */ + struct list_head fbs; }; /** Wait queue */ @@ -629,6 +632,8 @@ struct drm_gem_object { void *driver_private; }; +#include "drm_crtc.h" + /* per-master structure */ struct drm_master { @@ -792,6 +797,8 @@ struct drm_driver { #define DRM_MINOR_UNASSIGNED 0 #define DRM_MINOR_LEGACY 1 +#define DRM_MINOR_CONTROL 2 +#define DRM_MINOR_RENDER 3 /** * DRM minor structure. This structure represents a drm minor number. @@ -805,6 +812,7 @@ struct drm_minor { struct proc_dir_entry *dev_root; /**< proc directory entry */ struct drm_master *master; /* currently active master for this node */ struct list_head master_list; + struct drm_mode_group mode_group; }; /** @@ -855,6 +863,7 @@ struct drm_device { struct idr ctx_idr; struct list_head vmalist; /**< List of vmas (for debugging) */ + /*@} */ /** \name DMA queues (contexts) */ @@ -933,6 +942,7 @@ struct drm_device { struct drm_driver *driver; drm_local_map_t *agp_buffer_map; unsigned int agp_buffer_token; + struct drm_minor *control; /**< Control node for card */ struct drm_minor *primary; /**< render type primary screen head */ /** \name Drawable information */ @@ -941,6 +951,8 @@ struct drm_device { struct idr drw_idr; /*@} */ + struct drm_mode_config mode_config; /**< Current mode config */ + /** \name GEM information */ /*@{ */ spinlock_t object_name_lock; @@ -1201,6 +1213,8 @@ extern int drm_vblank_get(struct drm_device *dev, int crtc); extern void drm_vblank_put(struct drm_device *dev, int crtc); extern void drm_vblank_cleanup(struct drm_device *dev); /* Modesetting support */ +extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); +extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc); extern int drm_modeset_ctl(struct drm_device *dev, void *data, struct drm_file *file_priv); @@ -1286,7 +1300,11 @@ struct drm_sysfs_class; extern struct class *drm_sysfs_create(struct module *owner, char *name); extern void drm_sysfs_destroy(void); extern int drm_sysfs_device_add(struct drm_minor *minor); +extern void drm_sysfs_hotplug_event(struct drm_device *dev); extern void drm_sysfs_device_remove(struct drm_minor *minor); +extern char *drm_get_connector_status_name(enum drm_connector_status status); +extern int drm_sysfs_connector_add(struct drm_connector *connector); +extern void drm_sysfs_connector_remove(struct drm_connector *connector); /* * Basic memory manager support (drm_mm.c) diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h new file mode 100644 index 00000000000..08a884bea44 --- /dev/null +++ b/include/drm/drm_crtc.h @@ -0,0 +1,737 @@ +/* + * Copyright © 2006 Keith Packard + * Copyright © 2007-2008 Dave Airlie + * Copyright © 2007-2008 Intel Corporation + * Jesse Barnes + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __DRM_CRTC_H__ +#define __DRM_CRTC_H__ + +#include +#include +#include +#include + +#include + +struct drm_device; +struct drm_mode_set; +struct drm_framebuffer; + + +#define DRM_MODE_OBJECT_CRTC 0xcccccccc +#define DRM_MODE_OBJECT_CONNECTOR 0xc0c0c0c0 +#define DRM_MODE_OBJECT_ENCODER 0xe0e0e0e0 +#define DRM_MODE_OBJECT_MODE 0xdededede +#define DRM_MODE_OBJECT_PROPERTY 0xb0b0b0b0 +#define DRM_MODE_OBJECT_FB 0xfbfbfbfb +#define DRM_MODE_OBJECT_BLOB 0xbbbbbbbb + +struct drm_mode_object { + uint32_t id; + uint32_t type; +}; + +/* + * Note on terminology: here, for brevity and convenience, we refer to connector + * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS, + * DVI, etc. And 'screen' refers to the whole of the visible display, which + * may span multiple monitors (and therefore multiple CRTC and connector + * structures). + */ + +enum drm_mode_status { + MODE_OK = 0, /* Mode OK */ + MODE_HSYNC, /* hsync out of range */ + MODE_VSYNC, /* vsync out of range */ + MODE_H_ILLEGAL, /* mode has illegal horizontal timings */ + MODE_V_ILLEGAL, /* mode has illegal horizontal timings */ + MODE_BAD_WIDTH, /* requires an unsupported linepitch */ + MODE_NOMODE, /* no mode with a maching name */ + MODE_NO_INTERLACE, /* interlaced mode not supported */ + MODE_NO_DBLESCAN, /* doublescan mode not supported */ + MODE_NO_VSCAN, /* multiscan mode not supported */ + MODE_MEM, /* insufficient video memory */ + MODE_VIRTUAL_X, /* mode width too large for specified virtual size */ + MODE_VIRTUAL_Y, /* mode height too large for specified virtual size */ + MODE_MEM_VIRT, /* insufficient video memory given virtual size */ + MODE_NOCLOCK, /* no fixed clock available */ + MODE_CLOCK_HIGH, /* clock required is too high */ + MODE_CLOCK_LOW, /* clock required is too low */ + MODE_CLOCK_RANGE, /* clock/mode isn't in a ClockRange */ + MODE_BAD_HVALUE, /* horizontal timing was out of range */ + MODE_BAD_VVALUE, /* vertical timing was out of range */ + MODE_BAD_VSCAN, /* VScan value out of range */ + MODE_HSYNC_NARROW, /* horizontal sync too narrow */ + MODE_HSYNC_WIDE, /* horizontal sync too wide */ + MODE_HBLANK_NARROW, /* horizontal blanking too narrow */ + MODE_HBLANK_WIDE, /* horizontal blanking too wide */ + MODE_VSYNC_NARROW, /* vertical sync too narrow */ + MODE_VSYNC_WIDE, /* vertical sync too wide */ + MODE_VBLANK_NARROW, /* vertical blanking too narrow */ + MODE_VBLANK_WIDE, /* vertical blanking too wide */ + MODE_PANEL, /* exceeds panel dimensions */ + MODE_INTERLACE_WIDTH, /* width too large for interlaced mode */ + MODE_ONE_WIDTH, /* only one width is supported */ + MODE_ONE_HEIGHT, /* only one height is supported */ + MODE_ONE_SIZE, /* only one resolution is supported */ + MODE_NO_REDUCED, /* monitor doesn't accept reduced blanking */ + MODE_UNVERIFIED = -3, /* mode needs to reverified */ + MODE_BAD = -2, /* unspecified reason */ + MODE_ERROR = -1 /* error condition */ +}; + +#define DRM_MODE_TYPE_CLOCK_CRTC_C (DRM_MODE_TYPE_CLOCK_C | \ + DRM_MODE_TYPE_CRTC_C) + +#define DRM_MODE(nm, t, c, hd, hss, hse, ht, hsk, vd, vss, vse, vt, vs, f) \ + .name = nm, .status = 0, .type = (t), .clock = (c), \ + .hdisplay = (hd), .hsync_start = (hss), .hsync_end = (hse), \ + .htotal = (ht), .hskew = (hsk), .vdisplay = (vd), \ + .vsync_start = (vss), .vsync_end = (vse), .vtotal = (vt), \ + .vscan = (vs), .flags = (f), .vrefresh = 0 + +#define CRTC_INTERLACE_HALVE_V 0x1 /* halve V values for interlacing */ + +struct drm_display_mode { + /* Header */ + struct list_head head; + struct drm_mode_object base; + + char name[DRM_DISPLAY_MODE_LEN]; + + int connector_count; + enum drm_mode_status status; + int type; + + /* Proposed mode values */ + int clock; + int hdisplay; + int hsync_start; + int hsync_end; + int htotal; + int hskew; + int vdisplay; + int vsync_start; + int vsync_end; + int vtotal; + int vscan; + unsigned int flags; + + /* Addressable image size (may be 0 for projectors, etc.) */ + int width_mm; + int height_mm; + + /* Actual mode we give to hw */ + int clock_index; + int synth_clock; + int crtc_hdisplay; + int crtc_hblank_start; + int crtc_hblank_end; + int crtc_hsync_start; + int crtc_hsync_end; + int crtc_htotal; + int crtc_hskew; + int crtc_vdisplay; + int crtc_vblank_start; + int crtc_vblank_end; + int crtc_vsync_start; + int crtc_vsync_end; + int crtc_vtotal; + int crtc_hadjusted; + int crtc_vadjusted; + + /* Driver private mode info */ + int private_size; + int *private; + int private_flags; + + int vrefresh; + float hsync; +}; + +enum drm_connector_status { + connector_status_connected = 1, + connector_status_disconnected = 2, + connector_status_unknown = 3, +}; + +enum subpixel_order { + SubPixelUnknown = 0, + SubPixelHorizontalRGB, + SubPixelHorizontalBGR, + SubPixelVerticalRGB, + SubPixelVerticalBGR, + SubPixelNone, +}; + + +/* + * Describes a given display (e.g. CRT or flat panel) and its limitations. + */ +struct drm_display_info { + char name[DRM_DISPLAY_INFO_LEN]; + /* Input info */ + bool serration_vsync; + bool sync_on_green; + bool composite_sync; + bool separate_syncs; + bool blank_to_black; + unsigned char video_level; + bool digital; + /* Physical size */ + unsigned int width_mm; + unsigned int height_mm; + + /* Display parameters */ + unsigned char gamma; /* FIXME: storage format */ + bool gtf_supported; + bool standard_color; + enum { + monochrome = 0, + rgb, + other, + unknown, + } display_type; + bool active_off_supported; + bool suspend_supported; + bool standby_supported; + + /* Color info FIXME: storage format */ + unsigned short redx, redy; + unsigned short greenx, greeny; + unsigned short bluex, bluey; + unsigned short whitex, whitey; + + /* Clock limits FIXME: storage format */ + unsigned int min_vfreq, max_vfreq; + unsigned int min_hfreq, max_hfreq; + unsigned int pixel_clock; + + /* White point indices FIXME: storage format */ + unsigned int wpx1, wpy1; + unsigned int wpgamma1; + unsigned int wpx2, wpy2; + unsigned int wpgamma2; + + enum subpixel_order subpixel_order; + + char *raw_edid; /* if any */ +}; + +struct drm_framebuffer_funcs { + void (*destroy)(struct drm_framebuffer *framebuffer); + int (*create_handle)(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned int *handle); +}; + +struct drm_framebuffer { + struct drm_device *dev; + struct list_head head; + struct drm_mode_object base; + const struct drm_framebuffer_funcs *funcs; + unsigned int pitch; + unsigned int width; + unsigned int height; + /* depth can be 15 or 16 */ + unsigned int depth; + int bits_per_pixel; + int flags; + void *fbdev; + u32 pseudo_palette[17]; + struct list_head filp_head; +}; + +struct drm_property_blob { + struct drm_mode_object base; + struct list_head head; + unsigned int length; + void *data; +}; + +struct drm_property_enum { + uint64_t value; + struct list_head head; + char name[DRM_PROP_NAME_LEN]; +}; + +struct drm_property { + struct list_head head; + struct drm_mode_object base; + uint32_t flags; + char name[DRM_PROP_NAME_LEN]; + uint32_t num_values; + uint64_t *values; + + struct list_head enum_blob_list; +}; + +struct drm_crtc; +struct drm_connector; +struct drm_encoder; + +/** + * drm_crtc_funcs - control CRTCs for a given device + * @dpms: control display power levels + * @save: save CRTC state + * @resore: restore CRTC state + * @lock: lock the CRTC + * @unlock: unlock the CRTC + * @shadow_allocate: allocate shadow pixmap + * @shadow_create: create shadow pixmap for rotation support + * @shadow_destroy: free shadow pixmap + * @mode_fixup: fixup proposed mode + * @mode_set: set the desired mode on the CRTC + * @gamma_set: specify color ramp for CRTC + * @destroy: deinit and free object. + * + * The drm_crtc_funcs structure is the central CRTC management structure + * in the DRM. Each CRTC controls one or more connectors (note that the name + * CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc. + * connectors, not just CRTs). + * + * Each driver is responsible for filling out this structure at startup time, + * in addition to providing other modesetting features, like i2c and DDC + * bus accessors. + */ +struct drm_crtc_funcs { + /* Save CRTC state */ + void (*save)(struct drm_crtc *crtc); /* suspend? */ + /* Restore CRTC state */ + void (*restore)(struct drm_crtc *crtc); /* resume? */ + + /* cursor controls */ + int (*cursor_set)(struct drm_crtc *crtc, struct drm_file *file_priv, + uint32_t handle, uint32_t width, uint32_t height); + int (*cursor_move)(struct drm_crtc *crtc, int x, int y); + + /* Set gamma on the CRTC */ + void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, + uint32_t size); + /* Object destroy routine */ + void (*destroy)(struct drm_crtc *crtc); + + int (*set_config)(struct drm_mode_set *set); +}; + +/** + * drm_crtc - central CRTC control structure + * @enabled: is this CRTC enabled? + * @x: x position on screen + * @y: y position on screen + * @desired_mode: new desired mode + * @desired_x: desired x for desired_mode + * @desired_y: desired y for desired_mode + * @funcs: CRTC control functions + * + * Each CRTC may have one or more connectors associated with it. This structure + * allows the CRTC to be controlled. + */ +struct drm_crtc { + struct drm_device *dev; + struct list_head head; + + struct drm_mode_object base; + + /* framebuffer the connector is currently bound to */ + struct drm_framebuffer *fb; + + bool enabled; + + struct drm_display_mode mode; + + int x, y; + struct drm_display_mode *desired_mode; + int desired_x, desired_y; + const struct drm_crtc_funcs *funcs; + + /* CRTC gamma size for reporting to userspace */ + uint32_t gamma_size; + uint16_t *gamma_store; + + /* if you are using the helper */ + void *helper_private; +}; + + +/** + * drm_connector_funcs - control connectors on a given device + * @dpms: set power state (see drm_crtc_funcs above) + * @save: save connector state + * @restore: restore connector state + * @mode_valid: is this mode valid on the given connector? + * @mode_fixup: try to fixup proposed mode for this connector + * @mode_set: set this mode + * @detect: is this connector active? + * @get_modes: get mode list for this connector + * @set_property: property for this connector may need update + * @destroy: make object go away + * + * Each CRTC may have one or more connectors attached to it. The functions + * below allow the core DRM code to control connectors, enumerate available modes, + * etc. + */ +struct drm_connector_funcs { + void (*dpms)(struct drm_connector *connector, int mode); + void (*save)(struct drm_connector *connector); + void (*restore)(struct drm_connector *connector); + enum drm_connector_status (*detect)(struct drm_connector *connector); + void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height); + int (*set_property)(struct drm_connector *connector, struct drm_property *property, + uint64_t val); + void (*destroy)(struct drm_connector *connector); +}; + +struct drm_encoder_funcs { + void (*destroy)(struct drm_encoder *encoder); +}; + +#define DRM_CONNECTOR_MAX_UMODES 16 +#define DRM_CONNECTOR_MAX_PROPERTY 16 +#define DRM_CONNECTOR_LEN 32 +#define DRM_CONNECTOR_MAX_ENCODER 2 + +/** + * drm_encoder - central DRM encoder structure + */ +struct drm_encoder { + struct drm_device *dev; + struct list_head head; + + struct drm_mode_object base; + int encoder_type; + uint32_t possible_crtcs; + uint32_t possible_clones; + + struct drm_crtc *crtc; + const struct drm_encoder_funcs *funcs; + void *helper_private; +}; + +/** + * drm_connector - central DRM connector control structure + * @crtc: CRTC this connector is currently connected to, NULL if none + * @interlace_allowed: can this connector handle interlaced modes? + * @doublescan_allowed: can this connector handle doublescan? + * @available_modes: modes available on this connector (from get_modes() + user) + * @initial_x: initial x position for this connector + * @initial_y: initial y position for this connector + * @status: connector connected? + * @funcs: connector control functions + * + * Each connector may be connected to one or more CRTCs, or may be clonable by + * another connector if they can share a CRTC. Each connector also has a specific + * position in the broader display (referred to as a 'screen' though it could + * span multiple monitors). + */ +struct drm_connector { + struct drm_device *dev; + struct device kdev; + struct device_attribute *attr; + struct list_head head; + + struct drm_mode_object base; + + int connector_type; + int connector_type_id; + bool interlace_allowed; + bool doublescan_allowed; + struct list_head modes; /* list of modes on this connector */ + + int initial_x, initial_y; + enum drm_connector_status status; + + /* these are modes added by probing with DDC or the BIOS */ + struct list_head probed_modes; + + struct drm_display_info display_info; + const struct drm_connector_funcs *funcs; + + struct list_head user_modes; + struct drm_property_blob *edid_blob_ptr; + u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; + uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; + + void *helper_private; + + uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; + uint32_t force_encoder_id; + struct drm_encoder *encoder; /* currently active encoder */ +}; + +/** + * struct drm_mode_set + * + * Represents a single crtc the connectors that it drives with what mode + * and from which framebuffer it scans out from. + * + * This is used to set modes. + */ +struct drm_mode_set { + struct list_head head; + + struct drm_framebuffer *fb; + struct drm_crtc *crtc; + struct drm_display_mode *mode; + + uint32_t x; + uint32_t y; + + struct drm_connector **connectors; + size_t num_connectors; +}; + +/** + * struct drm_mode_config_funcs - configure CRTCs for a given screen layout + * @resize: adjust CRTCs as necessary for the proposed layout + * + * Currently only a resize hook is available. DRM will call back into the + * driver with a new screen width and height. If the driver can't support + * the proposed size, it can return false. Otherwise it should adjust + * the CRTC<->connector mappings as needed and update its view of the screen. + */ +struct drm_mode_config_funcs { + int (*resize_fb)(struct drm_device *dev, struct drm_file *file_priv, struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd); + struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); + int (*fb_changed)(struct drm_device *dev); +}; + +struct drm_mode_group { + uint32_t num_crtcs; + uint32_t num_encoders; + uint32_t num_connectors; + + /* list of object IDs for this group */ + uint32_t *id_list; +}; + +/** + * drm_mode_config - Mode configuration control structure + * + */ +struct drm_mode_config { + struct mutex mutex; /* protects configuration and IDR */ + struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ + /* this is limited to one for now */ + int num_fb; + struct list_head fb_list; + int num_connector; + struct list_head connector_list; + int num_encoder; + struct list_head encoder_list; + + int num_crtc; + struct list_head crtc_list; + + struct list_head property_list; + + /* in-kernel framebuffers - hung of filp_head in drm_framebuffer */ + struct list_head fb_kernel_list; + + int min_width, min_height; + int max_width, max_height; + struct drm_mode_config_funcs *funcs; + unsigned long fb_base; + + /* pointers to standard properties */ + struct list_head property_blob_list; + struct drm_property *edid_property; + struct drm_property *dpms_property; + + /* DVI-I properties */ + struct drm_property *dvi_i_subconnector_property; + struct drm_property *dvi_i_select_subconnector_property; + + /* TV properties */ + struct drm_property *tv_subconnector_property; + struct drm_property *tv_select_subconnector_property; + struct drm_property *tv_mode_property; + struct drm_property *tv_left_margin_property; + struct drm_property *tv_right_margin_property; + struct drm_property *tv_top_margin_property; + struct drm_property *tv_bottom_margin_property; + + /* Optional properties */ + struct drm_property *scaling_mode_property; + struct drm_property *dithering_mode_property; + + /* hotplug */ + uint32_t hotplug_counter; +}; + +#define obj_to_crtc(x) container_of(x, struct drm_crtc, base) +#define obj_to_connector(x) container_of(x, struct drm_connector, base) +#define obj_to_encoder(x) container_of(x, struct drm_encoder, base) +#define obj_to_mode(x) container_of(x, struct drm_display_mode, base) +#define obj_to_fb(x) container_of(x, struct drm_framebuffer, base) +#define obj_to_property(x) container_of(x, struct drm_property, base) +#define obj_to_blob(x) container_of(x, struct drm_property_blob, base) + + +extern void drm_crtc_init(struct drm_device *dev, + struct drm_crtc *crtc, + const struct drm_crtc_funcs *funcs); +extern void drm_crtc_cleanup(struct drm_crtc *crtc); + +extern void drm_connector_init(struct drm_device *dev, + struct drm_connector *connector, + const struct drm_connector_funcs *funcs, + int connector_type); + +extern void drm_connector_cleanup(struct drm_connector *connector); + +extern void drm_encoder_init(struct drm_device *dev, + struct drm_encoder *encoder, + const struct drm_encoder_funcs *funcs, + int encoder_type); + +extern void drm_encoder_cleanup(struct drm_encoder *encoder); + +extern char *drm_get_connector_name(struct drm_connector *connector); +extern char *drm_get_dpms_name(int val); +extern char *drm_get_dvi_i_subconnector_name(int val); +extern char *drm_get_dvi_i_select_name(int val); +extern char *drm_get_tv_subconnector_name(int val); +extern char *drm_get_tv_select_name(int val); +extern void drm_fb_release(struct file *filp); +extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group); +extern struct edid *drm_get_edid(struct drm_connector *connector, + struct i2c_adapter *adapter); +extern unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter); +extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid); +extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); +extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode); +extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev, + struct drm_display_mode *mode); +extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode); +extern void drm_mode_config_init(struct drm_device *dev); +extern void drm_mode_config_cleanup(struct drm_device *dev); +extern void drm_mode_set_name(struct drm_display_mode *mode); +extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2); +extern int drm_mode_width(struct drm_display_mode *mode); +extern int drm_mode_height(struct drm_display_mode *mode); + +/* for us by fb module */ +extern int drm_mode_attachmode_crtc(struct drm_device *dev, + struct drm_crtc *crtc, + struct drm_display_mode *mode); +extern int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode); + +extern struct drm_display_mode *drm_mode_create(struct drm_device *dev); +extern void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); +extern void drm_mode_list_concat(struct list_head *head, + struct list_head *new); +extern void drm_mode_validate_size(struct drm_device *dev, + struct list_head *mode_list, + int maxX, int maxY, int maxPitch); +extern void drm_mode_prune_invalid(struct drm_device *dev, + struct list_head *mode_list, bool verbose); +extern void drm_mode_sort(struct list_head *mode_list); +extern int drm_mode_vrefresh(struct drm_display_mode *mode); +extern void drm_mode_set_crtcinfo(struct drm_display_mode *p, + int adjust_flags); +extern void drm_mode_connector_list_update(struct drm_connector *connector); +extern int drm_mode_connector_update_edid_property(struct drm_connector *connector, + struct edid *edid); +extern int drm_connector_property_set_value(struct drm_connector *connector, + struct drm_property *property, + uint64_t value); +extern int drm_connector_property_get_value(struct drm_connector *connector, + struct drm_property *property, + uint64_t *value); +extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev); +extern void drm_framebuffer_set_object(struct drm_device *dev, + unsigned long handle); +extern int drm_framebuffer_init(struct drm_device *dev, + struct drm_framebuffer *fb, + const struct drm_framebuffer_funcs *funcs); +extern void drm_framebuffer_cleanup(struct drm_framebuffer *fb); +extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc); +extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb); +extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY); +extern bool drm_crtc_in_use(struct drm_crtc *crtc); + +extern int drm_connector_attach_property(struct drm_connector *connector, + struct drm_property *property, uint64_t init_val); +extern struct drm_property *drm_property_create(struct drm_device *dev, int flags, + const char *name, int num_values); +extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property); +extern int drm_property_add_enum(struct drm_property *property, int index, + uint64_t value, const char *name); +extern int drm_mode_create_dvi_i_properties(struct drm_device *dev); +extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats, + char *formats[]); +extern int drm_mode_create_scaling_mode_property(struct drm_device *dev); +extern int drm_mode_create_dithering_property(struct drm_device *dev); +extern char *drm_get_encoder_name(struct drm_encoder *encoder); + +extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, + struct drm_encoder *encoder); +extern void drm_mode_connector_detach_encoder(struct drm_connector *connector, + struct drm_encoder *encoder); +extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, + int gamma_size); +extern void *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); +/* IOCTLs */ +extern int drm_mode_getresources(struct drm_device *dev, + void *data, struct drm_file *file_priv); + +extern int drm_mode_getcrtc(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_getconnector(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_setcrtc(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_cursor_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_addfb(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_rmfb(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_getfb(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_addmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_rmmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_attachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_detachmode_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); + +extern int drm_mode_getproperty_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_getblob_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_connector_property_set_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_hotplug_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_replacefb(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_getencoder(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_gamma_get_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +extern int drm_mode_gamma_set_ioctl(struct drm_device *dev, + void *data, struct drm_file *file_priv); +#endif /* __DRM_CRTC_H__ */ diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h new file mode 100644 index 00000000000..a341828d1d1 --- /dev/null +++ b/include/drm/drm_crtc_helper.h @@ -0,0 +1,121 @@ +/* + * Copyright © 2006 Keith Packard + * Copyright © 2007-2008 Dave Airlie + * Copyright © 2007-2008 Intel Corporation + * Jesse Barnes + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The DRM mode setting helper functions are common code for drivers to use if + * they wish. Drivers are not forced to use this code in their + * implementations but it would be useful if they code they do use at least + * provides a consistent interface and operation to userspace + */ + +#ifndef __DRM_CRTC_HELPER_H__ +#define __DRM_CRTC_HELPER_H__ + +#include +#include +#include +#include + +#include + +struct drm_crtc_helper_funcs { + /* + * Control power levels on the CRTC. If the mode passed in is + * unsupported, the provider must use the next lowest power level. + */ + void (*dpms)(struct drm_crtc *crtc, int mode); + void (*prepare)(struct drm_crtc *crtc); + void (*commit)(struct drm_crtc *crtc); + + /* Provider can fixup or change mode timings before modeset occurs */ + bool (*mode_fixup)(struct drm_crtc *crtc, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /* Actually set the mode */ + void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode, int x, int y); + + /* Move the crtc on the current fb to the given position *optional* */ + void (*mode_set_base)(struct drm_crtc *crtc, int x, int y); +}; + +struct drm_encoder_helper_funcs { + void (*dpms)(struct drm_encoder *encoder, int mode); + void (*save)(struct drm_encoder *encoder); + void (*restore)(struct drm_encoder *encoder); + + bool (*mode_fixup)(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + void (*prepare)(struct drm_encoder *encoder); + void (*commit)(struct drm_encoder *encoder); + void (*mode_set)(struct drm_encoder *encoder, + struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + /* detect for DAC style encoders */ + enum drm_connector_status (*detect)(struct drm_encoder *encoder, + struct drm_connector *connector); +}; + +struct drm_connector_helper_funcs { + int (*get_modes)(struct drm_connector *connector); + int (*mode_valid)(struct drm_connector *connector, + struct drm_display_mode *mode); + struct drm_encoder *(*best_encoder)(struct drm_connector *connector); +}; + +extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); +extern void drm_helper_disable_unused_functions(struct drm_device *dev); +extern int drm_helper_hotplug_stage_two(struct drm_device *dev); +extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); +extern int drm_crtc_helper_set_config(struct drm_mode_set *set); +extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, + struct drm_display_mode *mode, + int x, int y); +extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); + +extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, + struct drm_mode_fb_cmd *mode_cmd); + +static inline void drm_crtc_helper_add(struct drm_crtc *crtc, + const struct drm_crtc_helper_funcs *funcs) +{ + crtc->helper_private = (void *)funcs; +} + +static inline void drm_encoder_helper_add(struct drm_encoder *encoder, + const struct drm_encoder_helper_funcs *funcs) +{ + encoder->helper_private = (void *)funcs; +} + +static inline void drm_connector_helper_add(struct drm_connector *connector, + const struct drm_connector_helper_funcs *funcs) +{ + connector->helper_private = (void *)funcs; +} + +extern int drm_helper_resume_force_mode(struct drm_device *dev); +#endif diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h new file mode 100644 index 00000000000..c707c15f516 --- /dev/null +++ b/include/drm/drm_edid.h @@ -0,0 +1,202 @@ +/* + * Copyright © 2007-2008 Intel Corporation + * Jesse Barnes + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef __DRM_EDID_H__ +#define __DRM_EDID_H__ + +#include + +#define EDID_LENGTH 128 +#define DDC_ADDR 0x50 + +#ifdef BIG_ENDIAN +#error "EDID structure is little endian, need big endian versions" +#else + +struct est_timings { + u8 t1; + u8 t2; + u8 mfg_rsvd; +} __attribute__((packed)); + +struct std_timing { + u8 hsize; /* need to multiply by 8 then add 248 */ + u8 vfreq:6; /* need to add 60 */ + u8 aspect_ratio:2; /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ +} __attribute__((packed)); + +/* If detailed data is pixel timing */ +struct detailed_pixel_timing { + u8 hactive_lo; + u8 hblank_lo; + u8 hblank_hi:4; + u8 hactive_hi:4; + u8 vactive_lo; + u8 vblank_lo; + u8 vblank_hi:4; + u8 vactive_hi:4; + u8 hsync_offset_lo; + u8 hsync_pulse_width_lo; + u8 vsync_pulse_width_lo:4; + u8 vsync_offset_lo:4; + u8 hsync_pulse_width_hi:2; + u8 hsync_offset_hi:2; + u8 vsync_pulse_width_hi:2; + u8 vsync_offset_hi:2; + u8 width_mm_lo; + u8 height_mm_lo; + u8 height_mm_hi:4; + u8 width_mm_hi:4; + u8 hborder; + u8 vborder; + u8 unknown0:1; + u8 vsync_positive:1; + u8 hsync_positive:1; + u8 separate_sync:2; + u8 stereo:1; + u8 unknown6:1; + u8 interlaced:1; +} __attribute__((packed)); + +/* If it's not pixel timing, it'll be one of the below */ +struct detailed_data_string { + u8 str[13]; +} __attribute__((packed)); + +struct detailed_data_monitor_range { + u8 min_vfreq; + u8 max_vfreq; + u8 min_hfreq_khz; + u8 max_hfreq_khz; + u8 pixel_clock_mhz; /* need to multiply by 10 */ + u16 sec_gtf_toggle; /* A000=use above, 20=use below */ /* FIXME: byte order */ + u8 hfreq_start_khz; /* need to multiply by 2 */ + u8 c; /* need to divide by 2 */ + u16 m; /* FIXME: byte order */ + u8 k; + u8 j; /* need to divide by 2 */ +} __attribute__((packed)); + +struct detailed_data_wpindex { + u8 white_y_lo:2; + u8 white_x_lo:2; + u8 pad:4; + u8 white_x_hi; + u8 white_y_hi; + u8 gamma; /* need to divide by 100 then add 1 */ +} __attribute__((packed)); + +struct detailed_data_color_point { + u8 windex1; + u8 wpindex1[3]; + u8 windex2; + u8 wpindex2[3]; +} __attribute__((packed)); + +struct detailed_non_pixel { + u8 pad1; + u8 type; /* ff=serial, fe=string, fd=monitor range, fc=monitor name + fb=color point data, fa=standard timing data, + f9=undefined, f8=mfg. reserved */ + u8 pad2; + union { + struct detailed_data_string str; + struct detailed_data_monitor_range range; + struct detailed_data_wpindex color; + struct std_timing timings[5]; + } data; +} __attribute__((packed)); + +#define EDID_DETAIL_STD_MODES 0xfa +#define EDID_DETAIL_MONITOR_CPDATA 0xfb +#define EDID_DETAIL_MONITOR_NAME 0xfc +#define EDID_DETAIL_MONITOR_RANGE 0xfd +#define EDID_DETAIL_MONITOR_STRING 0xfe +#define EDID_DETAIL_MONITOR_SERIAL 0xff + +struct detailed_timing { + u16 pixel_clock; /* need to multiply by 10 KHz */ /* FIXME: byte order */ + union { + struct detailed_pixel_timing pixel_data; + struct detailed_non_pixel other_data; + } data; +} __attribute__((packed)); + +struct edid { + u8 header[8]; + /* Vendor & product info */ + u8 mfg_id[2]; + u8 prod_code[2]; + u32 serial; /* FIXME: byte order */ + u8 mfg_week; + u8 mfg_year; + /* EDID version */ + u8 version; + u8 revision; + /* Display info: */ + /* input definition */ + u8 serration_vsync:1; + u8 sync_on_green:1; + u8 composite_sync:1; + u8 separate_syncs:1; + u8 blank_to_black:1; + u8 video_level:2; + u8 digital:1; /* bits below must be zero if set */ + u8 width_cm; + u8 height_cm; + u8 gamma; + /* feature support */ + u8 default_gtf:1; + u8 preferred_timing:1; + u8 standard_color:1; + u8 display_type:2; /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ + u8 pm_active_off:1; + u8 pm_suspend:1; + u8 pm_standby:1; + /* Color characteristics */ + u8 red_green_lo; + u8 black_white_lo; + u8 red_x; + u8 red_y; + u8 green_x; + u8 green_y; + u8 blue_x; + u8 blue_y; + u8 white_x; + u8 white_y; + /* Est. timings and mfg rsvd timings*/ + struct est_timings established_timings; + /* Standard timings 1-8*/ + struct std_timing standard_timings[8]; + /* Detailing timings 1-4 */ + struct detailed_timing detailed_timings[4]; + /* Number of 128 byte ext. blocks */ + u8 extensions; + /* Checksum */ + u8 checksum; +} __attribute__((packed)); + +#endif /* little endian structs */ + +#define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) + +#endif /* __DRM_EDID_H__ */ diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h new file mode 100644 index 00000000000..d2e791920ab --- /dev/null +++ b/include/drm/drm_mode.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2007 Dave Airlie + * Copyright (c) 2007 Jakob Bornecrantz + * Copyright (c) 2008 Red Hat Inc. + * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA + * Copyright (c) 2007-2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _DRM_MODE_H +#define _DRM_MODE_H + +#if !defined(__KERNEL__) && !defined(_KERNEL) +#include +#else +#include +#endif + +#define DRM_DISPLAY_INFO_LEN 32 +#define DRM_CONNECTOR_NAME_LEN 32 +#define DRM_DISPLAY_MODE_LEN 32 +#define DRM_PROP_NAME_LEN 32 + +#define DRM_MODE_TYPE_BUILTIN (1<<0) +#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) +#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN) +#define DRM_MODE_TYPE_PREFERRED (1<<3) +#define DRM_MODE_TYPE_DEFAULT (1<<4) +#define DRM_MODE_TYPE_USERDEF (1<<5) +#define DRM_MODE_TYPE_DRIVER (1<<6) + +/* Video mode flags */ +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_FLAG_PHSYNC (1<<0) +#define DRM_MODE_FLAG_NHSYNC (1<<1) +#define DRM_MODE_FLAG_PVSYNC (1<<2) +#define DRM_MODE_FLAG_NVSYNC (1<<3) +#define DRM_MODE_FLAG_INTERLACE (1<<4) +#define DRM_MODE_FLAG_DBLSCAN (1<<5) +#define DRM_MODE_FLAG_CSYNC (1<<6) +#define DRM_MODE_FLAG_PCSYNC (1<<7) +#define DRM_MODE_FLAG_NCSYNC (1<<8) +#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */ +#define DRM_MODE_FLAG_BCAST (1<<10) +#define DRM_MODE_FLAG_PIXMUX (1<<11) +#define DRM_MODE_FLAG_DBLCLK (1<<12) +#define DRM_MODE_FLAG_CLKDIV2 (1<<13) + +/* DPMS flags */ +/* bit compatible with the xorg definitions. */ +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 + +/* Scaling mode options */ +#define DRM_MODE_SCALE_NON_GPU 0 +#define DRM_MODE_SCALE_FULLSCREEN 1 +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_SCALE_ASPECT 3 + +/* Dithering mode options */ +#define DRM_MODE_DITHERING_OFF 0 +#define DRM_MODE_DITHERING_ON 1 + +struct drm_mode_modeinfo { + unsigned int clock; + unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; + unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; + + unsigned int vrefresh; /* vertical refresh * 1000 */ + + unsigned int flags; + unsigned int type; + char name[DRM_DISPLAY_MODE_LEN]; +}; + +struct drm_mode_card_res { + uint64_t fb_id_ptr; + uint64_t crtc_id_ptr; + uint64_t connector_id_ptr; + uint64_t encoder_id_ptr; + int count_fbs; + int count_crtcs; + int count_connectors; + int count_encoders; + int min_width, max_width; + int min_height, max_height; +}; + +struct drm_mode_crtc { + uint64_t set_connectors_ptr; + int count_connectors; + + unsigned int crtc_id; /**< Id */ + unsigned int fb_id; /**< Id of framebuffer */ + + int x, y; /**< Position on the frameuffer */ + + uint32_t gamma_size; + int mode_valid; + struct drm_mode_modeinfo mode; +}; + +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 + +struct drm_mode_get_encoder { + unsigned int encoder_id; + unsigned int encoder_type; + + unsigned int crtc_id; /**< Id of crtc */ + + uint32_t possible_crtcs; + uint32_t possible_clones; +}; + +/* This is for connectors with multiple signal types. */ +/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ +#define DRM_MODE_SUBCONNECTOR_Automatic 0 +#define DRM_MODE_SUBCONNECTOR_Unknown 0 +#define DRM_MODE_SUBCONNECTOR_DVID 3 +#define DRM_MODE_SUBCONNECTOR_DVIA 4 +#define DRM_MODE_SUBCONNECTOR_Composite 5 +#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 +#define DRM_MODE_SUBCONNECTOR_Component 8 + +#define DRM_MODE_CONNECTOR_Unknown 0 +#define DRM_MODE_CONNECTOR_VGA 1 +#define DRM_MODE_CONNECTOR_DVII 2 +#define DRM_MODE_CONNECTOR_DVID 3 +#define DRM_MODE_CONNECTOR_DVIA 4 +#define DRM_MODE_CONNECTOR_Composite 5 +#define DRM_MODE_CONNECTOR_SVIDEO 6 +#define DRM_MODE_CONNECTOR_LVDS 7 +#define DRM_MODE_CONNECTOR_Component 8 +#define DRM_MODE_CONNECTOR_9PinDIN 9 +#define DRM_MODE_CONNECTOR_DisplayPort 10 +#define DRM_MODE_CONNECTOR_HDMIA 11 +#define DRM_MODE_CONNECTOR_HDMIB 12 + +struct drm_mode_get_connector { + + uint64_t encoders_ptr; + uint64_t modes_ptr; + uint64_t props_ptr; + uint64_t prop_values_ptr; + + int count_modes; + int count_props; + int count_encoders; + + unsigned int encoder_id; /**< Current Encoder */ + unsigned int connector_id; /**< Id */ + unsigned int connector_type; + unsigned int connector_type_id; + + unsigned int connection; + unsigned int mm_width, mm_height; /**< HxW in millimeters */ + unsigned int subpixel; +}; + +#define DRM_MODE_PROP_PENDING (1<<0) +#define DRM_MODE_PROP_RANGE (1<<1) +#define DRM_MODE_PROP_IMMUTABLE (1<<2) +#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ +#define DRM_MODE_PROP_BLOB (1<<4) + +struct drm_mode_property_enum { + uint64_t value; + unsigned char name[DRM_PROP_NAME_LEN]; +}; + +struct drm_mode_get_property { + uint64_t values_ptr; /* values and blob lengths */ + uint64_t enum_blob_ptr; /* enum and blob id ptrs */ + + unsigned int prop_id; + unsigned int flags; + unsigned char name[DRM_PROP_NAME_LEN]; + + int count_values; + int count_enum_blobs; +}; + +struct drm_mode_connector_set_property { + uint64_t value; + unsigned int prop_id; + unsigned int connector_id; +}; + +struct drm_mode_get_blob { + uint32_t blob_id; + uint32_t length; + uint64_t data; +}; + +struct drm_mode_fb_cmd { + unsigned int buffer_id; + unsigned int width, height; + unsigned int pitch; + unsigned int bpp; + unsigned int depth; + + unsigned int handle; +}; + +struct drm_mode_mode_cmd { + unsigned int connector_id; + struct drm_mode_modeinfo mode; +}; + +#define DRM_MODE_CURSOR_BO 0x01 +#define DRM_MODE_CURSOR_MOVE 0x02 + +/* + * depending on the value in flags diffrent members are used. + * + * CURSOR_BO uses + * crtc + * width + * height + * handle - if 0 turns the cursor of + * + * CURSOR_MOVE uses + * crtc + * x + * y + */ +struct drm_mode_cursor { + unsigned int flags; + unsigned int crtc; + int x; + int y; + uint32_t width; + uint32_t height; + unsigned int handle; +}; + +/* + * oh so ugly hotplug + */ +struct drm_mode_hotplug { + uint32_t counter; +}; + +struct drm_mode_crtc_lut { + + uint32_t crtc_id; + uint32_t gamma_size; + + /* pointers to arrays */ + uint64_t red; + uint64_t green; + uint64_t blue; +}; + +#endif diff --git a/include/linux/console.h b/include/linux/console.h index 248e6e3b9b7..a67a90cf826 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -153,4 +153,8 @@ void vcs_remove_sysfs(struct tty_struct *tty); #define VESA_HSYNC_SUSPEND 2 #define VESA_POWERDOWN 3 +#ifdef CONFIG_VGA_CONSOLE +extern bool vgacon_text_force(void); +#endif + #endif /* _LINUX_CONSOLE_H */ -- cgit v1.2.3 From 79e539453b34e35f39299a899d263b0a1f1670bd Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 7 Nov 2008 14:24:08 -0800 Subject: DRM: i915: add mode setting support This commit adds i915 driver support for the DRM mode setting APIs. Currently, VGA, LVDS, SDVO DVI & VGA, TV and DVO LVDS outputs are supported. HDMI, DisplayPort and additional SDVO output support will follow. Support for the mode setting code is controlled by the new 'modeset' module option. A new config option, CONFIG_DRM_I915_KMS controls the default behavior, and whether a PCI ID list is built into the module for use by user level module utilities. Note that if mode setting is enabled, user level drivers that access display registers directly or that don't use the kernel graphics memory manager will likely corrupt kernel graphics memory, disrupt output configuration (possibly leading to hangs and/or blank displays), and prevent panic/oops messages from appearing. So use caution when enabling this code; be sure your user level code supports the new interfaces. A new SysRq key, 'g', provides emergency support for switching back to the kernel's framebuffer console; which is useful for testing. Co-authors: Dave Airlie , Hong Liu Signed-off-by: Jesse Barnes Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/i915_drm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 3f663ecc3db..0e506f438f4 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -198,7 +198,7 @@ typedef struct _drm_i915_sarea { /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. */ -typedef struct _drm_i915_batchbuffer { +typedef struct drm_i915_batchbuffer { int start; /* agp offset */ int used; /* nr bytes in use */ int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */ -- cgit v1.2.3 From e0c8463a8b00b467611607df0ff369d062528875 Mon Sep 17 00:00:00 2001 From: Jakob Bornecrantz Date: Fri, 19 Dec 2008 14:50:50 +1000 Subject: drm: sanitise drm modesetting API + remove unused hotplug The initially merged modesetting API has some uglies in it, this cleans up the struct members and ioctl ordering for initial submission. It also removes the unneeded hotplug infrastructure. airlied:- I've pulled this patch in from git modesetting-gem tree. Signed-off-by: Dave Airlie --- include/drm/drm_crtc.h | 3 - include/drm/drm_mode.h | 205 ++++++++++++++++++++++++------------------------- 2 files changed, 99 insertions(+), 109 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 08a884bea44..395c6139c89 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -573,9 +573,6 @@ struct drm_mode_config { /* Optional properties */ struct drm_property *scaling_mode_property; struct drm_property *dithering_mode_property; - - /* hotplug */ - uint32_t hotplug_counter; }; #define obj_to_crtc(x) container_of(x, struct drm_crtc, base) diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h index d2e791920ab..601d2bd839f 100644 --- a/include/drm/drm_mode.h +++ b/include/drm/drm_mode.h @@ -33,10 +33,10 @@ #include #endif -#define DRM_DISPLAY_INFO_LEN 32 -#define DRM_CONNECTOR_NAME_LEN 32 -#define DRM_DISPLAY_MODE_LEN 32 -#define DRM_PROP_NAME_LEN 32 +#define DRM_DISPLAY_INFO_LEN 32 +#define DRM_CONNECTOR_NAME_LEN 32 +#define DRM_DISPLAY_MODE_LEN 32 +#define DRM_PROP_NAME_LEN 32 #define DRM_MODE_TYPE_BUILTIN (1<<0) #define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN) @@ -65,30 +65,30 @@ /* DPMS flags */ /* bit compatible with the xorg definitions. */ -#define DRM_MODE_DPMS_ON 0 -#define DRM_MODE_DPMS_STANDBY 1 -#define DRM_MODE_DPMS_SUSPEND 2 -#define DRM_MODE_DPMS_OFF 3 +#define DRM_MODE_DPMS_ON 0 +#define DRM_MODE_DPMS_STANDBY 1 +#define DRM_MODE_DPMS_SUSPEND 2 +#define DRM_MODE_DPMS_OFF 3 /* Scaling mode options */ -#define DRM_MODE_SCALE_NON_GPU 0 -#define DRM_MODE_SCALE_FULLSCREEN 1 -#define DRM_MODE_SCALE_NO_SCALE 2 -#define DRM_MODE_SCALE_ASPECT 3 +#define DRM_MODE_SCALE_NON_GPU 0 +#define DRM_MODE_SCALE_FULLSCREEN 1 +#define DRM_MODE_SCALE_NO_SCALE 2 +#define DRM_MODE_SCALE_ASPECT 3 /* Dithering mode options */ -#define DRM_MODE_DITHERING_OFF 0 -#define DRM_MODE_DITHERING_ON 1 +#define DRM_MODE_DITHERING_OFF 0 +#define DRM_MODE_DITHERING_ON 1 struct drm_mode_modeinfo { - unsigned int clock; - unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew; - unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan; + uint32_t clock; + uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew; + uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan; - unsigned int vrefresh; /* vertical refresh * 1000 */ + uint32_t vrefresh; /* vertical refresh * 1000 */ - unsigned int flags; - unsigned int type; + uint32_t flags; + uint32_t type; char name[DRM_DISPLAY_MODE_LEN]; }; @@ -97,39 +97,39 @@ struct drm_mode_card_res { uint64_t crtc_id_ptr; uint64_t connector_id_ptr; uint64_t encoder_id_ptr; - int count_fbs; - int count_crtcs; - int count_connectors; - int count_encoders; - int min_width, max_width; - int min_height, max_height; + uint32_t count_fbs; + uint32_t count_crtcs; + uint32_t count_connectors; + uint32_t count_encoders; + uint32_t min_width, max_width; + uint32_t min_height, max_height; }; struct drm_mode_crtc { uint64_t set_connectors_ptr; - int count_connectors; + uint32_t count_connectors; - unsigned int crtc_id; /**< Id */ - unsigned int fb_id; /**< Id of framebuffer */ + uint32_t crtc_id; /**< Id */ + uint32_t fb_id; /**< Id of framebuffer */ - int x, y; /**< Position on the frameuffer */ + uint32_t x, y; /**< Position on the frameuffer */ uint32_t gamma_size; - int mode_valid; + uint32_t mode_valid; struct drm_mode_modeinfo mode; }; -#define DRM_MODE_ENCODER_NONE 0 -#define DRM_MODE_ENCODER_DAC 1 -#define DRM_MODE_ENCODER_TMDS 2 -#define DRM_MODE_ENCODER_LVDS 3 -#define DRM_MODE_ENCODER_TVDAC 4 +#define DRM_MODE_ENCODER_NONE 0 +#define DRM_MODE_ENCODER_DAC 1 +#define DRM_MODE_ENCODER_TMDS 2 +#define DRM_MODE_ENCODER_LVDS 3 +#define DRM_MODE_ENCODER_TVDAC 4 struct drm_mode_get_encoder { - unsigned int encoder_id; - unsigned int encoder_type; + uint32_t encoder_id; + uint32_t encoder_type; - unsigned int crtc_id; /**< Id of crtc */ + uint32_t crtc_id; /**< Id of crtc */ uint32_t possible_crtcs; uint32_t possible_clones; @@ -137,27 +137,27 @@ struct drm_mode_get_encoder { /* This is for connectors with multiple signal types. */ /* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */ -#define DRM_MODE_SUBCONNECTOR_Automatic 0 -#define DRM_MODE_SUBCONNECTOR_Unknown 0 -#define DRM_MODE_SUBCONNECTOR_DVID 3 -#define DRM_MODE_SUBCONNECTOR_DVIA 4 -#define DRM_MODE_SUBCONNECTOR_Composite 5 -#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 -#define DRM_MODE_SUBCONNECTOR_Component 8 - -#define DRM_MODE_CONNECTOR_Unknown 0 -#define DRM_MODE_CONNECTOR_VGA 1 -#define DRM_MODE_CONNECTOR_DVII 2 -#define DRM_MODE_CONNECTOR_DVID 3 -#define DRM_MODE_CONNECTOR_DVIA 4 -#define DRM_MODE_CONNECTOR_Composite 5 -#define DRM_MODE_CONNECTOR_SVIDEO 6 -#define DRM_MODE_CONNECTOR_LVDS 7 -#define DRM_MODE_CONNECTOR_Component 8 -#define DRM_MODE_CONNECTOR_9PinDIN 9 -#define DRM_MODE_CONNECTOR_DisplayPort 10 -#define DRM_MODE_CONNECTOR_HDMIA 11 -#define DRM_MODE_CONNECTOR_HDMIB 12 +#define DRM_MODE_SUBCONNECTOR_Automatic 0 +#define DRM_MODE_SUBCONNECTOR_Unknown 0 +#define DRM_MODE_SUBCONNECTOR_DVID 3 +#define DRM_MODE_SUBCONNECTOR_DVIA 4 +#define DRM_MODE_SUBCONNECTOR_Composite 5 +#define DRM_MODE_SUBCONNECTOR_SVIDEO 6 +#define DRM_MODE_SUBCONNECTOR_Component 8 + +#define DRM_MODE_CONNECTOR_Unknown 0 +#define DRM_MODE_CONNECTOR_VGA 1 +#define DRM_MODE_CONNECTOR_DVII 2 +#define DRM_MODE_CONNECTOR_DVID 3 +#define DRM_MODE_CONNECTOR_DVIA 4 +#define DRM_MODE_CONNECTOR_Composite 5 +#define DRM_MODE_CONNECTOR_SVIDEO 6 +#define DRM_MODE_CONNECTOR_LVDS 7 +#define DRM_MODE_CONNECTOR_Component 8 +#define DRM_MODE_CONNECTOR_9PinDIN 9 +#define DRM_MODE_CONNECTOR_DisplayPort 10 +#define DRM_MODE_CONNECTOR_HDMIA 11 +#define DRM_MODE_CONNECTOR_HDMIB 12 struct drm_mode_get_connector { @@ -166,47 +166,47 @@ struct drm_mode_get_connector { uint64_t props_ptr; uint64_t prop_values_ptr; - int count_modes; - int count_props; - int count_encoders; + uint32_t count_modes; + uint32_t count_props; + uint32_t count_encoders; - unsigned int encoder_id; /**< Current Encoder */ - unsigned int connector_id; /**< Id */ - unsigned int connector_type; - unsigned int connector_type_id; + uint32_t encoder_id; /**< Current Encoder */ + uint32_t connector_id; /**< Id */ + uint32_t connector_type; + uint32_t connector_type_id; - unsigned int connection; - unsigned int mm_width, mm_height; /**< HxW in millimeters */ - unsigned int subpixel; + uint32_t connection; + uint32_t mm_width, mm_height; /**< HxW in millimeters */ + uint32_t subpixel; }; -#define DRM_MODE_PROP_PENDING (1<<0) -#define DRM_MODE_PROP_RANGE (1<<1) -#define DRM_MODE_PROP_IMMUTABLE (1<<2) -#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ -#define DRM_MODE_PROP_BLOB (1<<4) +#define DRM_MODE_PROP_PENDING (1<<0) +#define DRM_MODE_PROP_RANGE (1<<1) +#define DRM_MODE_PROP_IMMUTABLE (1<<2) +#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */ +#define DRM_MODE_PROP_BLOB (1<<4) struct drm_mode_property_enum { uint64_t value; - unsigned char name[DRM_PROP_NAME_LEN]; + char name[DRM_PROP_NAME_LEN]; }; struct drm_mode_get_property { uint64_t values_ptr; /* values and blob lengths */ uint64_t enum_blob_ptr; /* enum and blob id ptrs */ - unsigned int prop_id; - unsigned int flags; - unsigned char name[DRM_PROP_NAME_LEN]; + uint32_t prop_id; + uint32_t flags; + char name[DRM_PROP_NAME_LEN]; - int count_values; - int count_enum_blobs; + uint32_t count_values; + uint32_t count_enum_blobs; }; struct drm_mode_connector_set_property { uint64_t value; - unsigned int prop_id; - unsigned int connector_id; + uint32_t prop_id; + uint32_t connector_id; }; struct drm_mode_get_blob { @@ -216,22 +216,22 @@ struct drm_mode_get_blob { }; struct drm_mode_fb_cmd { - unsigned int buffer_id; - unsigned int width, height; - unsigned int pitch; - unsigned int bpp; - unsigned int depth; - - unsigned int handle; + uint32_t fb_id; + uint32_t width, height; + uint32_t pitch; + uint32_t bpp; + uint32_t depth; + /* driver specific handle */ + uint32_t handle; }; struct drm_mode_mode_cmd { - unsigned int connector_id; + uint32_t connector_id; struct drm_mode_modeinfo mode; }; -#define DRM_MODE_CURSOR_BO 0x01 -#define DRM_MODE_CURSOR_MOVE 0x02 +#define DRM_MODE_CURSOR_BO (1<<0) +#define DRM_MODE_CURSOR_MOVE (1<<1) /* * depending on the value in flags diffrent members are used. @@ -248,24 +248,17 @@ struct drm_mode_mode_cmd { * y */ struct drm_mode_cursor { - unsigned int flags; - unsigned int crtc; - int x; - int y; + uint32_t flags; + uint32_t crtc_id; + int32_t x; + int32_t y; uint32_t width; uint32_t height; - unsigned int handle; -}; - -/* - * oh so ugly hotplug - */ -struct drm_mode_hotplug { - uint32_t counter; + /* driver specific handle */ + uint32_t handle; }; struct drm_mode_crtc_lut { - uint32_t crtc_id; uint32_t gamma_size; -- cgit v1.2.3 From 0c7c26647579e9e647e8b969bb0e7b3f5f1a1492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=EF=BF=BDgsberg?= Date: Thu, 18 Dec 2008 13:14:37 +1000 Subject: drm: drop DRM_IOCTL_MODE_REPLACEFB, add+remove works just as well. The replace fb ioctl replaces the backing buffer object for a modesetting framebuffer object. This can be acheived by just creating a new framebuffer backed by the new buffer object, setting that for the crtcs in question and then removing the old framebuffer object. Signed-off-by: Kristian Hogsberg Acked-by: Jakob Bornecrantz Signed-off-by: Dave Airlie --- include/drm/drm.h | 1 - include/drm/drm_crtc.h | 1 - 2 files changed, 2 deletions(-) (limited to 'include') diff --git a/include/drm/drm.h b/include/drm/drm.h index 76ce6fe300b..32e5096554e 100644 --- a/include/drm/drm.h +++ b/include/drm/drm.h @@ -687,7 +687,6 @@ struct drm_gem_open { #define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd) #define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, unsigned int) -#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd) /** * Device specific ioctls should only be in their respective headers diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 395c6139c89..0acb07f31fa 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -510,7 +510,6 @@ struct drm_mode_set { * the CRTC<->connector mappings as needed and update its view of the screen. */ struct drm_mode_config_funcs { - int (*resize_fb)(struct drm_device *dev, struct drm_file *file_priv, struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd); struct drm_framebuffer *(*fb_create)(struct drm_device *dev, struct drm_file *file_priv, struct drm_mode_fb_cmd *mode_cmd); int (*fb_changed)(struct drm_device *dev); }; -- cgit v1.2.3 From dfef24592257805af0bee42dced099459c68a307 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 19 Dec 2008 15:07:46 +1000 Subject: i915/drm: provide compat defines for userspace for certain struct members. Painfully userspace started using new names that were never actually to be used from the external repo. Also fill out the gaps in the structure for old/new userspace compat Add compat defines for these structs. Signed-off-by: Dave Airlie --- include/drm/i915_drm.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include') diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 0e506f438f4..5e7d81d1df5 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -113,8 +113,31 @@ typedef struct _drm_i915_sarea { int pipeB_y; int pipeB_w; int pipeB_h; + + /* fill out some space for old userspace triple buffer */ + drm_handle_t unused_handle; + uint32_t unused1, unused2, unused3; + + /* buffer object handles for static buffers. May change + * over the lifetime of the client. + */ + uint32_t front_bo_handle; + uint32_t back_bo_handle; + uint32_t unused_bo_handle; + uint32_t depth_bo_handle; + } drm_i915_sarea_t; +/* due to userspace building against these headers we need some compat here */ +#define planeA_x pipeA_x +#define planeA_y pipeA_y +#define planeA_w pipeA_w +#define planeA_h pipeA_h +#define planeB_x pipeB_x +#define planeB_y pipeB_y +#define planeB_w pipeB_w +#define planeB_h pipeB_h + /* Flags for perf_boxes */ #define I915_BOX_RING_EMPTY 0x1 -- cgit v1.2.3 From 8d391aa410ecb230fc4c3147b94eec25b9f3c20f Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 17 Dec 2008 22:32:14 -0800 Subject: drm/i915: Add missing userland definitions for gem init/execbuffer. fdo bug #19132. Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/i915_drm.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 5e7d81d1df5..b3bcf72dc65 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -201,6 +201,8 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) -- cgit v1.2.3 From 3c4fdcfb2941dc36b6a16bc509a2adb97c131716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 17 Dec 2008 22:14:46 -0500 Subject: drm: pin new and unpin old buffer when setting a mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This removes the requirement for user space to pin a buffer before setting a mode that is backed by the pixels from that buffer. Signed-off-by: Kristian Høgsberg Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drm_crtc_helper.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index a341828d1d1..4bc04cf460a 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -55,10 +55,12 @@ struct drm_crtc_helper_funcs { struct drm_display_mode *adjusted_mode); /* Actually set the mode */ void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode, int x, int y); + struct drm_display_mode *adjusted_mode, int x, int y, + struct drm_framebuffer *old_fb); /* Move the crtc on the current fb to the given position *optional* */ - void (*mode_set_base)(struct drm_crtc *crtc, int x, int y); + void (*mode_set_base)(struct drm_crtc *crtc, int x, int y, + struct drm_framebuffer *old_fb); }; struct drm_encoder_helper_funcs { @@ -93,7 +95,8 @@ extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, - int x, int y); + int x, int y, + struct drm_framebuffer *old_fb); extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, -- cgit v1.2.3 From fede5c91c4a8a7701d205b2b84b9835ddc7d6f02 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Fri, 19 Dec 2008 17:23:38 -0800 Subject: drm: Add a debug node for vblank state. Signed-off-by: Eric Anholt Signed-off-by: Dave Airlie --- include/drm/drmP.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7802c80f2b2..afb7858c068 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -911,6 +911,7 @@ struct drm_device { int *vblank_enabled; /* so we don't call enable more than once per disable */ int *vblank_inmodeset; /* Display driver is setting mode */ + u32 *last_vblank_wait; /* Last vblank seqno waited per CRTC */ struct timer_list vblank_disable_timer; u32 max_vblank_count; /**< size of vblank counter register */ -- cgit v1.2.3 From 773ff60e841461cb1f9374a713ffcda029b8c317 Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Tue, 23 Dec 2008 19:37:01 +0900 Subject: SLUB: failslab support Currently fault-injection capability for SLAB allocator is only available to SLAB. This patch makes it available to SLUB, too. [penberg@cs.helsinki.fi: unify slab and slub implementations] Cc: Christoph Lameter Cc: Matt Mackall Signed-off-by: Akinobu Mita Signed-off-by: Pekka Enberg --- include/linux/fault-inject.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include') diff --git a/include/linux/fault-inject.h b/include/linux/fault-inject.h index 32368c4f032..06ca9b21dad 100644 --- a/include/linux/fault-inject.h +++ b/include/linux/fault-inject.h @@ -81,4 +81,13 @@ static inline void cleanup_fault_attr_dentries(struct fault_attr *attr) #endif /* CONFIG_FAULT_INJECTION */ +#ifdef CONFIG_FAILSLAB +extern bool should_failslab(size_t size, gfp_t gfpflags); +#else +static inline bool should_failslab(size_t size, gfp_t gfpflags) +{ + return false; +} +#endif /* CONFIG_FAILSLAB */ + #endif /* _LINUX_FAULT_INJECT_H */ -- cgit v1.2.3 From dfcd3610289132a762b7dc0eaf33998262cd9e20 Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Tue, 25 Nov 2008 15:08:19 +0100 Subject: slab: Fix comment on #endif This #endif in slab.h is described as closing the inner block while it's for the big CONFIG_NUMA one. That makes reading the code a bit harder. This trivial patch fixes the comment. Signed-off-by: Pascal Terjan Signed-off-by: Pekka Enberg --- include/linux/slab.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/slab.h b/include/linux/slab.h index 000da12b5cf..9d8ca14be3c 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -285,7 +285,7 @@ extern void *__kmalloc_node_track_caller(size_t, gfp_t, int, void *); #define kmalloc_node_track_caller(size, flags, node) \ kmalloc_track_caller(size, flags) -#endif /* DEBUG_SLAB */ +#endif /* CONFIG_NUMA */ /* * Shortcuts -- cgit v1.2.3 From d61c72e52b98411d1cfef1fdb3f5a8bb070f8966 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 10 Dec 2008 14:07:21 +0100 Subject: DMI: add dmi_match Add a wrapper for testing system_info which will handle also NULL system infos. This will be used by the ata PIIX driver. Signed-off-by: Jiri Slaby Cc: Alexandru Romanescu Cc: Tejun Heo Cc: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/dmi.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 2bfda178f27..34161907b2f 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -47,6 +47,7 @@ extern int dmi_name_in_vendors(const char *str); extern int dmi_name_in_serial(const char *str); extern int dmi_available; extern int dmi_walk(void (*decode)(const struct dmi_header *)); +extern bool dmi_match(enum dmi_field f, const char *str); #else @@ -61,6 +62,8 @@ static inline int dmi_name_in_serial(const char *s) { return 0; } #define dmi_available 0 static inline int dmi_walk(void (*decode)(const struct dmi_header *)) { return -1; } +static inline bool dmi_match(enum dmi_field f, const char *str) + { return false; } #endif -- cgit v1.2.3 From b29f841378460c37e99a2398d0015d9bd7901a09 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 30 Nov 2008 10:39:01 -0600 Subject: [SCSI] remove timeout from struct scsi_device by removing the unused timeout parameter we ensure a compile failure if anyone is accidentally still using it rather than the block timeout. Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index a37a8148a31..2a1c1419994 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -159,8 +159,6 @@ struct scsi_device { atomic_t iodone_cnt; atomic_t ioerr_cnt; - int timeout; - struct device sdev_gendev, sdev_dev; -- cgit v1.2.3 From 63c62f1cb980241513c82cacd5b9f878527c6647 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:04 -0600 Subject: [SCSI] iscsi_tcp: prepare helpers for LLDs that can offload some operations cxgb3i is unlike qla4xxx and bnx2i in that it does not offload entire scsi commands or iscsi sequences. Instead it only offloads the transfer of a ISCSI DATA_IN pdu's data, the digests and padding. This patch fixes up the iscsi tcp recv path so that it exports its skb recv processing so cxgb3i and other drivers can call them. All they have to do is pass the function the skb with the hdr or data pdu header and this function will do the rest. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/iscsi_if.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 0c9514de5df..8e008c96e79 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -333,8 +333,9 @@ enum iscsi_host_param { #define CAP_TEXT_NEGO 0x80 #define CAP_MARKERS 0x100 #define CAP_FW_DB 0x200 -#define CAP_SENDTARGETS_OFFLOAD 0x400 -#define CAP_DATA_PATH_OFFLOAD 0x800 +#define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ +#define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */ +#define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ /* * These flags describes reason of stop_conn() call -- cgit v1.2.3 From 577577da6d197ea3dcf3ee19c4f902fbd3a9390a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:05 -0600 Subject: [SCSI] libiscsi: prepare libiscsi for new offload engines by modifying unsol data code cxgb3i offloads data transfers. It does not offload the entire scsi/iscsi procssing like qla4xxx and it does not offload the iscsi sequence processing like how bnx2i does. cxgb3i relies on iscsi_tcp for the seqeunce handling so this changes how we transfer unsolicitied data by adding a common r2t struct and helpers. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi.h | 34 +++++++++++++++++++++++++++------- include/scsi/scsi_transport_iscsi.h | 9 +++++++-- 2 files changed, 34 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 61e53f14f7e..51500573c0b 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -93,24 +93,38 @@ enum { ISCSI_TASK_RUNNING, }; +struct iscsi_r2t_info { + __be32 ttt; /* copied from R2T */ + __be32 exp_statsn; /* copied from R2T */ + uint32_t data_length; /* copied from R2T */ + uint32_t data_offset; /* copied from R2T */ + int data_count; /* DATA-Out payload progress */ + int datasn; + /* LLDs should set/update these values */ + int sent; /* R2T sequence progress */ +}; + struct iscsi_task { /* * Because LLDs allocate their hdr differently, this is a pointer * and length to that storage. It must be setup at session * creation time. */ - struct iscsi_cmd *hdr; + struct iscsi_hdr *hdr; unsigned short hdr_max; unsigned short hdr_len; /* accumulated size of hdr used */ + /* copied values in case we need to send tmfs */ + itt_t hdr_itt; + __be32 cmdsn; + uint8_t lun[8]; + int itt; /* this ITT */ - uint32_t unsol_datasn; unsigned imm_count; /* imm-data (bytes) */ - unsigned unsol_count; /* unsolicited (bytes)*/ /* offset in unsolicited stream (bytes); */ - unsigned unsol_offset; - unsigned data_count; /* remaining Data-Out */ + struct iscsi_r2t_info unsol_r2t; char *data; /* mgmt payload */ + unsigned data_count; struct scsi_cmnd *sc; /* associated SCSI cmd*/ struct iscsi_conn *conn; /* used connection */ @@ -121,6 +135,11 @@ struct iscsi_task { void *dd_data; /* driver/transport data */ }; +static inline int iscsi_task_has_unsol_data(struct iscsi_task *task) +{ + return task->unsol_r2t.data_length > task->unsol_r2t.sent; +} + static inline void* iscsi_next_hdr(struct iscsi_task *task) { return (void*)task->hdr + task->hdr_len; @@ -376,8 +395,9 @@ extern void iscsi_suspend_tx(struct iscsi_conn *conn); * pdu and task processing */ extern void iscsi_update_cmdsn(struct iscsi_session *, struct iscsi_nopin *); -extern void iscsi_prep_unsolicit_data_pdu(struct iscsi_task *, - struct iscsi_data *hdr); +extern void iscsi_prep_data_out_pdu(struct iscsi_task *task, + struct iscsi_r2t_info *r2t, + struct iscsi_data *hdr); extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index c667cc39654..c928234c018 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -113,10 +113,15 @@ struct iscsi_transport { char *data, uint32_t data_size); void (*get_stats) (struct iscsi_cls_conn *conn, struct iscsi_stats *stats); + int (*init_task) (struct iscsi_task *task); int (*xmit_task) (struct iscsi_task *task); - void (*cleanup_task) (struct iscsi_conn *conn, - struct iscsi_task *task); + void (*cleanup_task) (struct iscsi_task *task); + + int (*alloc_pdu) (struct iscsi_task *task); + int (*xmit_pdu) (struct iscsi_task *task); + int (*init_pdu) (struct iscsi_task *task, unsigned int offset, + unsigned int count); void (*session_recovery_timedout) (struct iscsi_cls_session *session); struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, int non_blocking); -- cgit v1.2.3 From a081c13e39b5c17052a7b46fafa61019c4c110ff Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:11 -0600 Subject: [SCSI] iscsi_tcp: split module into lib and lld As explained in the previous mails, cxgb3i needs iscsi_tcp's r2t/data_out and data_in procesing so this just moves functions that both drivers want to use to a new module libiscsi_tcp. The next patch will hook iscsi_tcp in. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi_tcp.h | 131 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 include/scsi/libiscsi_tcp.h (limited to 'include') diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h new file mode 100644 index 00000000000..e6bf8ef276b --- /dev/null +++ b/include/scsi/libiscsi_tcp.h @@ -0,0 +1,131 @@ +/* + * iSCSI over TCP/IP Data-Path lib + * + * Copyright (C) 2008 Mike Christie + * Copyright (C) 2008 Red Hat, Inc. All rights reserved. + * maintained by open-iscsi@googlegroups.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * See the file COPYING included with this distribution for more details. + */ + +#ifndef LIBISCSI_TCP_H +#define LIBISCSI_TCP_H + +#include + +struct iscsi_tcp_conn; +struct iscsi_segment; +struct sk_buff; +struct hash_desc; + +typedef int iscsi_segment_done_fn_t(struct iscsi_tcp_conn *, + struct iscsi_segment *); + +struct iscsi_segment { + unsigned char *data; + unsigned int size; + unsigned int copied; + unsigned int total_size; + unsigned int total_copied; + + struct hash_desc *hash; + unsigned char recv_digest[ISCSI_DIGEST_SIZE]; + unsigned char digest[ISCSI_DIGEST_SIZE]; + unsigned int digest_len; + + struct scatterlist *sg; + void *sg_mapped; + unsigned int sg_offset; + + iscsi_segment_done_fn_t *done; +}; + +/* Socket connection recieve helper */ +struct iscsi_tcp_recv { + struct iscsi_hdr *hdr; + struct iscsi_segment segment; + + /* Allocate buffer for BHS + AHS */ + uint32_t hdr_buf[64]; + + /* copied and flipped values */ + int datalen; +}; + +struct iscsi_tcp_conn { + struct iscsi_conn *iscsi_conn; + void *dd_data; + int stop_stage; /* conn_stop() flag: * + * stop to recover, * + * stop to terminate */ + /* control data */ + struct iscsi_tcp_recv in; /* TCP receive context */ + /* CRC32C (Rx) LLD should set this is they do not offload */ + struct hash_desc *rx_hash; +}; + +struct iscsi_tcp_task { + uint32_t exp_datasn; /* expected target's R2TSN/DataSN */ + int data_offset; + struct iscsi_r2t_info *r2t; /* in progress solict R2T */ + struct iscsi_pool r2tpool; + struct kfifo *r2tqueue; + void *dd_data; +}; + +enum { + ISCSI_TCP_SEGMENT_DONE, /* curr seg has been processed */ + ISCSI_TCP_SKB_DONE, /* skb is out of data */ + ISCSI_TCP_CONN_ERR, /* iscsi layer has fired a conn err */ + ISCSI_TCP_SUSPENDED, /* conn is suspended */ +}; + +extern void iscsi_tcp_hdr_recv_prep(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_recv_skb(struct iscsi_conn *conn, struct sk_buff *skb, + unsigned int offset, bool offloaded, int *status); +extern void iscsi_tcp_cleanup_task(struct iscsi_task *task); +extern int iscsi_tcp_task_init(struct iscsi_task *task); +extern int iscsi_tcp_task_xmit(struct iscsi_task *task); + +/* segment helpers */ +extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); +extern int iscsi_tcp_segment_done(struct iscsi_segment *segment, int recv, + unsigned copied); +extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); + +extern void iscsi_segment_init_linear(struct iscsi_segment *segment, + void *data, size_t size, + iscsi_segment_done_fn_t *done, + struct hash_desc *hash); +extern int +iscsi_segment_seek_sg(struct iscsi_segment *segment, + struct scatterlist *sg_list, unsigned int sg_count, + unsigned int offset, size_t size, + iscsi_segment_done_fn_t *done, struct hash_desc *hash); + +/* digest helpers */ +extern void iscsi_tcp_dgst_header(struct hash_desc *hash, const void *hdr, + size_t hdrlen, + unsigned char digest[ISCSI_DIGEST_SIZE]); +extern struct iscsi_cls_conn * +iscsi_tcp_conn_setup(struct iscsi_cls_session *cls_session, int dd_data_size, + uint32_t conn_idx); +extern void iscsi_tcp_conn_teardown(struct iscsi_cls_conn *cls_conn); + +/* misc helpers */ +extern int iscsi_tcp_r2tpool_alloc(struct iscsi_session *session); +extern void iscsi_tcp_r2tpool_free(struct iscsi_session *session); + +extern void iscsi_tcp_conn_get_stats(struct iscsi_cls_conn *cls_conn, + struct iscsi_stats *stats); +#endif /* LIBISCSI_TCP_H */ -- cgit v1.2.3 From 262ef63627977acb7d8dd38c4f0f290bf49fbbfd Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:13 -0600 Subject: [SCSI] libiscsi: allow drivers to modify the itt sent to the target bnx2i and cxgb3i need to encode LLD info in the itt so that the firmware/hardware can process the pdu. This patch allows the LLDs to encode info in the task->hdr->itt that they setup in the alloc_pdu callout (any resources that are allocated can be freed with the pdu in the cleanup_task callout). If the LLD encodes info in the itt they should implement a parse_pdu_itt callout. If parse_pdu_itt is not implemented libiscsi will do the right thing for the LLD. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi.h | 5 +++-- include/scsi/scsi_transport_iscsi.h | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 51500573c0b..7360e1916e7 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -30,6 +30,7 @@ #include #include #include +#include struct scsi_transport_template; struct scsi_host_template; @@ -70,12 +71,12 @@ enum { /* Connection suspend "bit" */ #define ISCSI_SUSPEND_BIT 1 -#define ISCSI_ITT_MASK (0x1fff) +#define ISCSI_ITT_MASK 0x1fff #define ISCSI_TOTAL_CMDS_MAX 4096 /* this must be a power of two greater than ISCSI_MGMT_CMDS_MAX */ #define ISCSI_TOTAL_CMDS_MIN 16 #define ISCSI_AGE_SHIFT 28 -#define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) +#define ISCSI_AGE_MASK 0xf #define ISCSI_ADDRESS_BUF_LEN 64 diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index c928234c018..e13cb20f1ea 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -122,6 +122,9 @@ struct iscsi_transport { int (*xmit_pdu) (struct iscsi_task *task); int (*init_pdu) (struct iscsi_task *task, unsigned int offset, unsigned int count); + void (*parse_pdu_itt) (struct iscsi_conn *conn, itt_t itt, + int *index, int *age); + void (*session_recovery_timedout) (struct iscsi_cls_session *session); struct iscsi_endpoint *(*ep_connect) (struct sockaddr *dst_addr, int non_blocking); -- cgit v1.2.3 From 2ff79d52d56eebcffd83e9327b89d7daedf1e897 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:14 -0600 Subject: [SCSI] libiscsi: pass opcode into alloc_pdu callout We do not need to allocate a itt for data_out, so this passes the opcode to the alloc_pdu callout. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/scsi_transport_iscsi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index e13cb20f1ea..b50aabe2861 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -118,7 +118,7 @@ struct iscsi_transport { int (*xmit_task) (struct iscsi_task *task); void (*cleanup_task) (struct iscsi_task *task); - int (*alloc_pdu) (struct iscsi_task *task); + int (*alloc_pdu) (struct iscsi_task *task, uint8_t opcode); int (*xmit_pdu) (struct iscsi_task *task); int (*init_pdu) (struct iscsi_task *task, unsigned int offset, unsigned int count); -- cgit v1.2.3 From 6df19a791bdd5d820cccd8c7a12679888ae62099 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 2 Dec 2008 00:32:16 -0600 Subject: [SCSI] libiscsi_tcp: support padding offload cxgb3i does not offload the processing of the header, but it will always process the padding. This patch adds a padding offload flag to detect when the LLD supports this. The patch also modifies the header processing so that we do not try to read/bypass the header dugest in the skb. cxgb3i will not include it with the header like with other offload cards. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/iscsi_if.h | 2 ++ include/scsi/libiscsi_tcp.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 8e008c96e79..d0ed5226f8c 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -336,6 +336,8 @@ enum iscsi_host_param { #define CAP_SENDTARGETS_OFFLOAD 0x400 /* offload discovery process */ #define CAP_DATA_PATH_OFFLOAD 0x800 /* offload entire IO path */ #define CAP_DIGEST_OFFLOAD 0x1000 /* offload hdr and data digests */ +#define CAP_PADDING_OFFLOAD 0x2000 /* offload padding insertion, removal, + and verification */ /* * These flags describes reason of stop_conn() call diff --git a/include/scsi/libiscsi_tcp.h b/include/scsi/libiscsi_tcp.h index e6bf8ef276b..83e32f6d785 100644 --- a/include/scsi/libiscsi_tcp.h +++ b/include/scsi/libiscsi_tcp.h @@ -99,7 +99,8 @@ extern int iscsi_tcp_task_xmit(struct iscsi_task *task); /* segment helpers */ extern int iscsi_tcp_recv_segment_is_hdr(struct iscsi_tcp_conn *tcp_conn); -extern int iscsi_tcp_segment_done(struct iscsi_segment *segment, int recv, +extern int iscsi_tcp_segment_done(struct iscsi_tcp_conn *tcp_conn, + struct iscsi_segment *segment, int recv, unsigned copied); extern void iscsi_tcp_segment_unmap(struct iscsi_segment *segment); -- cgit v1.2.3 From f4f4e47e4af6b02dd1c425b931c65d0165356e33 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 4 Dec 2008 14:24:39 +0900 Subject: [SCSI] add residual argument to scsi_execute and scsi_execute_req scsi_execute() and scsi_execute_req() discard the residual length information. Some callers need it. This adds residual argument (optional) to scsi_execute and scsi_execute_req. Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- include/scsi/scsi_device.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 2a1c1419994..01a4c58f8ba 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -365,10 +365,11 @@ extern int scsi_is_target_device(const struct device *); extern int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, unsigned char *sense, int timeout, int retries, - int flag); + int flag, int *resid); extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd, int data_direction, void *buffer, unsigned bufflen, - struct scsi_sense_hdr *, int timeout, int retries); + struct scsi_sense_hdr *, int timeout, int retries, + int *resid); extern int scsi_execute_async(struct scsi_device *sdev, const unsigned char *cmd, int cmd_len, int data_direction, void *buffer, unsigned bufflen, int use_sg, -- cgit v1.2.3 From f032c2f7cdaae0e8907cd3b26426fc651dc5c275 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 9 Dec 2008 15:10:11 -0800 Subject: [SCSI] FC protocol definition header files Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/fc/fc_els.h | 816 ++++++++++++++++++++++++++++++++++++++++++++ include/scsi/fc/fc_encaps.h | 138 ++++++++ include/scsi/fc/fc_fc2.h | 124 +++++++ include/scsi/fc/fc_fcoe.h | 114 +++++++ include/scsi/fc/fc_fcp.h | 199 +++++++++++ include/scsi/fc/fc_fs.h | 340 ++++++++++++++++++ include/scsi/fc/fc_gs.h | 93 +++++ include/scsi/fc/fc_ns.h | 159 +++++++++ 8 files changed, 1983 insertions(+) create mode 100644 include/scsi/fc/fc_els.h create mode 100644 include/scsi/fc/fc_encaps.h create mode 100644 include/scsi/fc/fc_fc2.h create mode 100644 include/scsi/fc/fc_fcoe.h create mode 100644 include/scsi/fc/fc_fcp.h create mode 100644 include/scsi/fc/fc_fs.h create mode 100644 include/scsi/fc/fc_gs.h create mode 100644 include/scsi/fc/fc_ns.h (limited to 'include') diff --git a/include/scsi/fc/fc_els.h b/include/scsi/fc/fc_els.h new file mode 100644 index 00000000000..195ca014d3c --- /dev/null +++ b/include/scsi/fc/fc_els.h @@ -0,0 +1,816 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_ELS_H_ +#define _FC_ELS_H_ + +/* + * Fibre Channel Switch - Enhanced Link Services definitions. + * From T11 FC-LS Rev 1.2 June 7, 2005. + */ + +/* + * ELS Command codes - byte 0 of the frame payload + */ +enum fc_els_cmd { + ELS_LS_RJT = 0x01, /* ESL reject */ + ELS_LS_ACC = 0x02, /* ESL Accept */ + ELS_PLOGI = 0x03, /* N_Port login */ + ELS_FLOGI = 0x04, /* F_Port login */ + ELS_LOGO = 0x05, /* Logout */ + ELS_ABTX = 0x06, /* Abort exchange - obsolete */ + ELS_RCS = 0x07, /* read connection status */ + ELS_RES = 0x08, /* read exchange status block */ + ELS_RSS = 0x09, /* read sequence status block */ + ELS_RSI = 0x0a, /* read sequence initiative */ + ELS_ESTS = 0x0b, /* establish streaming */ + ELS_ESTC = 0x0c, /* estimate credit */ + ELS_ADVC = 0x0d, /* advise credit */ + ELS_RTV = 0x0e, /* read timeout value */ + ELS_RLS = 0x0f, /* read link error status block */ + ELS_ECHO = 0x10, /* echo */ + ELS_TEST = 0x11, /* test */ + ELS_RRQ = 0x12, /* reinstate recovery qualifier */ + ELS_REC = 0x13, /* read exchange concise */ + ELS_SRR = 0x14, /* sequence retransmission request */ + ELS_PRLI = 0x20, /* process login */ + ELS_PRLO = 0x21, /* process logout */ + ELS_SCN = 0x22, /* state change notification */ + ELS_TPLS = 0x23, /* test process login state */ + ELS_TPRLO = 0x24, /* third party process logout */ + ELS_LCLM = 0x25, /* login control list mgmt (obs) */ + ELS_GAID = 0x30, /* get alias_ID */ + ELS_FACT = 0x31, /* fabric activate alias_id */ + ELS_FDACDT = 0x32, /* fabric deactivate alias_id */ + ELS_NACT = 0x33, /* N-port activate alias_id */ + ELS_NDACT = 0x34, /* N-port deactivate alias_id */ + ELS_QOSR = 0x40, /* quality of service request */ + ELS_RVCS = 0x41, /* read virtual circuit status */ + ELS_PDISC = 0x50, /* discover N_port service params */ + ELS_FDISC = 0x51, /* discover F_port service params */ + ELS_ADISC = 0x52, /* discover address */ + ELS_RNC = 0x53, /* report node cap (obs) */ + ELS_FARP_REQ = 0x54, /* FC ARP request */ + ELS_FARP_REPL = 0x55, /* FC ARP reply */ + ELS_RPS = 0x56, /* read port status block */ + ELS_RPL = 0x57, /* read port list */ + ELS_RPBC = 0x58, /* read port buffer condition */ + ELS_FAN = 0x60, /* fabric address notification */ + ELS_RSCN = 0x61, /* registered state change notification */ + ELS_SCR = 0x62, /* state change registration */ + ELS_RNFT = 0x63, /* report node FC-4 types */ + ELS_CSR = 0x68, /* clock synch. request */ + ELS_CSU = 0x69, /* clock synch. update */ + ELS_LINIT = 0x70, /* loop initialize */ + ELS_LSTS = 0x72, /* loop status */ + ELS_RNID = 0x78, /* request node ID data */ + ELS_RLIR = 0x79, /* registered link incident report */ + ELS_LIRR = 0x7a, /* link incident record registration */ + ELS_SRL = 0x7b, /* scan remote loop */ + ELS_SBRP = 0x7c, /* set bit-error reporting params */ + ELS_RPSC = 0x7d, /* report speed capabilities */ + ELS_QSA = 0x7e, /* query security attributes */ + ELS_EVFP = 0x7f, /* exchange virt. fabrics params */ + ELS_LKA = 0x80, /* link keep-alive */ + ELS_AUTH_ELS = 0x90, /* authentication ELS */ +}; + +/* + * Initializer useful for decoding table. + * Please keep this in sync with the above definitions. + */ +#define FC_ELS_CMDS_INIT { \ + [ELS_LS_RJT] = "LS_RJT", \ + [ELS_LS_ACC] = "LS_ACC", \ + [ELS_PLOGI] = "PLOGI", \ + [ELS_FLOGI] = "FLOGI", \ + [ELS_LOGO] = "LOGO", \ + [ELS_ABTX] = "ABTX", \ + [ELS_RCS] = "RCS", \ + [ELS_RES] = "RES", \ + [ELS_RSS] = "RSS", \ + [ELS_RSI] = "RSI", \ + [ELS_ESTS] = "ESTS", \ + [ELS_ESTC] = "ESTC", \ + [ELS_ADVC] = "ADVC", \ + [ELS_RTV] = "RTV", \ + [ELS_RLS] = "RLS", \ + [ELS_ECHO] = "ECHO", \ + [ELS_TEST] = "TEST", \ + [ELS_RRQ] = "RRQ", \ + [ELS_REC] = "REC", \ + [ELS_SRR] = "SRR", \ + [ELS_PRLI] = "PRLI", \ + [ELS_PRLO] = "PRLO", \ + [ELS_SCN] = "SCN", \ + [ELS_TPLS] = "TPLS", \ + [ELS_TPRLO] = "TPRLO", \ + [ELS_LCLM] = "LCLM", \ + [ELS_GAID] = "GAID", \ + [ELS_FACT] = "FACT", \ + [ELS_FDACDT] = "FDACDT", \ + [ELS_NACT] = "NACT", \ + [ELS_NDACT] = "NDACT", \ + [ELS_QOSR] = "QOSR", \ + [ELS_RVCS] = "RVCS", \ + [ELS_PDISC] = "PDISC", \ + [ELS_FDISC] = "FDISC", \ + [ELS_ADISC] = "ADISC", \ + [ELS_RNC] = "RNC", \ + [ELS_FARP_REQ] = "FARP_REQ", \ + [ELS_FARP_REPL] = "FARP_REPL", \ + [ELS_RPS] = "RPS", \ + [ELS_RPL] = "RPL", \ + [ELS_RPBC] = "RPBC", \ + [ELS_FAN] = "FAN", \ + [ELS_RSCN] = "RSCN", \ + [ELS_SCR] = "SCR", \ + [ELS_RNFT] = "RNFT", \ + [ELS_CSR] = "CSR", \ + [ELS_CSU] = "CSU", \ + [ELS_LINIT] = "LINIT", \ + [ELS_LSTS] = "LSTS", \ + [ELS_RNID] = "RNID", \ + [ELS_RLIR] = "RLIR", \ + [ELS_LIRR] = "LIRR", \ + [ELS_SRL] = "SRL", \ + [ELS_SBRP] = "SBRP", \ + [ELS_RPSC] = "RPSC", \ + [ELS_QSA] = "QSA", \ + [ELS_EVFP] = "EVFP", \ + [ELS_LKA] = "LKA", \ + [ELS_AUTH_ELS] = "AUTH_ELS", \ +} + +/* + * LS_ACC payload. + */ +struct fc_els_ls_acc { + __u8 la_cmd; /* command code ELS_LS_ACC */ + __u8 la_resv[3]; /* reserved */ +}; + +/* + * ELS reject payload. + */ +struct fc_els_ls_rjt { + __u8 er_cmd; /* command code ELS_LS_RJT */ + __u8 er_resv[4]; /* reserved must be zero */ + __u8 er_reason; /* reason (enum fc_els_rjt_reason below) */ + __u8 er_explan; /* explanation (enum fc_els_rjt_explan below) */ + __u8 er_vendor; /* vendor specific code */ +}; + +/* + * ELS reject reason codes (er_reason). + */ +enum fc_els_rjt_reason { + ELS_RJT_NONE = 0, /* no reject - not to be sent */ + ELS_RJT_INVAL = 0x01, /* invalid ELS command code */ + ELS_RJT_LOGIC = 0x03, /* logical error */ + ELS_RJT_BUSY = 0x05, /* logical busy */ + ELS_RJT_PROT = 0x07, /* protocol error */ + ELS_RJT_UNAB = 0x09, /* unable to perform command request */ + ELS_RJT_UNSUP = 0x0b, /* command not supported */ + ELS_RJT_INPROG = 0x0e, /* command already in progress */ + ELS_RJT_VENDOR = 0xff, /* vendor specific error */ +}; + + +/* + * reason code explanation (er_explan). + */ +enum fc_els_rjt_explan { + ELS_EXPL_NONE = 0x00, /* No additional explanation */ + ELS_EXPL_SPP_OPT_ERR = 0x01, /* service parameter error - options */ + ELS_EXPL_SPP_ICTL_ERR = 0x03, /* service parm error - initiator ctl */ + ELS_EXPL_AH = 0x11, /* invalid association header */ + ELS_EXPL_AH_REQ = 0x13, /* association_header required */ + ELS_EXPL_SID = 0x15, /* invalid originator S_ID */ + ELS_EXPL_OXID_RXID = 0x17, /* invalid OX_ID-RX_ID combination */ + ELS_EXPL_INPROG = 0x19, /* Request already in progress */ + ELS_EXPL_PLOGI_REQD = 0x1e, /* N_Port login required */ + ELS_EXPL_INSUF_RES = 0x29, /* insufficient resources */ + ELS_EXPL_UNAB_DATA = 0x2a, /* unable to supply requested data */ + ELS_EXPL_UNSUPR = 0x2c, /* Request not supported */ + ELS_EXPL_INV_LEN = 0x2d, /* Invalid payload length */ + /* TBD - above definitions incomplete */ +}; + +/* + * Common service parameters (N ports). + */ +struct fc_els_csp { + __u8 sp_hi_ver; /* highest version supported (obs.) */ + __u8 sp_lo_ver; /* highest version supported (obs.) */ + __be16 sp_bb_cred; /* buffer-to-buffer credits */ + __be16 sp_features; /* common feature flags */ + __be16 sp_bb_data; /* b-b state number and data field sz */ + union { + struct { + __be16 _sp_tot_seq; /* total concurrent sequences */ + __be16 _sp_rel_off; /* rel. offset by info cat */ + } sp_plogi; + struct { + __be32 _sp_r_a_tov; /* resource alloc. timeout msec */ + } sp_flogi_acc; + } sp_u; + __be32 sp_e_d_tov; /* error detect timeout value */ +}; +#define sp_tot_seq sp_u.sp_plogi._sp_tot_seq +#define sp_rel_off sp_u.sp_plogi._sp_rel_off +#define sp_r_a_tov sp_u.sp_flogi_acc._sp_r_a_tov + +#define FC_SP_BB_DATA_MASK 0xfff /* mask for data field size in sp_bb_data */ + +/* + * Minimum and maximum values for max data field size in service parameters. + */ +#define FC_SP_MIN_MAX_PAYLOAD FC_MIN_MAX_PAYLOAD +#define FC_SP_MAX_MAX_PAYLOAD FC_MAX_PAYLOAD + +/* + * sp_features + */ +#define FC_SP_FT_CIRO 0x8000 /* continuously increasing rel. off. */ +#define FC_SP_FT_CLAD 0x8000 /* clean address (in FLOGI LS_ACC) */ +#define FC_SP_FT_RAND 0x4000 /* random relative offset */ +#define FC_SP_FT_VAL 0x2000 /* valid vendor version level */ +#define FC_SP_FT_FPORT 0x1000 /* F port (1) vs. N port (0) */ +#define FC_SP_FT_ABB 0x0800 /* alternate BB_credit management */ +#define FC_SP_FT_EDTR 0x0400 /* E_D_TOV Resolution is nanoseconds */ +#define FC_SP_FT_MCAST 0x0200 /* multicast */ +#define FC_SP_FT_BCAST 0x0100 /* broadcast */ +#define FC_SP_FT_HUNT 0x0080 /* hunt group */ +#define FC_SP_FT_SIMP 0x0040 /* dedicated simplex */ +#define FC_SP_FT_SEC 0x0020 /* reserved for security */ +#define FC_SP_FT_CSYN 0x0010 /* clock synch. supported */ +#define FC_SP_FT_RTTOV 0x0008 /* R_T_TOV value 100 uS, else 100 mS */ +#define FC_SP_FT_HALF 0x0004 /* dynamic half duplex */ +#define FC_SP_FT_SEQC 0x0002 /* SEQ_CNT */ +#define FC_SP_FT_PAYL 0x0001 /* FLOGI payload length 256, else 116 */ + +/* + * Class-specific service parameters. + */ +struct fc_els_cssp { + __be16 cp_class; /* class flags */ + __be16 cp_init; /* initiator flags */ + __be16 cp_recip; /* recipient flags */ + __be16 cp_rdfs; /* receive data field size */ + __be16 cp_con_seq; /* concurrent sequences */ + __be16 cp_ee_cred; /* N-port end-to-end credit */ + __u8 cp_resv1; /* reserved */ + __u8 cp_open_seq; /* open sequences per exchange */ + __u8 _cp_resv2[2]; /* reserved */ +}; + +/* + * cp_class flags. + */ +#define FC_CPC_VALID 0x8000 /* class valid */ +#define FC_CPC_IMIX 0x4000 /* intermix mode */ +#define FC_CPC_SEQ 0x0800 /* sequential delivery */ +#define FC_CPC_CAMP 0x0200 /* camp-on */ +#define FC_CPC_PRI 0x0080 /* priority */ + +/* + * cp_init flags. + * (TBD: not all flags defined here). + */ +#define FC_CPI_CSYN 0x0010 /* clock synch. capable */ + +/* + * cp_recip flags. + */ +#define FC_CPR_CSYN 0x0008 /* clock synch. capable */ + +/* + * NFC_ELS_FLOGI: Fabric login request. + * NFC_ELS_PLOGI: Port login request (same format). + */ +struct fc_els_flogi { + __u8 fl_cmd; /* command */ + __u8 _fl_resvd[3]; /* must be zero */ + struct fc_els_csp fl_csp; /* common service parameters */ + __be64 fl_wwpn; /* port name */ + __be64 fl_wwnn; /* node name */ + struct fc_els_cssp fl_cssp[4]; /* class 1-4 service parameters */ + __u8 fl_vend[16]; /* vendor version level */ +} __attribute__((__packed__)); + +/* + * Process login service parameter page. + */ +struct fc_els_spp { + __u8 spp_type; /* type code or common service params */ + __u8 spp_type_ext; /* type code extension */ + __u8 spp_flags; + __u8 _spp_resvd; + __be32 spp_orig_pa; /* originator process associator */ + __be32 spp_resp_pa; /* responder process associator */ + __be32 spp_params; /* service parameters */ +}; + +/* + * spp_flags. + */ +#define FC_SPP_OPA_VAL 0x80 /* originator proc. assoc. valid */ +#define FC_SPP_RPA_VAL 0x40 /* responder proc. assoc. valid */ +#define FC_SPP_EST_IMG_PAIR 0x20 /* establish image pair */ +#define FC_SPP_RESP_MASK 0x0f /* mask for response code (below) */ + +/* + * SPP response code in spp_flags - lower 4 bits. + */ +enum fc_els_spp_resp { + FC_SPP_RESP_ACK = 1, /* request executed */ + FC_SPP_RESP_RES = 2, /* unable due to lack of resources */ + FC_SPP_RESP_INIT = 3, /* initialization not complete */ + FC_SPP_RESP_NO_PA = 4, /* unknown process associator */ + FC_SPP_RESP_CONF = 5, /* configuration precludes image pair */ + FC_SPP_RESP_COND = 6, /* request completed conditionally */ + FC_SPP_RESP_MULT = 7, /* unable to handle multiple SPPs */ + FC_SPP_RESP_INVL = 8, /* SPP is invalid */ +}; + +/* + * ELS_RRQ - Reinstate Recovery Qualifier + */ +struct fc_els_rrq { + __u8 rrq_cmd; /* command (0x12) */ + __u8 rrq_zero[3]; /* specified as zero - part of cmd */ + __u8 rrq_resvd; /* reserved */ + __u8 rrq_s_id[3]; /* originator FID */ + __be16 rrq_ox_id; /* originator exchange ID */ + __be16 rrq_rx_id; /* responders exchange ID */ +}; + +/* + * ELS_REC - Read exchange concise. + */ +struct fc_els_rec { + __u8 rec_cmd; /* command (0x13) */ + __u8 rec_zero[3]; /* specified as zero - part of cmd */ + __u8 rec_resvd; /* reserved */ + __u8 rec_s_id[3]; /* originator FID */ + __be16 rec_ox_id; /* originator exchange ID */ + __be16 rec_rx_id; /* responders exchange ID */ +}; + +/* + * ELS_REC LS_ACC payload. + */ +struct fc_els_rec_acc { + __u8 reca_cmd; /* accept (0x02) */ + __u8 reca_zero[3]; /* specified as zero - part of cmd */ + __be16 reca_ox_id; /* originator exchange ID */ + __be16 reca_rx_id; /* responders exchange ID */ + __u8 reca_resvd1; /* reserved */ + __u8 reca_ofid[3]; /* originator FID */ + __u8 reca_resvd2; /* reserved */ + __u8 reca_rfid[3]; /* responder FID */ + __be32 reca_fc4value; /* FC4 value */ + __be32 reca_e_stat; /* ESB (exchange status block) status */ +}; + +/* + * ELS_PRLI - Process login request and response. + */ +struct fc_els_prli { + __u8 prli_cmd; /* command */ + __u8 prli_spp_len; /* length of each serv. parm. page */ + __be16 prli_len; /* length of entire payload */ + /* service parameter pages follow */ +}; + +/* + * ELS_ADISC payload + */ +struct fc_els_adisc { + __u8 adisc_cmd; + __u8 adisc_resv[3]; + __u8 adisc_resv1; + __u8 adisc_hard_addr[3]; + __be64 adisc_wwpn; + __be64 adisc_wwnn; + __u8 adisc_resv2; + __u8 adisc_port_id[3]; +} __attribute__((__packed__)); + +/* + * ELS_LOGO - process or fabric logout. + */ +struct fc_els_logo { + __u8 fl_cmd; /* command code */ + __u8 fl_zero[3]; /* specified as zero - part of cmd */ + __u8 fl_resvd; /* reserved */ + __u8 fl_n_port_id[3];/* N port ID */ + __be64 fl_n_port_wwn; /* port name */ +}; + +/* + * ELS_RTV - read timeout value. + */ +struct fc_els_rtv { + __u8 rtv_cmd; /* command code 0x0e */ + __u8 rtv_zero[3]; /* specified as zero - part of cmd */ +}; + +/* + * LS_ACC for ELS_RTV - read timeout value. + */ +struct fc_els_rtv_acc { + __u8 rtv_cmd; /* command code 0x02 */ + __u8 rtv_zero[3]; /* specified as zero - part of cmd */ + __be32 rtv_r_a_tov; /* resource allocation timeout value */ + __be32 rtv_e_d_tov; /* error detection timeout value */ + __be32 rtv_toq; /* timeout qualifier (see below) */ +}; + +/* + * rtv_toq bits. + */ +#define FC_ELS_RTV_EDRES (1 << 26) /* E_D_TOV resolution is nS else mS */ +#define FC_ELS_RTV_RTTOV (1 << 19) /* R_T_TOV is 100 uS else 100 mS */ + +/* + * ELS_SCR - state change registration payload. + */ +struct fc_els_scr { + __u8 scr_cmd; /* command code */ + __u8 scr_resv[6]; /* reserved */ + __u8 scr_reg_func; /* registration function (see below) */ +}; + +enum fc_els_scr_func { + ELS_SCRF_FAB = 1, /* fabric-detected registration */ + ELS_SCRF_NPORT = 2, /* Nx_Port-detected registration */ + ELS_SCRF_FULL = 3, /* full registration */ + ELS_SCRF_CLEAR = 255, /* remove any current registrations */ +}; + +/* + * ELS_RSCN - registered state change notification payload. + */ +struct fc_els_rscn { + __u8 rscn_cmd; /* RSCN opcode (0x61) */ + __u8 rscn_page_len; /* page length (4) */ + __be16 rscn_plen; /* payload length including this word */ + + /* followed by 4-byte generic affected Port_ID pages */ +}; + +struct fc_els_rscn_page { + __u8 rscn_page_flags; /* event and address format */ + __u8 rscn_fid[3]; /* fabric ID */ +}; + +#define ELS_RSCN_EV_QUAL_BIT 2 /* shift count for event qualifier */ +#define ELS_RSCN_EV_QUAL_MASK 0xf /* mask for event qualifier */ +#define ELS_RSCN_ADDR_FMT_BIT 0 /* shift count for address format */ +#define ELS_RSCN_ADDR_FMT_MASK 0x3 /* mask for address format */ + +enum fc_els_rscn_ev_qual { + ELS_EV_QUAL_NONE = 0, /* unspecified */ + ELS_EV_QUAL_NS_OBJ = 1, /* changed name server object */ + ELS_EV_QUAL_PORT_ATTR = 2, /* changed port attribute */ + ELS_EV_QUAL_SERV_OBJ = 3, /* changed service object */ + ELS_EV_QUAL_SW_CONFIG = 4, /* changed switch configuration */ + ELS_EV_QUAL_REM_OBJ = 5, /* removed object */ +}; + +enum fc_els_rscn_addr_fmt { + ELS_ADDR_FMT_PORT = 0, /* rscn_fid is a port address */ + ELS_ADDR_FMT_AREA = 1, /* rscn_fid is a area address */ + ELS_ADDR_FMT_DOM = 2, /* rscn_fid is a domain address */ + ELS_ADDR_FMT_FAB = 3, /* anything on fabric may have changed */ +}; + +/* + * ELS_RNID - request Node ID. + */ +struct fc_els_rnid { + __u8 rnid_cmd; /* RNID opcode (0x78) */ + __u8 rnid_resv[3]; /* reserved */ + __u8 rnid_fmt; /* data format */ + __u8 rnid_resv2[3]; /* reserved */ +}; + +/* + * Node Identification Data formats (rnid_fmt) + */ +enum fc_els_rnid_fmt { + ELS_RNIDF_NONE = 0, /* no specific identification data */ + ELS_RNIDF_GEN = 0xdf, /* general topology discovery format */ +}; + +/* + * ELS_RNID response. + */ +struct fc_els_rnid_resp { + __u8 rnid_cmd; /* response code (LS_ACC) */ + __u8 rnid_resv[3]; /* reserved */ + __u8 rnid_fmt; /* data format */ + __u8 rnid_cid_len; /* common ID data length */ + __u8 rnid_resv2; /* reserved */ + __u8 rnid_sid_len; /* specific ID data length */ +}; + +struct fc_els_rnid_cid { + __be64 rnid_wwpn; /* N port name */ + __be64 rnid_wwnn; /* node name */ +}; + +struct fc_els_rnid_gen { + __u8 rnid_vend_id[16]; /* vendor-unique ID */ + __be32 rnid_atype; /* associated type (see below) */ + __be32 rnid_phys_port; /* physical port number */ + __be32 rnid_att_nodes; /* number of attached nodes */ + __u8 rnid_node_mgmt; /* node management (see below) */ + __u8 rnid_ip_ver; /* IP version (see below) */ + __be16 rnid_prot_port; /* UDP / TCP port number */ + __be32 rnid_ip_addr[4]; /* IP address */ + __u8 rnid_resvd[2]; /* reserved */ + __be16 rnid_vend_spec; /* vendor-specific field */ +}; + +enum fc_els_rnid_atype { + ELS_RNIDA_UNK = 0x01, /* unknown */ + ELS_RNIDA_OTHER = 0x02, /* none of the following */ + ELS_RNIDA_HUB = 0x03, + ELS_RNIDA_SWITCH = 0x04, + ELS_RNIDA_GATEWAY = 0x05, + ELS_RNIDA_CONV = 0x06, /* Obsolete, do not use this value */ + ELS_RNIDA_HBA = 0x07, /* Obsolete, do not use this value */ + ELS_RNIDA_PROXY = 0x08, /* Obsolete, do not use this value */ + ELS_RNIDA_STORAGE = 0x09, + ELS_RNIDA_HOST = 0x0a, + ELS_RNIDA_SUBSYS = 0x0b, /* storage subsystem (e.g., RAID) */ + ELS_RNIDA_ACCESS = 0x0e, /* access device (e.g. media changer) */ + ELS_RNIDA_NAS = 0x11, /* NAS server */ + ELS_RNIDA_BRIDGE = 0x12, /* bridge */ + ELS_RNIDA_VIRT = 0x13, /* virtualization device */ + ELS_RNIDA_MF = 0xff, /* multifunction device (bits below) */ + ELS_RNIDA_MF_HUB = 1UL << 31, /* hub */ + ELS_RNIDA_MF_SW = 1UL << 30, /* switch */ + ELS_RNIDA_MF_GW = 1UL << 29, /* gateway */ + ELS_RNIDA_MF_ST = 1UL << 28, /* storage */ + ELS_RNIDA_MF_HOST = 1UL << 27, /* host */ + ELS_RNIDA_MF_SUB = 1UL << 26, /* storage subsystem */ + ELS_RNIDA_MF_ACC = 1UL << 25, /* storage access dev */ + ELS_RNIDA_MF_WDM = 1UL << 24, /* wavelength division mux */ + ELS_RNIDA_MF_NAS = 1UL << 23, /* NAS server */ + ELS_RNIDA_MF_BR = 1UL << 22, /* bridge */ + ELS_RNIDA_MF_VIRT = 1UL << 21, /* virtualization device */ +}; + +enum fc_els_rnid_mgmt { + ELS_RNIDM_SNMP = 0, + ELS_RNIDM_TELNET = 1, + ELS_RNIDM_HTTP = 2, + ELS_RNIDM_HTTPS = 3, + ELS_RNIDM_XML = 4, /* HTTP + XML */ +}; + +enum fc_els_rnid_ipver { + ELS_RNIDIP_NONE = 0, /* no IP support or node mgmt. */ + ELS_RNIDIP_V4 = 1, /* IPv4 */ + ELS_RNIDIP_V6 = 2, /* IPv6 */ +}; + +/* + * ELS RPL - Read Port List. + */ +struct fc_els_rpl { + __u8 rpl_cmd; /* command */ + __u8 rpl_resv[5]; /* reserved - must be zero */ + __be16 rpl_max_size; /* maximum response size or zero */ + __u8 rpl_resv1; /* reserved - must be zero */ + __u8 rpl_index[3]; /* starting index */ +}; + +/* + * Port number block in RPL response. + */ +struct fc_els_pnb { + __be32 pnb_phys_pn; /* physical port number */ + __u8 pnb_resv; /* reserved */ + __u8 pnb_port_id[3]; /* port ID */ + __be64 pnb_wwpn; /* port name */ +}; + +/* + * RPL LS_ACC response. + */ +struct fc_els_rpl_resp { + __u8 rpl_cmd; /* ELS_LS_ACC */ + __u8 rpl_resv1; /* reserved - must be zero */ + __be16 rpl_plen; /* payload length */ + __u8 rpl_resv2; /* reserved - must be zero */ + __u8 rpl_llen[3]; /* list length */ + __u8 rpl_resv3; /* reserved - must be zero */ + __u8 rpl_index[3]; /* starting index */ + struct fc_els_pnb rpl_pnb[1]; /* variable number of PNBs */ +}; + +/* + * Link Error Status Block. + */ +struct fc_els_lesb { + __be32 lesb_link_fail; /* link failure count */ + __be32 lesb_sync_loss; /* loss of synchronization count */ + __be32 lesb_sig_loss; /* loss of signal count */ + __be32 lesb_prim_err; /* primitive sequence error count */ + __be32 lesb_inv_word; /* invalid transmission word count */ + __be32 lesb_inv_crc; /* invalid CRC count */ +}; + +/* + * ELS RPS - Read Port Status Block request. + */ +struct fc_els_rps { + __u8 rps_cmd; /* command */ + __u8 rps_resv[2]; /* reserved - must be zero */ + __u8 rps_flag; /* flag - see below */ + __be64 rps_port_spec; /* port selection */ +}; + +enum fc_els_rps_flag { + FC_ELS_RPS_DID = 0x00, /* port identified by D_ID of req. */ + FC_ELS_RPS_PPN = 0x01, /* port_spec is physical port number */ + FC_ELS_RPS_WWPN = 0x02, /* port_spec is port WWN */ +}; + +/* + * ELS RPS LS_ACC response. + */ +struct fc_els_rps_resp { + __u8 rps_cmd; /* command - LS_ACC */ + __u8 rps_resv[2]; /* reserved - must be zero */ + __u8 rps_flag; /* flag - see below */ + __u8 rps_resv2[2]; /* reserved */ + __be16 rps_status; /* port status - see below */ + struct fc_els_lesb rps_lesb; /* link error status block */ +}; + +enum fc_els_rps_resp_flag { + FC_ELS_RPS_LPEV = 0x01, /* L_port extension valid */ +}; + +enum fc_els_rps_resp_status { + FC_ELS_RPS_PTP = 1 << 5, /* point-to-point connection */ + FC_ELS_RPS_LOOP = 1 << 4, /* loop mode */ + FC_ELS_RPS_FAB = 1 << 3, /* fabric present */ + FC_ELS_RPS_NO_SIG = 1 << 2, /* loss of signal */ + FC_ELS_RPS_NO_SYNC = 1 << 1, /* loss of synchronization */ + FC_ELS_RPS_RESET = 1 << 0, /* in link reset protocol */ +}; + +/* + * ELS LIRR - Link Incident Record Registration request. + */ +struct fc_els_lirr { + __u8 lirr_cmd; /* command */ + __u8 lirr_resv[3]; /* reserved - must be zero */ + __u8 lirr_func; /* registration function */ + __u8 lirr_fmt; /* FC-4 type of RLIR requested */ + __u8 lirr_resv2[2]; /* reserved - must be zero */ +}; + +enum fc_els_lirr_func { + ELS_LIRR_SET_COND = 0x01, /* set - conditionally receive */ + ELS_LIRR_SET_UNCOND = 0x02, /* set - unconditionally receive */ + ELS_LIRR_CLEAR = 0xff /* clear registration */ +}; + +/* + * ELS SRL - Scan Remote Loop request. + */ +struct fc_els_srl { + __u8 srl_cmd; /* command */ + __u8 srl_resv[3]; /* reserved - must be zero */ + __u8 srl_flag; /* flag - see below */ + __u8 srl_flag_param[3]; /* flag parameter */ +}; + +enum fc_els_srl_flag { + FC_ELS_SRL_ALL = 0x00, /* scan all FL ports */ + FC_ELS_SRL_ONE = 0x01, /* scan specified loop */ + FC_ELS_SRL_EN_PER = 0x02, /* enable periodic scanning (param) */ + FC_ELS_SRL_DIS_PER = 0x03, /* disable periodic scanning */ +}; + +/* + * ELS RLS - Read Link Error Status Block request. + */ +struct fc_els_rls { + __u8 rls_cmd; /* command */ + __u8 rls_resv[4]; /* reserved - must be zero */ + __u8 rls_port_id[3]; /* port ID */ +}; + +/* + * ELS RLS LS_ACC Response. + */ +struct fc_els_rls_resp { + __u8 rls_cmd; /* ELS_LS_ACC */ + __u8 rls_resv[3]; /* reserved - must be zero */ + struct fc_els_lesb rls_lesb; /* link error status block */ +}; + +/* + * ELS RLIR - Registered Link Incident Report. + * This is followed by the CLIR and the CLID, described below. + */ +struct fc_els_rlir { + __u8 rlir_cmd; /* command */ + __u8 rlir_resv[3]; /* reserved - must be zero */ + __u8 rlir_fmt; /* format (FC4-type if type specific) */ + __u8 rlir_clr_len; /* common link incident record length */ + __u8 rlir_cld_len; /* common link incident desc. length */ + __u8 rlir_slr_len; /* spec. link incident record length */ +}; + +/* + * CLIR - Common Link Incident Record Data. - Sent via RLIR. + */ +struct fc_els_clir { + __be64 clir_wwpn; /* incident port name */ + __be64 clir_wwnn; /* incident port node name */ + __u8 clir_port_type; /* incident port type */ + __u8 clir_port_id[3]; /* incident port ID */ + + __be64 clir_conn_wwpn; /* connected port name */ + __be64 clir_conn_wwnn; /* connected node name */ + __be64 clir_fab_name; /* fabric name */ + __be32 clir_phys_port; /* physical port number */ + __be32 clir_trans_id; /* transaction ID */ + __u8 clir_resv[3]; /* reserved */ + __u8 clir_ts_fmt; /* time stamp format */ + __be64 clir_timestamp; /* time stamp */ +}; + +/* + * CLIR clir_ts_fmt - time stamp format values. + */ +enum fc_els_clir_ts_fmt { + ELS_CLIR_TS_UNKNOWN = 0, /* time stamp field unknown */ + ELS_CLIR_TS_SEC_FRAC = 1, /* time in seconds and fractions */ + ELS_CLIR_TS_CSU = 2, /* time in clock synch update format */ +}; + +/* + * Common Link Incident Descriptor - sent via RLIR. + */ +struct fc_els_clid { + __u8 clid_iq; /* incident qualifier flags */ + __u8 clid_ic; /* incident code */ + __be16 clid_epai; /* domain/area of ISL */ +}; + +/* + * CLID incident qualifier flags. + */ +enum fc_els_clid_iq { + ELS_CLID_SWITCH = 0x20, /* incident port is a switch node */ + ELS_CLID_E_PORT = 0x10, /* incident is an ISL (E) port */ + ELS_CLID_SEV_MASK = 0x0c, /* severity 2-bit field mask */ + ELS_CLID_SEV_INFO = 0x00, /* report is informational */ + ELS_CLID_SEV_INOP = 0x08, /* link not operational */ + ELS_CLID_SEV_DEG = 0x04, /* link degraded but operational */ + ELS_CLID_LASER = 0x02, /* subassembly is a laser */ + ELS_CLID_FRU = 0x01, /* format can identify a FRU */ +}; + +/* + * CLID incident code. + */ +enum fc_els_clid_ic { + ELS_CLID_IC_IMPL = 1, /* implicit incident */ + ELS_CLID_IC_BER = 2, /* bit-error-rate threshold exceeded */ + ELS_CLID_IC_LOS = 3, /* loss of synch or signal */ + ELS_CLID_IC_NOS = 4, /* non-operational primitive sequence */ + ELS_CLID_IC_PST = 5, /* primitive sequence timeout */ + ELS_CLID_IC_INVAL = 6, /* invalid primitive sequence */ + ELS_CLID_IC_LOOP_TO = 7, /* loop initialization time out */ + ELS_CLID_IC_LIP = 8, /* receiving LIP */ +}; + +#endif /* _FC_ELS_H_ */ diff --git a/include/scsi/fc/fc_encaps.h b/include/scsi/fc/fc_encaps.h new file mode 100644 index 00000000000..f180c3e1622 --- /dev/null +++ b/include/scsi/fc/fc_encaps.h @@ -0,0 +1,138 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ +#ifndef _FC_ENCAPS_H_ +#define _FC_ENCAPS_H_ + +/* + * Protocol definitions from RFC 3643 - Fibre Channel Frame Encapsulation. + * + * Note: The frame length field is the number of 32-bit words in + * the encapsulation including the fcip_encaps_header, CRC and EOF words. + * The minimum frame length value in bytes is (32 + 24 + 4 + 4) * 4 = 64. + * The maximum frame length value in bytes is (32 + 24 + 2112 + 4 + 4) = 2172. + */ +#define FC_ENCAPS_MIN_FRAME_LEN 64 /* min frame len (bytes) (see above) */ +#define FC_ENCAPS_MAX_FRAME_LEN (FC_ENCAPS_MIN_FRAME_LEN + FC_MAX_PAYLOAD) + +#define FC_ENCAPS_VER 1 /* current version number */ + +struct fc_encaps_hdr { + __u8 fc_proto; /* protocol number */ + __u8 fc_ver; /* version of encapsulation */ + __u8 fc_proto_n; /* ones complement of protocol */ + __u8 fc_ver_n; /* ones complement of version */ + + unsigned char fc_proto_data[8]; /* protocol specific data */ + + __be16 fc_len_flags; /* 10-bit length/4 w/ 6 flag bits */ + __be16 fc_len_flags_n; /* ones complement of length / flags */ + + /* + * Offset 0x10 + */ + __be32 fc_time[2]; /* time stamp: seconds and fraction */ + __be32 fc_crc; /* CRC */ + __be32 fc_sof; /* start of frame (see FC_SOF below) */ + + /* 0x20 - FC frame content followed by EOF word */ +}; + +#define FCIP_ENCAPS_HDR_LEN 0x20 /* expected length for asserts */ + +/* + * Macro's for making redundant copies of EOF and SOF. + */ +#define FC_XY(x, y) ((((x) & 0xff) << 8) | ((y) & 0xff)) +#define FC_XYXY(x, y) ((FCIP_XY(x, y) << 16) | FCIP_XY(x, y)) +#define FC_XYNN(x, y) (FCIP_XYXY(x, y) ^ 0xffff) + +#define FC_SOF_ENCODE(n) FC_XYNN(n, n) +#define FC_EOF_ENCODE(n) FC_XYNN(n, n) + +/* + * SOF / EOF bytes. + */ +enum fc_sof { + FC_SOF_F = 0x28, /* fabric */ + FC_SOF_I4 = 0x29, /* initiate class 4 */ + FC_SOF_I2 = 0x2d, /* initiate class 2 */ + FC_SOF_I3 = 0x2e, /* initiate class 3 */ + FC_SOF_N4 = 0x31, /* normal class 4 */ + FC_SOF_N2 = 0x35, /* normal class 2 */ + FC_SOF_N3 = 0x36, /* normal class 3 */ + FC_SOF_C4 = 0x39, /* activate class 4 */ +} __attribute__((packed)); + +enum fc_eof { + FC_EOF_N = 0x41, /* normal (not last frame of seq) */ + FC_EOF_T = 0x42, /* terminate (last frame of sequence) */ + FC_EOF_RT = 0x44, + FC_EOF_DT = 0x46, /* disconnect-terminate class-1 */ + FC_EOF_NI = 0x49, /* normal-invalid */ + FC_EOF_DTI = 0x4e, /* disconnect-terminate-invalid */ + FC_EOF_RTI = 0x4f, + FC_EOF_A = 0x50, /* abort */ +} __attribute__((packed)); + +#define FC_SOF_CLASS_MASK 0x06 /* mask for class of service in SOF */ + +/* + * Define classes in terms of the SOF code (initial). + */ +enum fc_class { + FC_CLASS_NONE = 0, /* software value indicating no class */ + FC_CLASS_2 = FC_SOF_I2, + FC_CLASS_3 = FC_SOF_I3, + FC_CLASS_4 = FC_SOF_I4, + FC_CLASS_F = FC_SOF_F, +}; + +/* + * Determine whether SOF code indicates the need for a BLS ACK. + */ +static inline int fc_sof_needs_ack(enum fc_sof sof) +{ + return (~sof) & 0x02; /* true for class 1, 2, 4, 6, or F */ +} + +/* + * Given an fc_class, return the normal (non-initial) SOF value. + */ +static inline enum fc_sof fc_sof_normal(enum fc_class class) +{ + return class + FC_SOF_N3 - FC_SOF_I3; /* diff is always 8 */ +} + +/* + * Compute class from SOF value. + */ +static inline enum fc_class fc_sof_class(enum fc_sof sof) +{ + return (sof & 0x7) | FC_SOF_F; +} + +/* + * Determine whether SOF is for the initial frame of a sequence. + */ +static inline int fc_sof_is_init(enum fc_sof sof) +{ + return sof < 0x30; +} + +#endif /* _FC_ENCAPS_H_ */ diff --git a/include/scsi/fc/fc_fc2.h b/include/scsi/fc/fc_fc2.h new file mode 100644 index 00000000000..cff8a8c22f5 --- /dev/null +++ b/include/scsi/fc/fc_fc2.h @@ -0,0 +1,124 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FC2_H_ +#define _FC_FC2_H_ + +/* + * Fibre Channel Exchanges and Sequences. + */ +#ifndef PACKED +#define PACKED __attribute__ ((__packed__)) +#endif /* PACKED */ + + +/* + * Sequence Status Block. + * This format is set by the FC-FS standard and is sent over the wire. + * Note that the fields aren't all naturally aligned. + */ +struct fc_ssb { + __u8 ssb_seq_id; /* sequence ID */ + __u8 _ssb_resvd; + __be16 ssb_low_seq_cnt; /* lowest SEQ_CNT */ + + __be16 ssb_high_seq_cnt; /* highest SEQ_CNT */ + __be16 ssb_s_stat; /* sequence status flags */ + + __be16 ssb_err_seq_cnt; /* error SEQ_CNT */ + __u8 ssb_fh_cs_ctl; /* frame header CS_CTL */ + __be16 ssb_fh_ox_id; /* frame header OX_ID */ + __be16 ssb_rx_id; /* responder's exchange ID */ + __u8 _ssb_resvd2[2]; +} PACKED; + +/* + * The SSB should be 17 bytes. Since it's layout is somewhat strange, + * we define the size here so that code can ASSERT that the size comes out + * correct. + */ +#define FC_SSB_SIZE 17 /* length of fc_ssb for assert */ + +/* + * ssb_s_stat - flags from FC-FS-2 T11/1619-D Rev 0.90. + */ +#define SSB_ST_RESP (1 << 15) /* sequence responder */ +#define SSB_ST_ACTIVE (1 << 14) /* sequence is active */ +#define SSB_ST_ABNORMAL (1 << 12) /* abnormal ending condition */ + +#define SSB_ST_REQ_MASK (3 << 10) /* ACK, abort sequence condition */ +#define SSB_ST_REQ_CONT (0 << 10) +#define SSB_ST_REQ_ABORT (1 << 10) +#define SSB_ST_REQ_STOP (2 << 10) +#define SSB_ST_REQ_RETRANS (3 << 10) + +#define SSB_ST_ABTS (1 << 9) /* ABTS protocol completed */ +#define SSB_ST_RETRANS (1 << 8) /* retransmission completed */ +#define SSB_ST_TIMEOUT (1 << 7) /* sequence timed out by recipient */ +#define SSB_ST_P_RJT (1 << 6) /* P_RJT transmitted */ + +#define SSB_ST_CLASS_BIT 4 /* class of service field LSB */ +#define SSB_ST_CLASS_MASK 3 /* class of service mask */ +#define SSB_ST_ACK (1 << 3) /* ACK (EOFt or EOFdt) transmitted */ + +/* + * Exchange Status Block. + * This format is set by the FC-FS standard and is sent over the wire. + * Note that the fields aren't all naturally aligned. + */ +struct fc_esb { + __u8 esb_cs_ctl; /* CS_CTL for frame header */ + __be16 esb_ox_id; /* originator exchange ID */ + __be16 esb_rx_id; /* responder exchange ID */ + __be32 esb_orig_fid; /* fabric ID of originator */ + __be32 esb_resp_fid; /* fabric ID of responder */ + __be32 esb_e_stat; /* status */ + __u8 _esb_resvd[4]; + __u8 esb_service_params[112]; /* TBD */ + __u8 esb_seq_status[8]; /* sequence statuses, 8 bytes each */ +} __attribute__((packed));; + + +/* + * Define expected size for ASSERTs. + * See comments on FC_SSB_SIZE. + */ +#define FC_ESB_SIZE (1 + 5*4 + 112 + 8) /* expected size */ + +/* + * esb_e_stat - flags from FC-FS-2 T11/1619-D Rev 0.90. + */ +#define ESB_ST_RESP (1 << 31) /* responder to exchange */ +#define ESB_ST_SEQ_INIT (1 << 30) /* port holds sequence initiaive */ +#define ESB_ST_COMPLETE (1 << 29) /* exchange is complete */ +#define ESB_ST_ABNORMAL (1 << 28) /* abnormal ending condition */ +#define ESB_ST_REC_QUAL (1 << 26) /* recovery qualifier active */ + +#define ESB_ST_ERRP_BIT 24 /* LSB for error policy */ +#define ESB_ST_ERRP_MASK (3 << 24) /* mask for error policy */ +#define ESB_ST_ERRP_MULT (0 << 24) /* abort, discard multiple sequences */ +#define ESB_ST_ERRP_SING (1 << 24) /* abort, discard single sequence */ +#define ESB_ST_ERRP_INF (2 << 24) /* process with infinite buffers */ +#define ESB_ST_ERRP_IMM (3 << 24) /* discard mult. with immed. retran. */ + +#define ESB_ST_OX_ID_INVL (1 << 23) /* originator XID invalid */ +#define ESB_ST_RX_ID_INVL (1 << 22) /* responder XID invalid */ +#define ESB_ST_PRI_INUSE (1 << 21) /* priority / preemption in use */ + +#endif /* _FC_FC2_H_ */ diff --git a/include/scsi/fc/fc_fcoe.h b/include/scsi/fc/fc_fcoe.h new file mode 100644 index 00000000000..57aaa8f0d61 --- /dev/null +++ b/include/scsi/fc/fc_fcoe.h @@ -0,0 +1,114 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FCOE_H_ +#define _FC_FCOE_H_ + +/* + * FCoE - Fibre Channel over Ethernet. + */ + +/* + * The FCoE ethertype eventually goes in net/if_ether.h. + */ +#ifndef ETH_P_FCOE +#define ETH_P_FCOE 0x8906 /* FCOE ether type */ +#endif + +#ifndef ETH_P_8021Q +#define ETH_P_8021Q 0x8100 +#endif + +/* + * FC_FCOE_OUI hasn't been standardized yet. XXX TBD. + */ +#ifndef FC_FCOE_OUI +#define FC_FCOE_OUI 0x0efc00 /* upper 24 bits of FCOE dest MAC TBD */ +#endif + +/* + * The destination MAC address for the fabric login may get a different OUI. + * This isn't standardized yet. + */ +#ifndef FC_FCOE_FLOGI_MAC +/* gateway MAC - TBD */ +#define FC_FCOE_FLOGI_MAC { 0x0e, 0xfc, 0x00, 0xff, 0xff, 0xfe } +#endif + +#define FC_FCOE_VER 0 /* version */ + +/* + * Ethernet Addresses based on FC S_ID and D_ID. + * Generated by FC_FCOE_OUI | S_ID/D_ID + */ +#define FC_FCOE_ENCAPS_ID(n) (((u64) FC_FCOE_OUI << 24) | (n)) +#define FC_FCOE_DECAPS_ID(n) ((n) >> 24) + +/* + * FCoE frame header - 14 bytes + * + * This is the August 2007 version of the FCoE header as defined by T11. + * This follows the VLAN header, which includes the ethertype. + */ +struct fcoe_hdr { + __u8 fcoe_ver; /* version field - upper 4 bits */ + __u8 fcoe_resvd[12]; /* reserved - send zero and ignore */ + __u8 fcoe_sof; /* start of frame per RFC 3643 */ +}; + +#define FC_FCOE_DECAPS_VER(hp) ((hp)->fcoe_ver >> 4) +#define FC_FCOE_ENCAPS_VER(hp, ver) ((hp)->fcoe_ver = (ver) << 4) + +/* + * FCoE CRC & EOF - 8 bytes. + */ +struct fcoe_crc_eof { + __le32 fcoe_crc32; /* CRC for FC packet */ + __u8 fcoe_eof; /* EOF from RFC 3643 */ + __u8 fcoe_resvd[3]; /* reserved - send zero and ignore */ +} __attribute__((packed)); + +/* + * Minimum FCoE + FC header length + * 14 bytes FCoE header + 24 byte FC header = 38 bytes + */ +#define FCOE_HEADER_LEN 38 + +/* + * Minimum FCoE frame size + * 14 bytes FCoE header + 24 byte FC header + 8 byte FCoE trailer = 46 bytes + */ +#define FCOE_MIN_FRAME 46 + +/* + * fc_fcoe_set_mac - Store OUI + DID into MAC address field. + * @mac: mac address to be set + * @did: fc dest id to use + */ +static inline void fc_fcoe_set_mac(u8 *mac, u8 *did) +{ + mac[0] = (u8) (FC_FCOE_OUI >> 16); + mac[1] = (u8) (FC_FCOE_OUI >> 8); + mac[2] = (u8) FC_FCOE_OUI; + mac[3] = did[0]; + mac[4] = did[1]; + mac[5] = did[2]; +} + +#endif /* _FC_FCOE_H_ */ diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h new file mode 100644 index 00000000000..5d38f1989f3 --- /dev/null +++ b/include/scsi/fc/fc_fcp.h @@ -0,0 +1,199 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FCP_H_ +#define _FC_FCP_H_ + +/* + * Fibre Channel Protocol for SCSI. + * From T10 FCP-3, T10 project 1560-D Rev 4, Sept. 13, 2005. + */ + +/* + * fc/fs.h defines FC_TYPE_FCP. + */ + +/* + * Service parameter page parameters (word 3 bits) for Process Login. + */ +#define FCP_SPPF_TASK_RETRY_ID 0x0200 /* task retry ID requested */ +#define FCP_SPPF_RETRY 0x0100 /* retry supported */ +#define FCP_SPPF_CONF_COMPL 0x0080 /* confirmed completion allowed */ +#define FCP_SPPF_OVLY_ALLOW 0x0040 /* data overlay allowed */ +#define FCP_SPPF_INIT_FCN 0x0020 /* initiator function */ +#define FCP_SPPF_TARG_FCN 0x0010 /* target function */ +#define FCP_SPPF_RD_XRDY_DIS 0x0002 /* disable XFER_RDY for reads */ +#define FCP_SPPF_WR_XRDY_DIS 0x0001 /* disable XFER_RDY for writes */ + +/* + * FCP_CMND IU Payload. + */ +struct fcp_cmnd { + __u8 fc_lun[8]; /* logical unit number */ + __u8 fc_cmdref; /* commmand reference number */ + __u8 fc_pri_ta; /* priority and task attribute */ + __u8 fc_tm_flags; /* task management flags */ + __u8 fc_flags; /* additional len & flags */ + __u8 fc_cdb[16]; /* base CDB */ + __be32 fc_dl; /* data length (must follow fc_cdb) */ +}; + +#define FCP_CMND_LEN 32 /* expected length of structure */ + +struct fcp_cmnd32 { + __u8 fc_lun[8]; /* logical unit number */ + __u8 fc_cmdref; /* commmand reference number */ + __u8 fc_pri_ta; /* priority and task attribute */ + __u8 fc_tm_flags; /* task management flags */ + __u8 fc_flags; /* additional len & flags */ + __u8 fc_cdb[32]; /* base CDB */ + __be32 fc_dl; /* data length (must follow fc_cdb) */ +}; + +#define FCP_CMND32_LEN 48 /* expected length of structure */ +#define FCP_CMND32_ADD_LEN (16 / 4) /* Additional cdb length */ + +/* + * fc_pri_ta. + */ +#define FCP_PTA_SIMPLE 0 /* simple task attribute */ +#define FCP_PTA_HEADQ 1 /* head of queue task attribute */ +#define FCP_PTA_ORDERED 2 /* ordered task attribute */ +#define FCP_PTA_ACA 4 /* auto. contigent allegiance */ +#define FCP_PRI_SHIFT 3 /* priority field starts in bit 3 */ +#define FCP_PRI_RESVD_MASK 0x80 /* reserved bits in priority field */ + +/* + * fc_tm_flags - task management flags field. + */ +#define FCP_TMF_CLR_ACA 0x40 /* clear ACA condition */ +#define FCP_TMF_LUN_RESET 0x10 /* logical unit reset task management */ +#define FCP_TMF_CLR_TASK_SET 0x04 /* clear task set */ +#define FCP_TMF_ABT_TASK_SET 0x02 /* abort task set */ + +/* + * fc_flags. + * Bits 7:2 are the additional FCP_CDB length / 4. + */ +#define FCP_CFL_LEN_MASK 0xfc /* mask for additional length */ +#define FCP_CFL_LEN_SHIFT 2 /* shift bits for additional length */ +#define FCP_CFL_RDDATA 0x02 /* read data */ +#define FCP_CFL_WRDATA 0x01 /* write data */ + +/* + * FCP_TXRDY IU - transfer ready payload. + */ +struct fcp_txrdy { + __be32 ft_data_ro; /* data relative offset */ + __be32 ft_burst_len; /* burst length */ + __u8 _ft_resvd[4]; /* reserved */ +}; + +#define FCP_TXRDY_LEN 12 /* expected length of structure */ + +/* + * FCP_RESP IU - response payload. + * + * The response payload comes in three parts: the flags/status, the + * sense/response lengths and the sense data/response info section. + * + * From FCP3r04, note 6 of section 9.5.13: + * + * Some early implementations presented the FCP_RSP IU without the FCP_RESID, + * FCP_SNS_LEN, and FCP_RSP_LEN fields if the FCP_RESID_UNDER, FCP_RESID_OVER, + * FCP_SNS_LEN_VALID, and FCP_RSP_LEN_VALID bits were all set to zero. This + * non-standard behavior should be tolerated. + * + * All response frames will always contain the fcp_resp template. Some + * will also include the fcp_resp_len template. + */ +struct fcp_resp { + __u8 _fr_resvd[8]; /* reserved */ + __be16 fr_retry_delay; /* retry delay timer */ + __u8 fr_flags; /* flags */ + __u8 fr_status; /* SCSI status code */ +}; + +#define FCP_RESP_LEN 12 /* expected length of structure */ + +struct fcp_resp_ext { + __be32 fr_resid; /* Residual value */ + __be32 fr_sns_len; /* SCSI Sense length */ + __be32 fr_rsp_len; /* Response Info length */ + + /* + * Optionally followed by RSP info and/or SNS info and/or + * bidirectional read residual length, if any. + */ +}; + +#define FCP_RESP_EXT_LEN 12 /* expected length of the structure */ + +struct fcp_resp_rsp_info { + __u8 _fr_resvd[3]; /* reserved */ + __u8 rsp_code; /* Response Info Code */ + __u8 _fr_resvd2[4]; /* reserved */ +}; + +struct fcp_resp_with_ext { + struct fcp_resp resp; + struct fcp_resp_ext ext; +}; + +#define FCP_RESP_WITH_EXT (FCP_RESP_LEN + FCP_RESP_EXT_LEN) + +/* + * fr_flags. + */ +#define FCP_BIDI_RSP 0x80 /* bidirectional read response */ +#define FCP_BIDI_READ_UNDER 0x40 /* bidir. read less than requested */ +#define FCP_BIDI_READ_OVER 0x20 /* DL insufficient for full transfer */ +#define FCP_CONF_REQ 0x10 /* confirmation requested */ +#define FCP_RESID_UNDER 0x08 /* transfer shorter than expected */ +#define FCP_RESID_OVER 0x04 /* DL insufficient for full transfer */ +#define FCP_SNS_LEN_VAL 0x02 /* SNS_LEN field is valid */ +#define FCP_RSP_LEN_VAL 0x01 /* RSP_LEN field is valid */ + +/* + * rsp_codes + */ +enum fcp_resp_rsp_codes { + FCP_TMF_CMPL = 0, + FCP_DATA_LEN_INVALID = 1, + FCP_CMND_FIELDS_INVALID = 2, + FCP_DATA_PARAM_MISMATCH = 3, + FCP_TMF_REJECTED = 4, + FCP_TMF_FAILED = 5, + FCP_TMF_INVALID_LUN = 9, +}; + +/* + * FCP SRR Link Service request - Sequence Retransmission Request. + */ +struct fcp_srr { + __u8 srr_op; /* opcode ELS_SRR */ + __u8 srr_resvd[3]; /* opcode / reserved - must be zero */ + __be16 srr_ox_id; /* OX_ID of failed command */ + __be16 srr_rx_id; /* RX_ID of failed command */ + __be32 srr_rel_off; /* relative offset */ + __u8 srr_r_ctl; /* r_ctl for the information unit */ + __u8 srr_resvd2[3]; /* reserved */ +}; + +#endif /* _FC_FCP_H_ */ diff --git a/include/scsi/fc/fc_fs.h b/include/scsi/fc/fc_fs.h new file mode 100644 index 00000000000..3e4801d2bdb --- /dev/null +++ b/include/scsi/fc/fc_fs.h @@ -0,0 +1,340 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FS_H_ +#define _FC_FS_H_ + +/* + * Fibre Channel Framing and Signalling definitions. + * From T11 FC-FS-2 Rev 0.90 - 9 August 2005. + */ + +/* + * Frame header + */ +struct fc_frame_header { + __u8 fh_r_ctl; /* routing control */ + __u8 fh_d_id[3]; /* Destination ID */ + + __u8 fh_cs_ctl; /* class of service control / pri */ + __u8 fh_s_id[3]; /* Source ID */ + + __u8 fh_type; /* see enum fc_fh_type below */ + __u8 fh_f_ctl[3]; /* frame control */ + + __u8 fh_seq_id; /* sequence ID */ + __u8 fh_df_ctl; /* data field control */ + __be16 fh_seq_cnt; /* sequence count */ + + __be16 fh_ox_id; /* originator exchange ID */ + __be16 fh_rx_id; /* responder exchange ID */ + __be32 fh_parm_offset; /* parameter or relative offset */ +}; + +#define FC_FRAME_HEADER_LEN 24 /* expected length of structure */ + +#define FC_MAX_PAYLOAD 2112U /* max payload length in bytes */ +#define FC_MIN_MAX_PAYLOAD 256U /* lower limit on max payload */ + +#define FC_MAX_FRAME (FC_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) +#define FC_MIN_MAX_FRAME (FC_MIN_MAX_PAYLOAD + FC_FRAME_HEADER_LEN) + +/* + * fh_r_ctl - Routing control definitions. + */ + /* + * FC-4 device_data. + */ +enum fc_rctl { + FC_RCTL_DD_UNCAT = 0x00, /* uncategorized information */ + FC_RCTL_DD_SOL_DATA = 0x01, /* solicited data */ + FC_RCTL_DD_UNSOL_CTL = 0x02, /* unsolicited control */ + FC_RCTL_DD_SOL_CTL = 0x03, /* solicited control or reply */ + FC_RCTL_DD_UNSOL_DATA = 0x04, /* unsolicited data */ + FC_RCTL_DD_DATA_DESC = 0x05, /* data descriptor */ + FC_RCTL_DD_UNSOL_CMD = 0x06, /* unsolicited command */ + FC_RCTL_DD_CMD_STATUS = 0x07, /* command status */ + +#define FC_RCTL_ILS_REQ FC_RCTL_DD_UNSOL_CTL /* ILS request */ +#define FC_RCTL_ILS_REP FC_RCTL_DD_SOL_CTL /* ILS reply */ + + /* + * Extended Link_Data + */ + FC_RCTL_ELS_REQ = 0x22, /* extended link services request */ + FC_RCTL_ELS_REP = 0x23, /* extended link services reply */ + FC_RCTL_ELS4_REQ = 0x32, /* FC-4 ELS request */ + FC_RCTL_ELS4_REP = 0x33, /* FC-4 ELS reply */ + /* + * Optional Extended Headers + */ + FC_RCTL_VFTH = 0x50, /* virtual fabric tagging header */ + FC_RCTL_IFRH = 0x51, /* inter-fabric routing header */ + FC_RCTL_ENCH = 0x52, /* encapsulation header */ + /* + * Basic Link Services fh_r_ctl values. + */ + FC_RCTL_BA_NOP = 0x80, /* basic link service NOP */ + FC_RCTL_BA_ABTS = 0x81, /* basic link service abort */ + FC_RCTL_BA_RMC = 0x82, /* remove connection */ + FC_RCTL_BA_ACC = 0x84, /* basic accept */ + FC_RCTL_BA_RJT = 0x85, /* basic reject */ + FC_RCTL_BA_PRMT = 0x86, /* dedicated connection preempted */ + /* + * Link Control Information. + */ + FC_RCTL_ACK_1 = 0xc0, /* acknowledge_1 */ + FC_RCTL_ACK_0 = 0xc1, /* acknowledge_0 */ + FC_RCTL_P_RJT = 0xc2, /* port reject */ + FC_RCTL_F_RJT = 0xc3, /* fabric reject */ + FC_RCTL_P_BSY = 0xc4, /* port busy */ + FC_RCTL_F_BSY = 0xc5, /* fabric busy to data frame */ + FC_RCTL_F_BSYL = 0xc6, /* fabric busy to link control frame */ + FC_RCTL_LCR = 0xc7, /* link credit reset */ + FC_RCTL_END = 0xc9, /* end */ +}; + /* incomplete list of definitions */ + +/* + * R_CTL names initializer. + * Please keep this matching the above definitions. + */ +#define FC_RCTL_NAMES_INIT { \ + [FC_RCTL_DD_UNCAT] = "uncat", \ + [FC_RCTL_DD_SOL_DATA] = "sol data", \ + [FC_RCTL_DD_UNSOL_CTL] = "unsol ctl", \ + [FC_RCTL_DD_SOL_CTL] = "sol ctl/reply", \ + [FC_RCTL_DD_UNSOL_DATA] = "unsol data", \ + [FC_RCTL_DD_DATA_DESC] = "data desc", \ + [FC_RCTL_DD_UNSOL_CMD] = "unsol cmd", \ + [FC_RCTL_DD_CMD_STATUS] = "cmd status", \ + [FC_RCTL_ELS_REQ] = "ELS req", \ + [FC_RCTL_ELS_REP] = "ELS rep", \ + [FC_RCTL_ELS4_REQ] = "FC-4 ELS req", \ + [FC_RCTL_ELS4_REP] = "FC-4 ELS rep", \ + [FC_RCTL_BA_NOP] = "BLS NOP", \ + [FC_RCTL_BA_ABTS] = "BLS abort", \ + [FC_RCTL_BA_RMC] = "BLS remove connection", \ + [FC_RCTL_BA_ACC] = "BLS accept", \ + [FC_RCTL_BA_RJT] = "BLS reject", \ + [FC_RCTL_BA_PRMT] = "BLS dedicated connection preempted", \ + [FC_RCTL_ACK_1] = "LC ACK_1", \ + [FC_RCTL_ACK_0] = "LC ACK_0", \ + [FC_RCTL_P_RJT] = "LC port reject", \ + [FC_RCTL_F_RJT] = "LC fabric reject", \ + [FC_RCTL_P_BSY] = "LC port busy", \ + [FC_RCTL_F_BSY] = "LC fabric busy to data frame", \ + [FC_RCTL_F_BSYL] = "LC fabric busy to link control frame",\ + [FC_RCTL_LCR] = "LC link credit reset", \ + [FC_RCTL_END] = "LC end", \ +} + +/* + * Well-known fabric addresses. + */ +enum fc_well_known_fid { + FC_FID_BCAST = 0xffffff, /* broadcast */ + FC_FID_FLOGI = 0xfffffe, /* fabric login */ + FC_FID_FCTRL = 0xfffffd, /* fabric controller */ + FC_FID_DIR_SERV = 0xfffffc, /* directory server */ + FC_FID_TIME_SERV = 0xfffffb, /* time server */ + FC_FID_MGMT_SERV = 0xfffffa, /* management server */ + FC_FID_QOS = 0xfffff9, /* QoS Facilitator */ + FC_FID_ALIASES = 0xfffff8, /* alias server (FC-PH2) */ + FC_FID_SEC_KEY = 0xfffff7, /* Security key dist. server */ + FC_FID_CLOCK = 0xfffff6, /* clock synch server */ + FC_FID_MCAST_SERV = 0xfffff5, /* multicast server */ +}; + +#define FC_FID_WELL_KNOWN_MAX 0xffffff /* highest well-known fabric ID */ +#define FC_FID_WELL_KNOWN_BASE 0xfffff5 /* start of well-known fabric ID */ + +/* + * Other well-known addresses, outside the above contiguous range. + */ +#define FC_FID_DOM_MGR 0xfffc00 /* domain manager base */ + +/* + * Fabric ID bytes. + */ +#define FC_FID_DOMAIN 0 +#define FC_FID_PORT 1 +#define FC_FID_LINK 2 + +/* + * fh_type codes + */ +enum fc_fh_type { + FC_TYPE_BLS = 0x00, /* basic link service */ + FC_TYPE_ELS = 0x01, /* extended link service */ + FC_TYPE_IP = 0x05, /* IP over FC, RFC 4338 */ + FC_TYPE_FCP = 0x08, /* SCSI FCP */ + FC_TYPE_CT = 0x20, /* Fibre Channel Services (FC-CT) */ + FC_TYPE_ILS = 0x22, /* internal link service */ +}; + +/* + * FC_TYPE names initializer. + * Please keep this matching the above definitions. + */ +#define FC_TYPE_NAMES_INIT { \ + [FC_TYPE_BLS] = "BLS", \ + [FC_TYPE_ELS] = "ELS", \ + [FC_TYPE_IP] = "IP", \ + [FC_TYPE_FCP] = "FCP", \ + [FC_TYPE_CT] = "CT", \ + [FC_TYPE_ILS] = "ILS", \ +} + +/* + * Exchange IDs. + */ +#define FC_XID_UNKNOWN 0xffff /* unknown exchange ID */ +#define FC_XID_MIN 0x0 /* supported min exchange ID */ +#define FC_XID_MAX 0xfffe /* supported max exchange ID */ + +/* + * fh_f_ctl - Frame control flags. + */ +#define FC_FC_EX_CTX (1 << 23) /* sent by responder to exchange */ +#define FC_FC_SEQ_CTX (1 << 22) /* sent by responder to sequence */ +#define FC_FC_FIRST_SEQ (1 << 21) /* first sequence of this exchange */ +#define FC_FC_LAST_SEQ (1 << 20) /* last sequence of this exchange */ +#define FC_FC_END_SEQ (1 << 19) /* last frame of sequence */ +#define FC_FC_END_CONN (1 << 18) /* end of class 1 connection pending */ +#define FC_FC_RES_B17 (1 << 17) /* reserved */ +#define FC_FC_SEQ_INIT (1 << 16) /* transfer of sequence initiative */ +#define FC_FC_X_ID_REASS (1 << 15) /* exchange ID has been changed */ +#define FC_FC_X_ID_INVAL (1 << 14) /* exchange ID invalidated */ + +#define FC_FC_ACK_1 (1 << 12) /* 13:12 = 1: ACK_1 expected */ +#define FC_FC_ACK_N (2 << 12) /* 13:12 = 2: ACK_N expected */ +#define FC_FC_ACK_0 (3 << 12) /* 13:12 = 3: ACK_0 expected */ + +#define FC_FC_RES_B11 (1 << 11) /* reserved */ +#define FC_FC_RES_B10 (1 << 10) /* reserved */ +#define FC_FC_RETX_SEQ (1 << 9) /* retransmitted sequence */ +#define FC_FC_UNI_TX (1 << 8) /* unidirectional transmit (class 1) */ +#define FC_FC_CONT_SEQ(i) ((i) << 6) +#define FC_FC_ABT_SEQ(i) ((i) << 4) +#define FC_FC_REL_OFF (1 << 3) /* parameter is relative offset */ +#define FC_FC_RES2 (1 << 2) /* reserved */ +#define FC_FC_FILL(i) ((i) & 3) /* 1:0: bytes of trailing fill */ + +/* + * BA_ACC payload. + */ +struct fc_ba_acc { + __u8 ba_seq_id_val; /* SEQ_ID validity */ +#define FC_BA_SEQ_ID_VAL 0x80 + __u8 ba_seq_id; /* SEQ_ID of seq last deliverable */ + __u8 ba_resvd[2]; /* reserved */ + __be16 ba_ox_id; /* OX_ID for aborted seq or exch */ + __be16 ba_rx_id; /* RX_ID for aborted seq or exch */ + __be16 ba_low_seq_cnt; /* low SEQ_CNT of aborted seq */ + __be16 ba_high_seq_cnt; /* high SEQ_CNT of aborted seq */ +}; + +/* + * BA_RJT: Basic Reject payload. + */ +struct fc_ba_rjt { + __u8 br_resvd; /* reserved */ + __u8 br_reason; /* reason code */ + __u8 br_explan; /* reason explanation */ + __u8 br_vendor; /* vendor unique code */ +}; + +/* + * BA_RJT reason codes. + * From FS-2. + */ +enum fc_ba_rjt_reason { + FC_BA_RJT_NONE = 0, /* in software this means no reject */ + FC_BA_RJT_INVL_CMD = 0x01, /* invalid command code */ + FC_BA_RJT_LOG_ERR = 0x03, /* logical error */ + FC_BA_RJT_LOG_BUSY = 0x05, /* logical busy */ + FC_BA_RJT_PROTO_ERR = 0x07, /* protocol error */ + FC_BA_RJT_UNABLE = 0x09, /* unable to perform request */ + FC_BA_RJT_VENDOR = 0xff, /* vendor-specific (see br_vendor) */ +}; + +/* + * BA_RJT reason code explanations. + */ +enum fc_ba_rjt_explan { + FC_BA_RJT_EXP_NONE = 0x00, /* no additional expanation */ + FC_BA_RJT_INV_XID = 0x03, /* invalid OX_ID-RX_ID combination */ + FC_BA_RJT_ABT = 0x05, /* sequence aborted, no seq info */ +}; + +/* + * P_RJT or F_RJT: Port Reject or Fabric Reject parameter field. + */ +struct fc_pf_rjt { + __u8 rj_action; /* reserved */ + __u8 rj_reason; /* reason code */ + __u8 rj_resvd; /* reserved */ + __u8 rj_vendor; /* vendor unique code */ +}; + +/* + * P_RJT and F_RJT reject reason codes. + */ +enum fc_pf_rjt_reason { + FC_RJT_NONE = 0, /* non-reject (reserved by standard) */ + FC_RJT_INVL_DID = 0x01, /* invalid destination ID */ + FC_RJT_INVL_SID = 0x02, /* invalid source ID */ + FC_RJT_P_UNAV_T = 0x03, /* port unavailable, temporary */ + FC_RJT_P_UNAV = 0x04, /* port unavailable, permanent */ + FC_RJT_CLS_UNSUP = 0x05, /* class not supported */ + FC_RJT_DEL_USAGE = 0x06, /* delimiter usage error */ + FC_RJT_TYPE_UNSUP = 0x07, /* type not supported */ + FC_RJT_LINK_CTL = 0x08, /* invalid link control */ + FC_RJT_R_CTL = 0x09, /* invalid R_CTL field */ + FC_RJT_F_CTL = 0x0a, /* invalid F_CTL field */ + FC_RJT_OX_ID = 0x0b, /* invalid originator exchange ID */ + FC_RJT_RX_ID = 0x0c, /* invalid responder exchange ID */ + FC_RJT_SEQ_ID = 0x0d, /* invalid sequence ID */ + FC_RJT_DF_CTL = 0x0e, /* invalid DF_CTL field */ + FC_RJT_SEQ_CNT = 0x0f, /* invalid SEQ_CNT field */ + FC_RJT_PARAM = 0x10, /* invalid parameter field */ + FC_RJT_EXCH_ERR = 0x11, /* exchange error */ + FC_RJT_PROTO = 0x12, /* protocol error */ + FC_RJT_LEN = 0x13, /* incorrect length */ + FC_RJT_UNEXP_ACK = 0x14, /* unexpected ACK */ + FC_RJT_FAB_CLASS = 0x15, /* class unsupported by fabric entity */ + FC_RJT_LOGI_REQ = 0x16, /* login required */ + FC_RJT_SEQ_XS = 0x17, /* excessive sequences attempted */ + FC_RJT_EXCH_EST = 0x18, /* unable to establish exchange */ + FC_RJT_FAB_UNAV = 0x1a, /* fabric unavailable */ + FC_RJT_VC_ID = 0x1b, /* invalid VC_ID (class 4) */ + FC_RJT_CS_CTL = 0x1c, /* invalid CS_CTL field */ + FC_RJT_INSUF_RES = 0x1d, /* insuff. resources for VC (Class 4) */ + FC_RJT_INVL_CLS = 0x1f, /* invalid class of service */ + FC_RJT_PREEMT_RJT = 0x20, /* preemption request rejected */ + FC_RJT_PREEMT_DIS = 0x21, /* preemption not enabled */ + FC_RJT_MCAST_ERR = 0x22, /* multicast error */ + FC_RJT_MCAST_ET = 0x23, /* multicast error terminate */ + FC_RJT_PRLI_REQ = 0x24, /* process login required */ + FC_RJT_INVL_ATT = 0x25, /* invalid attachment */ + FC_RJT_VENDOR = 0xff, /* vendor specific reject */ +}; + +#endif /* _FC_FS_H_ */ diff --git a/include/scsi/fc/fc_gs.h b/include/scsi/fc/fc_gs.h new file mode 100644 index 00000000000..ffab0272c65 --- /dev/null +++ b/include/scsi/fc/fc_gs.h @@ -0,0 +1,93 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_GS_H_ +#define _FC_GS_H_ + +/* + * Fibre Channel Services - Common Transport. + * From T11.org FC-GS-2 Rev 5.3 November 1998. + */ + +struct fc_ct_hdr { + __u8 ct_rev; /* revision */ + __u8 ct_in_id[3]; /* N_Port ID of original requestor */ + __u8 ct_fs_type; /* type of fibre channel service */ + __u8 ct_fs_subtype; /* subtype */ + __u8 ct_options; + __u8 _ct_resvd1; + __be16 ct_cmd; /* command / response code */ + __be16 ct_mr_size; /* maximum / residual size */ + __u8 _ct_resvd2; + __u8 ct_reason; /* reject reason */ + __u8 ct_explan; /* reason code explanation */ + __u8 ct_vendor; /* vendor unique data */ +}; + +#define FC_CT_HDR_LEN 16 /* expected sizeof (struct fc_ct_hdr) */ + +enum fc_ct_rev { + FC_CT_REV = 1 /* common transport revision */ +}; + +/* + * ct_fs_type values. + */ +enum fc_ct_fs_type { + FC_FST_ALIAS = 0xf8, /* alias service */ + FC_FST_MGMT = 0xfa, /* management service */ + FC_FST_TIME = 0xfb, /* time service */ + FC_FST_DIR = 0xfc, /* directory service */ +}; + +/* + * ct_cmd: Command / response codes + */ +enum fc_ct_cmd { + FC_FS_RJT = 0x8001, /* reject */ + FC_FS_ACC = 0x8002, /* accept */ +}; + +/* + * FS_RJT reason codes. + */ +enum fc_ct_reason { + FC_FS_RJT_CMD = 0x01, /* invalid command code */ + FC_FS_RJT_VER = 0x02, /* invalid version level */ + FC_FS_RJT_LOG = 0x03, /* logical error */ + FC_FS_RJT_IUSIZ = 0x04, /* invalid IU size */ + FC_FS_RJT_BSY = 0x05, /* logical busy */ + FC_FS_RJT_PROTO = 0x07, /* protocol error */ + FC_FS_RJT_UNABL = 0x09, /* unable to perform command request */ + FC_FS_RJT_UNSUP = 0x0b, /* command not supported */ +}; + +/* + * FS_RJT reason code explanations. + */ +enum fc_ct_explan { + FC_FS_EXP_NONE = 0x00, /* no additional explanation */ + FC_FS_EXP_PID = 0x01, /* port ID not registered */ + FC_FS_EXP_PNAM = 0x02, /* port name not registered */ + FC_FS_EXP_NNAM = 0x03, /* node name not registered */ + FC_FS_EXP_COS = 0x04, /* class of service not registered */ + /* definitions not complete */ +}; + +#endif /* _FC_GS_H_ */ diff --git a/include/scsi/fc/fc_ns.h b/include/scsi/fc/fc_ns.h new file mode 100644 index 00000000000..790d7b97d4b --- /dev/null +++ b/include/scsi/fc/fc_ns.h @@ -0,0 +1,159 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_NS_H_ +#define _FC_NS_H_ + +/* + * Fibre Channel Services - Name Service (dNS) + * From T11.org FC-GS-2 Rev 5.3 November 1998. + */ + +/* + * Common-transport sub-type for Name Server. + */ +#define FC_NS_SUBTYPE 2 /* fs_ct_hdr.ct_fs_subtype */ + +/* + * Name server Requests. + * Note: this is an incomplete list, some unused requests are omitted. + */ +enum fc_ns_req { + FC_NS_GA_NXT = 0x0100, /* get all next */ + FC_NS_GI_A = 0x0101, /* get identifiers - scope */ + FC_NS_GPN_ID = 0x0112, /* get port name by ID */ + FC_NS_GNN_ID = 0x0113, /* get node name by ID */ + FC_NS_GID_PN = 0x0121, /* get ID for port name */ + FC_NS_GID_NN = 0x0131, /* get IDs for node name */ + FC_NS_GID_FT = 0x0171, /* get IDs by FC4 type */ + FC_NS_GPN_FT = 0x0172, /* get port names by FC4 type */ + FC_NS_GID_PT = 0x01a1, /* get IDs by port type */ + FC_NS_RFT_ID = 0x0217, /* reg FC4 type for ID */ + FC_NS_RPN_ID = 0x0212, /* reg port name for ID */ + FC_NS_RNN_ID = 0x0213, /* reg node name for ID */ +}; + +/* + * Port type values. + */ +enum fc_ns_pt { + FC_NS_UNID_PORT = 0x00, /* unidentified */ + FC_NS_N_PORT = 0x01, /* N port */ + FC_NS_NL_PORT = 0x02, /* NL port */ + FC_NS_FNL_PORT = 0x03, /* F/NL port */ + FC_NS_NX_PORT = 0x7f, /* Nx port */ + FC_NS_F_PORT = 0x81, /* F port */ + FC_NS_FL_PORT = 0x82, /* FL port */ + FC_NS_E_PORT = 0x84, /* E port */ + FC_NS_B_PORT = 0x85, /* B port */ +}; + +/* + * Port type object. + */ +struct fc_ns_pt_obj { + __u8 pt_type; +}; + +/* + * Port ID object + */ +struct fc_ns_fid { + __u8 fp_flags; /* flags for responses only */ + __u8 fp_fid[3]; +}; + +/* + * fp_flags in port ID object, for responses only. + */ +#define FC_NS_FID_LAST 0x80 /* last object */ + +/* + * FC4-types object. + */ +#define FC_NS_TYPES 256 /* number of possible FC-4 types */ +#define FC_NS_BPW 32 /* bits per word in bitmap */ + +struct fc_ns_fts { + __be32 ff_type_map[FC_NS_TYPES / FC_NS_BPW]; /* bitmap of FC-4 types */ +}; + +/* + * GID_PT request. + */ +struct fc_ns_gid_pt { + __u8 fn_pt_type; + __u8 fn_domain_id_scope; + __u8 fn_area_id_scope; + __u8 fn_resvd; +}; + +/* + * GID_FT or GPN_FT request. + */ +struct fc_ns_gid_ft { + __u8 fn_resvd; + __u8 fn_domain_id_scope; + __u8 fn_area_id_scope; + __u8 fn_fc4_type; +}; + +/* + * GPN_FT response. + */ +struct fc_gpn_ft_resp { + __u8 fp_flags; /* see fp_flags definitions above */ + __u8 fp_fid[3]; /* port ID */ + __be32 fp_resvd; + __be64 fp_wwpn; /* port name */ +}; + +/* + * GID_PN request + */ +struct fc_ns_gid_pn { + __be64 fn_wwpn; /* port name */ +}; + +/* + * GID_PN response + */ +struct fc_gid_pn_resp { + __u8 fp_resvd; + __u8 fp_fid[3]; /* port ID */ +}; + +/* + * RFT_ID request - register FC-4 types for ID. + */ +struct fc_ns_rft_id { + struct fc_ns_fid fr_fid; /* port ID object */ + struct fc_ns_fts fr_fts; /* FC-4 types object */ +}; + +/* + * RPN_ID request - register port name for ID. + * RNN_ID request - register node name for ID. + */ +struct fc_ns_rn_id { + struct fc_ns_fid fr_fid; /* port ID object */ + __be64 fr_wwn; /* node name or port name */ +} __attribute__((__packed__)); + +#endif /* _FC_NS_H_ */ -- cgit v1.2.3 From 42e9a92fe6a9095bd68a379aaec7ad2be0337f7a Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 9 Dec 2008 15:10:17 -0800 Subject: [SCSI] libfc: A modular Fibre Channel library libFC is composed of 4 blocks supported by an exchange manager and a framing library. The upper 4 layers are fc_lport, fc_disc, fc_rport and fc_fcp. A LLD that uses libfc could choose to either use libfc's block, or using the transport template defined in libfc.h, override one or more blocks with its own implementation. The EM (Exchange Manager) manages exhcanges/sequences for all commands- ELS, CT and FCP. The framing library frames ELS and CT commands. The fc_lport block manages the library's representation of the host's FC enabled ports. The fc_disc block manages discovery of targets as well as handling changes that occur in the FC fabric (via. RSCN events). The fc_rport block manages the library's representation of other entities in the FC fabric. Currently the library uses this block for targets, its peer when in point-to-point mode and the directory server, but can be extended for other entities if needed. The fc_fcp block interacts with the scsi-ml and handles all I/O. Signed-off-by: Robert Love [jejb: added include of delay.h to fix ppc64 compile prob spotted by sfr] Signed-off-by: James Bottomley --- include/scsi/fc_encode.h | 309 ++++++++++++++++ include/scsi/fc_frame.h | 242 ++++++++++++ include/scsi/libfc.h | 938 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1489 insertions(+) create mode 100644 include/scsi/fc_encode.h create mode 100644 include/scsi/fc_frame.h create mode 100644 include/scsi/libfc.h (limited to 'include') diff --git a/include/scsi/fc_encode.h b/include/scsi/fc_encode.h new file mode 100644 index 00000000000..6300f556bce --- /dev/null +++ b/include/scsi/fc_encode.h @@ -0,0 +1,309 @@ +/* + * Copyright(c) 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_ENCODE_H_ +#define _FC_ENCODE_H_ +#include + +struct fc_ns_rft { + struct fc_ns_fid fid; /* port ID object */ + struct fc_ns_fts fts; /* FC4-types object */ +}; + +struct fc_ct_req { + struct fc_ct_hdr hdr; + union { + struct fc_ns_gid_ft gid; + struct fc_ns_rn_id rn; + struct fc_ns_rft rft; + } payload; +}; + +/** + * fill FC header fields in specified fc_frame + */ +static inline void fc_fill_fc_hdr(struct fc_frame *fp, enum fc_rctl r_ctl, + u32 did, u32 sid, enum fc_fh_type type, + u32 f_ctl, u32 parm_offset) +{ + struct fc_frame_header *fh; + + fh = fc_frame_header_get(fp); + WARN_ON(r_ctl == 0); + fh->fh_r_ctl = r_ctl; + hton24(fh->fh_d_id, did); + hton24(fh->fh_s_id, sid); + fh->fh_type = type; + hton24(fh->fh_f_ctl, f_ctl); + fh->fh_cs_ctl = 0; + fh->fh_df_ctl = 0; + fh->fh_parm_offset = htonl(parm_offset); +} + +/** + * fc_ct_hdr_fill- fills ct header and reset ct payload + * returns pointer to ct request. + */ +static inline struct fc_ct_req *fc_ct_hdr_fill(const struct fc_frame *fp, + unsigned int op, size_t req_size) +{ + struct fc_ct_req *ct; + size_t ct_plen; + + ct_plen = sizeof(struct fc_ct_hdr) + req_size; + ct = fc_frame_payload_get(fp, ct_plen); + memset(ct, 0, ct_plen); + ct->hdr.ct_rev = FC_CT_REV; + ct->hdr.ct_fs_type = FC_FST_DIR; + ct->hdr.ct_fs_subtype = FC_NS_SUBTYPE; + ct->hdr.ct_cmd = htons((u16) op); + return ct; +} + +/** + * fc_ct_fill - Fill in a name service request frame + */ +static inline int fc_ct_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op, enum fc_rctl *r_ctl, u32 *did, + enum fc_fh_type *fh_type) +{ + struct fc_ct_req *ct; + + switch (op) { + case FC_NS_GPN_FT: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_gid_ft)); + ct->payload.gid.fn_fc4_type = FC_TYPE_FCP; + break; + + case FC_NS_RFT_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rft)); + hton24(ct->payload.rft.fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + break; + + case FC_NS_RPN_ID: + ct = fc_ct_hdr_fill(fp, op, sizeof(struct fc_ns_rn_id)); + hton24(ct->payload.rn.fr_fid.fp_fid, + fc_host_port_id(lport->host)); + ct->payload.rft.fts = lport->fcts; + put_unaligned_be64(lport->wwpn, &ct->payload.rn.fr_wwn); + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + *r_ctl = FC_RCTL_DD_UNSOL_CTL; + *did = FC_FID_DIR_SERV; + *fh_type = FC_TYPE_CT; + return 0; +} + +/** + * fc_plogi_fill - Fill in plogi request frame + */ +static inline void fc_plogi_fill(struct fc_lport *lport, struct fc_frame *fp, + unsigned int op) +{ + struct fc_els_flogi *plogi; + struct fc_els_csp *csp; + struct fc_els_cssp *cp; + + plogi = fc_frame_payload_get(fp, sizeof(*plogi)); + memset(plogi, 0, sizeof(*plogi)); + plogi->fl_cmd = (u8) op; + put_unaligned_be64(lport->wwpn, &plogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &plogi->fl_wwnn); + + csp = &plogi->fl_csp; + csp->sp_hi_ver = 0x20; + csp->sp_lo_ver = 0x20; + csp->sp_bb_cred = htons(10); /* this gets set by gateway */ + csp->sp_bb_data = htons((u16) lport->mfs); + cp = &plogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); + csp->sp_features = htons(FC_SP_FT_CIRO); + csp->sp_tot_seq = htons(255); /* seq. we accept */ + csp->sp_rel_off = htons(0x1f); + csp->sp_e_d_tov = htonl(lport->e_d_tov); + + cp->cp_rdfs = htons((u16) lport->mfs); + cp->cp_con_seq = htons(255); + cp->cp_open_seq = 1; +} + +/** + * fc_flogi_fill - Fill in a flogi request frame. + */ +static inline void fc_flogi_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_csp *sp; + struct fc_els_cssp *cp; + struct fc_els_flogi *flogi; + + flogi = fc_frame_payload_get(fp, sizeof(*flogi)); + memset(flogi, 0, sizeof(*flogi)); + flogi->fl_cmd = (u8) ELS_FLOGI; + put_unaligned_be64(lport->wwpn, &flogi->fl_wwpn); + put_unaligned_be64(lport->wwnn, &flogi->fl_wwnn); + sp = &flogi->fl_csp; + sp->sp_hi_ver = 0x20; + sp->sp_lo_ver = 0x20; + sp->sp_bb_cred = htons(10); /* this gets set by gateway */ + sp->sp_bb_data = htons((u16) lport->mfs); + cp = &flogi->fl_cssp[3 - 1]; /* class 3 parameters */ + cp->cp_class = htons(FC_CPC_VALID | FC_CPC_SEQ); +} + +/** + * fc_logo_fill - Fill in a logo request frame. + */ +static inline void fc_logo_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_logo *logo; + + logo = fc_frame_payload_get(fp, sizeof(*logo)); + memset(logo, 0, sizeof(*logo)); + logo->fl_cmd = ELS_LOGO; + hton24(logo->fl_n_port_id, fc_host_port_id(lport->host)); + logo->fl_n_port_wwn = htonll(lport->wwpn); +} + +/** + * fc_rtv_fill - Fill in RTV (read timeout value) request frame. + */ +static inline void fc_rtv_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rtv *rtv; + + rtv = fc_frame_payload_get(fp, sizeof(*rtv)); + memset(rtv, 0, sizeof(*rtv)); + rtv->rtv_cmd = ELS_RTV; +} + +/** + * fc_rec_fill - Fill in rec request frame + */ +static inline void fc_rec_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_rec *rec; + struct fc_exch *ep = fc_seq_exch(fr_seq(fp)); + + rec = fc_frame_payload_get(fp, sizeof(*rec)); + memset(rec, 0, sizeof(*rec)); + rec->rec_cmd = ELS_REC; + hton24(rec->rec_s_id, fc_host_port_id(lport->host)); + rec->rec_ox_id = htons(ep->oxid); + rec->rec_rx_id = htons(ep->rxid); +} + +/** + * fc_prli_fill - Fill in prli request frame + */ +static inline void fc_prli_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct { + struct fc_els_prli prli; + struct fc_els_spp spp; + } *pp; + + pp = fc_frame_payload_get(fp, sizeof(*pp)); + memset(pp, 0, sizeof(*pp)); + pp->prli.prli_cmd = ELS_PRLI; + pp->prli.prli_spp_len = sizeof(struct fc_els_spp); + pp->prli.prli_len = htons(sizeof(*pp)); + pp->spp.spp_type = FC_TYPE_FCP; + pp->spp.spp_flags = FC_SPP_EST_IMG_PAIR; + pp->spp.spp_params = htonl(lport->service_params); +} + +/** + * fc_scr_fill - Fill in a scr request frame. + */ +static inline void fc_scr_fill(struct fc_lport *lport, struct fc_frame *fp) +{ + struct fc_els_scr *scr; + + scr = fc_frame_payload_get(fp, sizeof(*scr)); + memset(scr, 0, sizeof(*scr)); + scr->scr_cmd = ELS_SCR; + scr->scr_reg_func = ELS_SCRF_FULL; +} + +/** + * fc_els_fill - Fill in an ELS request frame + */ +static inline int fc_els_fill(struct fc_lport *lport, struct fc_rport *rport, + struct fc_frame *fp, unsigned int op, + enum fc_rctl *r_ctl, u32 *did, enum fc_fh_type *fh_type) +{ + switch (op) { + case ELS_PLOGI: + fc_plogi_fill(lport, fp, ELS_PLOGI); + *did = rport->port_id; + break; + + case ELS_FLOGI: + fc_flogi_fill(lport, fp); + *did = FC_FID_FLOGI; + break; + + case ELS_LOGO: + fc_logo_fill(lport, fp); + *did = FC_FID_FLOGI; + /* + * if rport is valid then it + * is port logo, therefore + * set did to rport id. + */ + if (rport) + *did = rport->port_id; + break; + + case ELS_RTV: + fc_rtv_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_REC: + fc_rec_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_PRLI: + fc_prli_fill(lport, fp); + *did = rport->port_id; + break; + + case ELS_SCR: + fc_scr_fill(lport, fp); + *did = FC_FID_FCTRL; + break; + + default: + FC_DBG("Invalid op code %x \n", op); + return -EINVAL; + } + + *r_ctl = FC_RCTL_ELS_REQ; + *fh_type = FC_TYPE_ELS; + return 0; +} +#endif /* _FC_ENCODE_H_ */ diff --git a/include/scsi/fc_frame.h b/include/scsi/fc_frame.h new file mode 100644 index 00000000000..04d34a71355 --- /dev/null +++ b/include/scsi/fc_frame.h @@ -0,0 +1,242 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _FC_FRAME_H_ +#define _FC_FRAME_H_ + +#include +#include +#include + +#include +#include +#include + +/* + * The fc_frame interface is used to pass frame data between functions. + * The frame includes the data buffer, length, and SOF / EOF delimiter types. + * A pointer to the port structure of the receiving port is also includeded. + */ + +#define FC_FRAME_HEADROOM 32 /* headroom for VLAN + FCoE headers */ +#define FC_FRAME_TAILROOM 8 /* trailer space for FCoE */ + +/* + * Information about an individual fibre channel frame received or to be sent. + * The buffer may be in up to 4 additional non-contiguous sections, + * but the linear section must hold the frame header. + */ +#define FC_FRAME_SG_LEN 4 /* scatter/gather list maximum length */ + +#define fp_skb(fp) (&((fp)->skb)) +#define fr_hdr(fp) ((fp)->skb.data) +#define fr_len(fp) ((fp)->skb.len) +#define fr_cb(fp) ((struct fcoe_rcv_info *)&((fp)->skb.cb[0])) +#define fr_dev(fp) (fr_cb(fp)->fr_dev) +#define fr_seq(fp) (fr_cb(fp)->fr_seq) +#define fr_sof(fp) (fr_cb(fp)->fr_sof) +#define fr_eof(fp) (fr_cb(fp)->fr_eof) +#define fr_flags(fp) (fr_cb(fp)->fr_flags) +#define fr_max_payload(fp) (fr_cb(fp)->fr_max_payload) +#define fr_cmd(fp) (fr_cb(fp)->fr_cmd) +#define fr_dir(fp) (fr_cmd(fp)->sc_data_direction) +#define fr_crc(fp) (fr_cb(fp)->fr_crc) + +struct fc_frame { + struct sk_buff skb; +}; + +struct fcoe_rcv_info { + struct packet_type *ptype; + struct fc_lport *fr_dev; /* transport layer private pointer */ + struct fc_seq *fr_seq; /* for use with exchange manager */ + struct scsi_cmnd *fr_cmd; /* for use of scsi command */ + u32 fr_crc; + u16 fr_max_payload; /* max FC payload */ + enum fc_sof fr_sof; /* start of frame delimiter */ + enum fc_eof fr_eof; /* end of frame delimiter */ + u8 fr_flags; /* flags - see below */ +}; + + +/* + * Get fc_frame pointer for an skb that's already been imported. + */ +static inline struct fcoe_rcv_info *fcoe_dev_from_skb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct fcoe_rcv_info) > sizeof(skb->cb)); + return (struct fcoe_rcv_info *) skb->cb; +} + +/* + * fr_flags. + */ +#define FCPHF_CRC_UNCHECKED 0x01 /* CRC not computed, still appended */ + +/* + * Initialize a frame. + * We don't do a complete memset here for performance reasons. + * The caller must set fr_free, fr_hdr, fr_len, fr_sof, and fr_eof eventually. + */ +static inline void fc_frame_init(struct fc_frame *fp) +{ + fr_dev(fp) = NULL; + fr_seq(fp) = NULL; + fr_flags(fp) = 0; +} + +struct fc_frame *fc_frame_alloc_fill(struct fc_lport *, size_t payload_len); + +struct fc_frame *__fc_frame_alloc(size_t payload_len); + +/* + * Get frame for sending via port. + */ +static inline struct fc_frame *_fc_frame_alloc(struct fc_lport *dev, + size_t payload_len) +{ + return __fc_frame_alloc(payload_len); +} + +/* + * Allocate fc_frame structure and buffer. Set the initial length to + * payload_size + sizeof (struct fc_frame_header). + */ +static inline struct fc_frame *fc_frame_alloc(struct fc_lport *dev, size_t len) +{ + struct fc_frame *fp; + + /* + * Note: Since len will often be a constant multiple of 4, + * this check will usually be evaluated and eliminated at compile time. + */ + if ((len % 4) != 0) + fp = fc_frame_alloc_fill(dev, len); + else + fp = _fc_frame_alloc(dev, len); + return fp; +} + +/* + * Free the fc_frame structure and buffer. + */ +static inline void fc_frame_free(struct fc_frame *fp) +{ + kfree_skb(fp_skb(fp)); +} + +static inline int fc_frame_is_linear(struct fc_frame *fp) +{ + return !skb_is_nonlinear(fp_skb(fp)); +} + +/* + * Get frame header from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + */ +static inline +struct fc_frame_header *fc_frame_header_get(const struct fc_frame *fp) +{ + WARN_ON(fr_len(fp) < sizeof(struct fc_frame_header)); + return (struct fc_frame_header *) fr_hdr(fp); +} + +/* + * Get frame payload from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. + * The len parameter is the minimum length for the payload portion. + * Returns NULL if the frame is too short. + * + * This assumes the interesting part of the payload is in the first part + * of the buffer for received data. This may not be appropriate to use for + * buffers being transmitted. + */ +static inline void *fc_frame_payload_get(const struct fc_frame *fp, + size_t len) +{ + void *pp = NULL; + + if (fr_len(fp) >= sizeof(struct fc_frame_header) + len) + pp = fc_frame_header_get(fp) + 1; + return pp; +} + +/* + * Get frame payload opcode (first byte) from message in fc_frame structure. + * This hides a cast and provides a place to add some checking. Return 0 + * if the frame has no payload. + */ +static inline u8 fc_frame_payload_op(const struct fc_frame *fp) +{ + u8 *cp; + + cp = fc_frame_payload_get(fp, sizeof(u8)); + if (!cp) + return 0; + return *cp; + +} + +/* + * Get FC class from frame. + */ +static inline enum fc_class fc_frame_class(const struct fc_frame *fp) +{ + return fc_sof_class(fr_sof(fp)); +} + +/* + * Check the CRC in a frame. + * The CRC immediately follows the last data item *AFTER* the length. + * The return value is zero if the CRC matches. + */ +u32 fc_frame_crc_check(struct fc_frame *); + +static inline u8 fc_frame_rctl(const struct fc_frame *fp) +{ + return fc_frame_header_get(fp)->fh_r_ctl; +} + +static inline bool fc_frame_is_cmd(const struct fc_frame *fp) +{ + return fc_frame_rctl(fp) == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool fc_frame_is_read(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_FROM_DEVICE; + return false; +} + +static inline bool fc_frame_is_write(const struct fc_frame *fp) +{ + if (fc_frame_is_cmd(fp) && fr_cmd(fp)) + return fr_dir(fp) == DMA_TO_DEVICE; + return false; +} + +/* + * Check for leaks. + * Print the frame header of any currently allocated frame, assuming there + * should be none at this point. + */ +void fc_frame_leak_check(void); + +#endif /* _FC_FRAME_H_ */ diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h new file mode 100644 index 00000000000..9f2876397dd --- /dev/null +++ b/include/scsi/libfc.h @@ -0,0 +1,938 @@ +/* + * Copyright(c) 2007 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFC_H_ +#define _LIBFC_H_ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#define LIBFC_DEBUG + +#ifdef LIBFC_DEBUG +/* Log messages */ +#define FC_DBG(fmt, args...) \ + do { \ + printk(KERN_INFO "%s " fmt, __func__, ##args); \ + } while (0) +#else +#define FC_DBG(fmt, args...) +#endif + +/* + * libfc error codes + */ +#define FC_NO_ERR 0 /* no error */ +#define FC_EX_TIMEOUT 1 /* Exchange timeout */ +#define FC_EX_CLOSED 2 /* Exchange closed */ + +/* some helpful macros */ + +#define ntohll(x) be64_to_cpu(x) +#define htonll(x) cpu_to_be64(x) + +#define ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2])) + +#define hton24(p, v) do { \ + p[0] = (((v) >> 16) & 0xFF); \ + p[1] = (((v) >> 8) & 0xFF); \ + p[2] = ((v) & 0xFF); \ + } while (0) + +/* + * FC HBA status + */ +#define FC_PAUSE (1 << 1) +#define FC_LINK_UP (1 << 0) + +enum fc_lport_state { + LPORT_ST_NONE = 0, + LPORT_ST_FLOGI, + LPORT_ST_DNS, + LPORT_ST_RPN_ID, + LPORT_ST_RFT_ID, + LPORT_ST_SCR, + LPORT_ST_READY, + LPORT_ST_LOGO, + LPORT_ST_RESET +}; + +enum fc_disc_event { + DISC_EV_NONE = 0, + DISC_EV_SUCCESS, + DISC_EV_FAILED +}; + +enum fc_rport_state { + RPORT_ST_NONE = 0, + RPORT_ST_INIT, /* initialized */ + RPORT_ST_PLOGI, /* waiting for PLOGI completion */ + RPORT_ST_PRLI, /* waiting for PRLI completion */ + RPORT_ST_RTV, /* waiting for RTV completion */ + RPORT_ST_READY, /* ready for use */ + RPORT_ST_LOGO, /* port logout sent */ +}; + +enum fc_rport_trans_state { + FC_PORTSTATE_ROGUE, + FC_PORTSTATE_REAL, +}; + +/** + * struct fc_disc_port - temporary discovery port to hold rport identifiers + * @lp: Fibre Channel host port instance + * @peers: node for list management during discovery and RSCN processing + * @ids: identifiers structure to pass to fc_remote_port_add() + * @rport_work: work struct for starting the rport state machine + */ +struct fc_disc_port { + struct fc_lport *lp; + struct list_head peers; + struct fc_rport_identifiers ids; + struct work_struct rport_work; +}; + +enum fc_rport_event { + RPORT_EV_NONE = 0, + RPORT_EV_CREATED, + RPORT_EV_FAILED, + RPORT_EV_STOP, + RPORT_EV_LOGO +}; + +struct fc_rport_operations { + void (*event_callback)(struct fc_lport *, struct fc_rport *, + enum fc_rport_event); +}; + +/** + * struct fc_rport_libfc_priv - libfc internal information about a remote port + * @local_port: Fibre Channel host port instance + * @rp_state: state tracks progress of PLOGI, PRLI, and RTV exchanges + * @flags: REC and RETRY supported flags + * @max_seq: maximum number of concurrent sequences + * @retries: retry count in current state + * @e_d_tov: error detect timeout value (in msec) + * @r_a_tov: resource allocation timeout value (in msec) + * @rp_mutex: mutex protects rport + * @retry_work: + * @event_callback: Callback for rport READY, FAILED or LOGO + */ +struct fc_rport_libfc_priv { + struct fc_lport *local_port; + enum fc_rport_state rp_state; + u16 flags; + #define FC_RP_FLAGS_REC_SUPPORTED (1 << 0) + #define FC_RP_FLAGS_RETRY (1 << 1) + u16 max_seq; + unsigned int retries; + unsigned int e_d_tov; + unsigned int r_a_tov; + enum fc_rport_trans_state trans_state; + struct mutex rp_mutex; + struct delayed_work retry_work; + enum fc_rport_event event; + struct fc_rport_operations *ops; + struct list_head peers; + struct work_struct event_work; +}; + +#define PRIV_TO_RPORT(x) \ + (struct fc_rport *)((void *)x - sizeof(struct fc_rport)); +#define RPORT_TO_PRIV(x) \ + (struct fc_rport_libfc_priv *)((void *)x + sizeof(struct fc_rport)); + +struct fc_rport *fc_rport_rogue_create(struct fc_disc_port *); + +static inline void fc_rport_set_name(struct fc_rport *rport, u64 wwpn, u64 wwnn) +{ + rport->node_name = wwnn; + rport->port_name = wwpn; +} + +/* + * fcoe stats structure + */ +struct fcoe_dev_stats { + u64 SecondsSinceLastReset; + u64 TxFrames; + u64 TxWords; + u64 RxFrames; + u64 RxWords; + u64 ErrorFrames; + u64 DumpedFrames; + u64 LinkFailureCount; + u64 LossOfSignalCount; + u64 InvalidTxWordCount; + u64 InvalidCRCCount; + u64 InputRequests; + u64 OutputRequests; + u64 ControlRequests; + u64 InputMegabytes; + u64 OutputMegabytes; +}; + +/* + * els data is used for passing ELS respone specific + * data to send ELS response mainly using infomation + * in exchange and sequence in EM layer. + */ +struct fc_seq_els_data { + struct fc_frame *fp; + enum fc_els_rjt_reason reason; + enum fc_els_rjt_explan explan; +}; + +/* + * FCP request structure, one for each scsi cmd request + */ +struct fc_fcp_pkt { + /* + * housekeeping stuff + */ + struct fc_lport *lp; /* handle to hba struct */ + u16 state; /* scsi_pkt state state */ + u16 tgt_flags; /* target flags */ + atomic_t ref_cnt; /* fcp pkt ref count */ + spinlock_t scsi_pkt_lock; /* Must be taken before the host lock + * if both are held at the same time */ + /* + * SCSI I/O related stuff + */ + struct scsi_cmnd *cmd; /* scsi command pointer. set/clear + * under host lock */ + struct list_head list; /* tracks queued commands. access under + * host lock */ + /* + * timeout related stuff + */ + struct timer_list timer; /* command timer */ + struct completion tm_done; + int wait_for_comp; + unsigned long start_time; /* start jiffie */ + unsigned long end_time; /* end jiffie */ + unsigned long last_pkt_time; /* jiffies of last frame received */ + + /* + * scsi cmd and data transfer information + */ + u32 data_len; + /* + * transport related veriables + */ + struct fcp_cmnd cdb_cmd; + size_t xfer_len; + u32 xfer_contig_end; /* offset of end of contiguous xfer */ + u16 max_payload; /* max payload size in bytes */ + + /* + * scsi/fcp return status + */ + u32 io_status; /* SCSI result upper 24 bits */ + u8 cdb_status; + u8 status_code; /* FCP I/O status */ + /* bit 3 Underrun bit 2: overrun */ + u8 scsi_comp_flags; + u32 req_flags; /* bit 0: read bit:1 write */ + u32 scsi_resid; /* residule length */ + + struct fc_rport *rport; /* remote port pointer */ + struct fc_seq *seq_ptr; /* current sequence pointer */ + /* + * Error Processing + */ + u8 recov_retry; /* count of recovery retries */ + struct fc_seq *recov_seq; /* sequence for REC or SRR */ +}; + +/* + * Structure and function definitions for managing Fibre Channel Exchanges + * and Sequences + * + * fc_exch holds state for one exchange and links to its active sequence. + * + * fc_seq holds the state for an individual sequence. + */ + +struct fc_exch_mgr; + +/* + * Sequence. + */ +struct fc_seq { + u8 id; /* seq ID */ + u16 ssb_stat; /* status flags for sequence status block */ + u16 cnt; /* frames sent so far on sequence */ + u32 rec_data; /* FC-4 value for REC */ +}; + +#define FC_EX_DONE (1 << 0) /* ep is completed */ +#define FC_EX_RST_CLEANUP (1 << 1) /* reset is forcing completion */ + +/* + * Exchange. + * + * Locking notes: The ex_lock protects following items: + * state, esb_stat, f_ctl, seq.ssb_stat + * seq_id + * sequence allocation + */ +struct fc_exch { + struct fc_exch_mgr *em; /* exchange manager */ + u32 state; /* internal driver state */ + u16 xid; /* our exchange ID */ + struct list_head ex_list; /* free or busy list linkage */ + spinlock_t ex_lock; /* lock covering exchange state */ + atomic_t ex_refcnt; /* reference counter */ + struct delayed_work timeout_work; /* timer for upper level protocols */ + struct fc_lport *lp; /* fc device instance */ + u16 oxid; /* originator's exchange ID */ + u16 rxid; /* responder's exchange ID */ + u32 oid; /* originator's FCID */ + u32 sid; /* source FCID */ + u32 did; /* destination FCID */ + u32 esb_stat; /* exchange status for ESB */ + u32 r_a_tov; /* r_a_tov from rport (msec) */ + u8 seq_id; /* next sequence ID to use */ + u32 f_ctl; /* F_CTL flags for sequences */ + u8 fh_type; /* frame type */ + enum fc_class class; /* class of service */ + struct fc_seq seq; /* single sequence */ + /* + * Handler for responses to this current exchange. + */ + void (*resp)(struct fc_seq *, struct fc_frame *, void *); + void (*destructor)(struct fc_seq *, void *); + /* + * arg is passed as void pointer to exchange + * resp and destructor handlers + */ + void *arg; +}; +#define fc_seq_exch(sp) container_of(sp, struct fc_exch, seq) + +struct libfc_function_template { + + /** + * Mandatory Fields + * + * These handlers must be implemented by the LLD. + */ + + /* + * Interface to send a FC frame + */ + int (*frame_send)(struct fc_lport *lp, struct fc_frame *fp); + + /** + * Optional Fields + * + * The LLD may choose to implement any of the following handlers. + * If LLD doesn't specify hander and leaves its pointer NULL then + * the default libfc function will be used for that handler. + */ + + /** + * ELS/CT interfaces + */ + + /* + * elsct_send - sends ELS/CT frame + */ + struct fc_seq *(*elsct_send)(struct fc_lport *lport, + struct fc_rport *rport, + struct fc_frame *fp, + unsigned int op, + void (*resp)(struct fc_seq *, + struct fc_frame *fp, + void *arg), + void *arg, u32 timer_msec); + /** + * Exhance Manager interfaces + */ + + /* + * Send the FC frame payload using a new exchange and sequence. + * + * The frame pointer with some of the header's fields must be + * filled before calling exch_seq_send(), those fields are, + * + * - routing control + * - FC port did + * - FC port sid + * - FC header type + * - frame control + * - parameter or relative offset + * + * The exchange response handler is set in this routine to resp() + * function pointer. It can be called in two scenarios: if a timeout + * occurs or if a response frame is received for the exchange. The + * fc_frame pointer in response handler will also indicate timeout + * as error using IS_ERR related macros. + * + * The exchange destructor handler is also set in this routine. + * The destructor handler is invoked by EM layer when exchange + * is about to free, this can be used by caller to free its + * resources along with exchange free. + * + * The arg is passed back to resp and destructor handler. + * + * The timeout value (in msec) for an exchange is set if non zero + * timer_msec argument is specified. The timer is canceled when + * it fires or when the exchange is done. The exchange timeout handler + * is registered by EM layer. + */ + struct fc_seq *(*exch_seq_send)(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, unsigned int timer_msec); + + /* + * send a frame using existing sequence and exchange. + */ + int (*seq_send)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + /* + * Send ELS response using mainly infomation + * in exchange and sequence in EM layer. + */ + void (*seq_els_rsp_send)(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + + /* + * Abort an exchange and sequence. Generally called because of a + * exchange timeout or an abort from the upper layer. + * + * A timer_msec can be specified for abort timeout, if non-zero + * timer_msec value is specified then exchange resp handler + * will be called with timeout error if no response to abort. + */ + int (*seq_exch_abort)(const struct fc_seq *req_sp, + unsigned int timer_msec); + + /* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + */ + void (*exch_done)(struct fc_seq *sp); + + /* + * Assigns a EM and a free XID for an new exchange and then + * allocates a new exchange and sequence pair. + * The fp can be used to determine free XID. + */ + struct fc_exch *(*exch_get)(struct fc_lport *lp, struct fc_frame *fp); + + /* + * Release previously assigned XID by exch_get API. + * The LLD may implement this if XID is assigned by LLD + * in exch_get(). + */ + void (*exch_put)(struct fc_lport *lp, struct fc_exch_mgr *mp, + u16 ex_id); + + /* + * Start a new sequence on the same exchange/sequence tuple. + */ + struct fc_seq *(*seq_start_next)(struct fc_seq *sp); + + /* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + */ + void (*exch_mgr_reset)(struct fc_exch_mgr *, + u32 s_id, u32 d_id); + + void (*rport_flush_queue)(void); + /** + * Local Port interfaces + */ + + /* + * Receive a frame to a local port. + */ + void (*lport_recv)(struct fc_lport *lp, struct fc_seq *sp, + struct fc_frame *fp); + + int (*lport_reset)(struct fc_lport *); + + /** + * Remote Port interfaces + */ + + /* + * Initiates the RP state machine. It is called from the LP module. + * This function will issue the following commands to the N_Port + * identified by the FC ID provided. + * + * - PLOGI + * - PRLI + * - RTV + */ + int (*rport_login)(struct fc_rport *rport); + + /* + * Logoff, and remove the rport from the transport if + * it had been added. This will send a LOGO to the target. + */ + int (*rport_logoff)(struct fc_rport *rport); + + /* + * Recieve a request from a remote port. + */ + void (*rport_recv_req)(struct fc_seq *, struct fc_frame *, + struct fc_rport *); + + struct fc_rport *(*rport_lookup)(const struct fc_lport *, u32); + + /** + * FCP interfaces + */ + + /* + * Send a fcp cmd from fsp pkt. + * Called with the SCSI host lock unlocked and irqs disabled. + * + * The resp handler is called when FCP_RSP received. + * + */ + int (*fcp_cmd_send)(struct fc_lport *lp, struct fc_fcp_pkt *fsp, + void (*resp)(struct fc_seq *, struct fc_frame *fp, + void *arg)); + + /* + * Used at least durring linkdown and reset + */ + void (*fcp_cleanup)(struct fc_lport *lp); + + /* + * Abort all I/O on a local port + */ + void (*fcp_abort_io)(struct fc_lport *lp); + + /** + * Discovery interfaces + */ + + void (*disc_recv_req)(struct fc_seq *, + struct fc_frame *, struct fc_lport *); + + /* + * Start discovery for a local port. + */ + void (*disc_start)(void (*disc_callback)(struct fc_lport *, + enum fc_disc_event), + struct fc_lport *); + + /* + * Stop discovery for a given lport. This will remove + * all discovered rports + */ + void (*disc_stop) (struct fc_lport *); + + /* + * Stop discovery for a given lport. This will block + * until all discovered rports are deleted from the + * FC transport class + */ + void (*disc_stop_final) (struct fc_lport *); +}; + +/* information used by the discovery layer */ +struct fc_disc { + unsigned char retry_count; + unsigned char delay; + unsigned char pending; + unsigned char requested; + unsigned short seq_count; + unsigned char buf_len; + enum fc_disc_event event; + + void (*disc_callback)(struct fc_lport *, + enum fc_disc_event); + + struct list_head rports; + struct fc_lport *lport; + struct mutex disc_mutex; + struct fc_gpn_ft_resp partial_buf; /* partial name buffer */ + struct delayed_work disc_work; +}; + +struct fc_lport { + struct list_head list; + + /* Associations */ + struct Scsi_Host *host; + struct fc_exch_mgr *emp; + struct fc_rport *dns_rp; + struct fc_rport *ptp_rp; + void *scsi_priv; + struct fc_disc disc; + + /* Operational Information */ + struct libfc_function_template tt; + u16 link_status; + enum fc_lport_state state; + unsigned long boot_time; + + struct fc_host_statistics host_stats; + struct fcoe_dev_stats *dev_stats[NR_CPUS]; + u64 wwpn; + u64 wwnn; + u8 retry_count; + + /* Capabilities */ + u32 sg_supp:1; /* scatter gather supported */ + u32 seq_offload:1; /* seq offload supported */ + u32 crc_offload:1; /* crc offload supported */ + u32 lro_enabled:1; /* large receive offload */ + u32 mfs; /* max FC payload size */ + unsigned int service_params; + unsigned int e_d_tov; + unsigned int r_a_tov; + u8 max_retry_count; + u16 link_speed; + u16 link_supported_speeds; + u16 lro_xid; /* max xid for fcoe lro */ + struct fc_ns_fts fcts; /* FC-4 type masks */ + struct fc_els_rnid_gen rnid_gen; /* RNID information */ + + /* Semaphores */ + struct mutex lp_mutex; + + /* Miscellaneous */ + struct delayed_work retry_work; + struct delayed_work disc_work; +}; + +/** + * FC_LPORT HELPER FUNCTIONS + *****************************/ +static inline void *lport_priv(const struct fc_lport *lp) +{ + return (void *)(lp + 1); +} + +static inline int fc_lport_test_ready(struct fc_lport *lp) +{ + return lp->state == LPORT_ST_READY; +} + +static inline void fc_set_wwnn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwnn = wwnn; +} + +static inline void fc_set_wwpn(struct fc_lport *lp, u64 wwnn) +{ + lp->wwpn = wwnn; +} + +static inline void fc_lport_state_enter(struct fc_lport *lp, + enum fc_lport_state state) +{ + if (state != lp->state) + lp->retry_count = 0; + lp->state = state; +} + + +/** + * LOCAL PORT LAYER + *****************************/ +int fc_lport_init(struct fc_lport *lp); + +/* + * Destroy the specified local port by finding and freeing all + * fc_rports associated with it and then by freeing the fc_lport + * itself. + */ +int fc_lport_destroy(struct fc_lport *lp); + +/* + * Logout the specified local port from the fabric + */ +int fc_fabric_logoff(struct fc_lport *lp); + +/* + * Initiate the LP state machine. This handler will use fc_host_attr + * to store the FLOGI service parameters, so fc_host_attr must be + * initialized before calling this handler. + */ +int fc_fabric_login(struct fc_lport *lp); + +/* + * The link is up for the given local port. + */ +void fc_linkup(struct fc_lport *); + +/* + * Link is down for the given local port. + */ +void fc_linkdown(struct fc_lport *); + +/* + * Pause and unpause traffic. + */ +void fc_pause(struct fc_lport *); +void fc_unpause(struct fc_lport *); + +/* + * Configure the local port. + */ +int fc_lport_config(struct fc_lport *); + +/* + * Reset the local port. + */ +int fc_lport_reset(struct fc_lport *); + +/* + * Set the mfs or reset + */ +int fc_set_mfs(struct fc_lport *lp, u32 mfs); + + +/** + * REMOTE PORT LAYER + *****************************/ +int fc_rport_init(struct fc_lport *lp); +void fc_rport_terminate_io(struct fc_rport *rp); + +/** + * DISCOVERY LAYER + *****************************/ +int fc_disc_init(struct fc_lport *lp); + + +/** + * SCSI LAYER + *****************************/ +/* + * Initialize the SCSI block of libfc + */ +int fc_fcp_init(struct fc_lport *); + +/* + * This section provides an API which allows direct interaction + * with the SCSI-ml. Each of these functions satisfies a function + * pointer defined in Scsi_Host and therefore is always called + * directly from the SCSI-ml. + */ +int fc_queuecommand(struct scsi_cmnd *sc_cmd, + void (*done)(struct scsi_cmnd *)); + +/* + * complete processing of a fcp packet + * + * This function may sleep if a fsp timer is pending. + * The host lock must not be held by caller. + */ +void fc_fcp_complete(struct fc_fcp_pkt *fsp); + +/* + * Send an ABTS frame to the target device. The sc_cmd argument + * is a pointer to the SCSI command to be aborted. + */ +int fc_eh_abort(struct scsi_cmnd *sc_cmd); + +/* + * Reset a LUN by sending send the tm cmd to the target. + */ +int fc_eh_device_reset(struct scsi_cmnd *sc_cmd); + +/* + * Reset the host adapter. + */ +int fc_eh_host_reset(struct scsi_cmnd *sc_cmd); + +/* + * Check rport status. + */ +int fc_slave_alloc(struct scsi_device *sdev); + +/* + * Adjust the queue depth. + */ +int fc_change_queue_depth(struct scsi_device *sdev, int qdepth); + +/* + * Change the tag type. + */ +int fc_change_queue_type(struct scsi_device *sdev, int tag_type); + +/* + * Free memory pools used by the FCP layer. + */ +void fc_fcp_destroy(struct fc_lport *); + +/** + * ELS/CT interface + *****************************/ +/* + * Initializes ELS/CT interface + */ +int fc_elsct_init(struct fc_lport *lp); + + +/** + * EXCHANGE MANAGER LAYER + *****************************/ +/* + * Initializes Exchange Manager related + * function pointers in struct libfc_function_template. + */ +int fc_exch_init(struct fc_lport *lp); + +/* + * Allocates an Exchange Manager (EM). + * + * The EM manages exchanges for their allocation and + * free, also allows exchange lookup for received + * frame. + * + * The class is used for initializing FC class of + * allocated exchange from EM. + * + * The min_xid and max_xid will limit new + * exchange ID (XID) within this range for + * a new exchange. + * The LLD may choose to have multiple EMs, + * e.g. one EM instance per CPU receive thread in LLD. + * The LLD can use exch_get() of struct libfc_function_template + * to specify XID for a new exchange within + * a specified EM instance. + * + * The em_idx to uniquely identify an EM instance. + */ +struct fc_exch_mgr *fc_exch_mgr_alloc(struct fc_lport *lp, + enum fc_class class, + u16 min_xid, + u16 max_xid); + +/* + * Free an exchange manager. + */ +void fc_exch_mgr_free(struct fc_exch_mgr *mp); + +/* + * Receive a frame on specified local port and exchange manager. + */ +void fc_exch_recv(struct fc_lport *lp, struct fc_exch_mgr *mp, + struct fc_frame *fp); + +/* + * This function is for exch_seq_send function pointer in + * struct libfc_function_template, see comment block on + * exch_seq_send for description of this function. + */ +struct fc_seq *fc_exch_seq_send(struct fc_lport *lp, + struct fc_frame *fp, + void (*resp)(struct fc_seq *sp, + struct fc_frame *fp, + void *arg), + void (*destructor)(struct fc_seq *sp, + void *arg), + void *arg, u32 timer_msec); + +/* + * send a frame using existing sequence and exchange. + */ +int fc_seq_send(struct fc_lport *lp, struct fc_seq *sp, struct fc_frame *fp); + +/* + * Send ELS response using mainly infomation + * in exchange and sequence in EM layer. + */ +void fc_seq_els_rsp_send(struct fc_seq *sp, enum fc_els_cmd els_cmd, + struct fc_seq_els_data *els_data); + +/* + * This function is for seq_exch_abort function pointer in + * struct libfc_function_template, see comment block on + * seq_exch_abort for description of this function. + */ +int fc_seq_exch_abort(const struct fc_seq *req_sp, unsigned int timer_msec); + +/* + * Indicate that an exchange/sequence tuple is complete and the memory + * allocated for the related objects may be freed. + */ +void fc_exch_done(struct fc_seq *sp); + +/* + * Assigns a EM and XID for a frame and then allocates + * a new exchange and sequence pair. + * The fp can be used to determine free XID. + */ +struct fc_exch *fc_exch_get(struct fc_lport *lp, struct fc_frame *fp); + +/* + * Allocate a new exchange and sequence pair. + * if ex_id is zero then next free exchange id + * from specified exchange manger mp will be assigned. + */ +struct fc_exch *fc_exch_alloc(struct fc_exch_mgr *mp, + struct fc_frame *fp, u16 ex_id); +/* + * Start a new sequence on the same exchange as the supplied sequence. + */ +struct fc_seq *fc_seq_start_next(struct fc_seq *sp); + +/* + * Reset an exchange manager, completing all sequences and exchanges. + * If s_id is non-zero, reset only exchanges originating from that FID. + * If d_id is non-zero, reset only exchanges sending to that FID. + */ +void fc_exch_mgr_reset(struct fc_exch_mgr *, u32 s_id, u32 d_id); + +/* + * Functions for fc_functions_template + */ +void fc_get_host_speed(struct Scsi_Host *shost); +void fc_get_host_port_type(struct Scsi_Host *shost); +void fc_get_host_port_state(struct Scsi_Host *shost); +void fc_set_rport_loss_tmo(struct fc_rport *rport, u32 timeout); +struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *); + +/* + * module setup functions. + */ +int fc_setup_exch_mgr(void); +void fc_destroy_exch_mgr(void); +int fc_setup_rport(void); +void fc_destroy_rport(void); + +#endif /* _LIBFC_H_ */ -- cgit v1.2.3 From 85b4aa4926a50210b683ac89326e338e7d131211 Mon Sep 17 00:00:00 2001 From: Robert Love Date: Tue, 9 Dec 2008 15:10:24 -0800 Subject: [SCSI] fcoe: Fibre Channel over Ethernet Encapsulation protocol for running Fibre Channel over Ethernet interfaces. Creates virtual Fibre Channel host adapters using libfc. This layer is the LLD to the scsi-ml. It allocates the Scsi_Host, utilizes libfc for Fibre Channel protocol processing and interacts with netdev to send/receive Ethernet packets. Signed-off-by: Robert Love Signed-off-by: James Bottomley --- include/scsi/fc_transport_fcoe.h | 54 ++++++++++++ include/scsi/libfcoe.h | 176 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+) create mode 100644 include/scsi/fc_transport_fcoe.h create mode 100644 include/scsi/libfcoe.h (limited to 'include') diff --git a/include/scsi/fc_transport_fcoe.h b/include/scsi/fc_transport_fcoe.h new file mode 100644 index 00000000000..8dca2af14ff --- /dev/null +++ b/include/scsi/fc_transport_fcoe.h @@ -0,0 +1,54 @@ +#ifndef FC_TRANSPORT_FCOE_H +#define FC_TRANSPORT_FCOE_H + +#include +#include +#include +#include + +/** + * struct fcoe_transport - FCoE transport struct for generic transport + * for Ethernet devices as well as pure HBAs + * + * @name: name for thsi transport + * @bus: physical bus type (pci_bus_type) + * @driver: physical bus driver for network device + * @create: entry create function + * @destroy: exit destroy function + * @list: list of transports + */ +struct fcoe_transport { + char *name; + unsigned short vendor; + unsigned short device; + struct bus_type *bus; + struct device_driver *driver; + int (*create)(struct net_device *device); + int (*destroy)(struct net_device *device); + bool (*match)(struct net_device *device); + struct list_head list; + struct list_head devlist; + struct mutex devlock; +}; + +/** + * MODULE_ALIAS_FCOE_PCI + * + * some care must be taken with this, vendor and device MUST be a hex value + * preceded with 0x and with letters in lower case (0x12ab, not 0x12AB or 12AB) + */ +#define MODULE_ALIAS_FCOE_PCI(vendor, device) \ + MODULE_ALIAS("fcoe-pci-" __stringify(vendor) "-" __stringify(device)) + +/* exported funcs */ +int fcoe_transport_attach(struct net_device *netdev); +int fcoe_transport_release(struct net_device *netdev); +int fcoe_transport_register(struct fcoe_transport *t); +int fcoe_transport_unregister(struct fcoe_transport *t); +int fcoe_load_transport_driver(struct net_device *netdev); +int __init fcoe_transport_init(void); +int __exit fcoe_transport_exit(void); + +/* fcow_sw is the default transport */ +extern struct fcoe_transport fcoe_sw_transport; +#endif /* FC_TRANSPORT_FCOE_H */ diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h new file mode 100644 index 00000000000..89fdbb9a6a1 --- /dev/null +++ b/include/scsi/libfcoe.h @@ -0,0 +1,176 @@ +/* + * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Maintained at www.Open-FCoE.org + */ + +#ifndef _LIBFCOE_H +#define _LIBFCOE_H + +#include +#include +#include +#include + +/* + * this percpu struct for fcoe + */ +struct fcoe_percpu_s { + int cpu; + struct task_struct *thread; + struct sk_buff_head fcoe_rx_list; + struct page *crc_eof_page; + int crc_eof_offset; +}; + +/* + * the fcoe sw transport private data + */ +struct fcoe_softc { + struct list_head list; + struct fc_lport *lp; + struct net_device *real_dev; + struct net_device *phys_dev; /* device with ethtool_ops */ + struct packet_type fcoe_packet_type; + struct sk_buff_head fcoe_pending_queue; + + u8 dest_addr[ETH_ALEN]; + u8 ctl_src_addr[ETH_ALEN]; + u8 data_src_addr[ETH_ALEN]; + /* + * fcoe protocol address learning related stuff + */ + u16 flogi_oxid; + u8 flogi_progress; + u8 address_mode; +}; + +static inline struct fcoe_softc *fcoe_softc( + const struct fc_lport *lp) +{ + return (struct fcoe_softc *)lport_priv(lp); +} + +static inline struct net_device *fcoe_netdev( + const struct fc_lport *lp) +{ + return fcoe_softc(lp)->real_dev; +} + +static inline struct fcoe_hdr *skb_fcoe_header(const struct sk_buff *skb) +{ + return (struct fcoe_hdr *)skb_network_header(skb); +} + +static inline int skb_fcoe_offset(const struct sk_buff *skb) +{ + return skb_network_offset(skb); +} + +static inline struct fc_frame_header *skb_fc_header(const struct sk_buff *skb) +{ + return (struct fc_frame_header *)skb_transport_header(skb); +} + +static inline int skb_fc_offset(const struct sk_buff *skb) +{ + return skb_transport_offset(skb); +} + +static inline void skb_reset_fc_header(struct sk_buff *skb) +{ + skb_reset_network_header(skb); + skb_set_transport_header(skb, skb_network_offset(skb) + + sizeof(struct fcoe_hdr)); +} + +static inline bool skb_fc_is_data(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_SOL_DATA; +} + +static inline bool skb_fc_is_cmd(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD; +} + +static inline bool skb_fc_has_exthdr(const struct sk_buff *skb) +{ + return (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_VFTH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_IFRH) || + (skb_fc_header(skb)->fh_r_ctl == FC_RCTL_ENCH); +} + +static inline bool skb_fc_is_roff(const struct sk_buff *skb) +{ + return skb_fc_header(skb)->fh_f_ctl[2] & FC_FC_REL_OFF; +} + +static inline u16 skb_fc_oxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_ox_id); +} + +static inline u16 skb_fc_rxid(const struct sk_buff *skb) +{ + return be16_to_cpu(skb_fc_header(skb)->fh_rx_id); +} + +/* FIXME - DMA_BIDIRECTIONAL ? */ +#define skb_cb(skb) ((struct fcoe_rcv_info *)&((skb)->cb[0])) +#define skb_cmd(skb) (skb_cb(skb)->fr_cmd) +#define skb_dir(skb) (skb_cmd(skb)->sc_data_direction) +static inline bool skb_fc_is_read(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_FROM_DEVICE; + return false; +} + +static inline bool skb_fc_is_write(const struct sk_buff *skb) +{ + if (skb_fc_is_cmd(skb) && skb_cmd(skb)) + return skb_dir(skb) == DMA_TO_DEVICE; + return false; +} + +/* libfcoe funcs */ +int fcoe_reset(struct Scsi_Host *shost); +u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN], + unsigned int scheme, unsigned int port); + +u32 fcoe_fc_crc(struct fc_frame *fp); +int fcoe_xmit(struct fc_lport *, struct fc_frame *); +int fcoe_rcv(struct sk_buff *, struct net_device *, + struct packet_type *, struct net_device *); + +int fcoe_percpu_receive_thread(void *arg); +void fcoe_clean_pending_queue(struct fc_lport *lp); +void fcoe_percpu_clean(struct fc_lport *lp); +void fcoe_watchdog(ulong vp); +int fcoe_link_ok(struct fc_lport *lp); + +struct fc_lport *fcoe_hostlist_lookup(const struct net_device *); +int fcoe_hostlist_add(const struct fc_lport *); +int fcoe_hostlist_remove(const struct fc_lport *); + +struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *, int); +int fcoe_libfc_config(struct fc_lport *, struct libfc_function_template *); + +/* fcoe sw hba */ +int __init fcoe_sw_init(void); +int __exit fcoe_sw_exit(void); +#endif /* _LIBFCOE_H */ -- cgit v1.2.3 From 2a2ca6a96194c4744a2adeefbc09ce881f3c5abe Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:31 +0100 Subject: ide: replace the global ide_lock spinlock by per-hwgroup spinlocks (v2) Now that (almost) all host drivers have been fixed not to abuse ide_lock and core code usage of ide_lock has been sanitized we may safely replace ide_lock by per-hwgroup locks. This patch is partially based on earlier patch from Ravikiran G Thirumalai. While at it: - don't use deprecated HWIF() and HWGROUP() macros - update locking documentation in ide.h v2: Add missing spin_lock_init(&hwgroup->lock). (Noticed by Elias Oltmanns) Cc: Vaibhav V. Nivargi Cc: Alok N. Kataria Cc: Shai Fultheim Signed-off-by: Ravikiran Thirumalai Cc: Elias Oltmanns Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 010fb26a157..c871d325ced 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -909,6 +909,8 @@ typedef struct hwgroup_s { int req_gen; int req_gen_timer; + + spinlock_t lock; } ide_hwgroup_t; typedef struct ide_driver_s ide_driver_t; @@ -1610,13 +1612,13 @@ extern struct mutex ide_cfg_mtx; /* * Structure locking: * - * ide_cfg_mtx and ide_lock together protect changes to - * ide_hwif_t->{next,hwgroup} + * ide_cfg_mtx and hwgroup->lock together protect changes to + * ide_hwif_t->next * ide_drive_t->next * - * ide_hwgroup_t->busy: ide_lock - * ide_hwgroup_t->hwif: ide_lock - * ide_hwif_t->mate: constant, no locking + * ide_hwgroup_t->busy: hwgroup->lock + * ide_hwgroup_t->hwif: hwgroup->lock + * ide_hwif_t->{hwgroup,mate}: constant, no locking * ide_drive_t->hwif: constant, no locking */ -- cgit v1.2.3 From 27c01c2db05c3cf8824975e50403cd4fd9356dca Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: ide-cd: remove obsolete seek optimization It doesn't make much sense nowadays and is problematic on some drives. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index c871d325ced..0b8af0535d8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -122,8 +122,6 @@ struct ide_io_ports { #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ #define SECTOR_SIZE 512 -#define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t))) - /* * Timeouts for various operations: */ @@ -496,8 +494,6 @@ enum { * when more than one interrupt is needed. */ IDE_AFLAG_LIMIT_NFRAMES = (1 << 7), - /* Seeking in progress. */ - IDE_AFLAG_SEEKING = (1 << 8), /* Saved TOC information is current. */ IDE_AFLAG_TOC_VALID = (1 << 9), /* We think that the drive door is locked. */ -- cgit v1.2.3 From 6b5cde3629701258004b94cde75dd1089b556b02 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:32 +0100 Subject: cmd64x: set IDE_HFLAG_SERIALIZE explictly for CMD646 * Set IDE_HFLAG_SERIALIZE explictly for CMD646. * Remove no longer needed ide_cmd646 chipset type (which has a nice side-effect of fixing handling of unexpected IRQs). Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 0b8af0535d8..150e42311ee 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -171,7 +171,7 @@ enum { ide_unknown, ide_generic, ide_pci, ide_cmd640, ide_dtc2278, ide_ali14xx, ide_qd65xx, ide_umc8672, ide_ht6560b, ide_rz1000, ide_trm290, - ide_cmd646, ide_cy82c693, ide_4drives, + ide_cy82c693, ide_4drives, ide_pmac, ide_acorn, ide_au1xxx, ide_palm3710 }; -- cgit v1.2.3 From f58c1ab8deebc2360cef998f169a6727c288210f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: ide: always set nIEN on idle devices * Set nIEN for previous port/device in ide_do_request() also if port uses a non-shared IRQ. * Remove no longer needed ide_hwif_t.sharing_irq. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 150e42311ee..1d28006aec6 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -842,7 +842,6 @@ typedef struct hwif_s { unsigned present : 1; /* this interface exists */ unsigned serialized : 1; /* serialized all channel operation */ - unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ struct device gendev; -- cgit v1.2.3 From 7f1ac8c4b9dadc55ec656b368f5f470f2cbe3083 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:33 +0100 Subject: rz1000: apply chipset quirks early (v2) * Use pci_name(dev) instead of hwif->name in init_hwif_rz1000(). * init_hwif_rz1000() -> rz1000_init_chipset(). Update rz1000_init_one() to use rz1000_init_chipset() and add now required rz1000_remove(). * Remove superfluous ide_rz1000 chipset type. v2: * unsigned int rz1000_init_chipset() -> int rz1000_disable_readahead() per Sergei's suggestion. Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 1d28006aec6..fc1a966c7b7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -170,8 +170,7 @@ typedef int (ide_ack_intr_t)(struct hwif_s *); enum { ide_unknown, ide_generic, ide_pci, ide_cmd640, ide_dtc2278, ide_ali14xx, ide_qd65xx, ide_umc8672, ide_ht6560b, - ide_rz1000, ide_trm290, - ide_cy82c693, ide_4drives, + ide_trm290, ide_cy82c693, ide_4drives, ide_pmac, ide_acorn, ide_au1xxx, ide_palm3710 }; -- cgit v1.2.3 From 6b4924962c49655494d2c8e9d3faab0e349a3062 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: ide: add ->max_sectors field to struct ide_port_info * Add ->max_sectors field to struct ide_port_info to allow host drivers to specify value used for hwif->rqsize (if smaller than the default). * Convert pdc202xx_old to use ->max_sectors and remove no longer needed IDE_HFLAG_RQSIZE_256 flag. There should be no functional changes caused by this patch. Acked-by: Sergei Shtyltov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index fc1a966c7b7..2574dda4a3e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1372,8 +1372,6 @@ enum { IDE_HFLAG_LEGACY_IRQS = (1 << 21), /* force use of legacy IRQs */ IDE_HFLAG_FORCE_LEGACY_IRQS = (1 << 22), - /* limit LBA48 requests to 256 sectors */ - IDE_HFLAG_RQSIZE_256 = (1 << 23), /* use 32-bit I/O ops */ IDE_HFLAG_IO_32BIT = (1 << 24), /* unmask IRQs */ @@ -1411,6 +1409,9 @@ struct ide_port_info { ide_pci_enablebit_t enablebits[2]; hwif_chipset_t chipset; + + u16 max_sectors; /* if < than the default one */ + u32 host_flags; u8 pio_mask; u8 swdma_mask; -- cgit v1.2.3 From 1f66019bdf902cb59adf959e462bcd3f4c01f683 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: trm290: add IDE_HFLAG_TRM290 host flag * Add IDE_HFLAG_TRM290 host flag and use it in ide_build_dmatable(). * Remove no longer needed ide_trm290 chipset type. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 2574dda4a3e..f62d35a5fb7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -170,7 +170,7 @@ typedef int (ide_ack_intr_t)(struct hwif_s *); enum { ide_unknown, ide_generic, ide_pci, ide_cmd640, ide_dtc2278, ide_ali14xx, ide_qd65xx, ide_umc8672, ide_ht6560b, - ide_trm290, ide_cy82c693, ide_4drives, + ide_cy82c693, ide_4drives, ide_pmac, ide_acorn, ide_au1xxx, ide_palm3710 }; @@ -1372,6 +1372,8 @@ enum { IDE_HFLAG_LEGACY_IRQS = (1 << 21), /* force use of legacy IRQs */ IDE_HFLAG_FORCE_LEGACY_IRQS = (1 << 22), + /* host is TRM290 */ + IDE_HFLAG_TRM290 = (1 << 23), /* use 32-bit I/O ops */ IDE_HFLAG_IO_32BIT = (1 << 24), /* unmask IRQs */ -- cgit v1.2.3 From b7876a6fb6e9bf6cbcf7b40cf034aa4138d7978f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:34 +0100 Subject: cy82c693: remove superfluous ide_cy82c693 chipset type Since CY82C693 doesn't require serialization we may as well use the default ide_pci chipset type. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index f62d35a5fb7..f89d6d69a38 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -170,8 +170,7 @@ typedef int (ide_ack_intr_t)(struct hwif_s *); enum { ide_unknown, ide_generic, ide_pci, ide_cmd640, ide_dtc2278, ide_ali14xx, ide_qd65xx, ide_umc8672, ide_ht6560b, - ide_cy82c693, ide_4drives, - ide_pmac, ide_acorn, + ide_4drives, ide_pmac, ide_acorn, ide_au1xxx, ide_palm3710 }; -- cgit v1.2.3 From 702c026be87ef8374ae58122969a4b0b081ce6f2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:36 +0100 Subject: ide: rework handling of serialized ports (v2) * hpt366: set IDE_HFLAG_SERIALIZE in ->host_flags if needed in init_hwif_hpt366(). Remove HPT_SERIALIZE_IO while at it. * Set IDE_HFLAG_SERIALIZE in ->host_flags if needed in ide_init_port(). * Convert init_irq() to use IDE_HFLAG_SERIALIZE together with hwif->host to find out ports which need to be serialized. * Remove no longer needed save_match() and ide_hwif_t.serialized. v2: * Set host's ->host_flags field instead of port's copy. This patch should fix the incorrect grouping of port(s) from host(s) that need serialization with port(s) that happen to use the same IRQ(s) but are from the host(s) that don't need it. Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index f89d6d69a38..9b89cab6d49 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -839,7 +839,6 @@ typedef struct hwif_s { unsigned extra_ports; /* number of extra dma ports */ unsigned present : 1; /* this interface exists */ - unsigned serialized : 1; /* serialized all channel operation */ unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ struct device gendev; -- cgit v1.2.3 From e2984c628c924442132304ae662da433f41c05c9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 29 Dec 2008 20:27:37 +0100 Subject: ide: move Power Management support to ide-pm.c There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include') diff --git a/include/linux/ide.h b/include/linux/ide.h index 9b89cab6d49..e99c56de7f5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1116,6 +1116,14 @@ enum { IDE_PM_COMPLETED, }; +int generic_ide_suspend(struct device *, pm_message_t); +int generic_ide_resume(struct device *); + +void ide_complete_power_step(ide_drive_t *, struct request *); +ide_startstop_t ide_start_power_step(ide_drive_t *, struct request *); +void ide_complete_pm_request(ide_drive_t *, struct request *); +void ide_check_pm_state(ide_drive_t *, struct request *); + /* * Subdrivers support. * -- cgit v1.2.3 From 08a66aea55154b50f9e9e2e89cc85d8b75121568 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 24 Oct 2008 15:43:07 -0300 Subject: V4L/DVB (9488): Add ov772x driver This patch adds ov772x driver that use soc_camera framework. It was tested on SH Migo-r board. Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/ov772x.h | 21 +++++++++++++++++++++ include/media/v4l2-chip-ident.h | 1 + 2 files changed, 22 insertions(+) create mode 100644 include/media/ov772x.h (limited to 'include') diff --git a/include/media/ov772x.h b/include/media/ov772x.h new file mode 100644 index 00000000000..e391d55edb9 --- /dev/null +++ b/include/media/ov772x.h @@ -0,0 +1,21 @@ +/* ov772x Camera + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __OV772X_H__ +#define __OV772X_H__ + +#include + +struct ov772x_camera_info { + unsigned long buswidth; + struct soc_camera_link link; +}; + +#endif /* __OV772X_H__ */ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index d73a8e9028a..bfe5142e667 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -60,6 +60,7 @@ enum { /* OmniVision sensors: reserved range 250-299 */ V4L2_IDENT_OV7670 = 250, + V4L2_IDENT_OV772X = 251, /* Conexant MPEG encoder/decoders: reserved range 410-420 */ V4L2_IDENT_CX23415 = 415, -- cgit v1.2.3 From f473bf76c71ca734a16f9331ce6b6e9603641888 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 1 Nov 2008 08:25:11 -0300 Subject: V4L/DVB (9503): v4l: remove inode argument from video_usercopy The inode argument was never used. Removing it from video_usercopy brings the function pointer type of video_usercopy in line with similar v4l2 functions, thus simplifying several drivers. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/saa7146_vv.h | 3 +-- include/media/v4l2-ioctl.h | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/media/saa7146_vv.h b/include/media/saa7146_vv.h index 1d104096619..6bbb0d93bb5 100644 --- a/include/media/saa7146_vv.h +++ b/include/media/saa7146_vv.h @@ -216,8 +216,7 @@ void saa7146_set_gpio(struct saa7146_dev *saa, u8 pin, u8 data); extern struct saa7146_use_ops saa7146_video_uops; int saa7146_start_preview(struct saa7146_fh *fh); int saa7146_stop_preview(struct saa7146_fh *fh); -int saa7146_video_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg); +int saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg); /* from saa7146_vbi.c */ extern struct saa7146_use_ops saa7146_vbi_uops; diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index e6ba25b3d7c..f5985724c45 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -285,10 +285,8 @@ extern long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg); /* Include support for obsoleted stuff */ -extern int video_usercopy(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg, - int (*func)(struct inode *inode, struct file *file, - unsigned int cmd, void *arg)); +extern int video_usercopy(struct file *file, unsigned int cmd, + unsigned long arg, v4l2_kioctl func); /* Standard handlers for V4L ioctl's */ -- cgit v1.2.3 From af128a102c4aee994b4ff6e422b3cfab17127578 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Oct 2008 00:51:46 -0300 Subject: V4L/DVB (9521): V4L: struct device - replace bus_id with dev_name(), dev_set_name() This patch is part of a larger patch series which will remove the "char bus_id[20]" name string from struct device. The device name is managed in the kobject anyway, and without any size limitation, and just needlessly copied into "struct device". To set and read the device name dev_name(dev) and dev_set_name(dev) must be used. If your code uses static kobjects, which it shouldn't do, "const char *init_name" can be used to statically provide the name the registered device should have. At registration time, the init_name field is cleared, to enforce the use of dev_name(dev) to access the device name at a later time. We need to get rid of all occurrences of bus_id in the entire tree to be able to enable the new interface. Please apply this patch, and possibly convert any remaining remaining occurrences of bus_id. We want to submit a patch to -next, which will remove bus_id from "struct device", to find the remaining pieces to convert, and finally switch over to the new api, which will remove the 20 bytes array and does no longer have a size limitation. Thanks, Kay Signed-off-by: Kay Sievers Acked-by: Greg Kroah-Hartman Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index c5de7bb19fd..9231e2d908f 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -56,7 +56,7 @@ struct soc_camera_host { struct device dev; unsigned char nr; /* Host number */ void *priv; - char *drv_name; + const char *drv_name; struct soc_camera_host_ops *ops; }; @@ -107,7 +107,7 @@ extern int soc_camera_video_start(struct soc_camera_device *icd); extern void soc_camera_video_stop(struct soc_camera_device *icd); struct soc_camera_data_format { - char *name; + const char *name; unsigned int depth; __u32 fourcc; enum v4l2_colorspace colorspace; -- cgit v1.2.3 From 69acdf1e5a9146ec6667f6c4b439acd38c18f5ea Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 4 Nov 2008 21:59:37 -0300 Subject: V4L/DVB (9530): Add new pixel format VYUY 16 bits wide. There were already 3 YUV formats defined : - YUYV - YVYU - UYVY The only left combination is VYUY, which is added in this patch. Signed-off-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4669d7e72e7..ec311d4616c 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -293,6 +293,7 @@ struct v4l2_pix_format { #define V4L2_PIX_FMT_YVU420 v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */ #define V4L2_PIX_FMT_YUYV v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_UYVY v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */ #define V4L2_PIX_FMT_YUV422P v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */ #define V4L2_PIX_FMT_YUV411P v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */ #define V4L2_PIX_FMT_Y41P v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */ -- cgit v1.2.3 From 74d83fa0241f603a4067f071a88ef8b9a7c415a0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 11 Nov 2008 21:13:47 -0300 Subject: V4L/DVB (9578): v4l core: add support for enumerating frame sizes and intervals video_ioctl2 lacks implementation of those two ioctls: - VIDIOC_ENUM_FRAMESIZES and VIDIOC_ENUM_FRAMEINTERVALS Adds implementation for those. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ioctl.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index f5985724c45..c884432f938 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -232,6 +232,12 @@ struct v4l2_ioctl_ops { int (*vidioc_g_chip_ident) (struct file *file, void *fh, struct v4l2_chip_ident *chip); + int (*vidioc_enum_framesizes) (struct file *file, void *fh, + struct v4l2_frmsizeenum *fsize); + + int (*vidioc_enum_frameintervals) (struct file *file, void *fh, + struct v4l2_frmivalenum *fival); + /* For other private ioctls */ int (*vidioc_default) (struct file *file, void *fh, int cmd, void *arg); -- cgit v1.2.3 From 60245e858ddb2255d458868be16ba814f6f8d446 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Sun, 16 Nov 2008 08:03:53 -0300 Subject: V4L/DVB (9629): Add support for the ATI TV Wonder HD 600 USB Remote Control Add support for the ATI TV Wonder HD 600 USB Remote Control (required a new keymap) [mchehab@redhat.com: Fix CodingStyle] Signed-off-by: Devin Heitmueller Signed-off-by: Mauro Carvalho Chehab --- include/media/ir-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 38f2d93c395..3a88e13a20e 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -157,6 +157,7 @@ extern IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE]; #endif /* -- cgit v1.2.3 From 480daab42c4dd74b3c07031ddf9031251c530c77 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Dec 2008 09:25:56 -0600 Subject: virtio: Don't use PAGE_SIZE in virtio_pci.c The virtio PCI devices don't depend on the guest page size. This matters now PowerPC virtio is gaining ground (they like 64k pages). Signed-off-by: Rusty Russell --- include/linux/virtio_pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h index cdef3574293..e13d7ebcf57 100644 --- a/include/linux/virtio_pci.h +++ b/include/linux/virtio_pci.h @@ -53,4 +53,8 @@ /* Virtio ABI version, this must match exactly */ #define VIRTIO_PCI_ABI_VERSION 0 + +/* How many bits to shift physical queue address written to QUEUE_PFN. + * 12 is historical, and due to x86 page size. */ +#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 #endif -- cgit v1.2.3 From 5f0d1d7f2286c8a02dab69f5f0bd51681fab161e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Dec 2008 09:25:57 -0600 Subject: virtio: rename 'pagesize' arg to vring_init/vring_size It's really the alignment desired for consumer/producer separation; historically this x86 pagesize, but with PowerPC it'll still be x86 pagesize. And in theory lguest could choose a different value. Signed-off-by: Rusty Russell --- include/linux/virtio_ring.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index c4a598fb382..01bf3124e31 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -83,7 +83,7 @@ struct vring { * __u16 avail_idx; * __u16 available[num]; * - * // Padding to the next page boundary. + * // Padding to the next align boundary. * char pad[]; * * // A ring of used descriptor heads with free-running index. @@ -93,19 +93,19 @@ struct vring { * }; */ static inline void vring_init(struct vring *vr, unsigned int num, void *p, - unsigned long pagesize) + unsigned long align) { vr->num = num; vr->desc = p; vr->avail = p + num*sizeof(struct vring_desc); - vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + pagesize-1) - & ~(pagesize - 1)); + vr->used = (void *)(((unsigned long)&vr->avail->ring[num] + align-1) + & ~(align - 1)); } -static inline unsigned vring_size(unsigned int num, unsigned long pagesize) +static inline unsigned vring_size(unsigned int num, unsigned long align) { return ((sizeof(struct vring_desc) * num + sizeof(__u16) * (2 + num) - + pagesize - 1) & ~(pagesize - 1)) + + align - 1) & ~(align - 1)) + sizeof(__u16) * 2 + sizeof(struct vring_used_elem) * num; } -- cgit v1.2.3 From 498af14783935af487d17dbee4ac451783cbc2b7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Dec 2008 09:25:57 -0600 Subject: virtio: Don't use PAGE_SIZE for vring alignment in virtio_pci. That doesn't work for non-4k guests which are now appearing. Signed-off-by: Rusty Russell --- include/linux/virtio_pci.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/virtio_pci.h b/include/linux/virtio_pci.h index e13d7ebcf57..cd0fd5d181a 100644 --- a/include/linux/virtio_pci.h +++ b/include/linux/virtio_pci.h @@ -57,4 +57,8 @@ /* How many bits to shift physical queue address written to QUEUE_PFN. * 12 is historical, and due to x86 page size. */ #define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12 + +/* The alignment to use between consumer and producer parts of vring. + * x86 pagesize again. */ +#define VIRTIO_PCI_VRING_ALIGN 4096 #endif -- cgit v1.2.3 From 2966af73e70dee461c256b5eb877b2ff757f8c82 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Dec 2008 09:25:58 -0600 Subject: virtio: use LGUEST_VRING_ALIGN instead of relying on pagesize This doesn't really matter, since lguest is i386 only at the moment, but we could actually choose a different value. (lguest doesn't have a guarenteed ABI). Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index e7217dc58f3..bd0eba76052 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -59,4 +59,8 @@ enum lguest_req LHREQ_IRQ, /* + irq */ LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */ }; + +/* The alignment to use between consumer and producer parts of vring. + * x86 pagesize for historical reasons. */ +#define LGUEST_VRING_ALIGN 4096 #endif /* _LINUX_LGUEST_LAUNCHER */ -- cgit v1.2.3 From 87c7d57c17ade5024d95b6ca0da249da49b0672a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 30 Dec 2008 09:26:03 -0600 Subject: virtio: hand virtio ring alignment as argument to vring_new_virtqueue This allows each virtio user to hand in the alignment appropriate to their virtio_ring structures. Signed-off-by: Rusty Russell Acked-by: Christian Borntraeger --- include/linux/virtio_ring.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/virtio_ring.h b/include/linux/virtio_ring.h index 01bf3124e31..71e03722fb5 100644 --- a/include/linux/virtio_ring.h +++ b/include/linux/virtio_ring.h @@ -115,6 +115,7 @@ struct virtio_device; struct virtqueue; struct virtqueue *vring_new_virtqueue(unsigned int num, + unsigned int vring_align, struct virtio_device *vdev, void *pages, void (*notify)(struct virtqueue *vq), -- cgit v1.2.3 From 1b4aa2faeca1b9922033daf2475b6fc13b0ffea6 Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Thu, 13 Nov 2008 15:48:33 -0600 Subject: virtio: avoid implicit use of Linux page size in balloon interface Make the balloon interface always use 4K pages, and convert Linux pfns if necessary. This patch assumes that Linux's PAGE_SHIFT will never be less than 12. Signed-off-by: Hollis Blanchard Signed-off-by: Rusty Russell (modified) --- include/linux/virtio_balloon.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/linux/virtio_balloon.h b/include/linux/virtio_balloon.h index c30c7bfbf39..8726ff77763 100644 --- a/include/linux/virtio_balloon.h +++ b/include/linux/virtio_balloon.h @@ -10,6 +10,9 @@ /* The feature bitmap for virtio balloon */ #define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */ +/* Size of a PFN in the balloon interface. */ +#define VIRTIO_BALLOON_PFN_SHIFT 12 + struct virtio_balloon_config { /* Number of pages host wants Guest to give up. */ -- cgit v1.2.3 From c29834584ea4eafccf2f62a0b8a32e64f792044c Mon Sep 17 00:00:00 2001 From: Christian Borntraeger Date: Tue, 25 Nov 2008 13:36:26 +0100 Subject: virtio_console: support console resizing this patch uses the new hvc callback hvc_resize to set the window size which allows to change the tty size of hvc_console via a hvc_resize function. I have added a new feature bit VIRTIO_CONSOLE_F_SIZE. The driver will change the window size on tty open and via the config_changed callback of the transport. Currently lguest and kvm_s390 have not implemented this callback, but the callback can be implemented at a later point in time. Signed-off-by: Christian Borntraeger Signed-off-by: Rusty Russell --- include/linux/virtio_console.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/linux/virtio_console.h b/include/linux/virtio_console.h index 19a0da0dba4..7615ffcdd55 100644 --- a/include/linux/virtio_console.h +++ b/include/linux/virtio_console.h @@ -7,6 +7,17 @@ /* The ID for virtio console */ #define VIRTIO_ID_CONSOLE 3 +/* Feature bits */ +#define VIRTIO_CONSOLE_F_SIZE 0 /* Does host provide console size? */ + +struct virtio_console_config { + /* colums of the screens */ + __u16 cols; + /* rows of the screens */ + __u16 rows; +} __attribute__((packed)); + + #ifdef __KERNEL__ int __init virtio_cons_early_init(int (*put_chars)(u32, const char *, int)); #endif /* __KERNEL__ */ -- cgit v1.2.3 From 58a24566449892dda409b9ad92c2e56c76c5670c Mon Sep 17 00:00:00 2001 From: Matias Zabaljauregui Date: Mon, 29 Sep 2008 01:40:07 -0300 Subject: lguest: move the initial guest page table creation code to the host This patch moves the initial guest page table creation code to the host, so the launcher keeps working with PAE enabled configs. Signed-off-by: Matias Zabaljauregui Signed-off-by: Rusty Russell --- include/linux/lguest_launcher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/lguest_launcher.h b/include/linux/lguest_launcher.h index bd0eba76052..a53407a4165 100644 --- a/include/linux/lguest_launcher.h +++ b/include/linux/lguest_launcher.h @@ -54,7 +54,7 @@ struct lguest_vqconfig { /* Write command first word is a request. */ enum lguest_req { - LHREQ_INITIALIZE, /* + base, pfnlimit, pgdir, start */ + LHREQ_INITIALIZE, /* + base, pfnlimit, start */ LHREQ_GETDMA, /* No longer used */ LHREQ_IRQ, /* + irq */ LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */ -- cgit v1.2.3 From 26d5f3a3fe917232cb77e2e3450f7d7f8698259c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 7 Dec 2008 13:19:29 -0300 Subject: V4L/DVB (9772): saa7134: Add support for Kworld Plus TV Analog Lite PCI Thanks to Sistema Fenix (http://www.sistemafenix.com.br/) for sponsoring this development. Signed-off-by: Gilberto Signed-off-by: Mauro Carvalho Chehab --- include/media/ir-common.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/ir-common.h b/include/media/ir-common.h index 3a88e13a20e..5bf2ea00678 100644 --- a/include/media/ir-common.h +++ b/include/media/ir-common.h @@ -158,6 +158,7 @@ extern IR_KEYTAB_TYPE ir_codes_encore_enltv_fm53[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_real_audio_220_32_keys[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_msi_tvanywhere_plus[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE]; #endif /* -- cgit v1.2.3 From a2c8c68cca3dbb0c87f5034ab8ea29350174ec4a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Dec 2008 09:44:53 -0300 Subject: V4L/DVB (9785): soc-camera: merge .try_bus_param() into .try_fmt_cap() .try_bus_param() method from struct soc_camera_host_ops is only called at one location immediately before .try_fmt_cap(), there is no value in keeping these two methods separate, merge them. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 9231e2d908f..ee0e6b4bed3 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -73,7 +73,6 @@ struct soc_camera_host_ops { struct soc_camera_device *); int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); - int (*try_bus_param)(struct soc_camera_device *, __u32); int (*set_bus_param)(struct soc_camera_device *, __u32); unsigned int (*poll)(struct file *, poll_table *); }; -- cgit v1.2.3 From 25c4d74ea6f07f2aaa3df537619680ba967043f5 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Dec 2008 09:44:59 -0300 Subject: V4L/DVB (9787): soc-camera: let camera host drivers decide upon pixel format Pixel format requested by the user is not necessarily the same, as what a sensor driver provides. There are situations, when a camera host driver provides the required format, but requires a different format from the sensor. Further, the list of formats, supported by sensors is pretty static and can be pretty good described with a constant list of structures. Whereas decisions, made by camera host drivers to support requested formats can be quite complex, therefore it is better to let the host driver do the work. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index ee0e6b4bed3..8e8fcb75dac 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -105,6 +105,9 @@ extern void soc_camera_device_unregister(struct soc_camera_device *icd); extern int soc_camera_video_start(struct soc_camera_device *icd); extern void soc_camera_video_stop(struct soc_camera_device *icd); +extern const struct soc_camera_data_format *soc_camera_format_by_fourcc( + struct soc_camera_device *icd, unsigned int fourcc); + struct soc_camera_data_format { const char *name; unsigned int depth; -- cgit v1.2.3 From d8fac217c58f0101a351b9c8c80f1665bd9efef9 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Dec 2008 09:45:21 -0300 Subject: V4L/DVB (9788): soc-camera: simplify naming We anyway don't follow the s_fmt_vid_cap / g_fmt_vid_cap / try_fmt_vid_cap naming, and soc-camera is so far only about video capture, let's simplify operation names a bit further. set_fmt_cap / try_fmt_cap wasn't a very good choice too. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 8e8fcb75dac..b14f6ddc9e1 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -66,9 +66,8 @@ struct soc_camera_host_ops { void (*remove)(struct soc_camera_device *); int (*suspend)(struct soc_camera_device *, pm_message_t state); int (*resume)(struct soc_camera_device *); - int (*set_fmt_cap)(struct soc_camera_device *, __u32, - struct v4l2_rect *); - int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); + int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *); + int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, struct soc_camera_device *); int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); @@ -125,9 +124,8 @@ struct soc_camera_ops { int (*release)(struct soc_camera_device *); int (*start_capture)(struct soc_camera_device *); int (*stop_capture)(struct soc_camera_device *); - int (*set_fmt_cap)(struct soc_camera_device *, __u32, - struct v4l2_rect *); - int (*try_fmt_cap)(struct soc_camera_device *, struct v4l2_format *); + int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *); + int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); unsigned long (*query_bus_param)(struct soc_camera_device *); int (*set_bus_param)(struct soc_camera_device *, unsigned long); int (*get_chip_id)(struct soc_camera_device *, -- cgit v1.2.3 From d2e3dce083bc96b3bfb71603eaa1726181f7184b Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Dec 2008 09:45:24 -0300 Subject: V4L/DVB (9789): soc-camera: add a per-camera device host private data pointer This pointer will be used by pxa_camera.c to point to its pixel format data. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index b14f6ddc9e1..dddaf45c958 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -42,6 +42,7 @@ struct soc_camera_device { const struct soc_camera_data_format *formats; int num_formats; struct module *owner; + void *host_priv; /* per-device host private data */ /* soc_camera.c private count. Only accessed with video_lock held */ int use_count; }; -- cgit v1.2.3 From c2786ad27104c558b92343e8816e18654aae1759 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 1 Dec 2008 09:45:27 -0300 Subject: V4L/DVB (9790): soc-camera: pixel format negotiation - core support Allocate and fill a list of formats, supported by this specific camera-host combination. Use it for format enumeration. Take care to stay backwards-compatible. Camera hosts rely on sensor formats available, as well as host specific translations. We add a structure so that hosts can define a translation table and use it for format check and setup. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Robert Jarzmik Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index dddaf45c958..da57ffdaec4 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -41,6 +41,8 @@ struct soc_camera_device { const struct soc_camera_data_format *current_fmt; const struct soc_camera_data_format *formats; int num_formats; + struct soc_camera_format_xlate *user_formats; + int num_user_formats; struct module *owner; void *host_priv; /* per-device host private data */ /* soc_camera.c private count. Only accessed with video_lock held */ @@ -65,8 +67,10 @@ struct soc_camera_host_ops { struct module *owner; int (*add)(struct soc_camera_device *); void (*remove)(struct soc_camera_device *); - int (*suspend)(struct soc_camera_device *, pm_message_t state); + int (*suspend)(struct soc_camera_device *, pm_message_t); int (*resume)(struct soc_camera_device *); + int (*get_formats)(struct soc_camera_device *, int, + struct soc_camera_format_xlate *); int (*set_fmt)(struct soc_camera_device *, __u32, struct v4l2_rect *); int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, @@ -107,6 +111,8 @@ extern void soc_camera_video_stop(struct soc_camera_device *icd); extern const struct soc_camera_data_format *soc_camera_format_by_fourcc( struct soc_camera_device *icd, unsigned int fourcc); +extern const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( + struct soc_camera_device *icd, unsigned int fourcc); struct soc_camera_data_format { const char *name; @@ -115,6 +121,23 @@ struct soc_camera_data_format { enum v4l2_colorspace colorspace; }; +/** + * struct soc_camera_format_xlate - match between host and sensor formats + * @cam_fmt: sensor format provided by the sensor + * @host_fmt: host format after host translation from cam_fmt + * @buswidth: bus width for this format + * + * Host and sensor translation structure. Used in table of host and sensor + * formats matchings in soc_camera_device. A host can override the generic list + * generation by implementing get_formats(), and use it for format checks and + * format setup. + */ +struct soc_camera_format_xlate { + const struct soc_camera_data_format *cam_fmt; + const struct soc_camera_data_format *host_fmt; + unsigned char buswidth; +}; + struct soc_camera_ops { struct module *owner; int (*probe)(struct soc_camera_device *); -- cgit v1.2.3 From 67bc04dd04bfe6a6337a9c6773e4c36645360332 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Fri, 5 Dec 2008 10:13:40 -0300 Subject: V4L/DVB (9816): v4l2-int-if: add three new ioctls for std handling and routing These changes are needed for the new TVP514x driver. Signed-off-by: Brijesh Jadav Signed-off-by: Hardik Shah Signed-off-by: Manjunath Hadli Signed-off-by: R Sivaraj Signed-off-by: Vaibhav Hiremath Signed-off-by: Karicheri Muralidharan Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-int-device.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h index 9c2df41dbf9..ecda3c72583 100644 --- a/include/media/v4l2-int-device.h +++ b/include/media/v4l2-int-device.h @@ -183,6 +183,9 @@ enum v4l2_int_ioctl_num { vidioc_int_s_crop_num, vidioc_int_g_parm_num, vidioc_int_s_parm_num, + vidioc_int_querystd_num, + vidioc_int_s_std_num, + vidioc_int_s_video_routing_num, /* * @@ -284,6 +287,9 @@ V4L2_INT_WRAPPER_1(g_crop, struct v4l2_crop, *); V4L2_INT_WRAPPER_1(s_crop, struct v4l2_crop, *); V4L2_INT_WRAPPER_1(g_parm, struct v4l2_streamparm, *); V4L2_INT_WRAPPER_1(s_parm, struct v4l2_streamparm, *); +V4L2_INT_WRAPPER_1(querystd, v4l2_std_id, *); +V4L2_INT_WRAPPER_1(s_std, v4l2_std_id, *); +V4L2_INT_WRAPPER_1(s_video_routing, struct v4l2_routing, *); V4L2_INT_WRAPPER_0(dev_init); V4L2_INT_WRAPPER_0(dev_exit); -- cgit v1.2.3 From 07b1747c8d0bb463311f9dd05d4c013765abe2eb Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Fri, 5 Dec 2008 10:19:36 -0300 Subject: V4L/DVB (9817): v4l: add new tvp514x I2C video decoder driver Signed-off-by: Brijesh Jadav Signed-off-by: Hardik Shah Signed-off-by: Manjunath Hadli Signed-off-by: R Sivaraj Signed-off-by: Vaibhav Hiremath Signed-off-by: Karicheri Muralidharan Signed-off-by: Hans Verkuil Reviewed-by: Hans Verkuil Reviewed-by: David Brownell Signed-off-by: Mauro Carvalho Chehab --- include/media/tvp514x.h | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 include/media/tvp514x.h (limited to 'include') diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h new file mode 100644 index 00000000000..5e7ee968c6d --- /dev/null +++ b/include/media/tvp514x.h @@ -0,0 +1,118 @@ +/* + * drivers/media/video/tvp514x.h + * + * Copyright (C) 2008 Texas Instruments Inc + * Author: Vaibhav Hiremath + * + * Contributors: + * Sivaraj R + * Brijesh R Jadav + * Hardik Shah + * Manjunath Hadli + * Karicheri Muralidharan + * + * This package is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _TVP514X_H +#define _TVP514X_H + +/* + * Other macros + */ +#define TVP514X_MODULE_NAME "tvp514x" + +#define TVP514X_XCLK_BT656 (27000000) + +/* Number of pixels and number of lines per frame for different standards */ +#define NTSC_NUM_ACTIVE_PIXELS (720) +#define NTSC_NUM_ACTIVE_LINES (480) +#define PAL_NUM_ACTIVE_PIXELS (720) +#define PAL_NUM_ACTIVE_LINES (576) + +/** + * enum tvp514x_input - enum for different decoder input pin + * configuration. + */ +enum tvp514x_input { + /* + * CVBS input selection + */ + INPUT_CVBS_VI1A = 0x0, + INPUT_CVBS_VI1B, + INPUT_CVBS_VI1C, + INPUT_CVBS_VI2A = 0x04, + INPUT_CVBS_VI2B, + INPUT_CVBS_VI2C, + INPUT_CVBS_VI3A = 0x08, + INPUT_CVBS_VI3B, + INPUT_CVBS_VI3C, + INPUT_CVBS_VI4A = 0x0C, + /* + * S-Video input selection + */ + INPUT_SVIDEO_VI2A_VI1A = 0x44, + INPUT_SVIDEO_VI2B_VI1B, + INPUT_SVIDEO_VI2C_VI1C, + INPUT_SVIDEO_VI2A_VI3A = 0x54, + INPUT_SVIDEO_VI2B_VI3B, + INPUT_SVIDEO_VI2C_VI3C, + INPUT_SVIDEO_VI4A_VI1A = 0x4C, + INPUT_SVIDEO_VI4A_VI1B, + INPUT_SVIDEO_VI4A_VI1C, + INPUT_SVIDEO_VI4A_VI3A = 0x5C, + INPUT_SVIDEO_VI4A_VI3B, + INPUT_SVIDEO_VI4A_VI3C, + + /* Need to add entries for + * RGB, YPbPr and SCART. + */ + INPUT_INVALID +}; + +/** + * enum tvp514x_output - enum for output format + * supported. + * + */ +enum tvp514x_output { + OUTPUT_10BIT_422_EMBEDDED_SYNC = 0, + OUTPUT_20BIT_422_SEPERATE_SYNC, + OUTPUT_10BIT_422_SEPERATE_SYNC = 3, + OUTPUT_INVALID +}; + +/** + * struct tvp514x_platform_data - Platform data values and access functions. + * @power_set: Power state access function, zero is off, non-zero is on. + * @ifparm: Interface parameters access function. + * @priv_data_set: Device private data (pointer) access function. + * @clk_polarity: Clock polarity of the current interface. + * @ hs_polarity: HSYNC Polarity configuration for current interface. + * @ vs_polarity: VSYNC Polarity configuration for current interface. + */ +struct tvp514x_platform_data { + char *master; + int (*power_set) (enum v4l2_power on); + int (*ifparm) (struct v4l2_ifparm *p); + int (*priv_data_set) (void *); + /* Interface control params */ + bool clk_polarity; + bool hs_polarity; + bool vs_polarity; +}; + + +#endif /* ifndef _TVP514X_H */ -- cgit v1.2.3 From 2a1fcdf08230522bd5024f91da24aaa6e8d81f59 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 29 Nov 2008 21:36:58 -0300 Subject: V4L/DVB (9820): v4l2: add v4l2_device and v4l2_subdev structs to the v4l2 framework. Start implementing a proper v4l2 framework as discussed during the Linux Plumbers Conference 2008. Introduces v4l2_device (for device instances) and v4l2_subdev (representing sub-device instances). Signed-off-by: Hans Verkuil Reviewed-by: Laurent Pinchart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Andy Walls Reviewed-by: David Brownell Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-device.h | 109 +++++++++++++++++++++++++ include/media/v4l2-subdev.h | 188 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 include/media/v4l2-device.h create mode 100644 include/media/v4l2-subdev.h (limited to 'include') diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h new file mode 100644 index 00000000000..97b283a0428 --- /dev/null +++ b/include/media/v4l2-device.h @@ -0,0 +1,109 @@ +/* + V4L2 device support header. + + Copyright (C) 2008 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L2_DEVICE_H +#define _V4L2_DEVICE_H + +#include + +/* Each instance of a V4L2 device should create the v4l2_device struct, + either stand-alone or embedded in a larger struct. + + It allows easy access to sub-devices (see v4l2-subdev.h) and provides + basic V4L2 device-level support. + */ + +#define V4L2_DEVICE_NAME_SIZE (BUS_ID_SIZE + 16) + +struct v4l2_device { + /* dev->driver_data points to this struct */ + struct device *dev; + /* used to keep track of the registered subdevs */ + struct list_head subdevs; + /* lock this struct; can be used by the driver as well if this + struct is embedded into a larger struct. */ + spinlock_t lock; + /* unique device name, by default the driver name + bus ID */ + char name[V4L2_DEVICE_NAME_SIZE]; +}; + +/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev */ +int __must_check v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); +/* Set v4l2_dev->dev->driver_data to NULL and unregister all sub-devices */ +void v4l2_device_unregister(struct v4l2_device *v4l2_dev); + +/* Register a subdev with a v4l2 device. While registered the subdev module + is marked as in-use. An error is returned if the module is no longer + loaded when you attempt to register it. */ +int __must_check v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd); +/* Unregister a subdev with a v4l2 device. Can also be called if the subdev + wasn't registered. In that case it will do nothing. */ +void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); + +/* Iterate over all subdevs. */ +#define v4l2_device_for_each_subdev(sd, dev) \ + list_for_each_entry(sd, &(dev)->subdevs, list) + +/* Call the specified callback for all subdevs matching the condition. + Ignore any errors. Note that you cannot add or delete a subdev + while walking the subdevs list. */ +#define __v4l2_device_call_subdevs(dev, cond, o, f, args...) \ + do { \ + struct v4l2_subdev *sd; \ + \ + list_for_each_entry(sd, &(dev)->subdevs, list) \ + if ((cond) && sd->ops->o && sd->ops->o->f) \ + sd->ops->o->f(sd , ##args); \ + } while (0) + +/* Call the specified callback for all subdevs matching the condition. + If the callback returns an error other than 0 or -ENOIOCTLCMD, then + return with that error code. Note that you cannot add or delete a + subdev while walking the subdevs list. */ +#define __v4l2_device_call_subdevs_until_err(dev, cond, o, f, args...) \ +({ \ + struct v4l2_subdev *sd; \ + int err = 0; \ + \ + list_for_each_entry(sd, &(dev)->subdevs, list) { \ + if ((cond) && sd->ops->o && sd->ops->o->f) \ + err = sd->ops->o->f(sd , ##args); \ + if (err && err != -ENOIOCTLCMD) \ + break; \ + } \ + (err == -ENOIOCTLCMD) ? 0 : err; \ +}) + +/* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). Ignore any errors. Note that you cannot add or delete + a subdev while walking the subdevs list. */ +#define v4l2_device_call_all(dev, grp_id, o, f, args...) \ + __v4l2_device_call_subdevs(dev, \ + !(grp_id) || sd->grp_id == (grp_id), o, f , ##args) + +/* Call the specified callback for all subdevs matching grp_id (if 0, then + match them all). If the callback returns an error other than 0 or + -ENOIOCTLCMD, then return with that error code. Note that you cannot + add or delete a subdev while walking the subdevs list. */ +#define v4l2_device_call_until_err(dev, grp_id, o, f, args...) \ + __v4l2_device_call_subdevs_until_err(dev, \ + !(grp_id) || sd->grp_id == (grp_id), o, f , ##args) + +#endif diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h new file mode 100644 index 00000000000..bc9e0fbf282 --- /dev/null +++ b/include/media/v4l2-subdev.h @@ -0,0 +1,188 @@ +/* + V4L2 sub-device support header. + + Copyright (C) 2008 Hans Verkuil + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _V4L2_SUBDEV_H +#define _V4L2_SUBDEV_H + +#include + +struct v4l2_device; +struct v4l2_subdev; +struct tuner_setup; + +/* Sub-devices are devices that are connected somehow to the main bridge + device. These devices are usually audio/video muxers/encoders/decoders or + sensors and webcam controllers. + + Usually these devices are controlled through an i2c bus, but other busses + may also be used. + + The v4l2_subdev struct provides a way of accessing these devices in a + generic manner. Most operations that these sub-devices support fall in + a few categories: core ops, audio ops, video ops and tuner ops. + + More categories can be added if needed, although this should remain a + limited set (no more than approx. 8 categories). + + Each category has its own set of ops that subdev drivers can implement. + + A subdev driver can leave the pointer to the category ops NULL if + it does not implement them (e.g. an audio subdev will generally not + implement the video category ops). The exception is the core category: + this must always be present. + + These ops are all used internally so it is no problem to change, remove + or add ops or move ops from one to another category. Currently these + ops are based on the original ioctls, but since ops are not limited to + one argument there is room for improvement here once all i2c subdev + drivers are converted to use these ops. + */ + +/* Core ops: it is highly recommended to implement at least these ops: + + g_chip_ident + log_status + g_register + s_register + + This provides basic debugging support. + + The ioctl ops is meant for generic ioctl-like commands. Depending on + the use-case it might be better to use subdev-specific ops (currently + not yet implemented) since ops provide proper type-checking. + */ +struct v4l2_subdev_core_ops { + int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_chip_ident *chip); + int (*log_status)(struct v4l2_subdev *sd); + int (*init)(struct v4l2_subdev *sd, u32 val); + int (*s_standby)(struct v4l2_subdev *sd, u32 standby); + int (*reset)(struct v4l2_subdev *sd, u32 val); + int (*s_gpio)(struct v4l2_subdev *sd, u32 val); + int (*queryctrl)(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc); + int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); + int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); + int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); + int (*ioctl)(struct v4l2_subdev *sd, int cmd, void *arg); +#ifdef CONFIG_VIDEO_ADV_DEBUG + int (*g_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); + int (*s_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); +#endif +}; + +struct v4l2_subdev_tuner_ops { + int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); + int (*s_radio)(struct v4l2_subdev *sd); + int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); + int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); + int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt); + int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt); + int (*s_std)(struct v4l2_subdev *sd, v4l2_std_id norm); + int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type); + int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config); +}; + +struct v4l2_subdev_audio_ops { + int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq); + int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq); + int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route); +}; + +struct v4l2_subdev_video_ops { + int (*s_routing)(struct v4l2_subdev *sd, const struct v4l2_routing *route); + int (*s_crystal_freq)(struct v4l2_subdev *sd, struct v4l2_crystal_freq *freq); + int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line); + int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data); + int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data); + int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); + int (*s_stream)(struct v4l2_subdev *sd, int enable); + int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); + int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); +}; + +struct v4l2_subdev_ops { + const struct v4l2_subdev_core_ops *core; + const struct v4l2_subdev_tuner_ops *tuner; + const struct v4l2_subdev_audio_ops *audio; + const struct v4l2_subdev_video_ops *video; +}; + +#define V4L2_SUBDEV_NAME_SIZE 32 + +/* Each instance of a subdev driver should create this struct, either + stand-alone or embedded in a larger struct. + */ +struct v4l2_subdev { + struct list_head list; + struct module *owner; + struct v4l2_device *dev; + const struct v4l2_subdev_ops *ops; + /* name must be unique */ + char name[V4L2_SUBDEV_NAME_SIZE]; + /* can be used to group similar subdevs, value is driver-specific */ + u32 grp_id; + /* pointer to private data */ + void *priv; +}; + +static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) +{ + sd->priv = p; +} + +static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) +{ + return sd->priv; +} + +/* Convert an ioctl-type command to the proper v4l2_subdev_ops function call. + This is used by subdev modules that can be called by both old-style ioctl + commands and through the v4l2_subdev_ops. + + The ioctl API of the subdev driver can call this function to call the + right ops based on the ioctl cmd and arg. + + Once all subdev drivers have been converted and all drivers no longer + use the ioctl interface, then this function can be removed. + */ +int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg); + +static inline void v4l2_subdev_init(struct v4l2_subdev *sd, + const struct v4l2_subdev_ops *ops) +{ + INIT_LIST_HEAD(&sd->list); + /* ops->core MUST be set */ + BUG_ON(!ops || !ops->core); + sd->ops = ops; + sd->dev = NULL; + sd->name[0] = '\0'; + sd->grp_id = 0; + sd->priv = NULL; +} + +/* Call an ops of a v4l2_subdev, doing the right checks against + NULL pointers. + + Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip); + */ +#define v4l2_subdev_call(sd, o, f, args...) \ + (!(sd) ? -ENODEV : (((sd) && (sd)->ops->o && (sd)->ops->o->f) ? \ + (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) + +#endif -- cgit v1.2.3 From dd99120c7165c6873a423977d1eaa41b6e2d1ffc Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 23 Nov 2008 12:19:45 -0300 Subject: V4L/DVB (9821): v4l2-common: add i2c helper functions Add helper functions to load i2c sub-devices, integrating them into the v4l2-framework. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-common.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 2f8719abf5c..f99c866d8c3 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -57,6 +57,29 @@ /* ------------------------------------------------------------------------- */ +/* These printk constructs can be used with v4l2_device and v4l2_subdev */ +#define v4l2_printk(level, dev, fmt, arg...) \ + printk(level "%s: " fmt, (dev)->name , ## arg) + +#define v4l2_err(dev, fmt, arg...) \ + v4l2_printk(KERN_ERR, dev, fmt , ## arg) + +#define v4l2_warn(dev, fmt, arg...) \ + v4l2_printk(KERN_WARNING, dev, fmt , ## arg) + +#define v4l2_info(dev, fmt, arg...) \ + v4l2_printk(KERN_INFO, dev, fmt , ## arg) + +/* These three macros assume that the debug level is set with a module + parameter called 'debug'. */ +#define v4l2_dbg(level, debug, dev, fmt, arg...) \ + do { \ + if (debug >= (level)) \ + v4l2_printk(KERN_DEBUG, dev, fmt , ## arg); \ + } while (0) + +/* ------------------------------------------------------------------------- */ + /* Priority helper functions */ struct v4l2_prio_state { @@ -104,11 +127,29 @@ struct i2c_driver; struct i2c_adapter; struct i2c_client; struct i2c_device_id; +struct v4l2_device; +struct v4l2_subdev; +struct v4l2_subdev_ops; int v4l2_i2c_attach(struct i2c_adapter *adapter, int address, struct i2c_driver *driver, const char *name, int (*probe)(struct i2c_client *, const struct i2c_device_id *)); +/* Load an i2c module and return an initialized v4l2_subdev struct. + Only call request_module if module_name != NULL. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter, + const char *module_name, const char *client_type, u8 addr); +/* Probe and load an i2c module and return an initialized v4l2_subdev struct. + Only call request_module if module_name != NULL. + The client_type argument is the name of the chip that's on the adapter. */ +struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter, + const char *module_name, const char *client_type, + const unsigned short *addrs); +/* Initialize an v4l2_subdev with data from an i2c_client struct */ +void v4l2_i2c_subdev_init(struct v4l2_subdev *sd, struct i2c_client *client, + const struct v4l2_subdev_ops *ops); + /* ------------------------------------------------------------------------- */ /* Internal ioctls */ -- cgit v1.2.3 From 0877258d98154565def498833ccb208234c85084 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 14 Dec 2008 16:21:16 -0300 Subject: V4L/DVB (9897): v4l2: Add camera zoom controls The zoom controls move the zoom lens group to a an absolute position, as a relative displacement or at a given speed until reaching physical device limits. Positive values move the zoom lens group towards the telephoto direction, negative values towards the wide-angle direction. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index ec311d4616c..e450a92a622 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1118,6 +1118,10 @@ enum v4l2_exposure_auto_type { #define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11) #define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12) +#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13) +#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) +#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) + /* * T U N I N G */ -- cgit v1.2.3 From 046425f8c4ac431db00c09a6d9fba16560b8e5b9 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sun, 14 Dec 2008 16:22:05 -0300 Subject: V4L/DVB (9898): v4l2: Add privacy control The privacy control prevents video from being acquired by the camera. A true value indicates that no image can be captured. Devices that implement the privacy control must support read access and may support write access. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e450a92a622..6e6743bd0f9 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1122,6 +1122,8 @@ enum v4l2_exposure_auto_type { #define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14) #define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15) +#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16) + /* * T U N I N G */ -- cgit v1.2.3 From 92f45badbbaccdbc1be25085292a1e258948e221 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 21 Dec 2008 10:35:25 -0300 Subject: V4L/DVB (9932): v4l2-compat32: fix 32-64 compatibility module Added all missing v4l1/2 ioctls and fix several broken conversions. Partially based on work done by Cody Pisto . Tested-by: Brandon Jenkins Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 6e6743bd0f9..e2cfd6add78 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1465,6 +1465,8 @@ struct v4l2_chip_ident { #define VIDIOC_G_CHIP_IDENT _IOWR('V', 81, struct v4l2_chip_ident) #endif #define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct v4l2_hw_freq_seek) +/* Reminder: when adding new ioctls please add support for them to + drivers/media/video/v4l2-compat-ioctl32.c as well! */ #ifdef __OLD_VIDIOC_ /* for compatibility, will go away some day */ -- cgit v1.2.3 From 77587c5627aab50636ea0f93c28d2013cd0b7004 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 19 Dec 2008 07:18:38 -0300 Subject: V4L/DVB (9940): bt832: remove this driver The bt832 i2c driver was never used or even compiled and is no longer maintained. It is now removed completely. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/i2c-addr.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/media/i2c-addr.h b/include/media/i2c-addr.h index e7ff44a35ca..5d0f56054d2 100644 --- a/include/media/i2c-addr.h +++ b/include/media/i2c-addr.h @@ -12,8 +12,6 @@ /* bttv address list */ #define I2C_ADDR_TSA5522 0xc2 #define I2C_ADDR_TDA7432 0x8a -#define I2C_ADDR_BT832_ALT1 0x88 -#define I2C_ADDR_BT832_ALT2 0x8a // alternate setting #define I2C_ADDR_TDA8425 0x82 #define I2C_ADDR_TDA9840 0x84 #define I2C_ADDR_TDA9850 0xb6 /* also used by 9855,9873 */ -- cgit v1.2.3 From 4b00eb25340c1a9b9eedaf0bc5b0f0d18eddb028 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 19 Dec 2008 11:17:56 -0300 Subject: V4L/DVB (9944): videodev2.h: fix typo. The comment said CX2584X instead of CX2341X. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e2cfd6add78..754c8d9685a 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1051,7 +1051,7 @@ enum v4l2_mpeg_video_bitrate_mode { #define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210) #define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211) -/* MPEG-class control IDs specific to the CX2584x driver as defined by V4L2 */ +/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */ #define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000) #define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0) enum v4l2_mpeg_cx2341x_video_spatial_filter_mode { -- cgit v1.2.3 From 531c98e71805b32e9ea35a218119100bbd2b7615 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Dec 2008 13:18:27 -0300 Subject: V4L/DVB (9953): em28xx: Add suport for debugging AC97 anciliary chips The em28xx driver can be coupled to an anciliary AC97 chip. This patch allows read/write AC97 registers directly. Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 754c8d9685a..e31144d2223 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -1376,6 +1376,7 @@ struct v4l2_streamparm { #define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */ #define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver ID */ #define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */ +#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */ struct v4l2_register { __u32 match_type; /* Match type */ -- cgit v1.2.3 From 1fe2740ff10b3de1aab8f88f2f05547e5f369035 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 18 Dec 2008 11:16:24 -0300 Subject: V4L/DVB (9957): v4l2-subdev: add g_sliced_vbi_cap and add NULL pointer checks Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index bc9e0fbf282..bca25e8eab6 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -110,6 +110,7 @@ struct v4l2_subdev_video_ops { int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line); int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data); int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data); + int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap); int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); int (*s_stream)(struct v4l2_subdev *sd, int enable); int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); -- cgit v1.2.3 From 035f8dc1e478c67ea2682fde8f26ee9d0982a2e7 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Thu, 18 Dec 2008 12:27:28 -0300 Subject: V4L/DVB (9960): v4l2-subdev: ioctl ops should use unsigned for cmd arg. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-subdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index bca25e8eab6..ceef016bb0b 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -79,7 +79,7 @@ struct v4l2_subdev_core_ops { int (*g_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); int (*s_ctrl)(struct v4l2_subdev *sd, struct v4l2_control *ctrl); int (*querymenu)(struct v4l2_subdev *sd, struct v4l2_querymenu *qm); - int (*ioctl)(struct v4l2_subdev *sd, int cmd, void *arg); + int (*ioctl)(struct v4l2_subdev *sd, unsigned int cmd, void *arg); #ifdef CONFIG_VIDEO_ADV_DEBUG int (*g_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); int (*s_register)(struct v4l2_subdev *sd, struct v4l2_register *reg); -- cgit v1.2.3 From bc97430510960846b6e8f2d62c503653031991e1 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 22 Dec 2008 20:34:18 -0300 Subject: V4L/DVB (9969): tvp5150: add support for VIDIOC_G_CHIP_IDENT ioctl Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-chip-ident.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index bfe5142e667..e3e5b53931d 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -70,6 +70,9 @@ enum { /* module vp27smpx: just ident 2700 */ V4L2_IDENT_VP27SMPX = 2700, + /* module tvp5150 */ + V4L2_IDENT_TVP5150 = 5150, + /* module cs5345: just ident 5345 */ V4L2_IDENT_CS5345 = 5345, -- cgit v1.2.3 From dc93a70cc7f92e1dbaf29fa7dfd914b0f618fb31 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 19 Dec 2008 21:28:27 -0300 Subject: V4L/DVB (9973): v4l2-dev: use the release callback from device instead of cdev Instead of relying on the cdev release callback we should rely on the release callback from the device struct. This requires that we use get_device/put_device to do proper refcounting. In order to do this safely v4l2-dev.c now sets up its own file_operations that call out to the driver's ops. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dev.h | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index a0a6b41c5e0..e0d72d2c6f0 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -26,6 +26,11 @@ struct v4l2_ioctl_callbacks; +/* Flag to mark the video_device struct as unregistered. + Drivers can set this flag if they want to block all future + device access. It is set by video_unregister_device. */ +#define V4L2_FL_UNREGISTERED (0) + /* * Newer version of video_device, handled by videodev2.c * This version moves redundant code from video device code to @@ -39,15 +44,17 @@ struct video_device /* sysfs */ struct device dev; /* v4l device */ - struct cdev cdev; /* character device */ - void (*cdev_release)(struct kobject *kobj); + struct cdev *cdev; /* character device */ struct device *parent; /* device parent */ /* device info */ char name[32]; int vfl_type; + /* 'minor' is set to -1 if the registration failed */ int minor; u16 num; + /* use bitops to set/clear/test flags */ + unsigned long flags; /* attribute to differentiate multiple indices on one physical device */ int index; @@ -58,7 +65,7 @@ struct video_device v4l2_std_id current_norm; /* Current tvnorm */ /* callbacks */ - void (*release)(struct video_device *vfd); + void (*release)(struct video_device *vdev); /* ioctl callbacks */ const struct v4l2_ioctl_ops *ioctl_ops; @@ -67,36 +74,41 @@ struct video_device /* dev to video-device */ #define to_video_device(cd) container_of(cd, struct video_device, dev) -/* Register and unregister devices. Note that if video_register_device fails, +/* Register video devices. Note that if video_register_device fails, the release() callback of the video_device structure is *not* called, so the caller is responsible for freeing any data. Usually that means that - you call video_device_release() on failure. */ -int __must_check video_register_device(struct video_device *vfd, int type, int nr); -int __must_check video_register_device_index(struct video_device *vfd, + you call video_device_release() on failure. + + Also note that vdev->minor is set to -1 if the registration failed. */ +int __must_check video_register_device(struct video_device *vdev, int type, int nr); +int __must_check video_register_device_index(struct video_device *vdev, int type, int nr, int index); -void video_unregister_device(struct video_device *vfd); + +/* Unregister video devices. Will do nothing if vdev == NULL or + vdev->minor < 0. */ +void video_unregister_device(struct video_device *vdev); /* helper functions to alloc/release struct video_device, the latter can also be used for video_device->release(). */ struct video_device * __must_check video_device_alloc(void); -/* this release function frees the vfd pointer */ -void video_device_release(struct video_device *vfd); +/* this release function frees the vdev pointer */ +void video_device_release(struct video_device *vdev); /* this release function does nothing, use when the video_device is a static global struct. Note that having a static video_device is a dubious construction at best. */ -void video_device_release_empty(struct video_device *vfd); +void video_device_release_empty(struct video_device *vdev); /* helper functions to access driver private data. */ -static inline void *video_get_drvdata(struct video_device *dev) +static inline void *video_get_drvdata(struct video_device *vdev) { - return dev_get_drvdata(&dev->dev); + return dev_get_drvdata(&vdev->dev); } -static inline void video_set_drvdata(struct video_device *dev, void *data) +static inline void video_set_drvdata(struct video_device *vdev, void *data) { - dev_set_drvdata(&dev->dev, data); + dev_set_drvdata(&vdev->dev, data); } struct video_device *video_devdata(struct file *file); @@ -108,4 +120,9 @@ static inline void *video_drvdata(struct file *file) return video_get_drvdata(video_devdata(file)); } +static inline int video_is_unregistered(struct video_device *vdev) +{ + return test_bit(V4L2_FL_UNREGISTERED, &vdev->flags); +} + #endif /* _V4L2_DEV_H */ -- cgit v1.2.3 From 9bea3514dd4a44490b53cc52498b2967e48056dd Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 23 Dec 2008 07:35:17 -0300 Subject: V4L/DVB (9974): v4l2-dev: allow drivers to pass v4l2_device as parent Drivers that use v4l2_device can set that as parent pointer in the v4l2_dev field instead of using the struct device parent field. This allows v4l2-dev.c to check whether this driver is v4l2_device based, and if so then it can offer additional services. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-dev.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h index e0d72d2c6f0..0a88d1d17d3 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -25,6 +25,7 @@ #define VFL_TYPE_MAX 4 struct v4l2_ioctl_callbacks; +struct v4l2_device; /* Flag to mark the video_device struct as unregistered. Drivers can set this flag if they want to block all future @@ -45,7 +46,10 @@ struct video_device /* sysfs */ struct device dev; /* v4l device */ struct cdev *cdev; /* character device */ + + /* Set either parent or v4l2_dev if your driver uses v4l2_device */ struct device *parent; /* device parent */ + struct v4l2_device *v4l2_dev; /* v4l2_device parent */ /* device info */ char name[32]; -- cgit v1.2.3 From aeabc882a3ad9a320783815e0446b12526fd2102 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 18 Dec 2008 11:05:49 -0300 Subject: V4L/DVB (10068): Change device ID selection method on ov772x driver Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-chip-ident.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index e3e5b53931d..56974e689a4 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -60,7 +60,7 @@ enum { /* OmniVision sensors: reserved range 250-299 */ V4L2_IDENT_OV7670 = 250, - V4L2_IDENT_OV772X = 251, + V4L2_IDENT_OV7720 = 251, /* Conexant MPEG encoder/decoders: reserved range 410-420 */ V4L2_IDENT_CX23415 = 415, -- cgit v1.2.3 From 3cac2cab4f5b7eb7d9f7afc42cb251c45b96be36 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 18 Dec 2008 11:07:11 -0300 Subject: V4L/DVB (10069): Add ov7725 support to ov772x driver Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-chip-ident.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 56974e689a4..15fd93caaf6 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -61,6 +61,7 @@ enum { /* OmniVision sensors: reserved range 250-299 */ V4L2_IDENT_OV7670 = 250, V4L2_IDENT_OV7720 = 251, + V4L2_IDENT_OV7725 = 252, /* Conexant MPEG encoder/decoders: reserved range 410-420 */ V4L2_IDENT_CX23415 = 415, -- cgit v1.2.3 From bd73b36f0c41b0c02ef4b10a307db1c43537e006 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Tue, 23 Dec 2008 05:54:45 -0300 Subject: V4L/DVB (10072): soc-camera: Add signal inversion flags to be used by camera drivers As reported by Antonio Ospite two platforms with a mt9m111 camera require opposite pixel clock polarity, which means one of them inverts it. This patch adds support for inversion flags and switches all available camera drivers to using them. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index da57ffdaec4..e6ed0d94ac1 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -81,11 +81,19 @@ struct soc_camera_host_ops { unsigned int (*poll)(struct file *, poll_table *); }; +#define SOCAM_SENSOR_INVERT_PCLK (1 << 0) +#define SOCAM_SENSOR_INVERT_MCLK (1 << 1) +#define SOCAM_SENSOR_INVERT_HSYNC (1 << 2) +#define SOCAM_SENSOR_INVERT_VSYNC (1 << 3) +#define SOCAM_SENSOR_INVERT_DATA (1 << 4) + struct soc_camera_link { /* Camera bus id, used to match a camera and a bus */ int bus_id; /* GPIO number to switch between 8 and 10 bit modes */ unsigned int gpio; + /* Per camera SOCAM_SENSOR_* bus flags */ + unsigned long flags; /* Optional callbacks to power on or off and reset the sensor */ int (*power)(struct device *, int); int (*reset)(struct device *); @@ -206,4 +214,7 @@ static inline unsigned long soc_camera_bus_param_compatible( return (!hsync || !vsync || !pclk) ? 0 : common_flags; } +extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, + unsigned long flags); + #endif -- cgit v1.2.3 From a9bef518cd78d569a3ff0b1ac2afa5e2d8b3573a Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 18 Dec 2008 11:34:20 -0300 Subject: V4L/DVB (10074): soc-camera: add camera sense data Add a struct soc_camera_sense, that can be used by camera host drivers to request additional information from a camera driver, for example, when changing data format. This struct can be extended in the future, its first use is to request the camera driver whether the pixel-clock frequency has changed. Tested-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index e6ed0d94ac1..38b826c608b 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -36,6 +36,7 @@ struct soc_camera_device { unsigned char iface; /* Host number */ unsigned char devnum; /* Device number per host */ unsigned char buswidth; /* See comment in .c */ + struct soc_camera_sense *sense; /* See comment in struct definition */ struct soc_camera_ops *ops; struct video_device *vdev; const struct soc_camera_data_format *current_fmt; @@ -172,6 +173,32 @@ struct soc_camera_ops { int num_controls; }; +#define SOCAM_SENSE_PCLK_CHANGED (1 << 0) + +/** + * This struct can be attached to struct soc_camera_device by the host driver + * to request sense from the camera, for example, when calling .set_fmt(). The + * host then can check which flags are set and verify respective values if any. + * For example, if SOCAM_SENSE_PCLK_CHANGED is set, it means, pixclock has + * changed during this operation. After completion the host should detach sense. + * + * @flags ored SOCAM_SENSE_* flags + * @master_clock if the host wants to be informed about pixel-clock + * change, it better set master_clock. + * @pixel_clock_max maximum pixel clock frequency supported by the host, + * camera is not allowed to exceed this. + * @pixel_clock if the camera driver changed pixel clock during this + * operation, it sets SOCAM_SENSE_PCLK_CHANGED, uses + * master_clock to calculate the new pixel-clock and + * sets this field. + */ +struct soc_camera_sense { + unsigned long flags; + unsigned long master_clock; + unsigned long pixel_clock_max; + unsigned long pixel_clock; +}; + static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( struct soc_camera_ops *ops, int id) { -- cgit v1.2.3 From 9b9fd6c71fb46a4a710040c8ef28f1e84b88a830 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Thu, 18 Dec 2008 11:42:54 -0300 Subject: V4L/DVB (10076): v4l: add chip ID for MT9M112 camera sensor from Micron The chip is largely compatible with MT9M111 and is going to be supported by the same driver. Signed-off-by: Mike Rapoport Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-chip-ident.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 15fd93caaf6..30448cd5175 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -171,6 +171,7 @@ enum { V4L2_IDENT_MT9M001C12ST = 45000, V4L2_IDENT_MT9M001C12STM = 45005, V4L2_IDENT_MT9M111 = 45007, + V4L2_IDENT_MT9M112 = 45008, V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ }; -- cgit v1.2.3 From 91962fa713bd8bf47434b02ac661fdc201365fa5 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 18 Dec 2008 11:45:00 -0300 Subject: V4L/DVB (10078): video: add NV16 and NV61 pixel formats This patch adds support for NV16 and NV61 pixel formats. These pixel formats use two planes; one for 8-bit Y values and one for interleaved 8-bit U and V values. NV16/NV61 formats are very similar to NV12/NV21 with the exception that NV16/NV61 are using the same number of lines for both planes. The difference between NV16 and NV61 is the U and V byte order. The fourcc values are extrapolated from the NV12/NV21 case. Signed-off-by: Magnus Damm Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index e31144d2223..1f126e30766 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -305,6 +305,8 @@ struct v4l2_pix_format { /* two planes -- one Y, one Cr + Cb interleaved */ #define V4L2_PIX_FMT_NV12 v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */ #define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ +#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ /* The following formats are not defined in the V4L2 specification */ #define V4L2_PIX_FMT_YUV410 v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */ -- cgit v1.2.3 From 1c3bb7431d16f7486a8523d54380bad89c485dc8 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 18 Dec 2008 12:28:54 -0300 Subject: V4L/DVB (10083): soc-camera: unify locking, play nicer with videobuf locking Move mutex from host drivers to camera device object, take into account videobuf locking. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 38b826c608b..8bae9a359d9 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -12,9 +12,10 @@ #ifndef SOC_CAMERA_H #define SOC_CAMERA_H +#include +#include #include #include -#include struct soc_camera_device { struct list_head list; @@ -45,9 +46,10 @@ struct soc_camera_device { struct soc_camera_format_xlate *user_formats; int num_user_formats; struct module *owner; - void *host_priv; /* per-device host private data */ - /* soc_camera.c private count. Only accessed with video_lock held */ + void *host_priv; /* Per-device host private data */ + /* soc_camera.c private count. Only accessed with .video_lock held */ int use_count; + struct mutex video_lock; /* Protects device data */ }; struct soc_camera_file { -- cgit v1.2.3 From 513791aba6266e0c15d5b697b97e956e83537f5a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 18 Dec 2008 12:46:45 -0300 Subject: V4L/DVB (10086): Add new set_std function on soc_camera This patch presents new method to be able to check v4l2_std_id Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 8bae9a359d9..26dede82057 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -165,6 +165,7 @@ struct soc_camera_ops { int (*set_bus_param)(struct soc_camera_device *, unsigned long); int (*get_chip_id)(struct soc_camera_device *, struct v4l2_chip_ident *); + int (*set_std)(struct soc_camera_device *, v4l2_std_id *); #ifdef CONFIG_VIDEO_ADV_DEBUG int (*get_register)(struct soc_camera_device *, struct v4l2_register *); int (*set_register)(struct soc_camera_device *, struct v4l2_register *); -- cgit v1.2.3 From 34d359db7d683e227f27595ad3702fb2ae96108a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 18 Dec 2008 12:47:46 -0300 Subject: V4L/DVB (10087): Add new enum_input function on soc_camera This patch presents new method to be able to select V4L2 input type Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 26dede82057..50f4447566d 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -166,6 +166,7 @@ struct soc_camera_ops { int (*get_chip_id)(struct soc_camera_device *, struct v4l2_chip_ident *); int (*set_std)(struct soc_camera_device *, v4l2_std_id *); + int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); #ifdef CONFIG_VIDEO_ADV_DEBUG int (*get_register)(struct soc_camera_device *, struct v4l2_register *); int (*set_register)(struct soc_camera_device *, struct v4l2_register *); -- cgit v1.2.3 From 042d87900217228f865654fa70fade8139bd42cf Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 19 Dec 2008 10:07:49 -0300 Subject: V4L/DVB (10093): soc-camera: add new bus width and signal polarity flags In preparation for i.MX31 camera host driver add flags for 4 and 15 bit bus widths and for data lines polarity inversion. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/soc_camera.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 50f4447566d..425b6a98c95 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -221,15 +221,20 @@ static inline struct v4l2_queryctrl const *soc_camera_find_qctrl( #define SOCAM_HSYNC_ACTIVE_LOW (1 << 3) #define SOCAM_VSYNC_ACTIVE_HIGH (1 << 4) #define SOCAM_VSYNC_ACTIVE_LOW (1 << 5) -#define SOCAM_DATAWIDTH_8 (1 << 6) -#define SOCAM_DATAWIDTH_9 (1 << 7) -#define SOCAM_DATAWIDTH_10 (1 << 8) -#define SOCAM_DATAWIDTH_16 (1 << 9) -#define SOCAM_PCLK_SAMPLE_RISING (1 << 10) -#define SOCAM_PCLK_SAMPLE_FALLING (1 << 11) - -#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_9 | \ - SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_16) +#define SOCAM_DATAWIDTH_4 (1 << 6) +#define SOCAM_DATAWIDTH_8 (1 << 7) +#define SOCAM_DATAWIDTH_9 (1 << 8) +#define SOCAM_DATAWIDTH_10 (1 << 9) +#define SOCAM_DATAWIDTH_15 (1 << 10) +#define SOCAM_DATAWIDTH_16 (1 << 11) +#define SOCAM_PCLK_SAMPLE_RISING (1 << 12) +#define SOCAM_PCLK_SAMPLE_FALLING (1 << 13) +#define SOCAM_DATA_ACTIVE_HIGH (1 << 14) +#define SOCAM_DATA_ACTIVE_LOW (1 << 15) + +#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \ + SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \ + SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_16) static inline unsigned long soc_camera_bus_param_compatible( unsigned long camera_flags, unsigned long bus_flags) -- cgit v1.2.3 From ed922a892e535c14035210b5be328af1f49561c8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 29 Dec 2008 06:04:06 -0300 Subject: V4L/DVB (10094): Add tw9910 driver This patch adds tw9910 driver that use soc_camera framework. It was tested on SH Migo-r board and mplayer. create mode 100644 drivers/media/video/tw9910.c create mode 100644 include/media/tw9910.h Signed-off-by: Kuninori Morimoto Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- include/media/tw9910.h | 39 +++++++++++++++++++++++++++++++++++++++ include/media/v4l2-chip-ident.h | 3 +++ 2 files changed, 42 insertions(+) create mode 100644 include/media/tw9910.h (limited to 'include') diff --git a/include/media/tw9910.h b/include/media/tw9910.h new file mode 100644 index 00000000000..73231e7880d --- /dev/null +++ b/include/media/tw9910.h @@ -0,0 +1,39 @@ +/* + * tw9910 Driver header + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Kuninori Morimoto + * + * Based on ov772x.h + * + * Copyright (C) Kuninori Morimoto + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __TW9910_H__ +#define __TW9910_H__ + +#include + +enum tw9910_mpout_pin { + TW9910_MPO_VLOSS, + TW9910_MPO_HLOCK, + TW9910_MPO_SLOCK, + TW9910_MPO_VLOCK, + TW9910_MPO_MONO, + TW9910_MPO_DET50, + TW9910_MPO_FIELD, + TW9910_MPO_RTCO, +}; + +struct tw9910_video_info { + unsigned long buswidth; + enum tw9910_mpout_pin mpout; + struct soc_camera_link link; +}; + + +#endif /* __TW9910_H__ */ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 30448cd5175..f9d42ad99b4 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -87,6 +87,9 @@ enum { /* module wm8775: just ident 8775 */ V4L2_IDENT_WM8775 = 8775, + /* module tw9910: just ident 9910 */ + V4L2_IDENT_TW9910 = 9910, + /* module cs53132a: just ident 53132 */ V4L2_IDENT_CS53l32A = 53132, -- cgit v1.2.3 From 4e96fd088cf6fb95ba4b212e5e72bac1e6d34e79 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 29 Dec 2008 06:04:59 -0300 Subject: V4L/DVB (10099): soc-camera: add support for MT9T031 CMOS camera sensor from Micron This camera is rather similar to MT9M001, but also has a couple of enhanced features, like pixel binning. create mode 100644 drivers/media/video/mt9t031.c Signed-off-by: Guennadi Liakhovetski Acked-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-chip-ident.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include') diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index f9d42ad99b4..43dbb659f1f 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -177,6 +177,7 @@ enum { V4L2_IDENT_MT9M112 = 45008, V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ + V4L2_IDENT_MT9T031 = 45020, }; #endif -- cgit v1.2.3 From 92ab7886119da6375a983713eedab444e32094f6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 29 Dec 2008 19:15:43 -0300 Subject: V4L/DVB (10110): v4l2-ioctl: Fix warnings when using .unlocked_ioctl = __video_ioctl2 This patch fixes this warning: drivers/media/video/gspca/gspca.c:1811: warning: initialization from incompatible pointer type The reason is that the returned argument should be a long, not an integer. Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h index c884432f938..fcdb58c4ce0 100644 --- a/include/media/v4l2-ioctl.h +++ b/include/media/v4l2-ioctl.h @@ -297,7 +297,7 @@ extern int video_usercopy(struct file *file, unsigned int cmd, /* Standard handlers for V4L ioctl's */ /* This prototype is used on fops.unlocked_ioctl */ -extern int __video_ioctl2(struct file *file, +extern long __video_ioctl2(struct file *file, unsigned int cmd, unsigned long arg); /* This prototype is used on fops.ioctl -- cgit v1.2.3