From 63cc8c75156462d4b42cbdd76c293b7eee7ddbfe Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 12 May 2008 15:44:40 +0200 Subject: percpu: introduce DEFINE_PER_CPU_PAGE_ALIGNED() macro While examining holes in percpu section I found this : c05f5000 D per_cpu__current_task c05f5000 D __per_cpu_start c05f5004 D per_cpu__cpu_number c05f5008 D per_cpu__irq_regs c05f500c d per_cpu__cpu_devices c05f5040 D per_cpu__cyc2ns c05f6000 d per_cpu__cpuid4_info c05f6004 d per_cpu__cache_kobject c05f6008 d per_cpu__index_kobject c05f7000 D per_cpu__gdt_page This is because gdt_page is a percpu variable, defined with a page alignement, and linker is doing its job, two times because of .o nesting in the build process. I introduced a new macro DEFINE_PER_CPU_PAGE_ALIGNED() to avoid wasting this space. All page aligned variables (only one at this time) are put in a separate subsection .data.percpu.page_aligned, at the very begining of percpu zone. Before patch , on a x86_32 machine : .data.percpu 30232 3227471872 .data.percpu 22168 3227471872 Thats 8064 bytes saved for each CPU. Signed-off-by: Eric Dumazet Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/percpu.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 4cdd393e71e..2edacc8e6b8 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h @@ -23,12 +23,19 @@ __attribute__((__section__(SHARED_ALIGNED_SECTION))) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name \ ____cacheline_aligned_in_smp + +#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ + __attribute__((__section__(".data.percpu.page_aligned"))) \ + PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name #else #define DEFINE_PER_CPU(type, name) \ PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name #define DEFINE_PER_CPU_SHARED_ALIGNED(type, name) \ DEFINE_PER_CPU(type, name) + +#define DEFINE_PER_CPU_PAGE_ALIGNED(type, name) \ + DEFINE_PER_CPU(type, name) #endif #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) -- cgit v1.2.3 From 70ef6d595b6e51618a0cbe44b848d8c9db11a010 Mon Sep 17 00:00:00 2001 From: Kevin Hao Date: Thu, 29 May 2008 18:41:04 +0800 Subject: x86: get irq for hpet timer HPET timer's IRQ is 0 by default. So we have to select which irq will be used by these timers. We wait to set the timer's irq until we really open it in order to reduce the chance of conflicting with other device. Signed-off-by: Kevin Hao Signed-off-by: Ingo Molnar --- include/linux/hpet.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hpet.h b/include/linux/hpet.h index 2dc29ce6c8e..6d2626b63a9 100644 --- a/include/linux/hpet.h +++ b/include/linux/hpet.h @@ -37,6 +37,7 @@ struct hpet { #define hpet_compare _u1._hpet_compare #define HPET_MAX_TIMERS (32) +#define HPET_MAX_IRQ (32) /* * HPET general capabilities register @@ -64,7 +65,7 @@ struct hpet { */ #define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL) -#define Tn_INI_ROUTE_CAP_SHIFT (32UL) +#define Tn_INT_ROUTE_CAP_SHIFT (32UL) #define Tn_FSB_INT_DELCAP_MASK (0x8000UL) #define Tn_FSB_INT_DELCAP_SHIFT (15) #define Tn_FSB_EN_CNF_MASK (0x4000UL) -- cgit v1.2.3 From 59ea746337c69f6a5f1bc4d5e8544b3cbf12f801 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 12 Jun 2008 13:56:40 +0200 Subject: MM: virtual address debug Add some (configurable) expensive sanity checking to catch wrong address translations on x86. - create linux/mmdebug.h file to be able include this file in asm headers to not get unsolvable loops in header files - __phys_addr on x86_32 became a function in ioremap.c since PAGE_OFFSET, is_vmalloc_addr and VMALLOC_* non-constasts are undefined if declared in page_32.h - add __phys_addr_const for initializing doublefault_tss.__cr3 Tested on 386, 386pae, x86_64 and x86_64 numa=fake=2. Contains Andi's enable numa virtual address debug patch. Signed-off-by: Jiri Slaby Cc: Andi Kleen Signed-off-by: Ingo Molnar --- include/linux/mm.h | 7 +------ include/linux/mmdebug.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 include/linux/mmdebug.h (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 586a943cab0..3414a8813e9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -210,12 +211,6 @@ struct inode; */ #include -#ifdef CONFIG_DEBUG_VM -#define VM_BUG_ON(cond) BUG_ON(cond) -#else -#define VM_BUG_ON(condition) do { } while(0) -#endif - /* * Methods to modify the page usage count. * diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h new file mode 100644 index 00000000000..860ed1a71bb --- /dev/null +++ b/include/linux/mmdebug.h @@ -0,0 +1,18 @@ +#ifndef LINUX_MM_DEBUG_H +#define LINUX_MM_DEBUG_H 1 + +#include + +#ifdef CONFIG_DEBUG_VM +#define VM_BUG_ON(cond) BUG_ON(cond) +#else +#define VM_BUG_ON(cond) do { } while(0) +#endif + +#ifdef CONFIG_DEBUG_VIRTUAL +#define VIRTUAL_BUG_ON(cond) BUG_ON(cond) +#else +#define VIRTUAL_BUG_ON(cond) do { } while(0) +#endif + +#endif -- cgit v1.2.3 From 7aa413def76146f7b3784228556d9e4bc562eab3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 19 Jun 2008 13:28:11 +0200 Subject: x86, MM: virtual address debug, cleanups Signed-off-by: Ingo Molnar --- include/linux/mmdebug.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmdebug.h b/include/linux/mmdebug.h index 860ed1a71bb..8a550987719 100644 --- a/include/linux/mmdebug.h +++ b/include/linux/mmdebug.h @@ -6,13 +6,13 @@ #ifdef CONFIG_DEBUG_VM #define VM_BUG_ON(cond) BUG_ON(cond) #else -#define VM_BUG_ON(cond) do { } while(0) +#define VM_BUG_ON(cond) do { } while (0) #endif #ifdef CONFIG_DEBUG_VIRTUAL #define VIRTUAL_BUG_ON(cond) BUG_ON(cond) #else -#define VIRTUAL_BUG_ON(cond) do { } while(0) +#define VIRTUAL_BUG_ON(cond) do { } while (0) #endif #endif -- cgit v1.2.3 From 1886e8a90a580f3ad343f2065c84c1b9e1dac9ef Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:37 -0700 Subject: x64, x2apic/intr-remap: code re-structuring, to be used by both DMA and Interrupt remapping Allocate the iommu during the parse of DMA remapping hardware definition structures. And also, introduce routines for device scope initialization which will be explicitly called during dma-remapping initialization. These will be used for enabling interrupt remapping separately from the existing DMA-remapping enabling sequence. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 56c73b84755..3ab07e42558 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -46,12 +46,14 @@ extern int intel_iommu_init(void); extern int dmar_table_init(void); extern int early_dmar_detect(void); +extern int dmar_dev_scope_init(void); extern struct list_head dmar_drhd_units; extern struct list_head dmar_rmrr_units; struct dmar_drhd_unit { struct list_head list; /* list of drhd units */ + struct acpi_dmar_header *hdr; /* ACPI header */ u64 reg_base_addr; /* register base address*/ struct pci_dev **devices; /* target device array */ int devices_cnt; /* target device count */ @@ -62,6 +64,7 @@ struct dmar_drhd_unit { struct dmar_rmrr_unit { struct list_head list; /* list of rmrr units */ + struct acpi_dmar_header *hdr; /* ACPI header */ u64 base_address; /* reserved base address*/ u64 end_address; /* reserved end address */ struct pci_dev **devices; /* target devices */ @@ -72,6 +75,8 @@ struct dmar_rmrr_unit { list_for_each_entry(drhd, &dmar_drhd_units, list) #define for_each_rmrr_units(rmrr) \ list_for_each_entry(rmrr, &dmar_rmrr_units, list) + +extern int alloc_iommu(struct dmar_drhd_unit *); #else static inline void detect_intel_iommu(void) { @@ -81,6 +86,9 @@ static inline int intel_iommu_init(void) { return -ENODEV; } - +static inline int dmar_table_init(void) +{ + return -ENODEV; +} #endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ -- cgit v1.2.3 From ad3ad3f6a2caebf56869b83b69e23eb9fa5e0ab6 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:40 -0700 Subject: x64, x2apic/intr-remap: parse ioapic scope under vt-d structures Parse the vt-d device scope structures to find the mapping between IO-APICs and the interrupt remapping hardware units. This will be used later for enabling Interrupt-remapping for IOAPIC devices. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 3ab07e42558..c4e96eb2961 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -47,6 +47,7 @@ extern int intel_iommu_init(void); extern int dmar_table_init(void); extern int early_dmar_detect(void); extern int dmar_dev_scope_init(void); +extern int parse_ioapics_under_ir(void); extern struct list_head dmar_drhd_units; extern struct list_head dmar_rmrr_units; -- cgit v1.2.3 From 2ae21010694e56461a63bfc80e960090ce0a5ed9 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:43 -0700 Subject: x64, x2apic/intr-remap: Interrupt remapping infrastructure Interrupt remapping (part of Intel Virtualization Tech for directed I/O) infrastructure. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 120 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index c4e96eb2961..8a0238dd2c1 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -25,9 +25,85 @@ #include #include -#ifdef CONFIG_DMAR +#if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) struct intel_iommu; +struct dmar_drhd_unit { + struct list_head list; /* list of drhd units */ + struct acpi_dmar_header *hdr; /* ACPI header */ + u64 reg_base_addr; /* register base address*/ + struct pci_dev **devices; /* target device array */ + int devices_cnt; /* target device count */ + u8 ignored:1; /* ignore drhd */ + u8 include_all:1; + struct intel_iommu *iommu; +}; + +extern struct list_head dmar_drhd_units; + +#define for_each_drhd_unit(drhd) \ + list_for_each_entry(drhd, &dmar_drhd_units, list) + +extern int dmar_table_init(void); +extern int early_dmar_detect(void); +extern int dmar_dev_scope_init(void); + +/* Intel IOMMU detection */ +extern void detect_intel_iommu(void); + + +extern int parse_ioapics_under_ir(void); +extern int alloc_iommu(struct dmar_drhd_unit *); +#else +static inline void detect_intel_iommu(void) +{ + return; +} + +static inline int dmar_table_init(void) +{ + return -ENODEV; +} +#endif /* !CONFIG_DMAR && !CONFIG_INTR_REMAP */ + +#ifdef CONFIG_INTR_REMAP +extern int intr_remapping_enabled; +extern int enable_intr_remapping(int); + +struct irte { + union { + struct { + __u64 present : 1, + fpd : 1, + dst_mode : 1, + redir_hint : 1, + trigger_mode : 1, + dlvry_mode : 3, + avail : 4, + __reserved_1 : 4, + vector : 8, + __reserved_2 : 8, + dest_id : 32; + }; + __u64 low; + }; + + union { + struct { + __u64 sid : 16, + sq : 2, + svt : 2, + __reserved_3 : 44; + }; + __u64 high; + }; +}; +#else +#define enable_intr_remapping(mode) (-1) +#define intr_remapping_enabled (0) +#endif + +#ifdef CONFIG_DMAR extern const char *dmar_get_fault_reason(u8 fault_reason); /* Can't use the common MSI interrupt functions @@ -40,29 +116,8 @@ extern void dmar_msi_write(int irq, struct msi_msg *msg); extern int dmar_set_interrupt(struct intel_iommu *iommu); extern int arch_setup_dmar_msi(unsigned int irq); -/* Intel IOMMU detection and initialization functions */ -extern void detect_intel_iommu(void); -extern int intel_iommu_init(void); - -extern int dmar_table_init(void); -extern int early_dmar_detect(void); -extern int dmar_dev_scope_init(void); -extern int parse_ioapics_under_ir(void); - -extern struct list_head dmar_drhd_units; +extern int iommu_detected, no_iommu; extern struct list_head dmar_rmrr_units; - -struct dmar_drhd_unit { - struct list_head list; /* list of drhd units */ - struct acpi_dmar_header *hdr; /* ACPI header */ - u64 reg_base_addr; /* register base address*/ - struct pci_dev **devices; /* target device array */ - int devices_cnt; /* target device count */ - u8 ignored:1; /* ignore drhd */ - u8 include_all:1; - struct intel_iommu *iommu; -}; - struct dmar_rmrr_unit { struct list_head list; /* list of rmrr units */ struct acpi_dmar_header *hdr; /* ACPI header */ @@ -72,24 +127,19 @@ struct dmar_rmrr_unit { int devices_cnt; /* target device count */ }; -#define for_each_drhd_unit(drhd) \ - list_for_each_entry(drhd, &dmar_drhd_units, list) #define for_each_rmrr_units(rmrr) \ list_for_each_entry(rmrr, &dmar_rmrr_units, list) - -extern int alloc_iommu(struct dmar_drhd_unit *); +/* Intel DMAR initialization functions */ +extern int intel_iommu_init(void); +extern int dmar_disabled; #else -static inline void detect_intel_iommu(void) -{ - return; -} static inline int intel_iommu_init(void) { +#ifdef CONFIG_INTR_REMAP + return dmar_dev_scope_init(); +#else return -ENODEV; -} -static inline int dmar_table_init(void) -{ - return -ENODEV; +#endif } #endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ -- cgit v1.2.3 From b6fcb33ad6c05f152a672f7c96c1fab006527b80 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:44 -0700 Subject: x64, x2apic/intr-remap: routines managing Interrupt remapping table entries. Routines handling the management of interrupt remapping table entries. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 8a0238dd2c1..324bbca85a2 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -98,7 +98,19 @@ struct irte { __u64 high; }; }; +extern int get_irte(int irq, struct irte *entry); +extern int modify_irte(int irq, struct irte *irte_modified); +extern int alloc_irte(struct intel_iommu *iommu, int irq, u16 count); +extern int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, + u16 sub_handle); +extern int map_irq_to_irte_handle(int irq, u16 *sub_handle); +extern int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index); +extern int flush_irte(int irq); +extern int free_irte(int irq); + +extern int irq_remapped(int irq); #else +#define irq_remapped(irq) (0) #define enable_intr_remapping(mode) (-1) #define intr_remapping_enabled (0) #endif -- cgit v1.2.3 From 72b1e22dfcad1daca6906148fd956ffe404bb0bc Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:45 -0700 Subject: x64, x2apic/intr-remap: generic irq migration support from process context Generic infrastructure for migrating the irq from the process context in the presence of CONFIG_GENERIC_PENDING_IRQ. This will be used later for migrating irq in the presence of interrupt-remapping. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/irq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 552e0ec269c..c211984b55e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -62,6 +62,7 @@ typedef void (*irq_flow_handler_t)(unsigned int irq, #define IRQ_MOVE_PENDING 0x00200000 /* need to re-target IRQ destination */ #define IRQ_NO_BALANCING 0x00400000 /* IRQ is excluded from balancing */ #define IRQ_SPURIOUS_DISABLED 0x00800000 /* IRQ was disabled by the spurious trap */ +#define IRQ_MOVE_PCNTXT 0x01000000 /* IRQ migration from process context */ #ifdef CONFIG_IRQ_PER_CPU # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU) -- cgit v1.2.3 From 89027d35aa5b8f45ce0f7fa0911db85b46563da0 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:56 -0700 Subject: x64, x2apic/intr-remap: IO-APIC support for interrupt-remapping IO-APIC support in the presence of interrupt-remapping infrastructure. IO-APIC RTE will be programmed with interrupt-remapping table entry(IRTE) index and the IRTE will contain information about the vector, cpu destination, trigger mode etc, which traditionally was present in the IO-APIC RTE. Introduce a new irq_chip for cleaner irq migration (in the process context as opposed to the current irq migration in the context of an interrupt. interrupt-remapping infrastructure will help us achieve this cleanly). For edge triggered, irq migration is a simple atomic update(of vector and cpu destination) of IRTE and flush the hardware cache. For level triggered, we need to modify the io-apic RTE aswell with the update vector information, along with modifying IRTE with vector and cpu destination. So irq migration for level triggered is little bit more complex compared to edge triggered migration. But the good news is, we use the same algorithm for level triggered migration as we have today, only difference being, we now initiate the irq migration from process context instead of the interrupt context. In future, when we do a directed EOI (combined with cpu EOI broadcast suppression) to the IO-APIC, level triggered irq migration will also be as simple as edge triggered migration and we can do the irq migration with a simple atomic update to IO-APIC RTE. TBD: some tests/changes needed in the presence of fixup_irqs() for level triggered irq migration. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index 324bbca85a2..bf41ffa7470 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -109,6 +109,7 @@ extern int flush_irte(int irq); extern int free_irte(int irq); extern int irq_remapped(int irq); +extern struct intel_iommu *map_ioapic_to_ir(int apic); #else #define irq_remapped(irq) (0) #define enable_intr_remapping(mode) (-1) -- cgit v1.2.3 From 75c46fa61bc5b4ccd20a168ff325c58771248fcd Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 10 Jul 2008 11:16:57 -0700 Subject: x64, x2apic/intr-remap: MSI and MSI-X support for interrupt remapping infrastructure MSI and MSI-X support for interrupt remapping infrastructure. MSI address register will be programmed with interrupt-remapping table entry(IRTE) index and the IRTE will contain information about the vector, cpu destination, etc. For MSI-X, all the IRTE's will be consecutively allocated in the table, and the address registers will contain the starting index to the block and the data register will contain the subindex with in that block. This also introduces a new irq_chip for cleaner irq migration (in the process context as opposed to the current irq migration in the context of an interrupt. interrupt-remapping infrastructure will help us achieve this). As MSI is edge triggered, irq migration is a simple atomic update(of vector and cpu destination) of IRTE and flushing the hardware cache. Signed-off-by: Suresh Siddha Cc: akpm@linux-foundation.org Cc: arjan@linux.intel.com Cc: andi@firstfloor.org Cc: ebiederm@xmission.com Cc: jbarnes@virtuousgeek.org Cc: steiner@sgi.com Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index bf41ffa7470..c360c558e59 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -109,6 +109,7 @@ extern int flush_irte(int irq); extern int free_irte(int irq); extern int irq_remapped(int irq); +extern struct intel_iommu *map_dev_to_ir(struct pci_dev *dev); extern struct intel_iommu *map_ioapic_to_ir(int apic); #else #define irq_remapped(irq) (0) -- cgit v1.2.3 From 3cac97cbb14aed00d83eb33d4613b0fe3aaea863 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sun, 6 Jul 2008 17:23:55 +0800 Subject: rcu classic: simplify the next pending batch use a batch number(rcp->pending) instead of a flag(rcp->next_pending) rcu_start_batch() need to change this flag, so mb()s is needed for memory-access safe. but(after this patch applied) rcu_start_batch() do not change this batch number(rcp->pending), rcp->pending is managed by __rcu_process_callbacks only, and troublesome mb()s are eliminated. And codes look simpler and clearer. Signed-off-by: Lai Jiangshan Cc: "Paul E. McKenney" Cc: Dipankar Sarma Cc: Gautham Shenoy Cc: Dhaval Giani Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 8c774905dcf..c847e59c600 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -45,7 +45,7 @@ struct rcu_ctrlblk { long cur; /* Current batch number. */ long completed; /* Number of the last completed batch */ - int next_pending; /* Is the next batch already waiting? */ + long pending; /* Number of the last pending batch */ int signaled; -- cgit v1.2.3 From 5127bed588a2f8f3a1f732de2a8a190b7df5dce3 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sun, 6 Jul 2008 17:23:59 +0800 Subject: rcu classic: new algorithm for callbacks-processing(v2) This is v2, it's a little deference from v1 that I had send to lkml. use ACCESS_ONCE use rcu_batch_after/rcu_batch_before for batch # comparison. rcutorture test result: (hotplugs: do cpu-online/offline once per second) No CONFIG_NO_HZ: OK, 12hours No CONFIG_NO_HZ, hotplugs: OK, 12hours CONFIG_NO_HZ=y: OK, 24hours CONFIG_NO_HZ=y, hotplugs: Failed. (Failed also without my patch applied, exactly the same bug occurred, http://lkml.org/lkml/2008/7/3/24) v1's email thread: http://lkml.org/lkml/2008/6/2/539 v1's description: The code/algorithm of the implement of current callbacks-processing is very efficient and technical. But when I studied it and I found a disadvantage: In multi-CPU systems, when a new RCU callback is being queued(call_rcu[_bh]), this callback will be invoked after the grace period for the batch with batch number = rcp->cur+2 has completed very very likely in current implement. Actually, this callback can be invoked after the grace period for the batch with batch number = rcp->cur+1 has completed. The delay of invocation means that latency of synchronize_rcu() is extended. But more important thing is that the callbacks usually free memory, and these works are delayed too! it's necessary for reclaimer to free memory as soon as possible when left memory is few. A very simple way can solve this problem: a field(struct rcu_head::batch) is added to record the batch number for the RCU callback. And when a new RCU callback is being queued, we determine the batch number for this callback(head->batch = rcp->cur+1) and we move this callback to rdp->donelist if we find that head->batch <= rcp->completed when we process callbacks. This simple way reduces the wait time for invocation a lot. (about 2.5Grace Period -> 1.5Grace Period in average in multi-CPU systems) This is my algorithm. But I do not add any field for struct rcu_head in my implement. We just need to memorize the last 2 batches and their batch number, because these 2 batches include all entries that for whom the grace period hasn't completed. So we use a special linked-list rather than add a field. Please see the comment of struct rcu_data. Signed-off-by: Lai Jiangshan Cc: "Paul E. McKenney" Cc: Dipankar Sarma Cc: Gautham Shenoy Cc: Dhaval Giani Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index c847e59c600..04c728147be 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -66,11 +66,7 @@ static inline int rcu_batch_after(long a, long b) return (a - b) > 0; } -/* - * Per-CPU data for Read-Copy UPdate. - * nxtlist - new callbacks are added here - * curlist - current batch for which quiescent cycle started if any - */ +/* Per-CPU data for Read-Copy UPdate. */ struct rcu_data { /* 1) quiescent state handling : */ long quiescbatch; /* Batch # for grace period */ @@ -78,12 +74,24 @@ struct rcu_data { int qs_pending; /* core waits for quiesc state */ /* 2) batch handling */ - long batch; /* Batch # for current RCU batch */ + /* + * if nxtlist is not NULL, then: + * batch: + * The batch # for the last entry of nxtlist + * [*nxttail[1], NULL = *nxttail[2]): + * Entries that batch # <= batch + * [*nxttail[0], *nxttail[1]): + * Entries that batch # <= batch - 1 + * [nxtlist, *nxttail[0]): + * Entries that batch # <= batch - 2 + * The grace period for these entries has completed, and + * the other grace-period-completed entries may be moved + * here temporarily in rcu_process_callbacks(). + */ + long batch; struct rcu_head *nxtlist; - struct rcu_head **nxttail; + struct rcu_head **nxttail[3]; long qlen; /* # of queued callbacks */ - struct rcu_head *curlist; - struct rcu_head **curtail; struct rcu_head *donelist; struct rcu_head **donetail; long blimit; /* Upper limit on a processed batch */ -- cgit v1.2.3 From 8d00a6c8f6b08e7167bc03bf955cdc7e47c5132e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 22 Jul 2008 08:39:57 +0200 Subject: genirq: remove last NO_IDLE_HZ leftovers Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 8ccb462ea42..f3047df2d23 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -197,10 +197,6 @@ extern int setup_irq(unsigned int irq, struct irqaction *new); #ifdef CONFIG_GENERIC_HARDIRQS -#ifndef handle_dynamic_tick -# define handle_dynamic_tick(a) do { } while (0) -#endif - #ifdef CONFIG_SMP #if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) -- cgit v1.2.3 From 021f8b75e78f9da67421a2c2e320e8934a90914a Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 22 Jul 2008 21:08:45 +0200 Subject: x86: add PCI IDs for AMD Barcelona PCI devices Signed-off-by: Robert Richter Cc: oprofile-list Cc: Barry Kasindorf Signed-off-by: Ingo Molnar --- include/linux/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c3b1761aba2..917d48e5ea0 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -497,6 +497,11 @@ #define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP 0x1101 #define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL 0x1102 #define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 +#define PCI_DEVICE_ID_AMD_10H_NB_HT 0x1200 +#define PCI_DEVICE_ID_AMD_10H_NB_MAP 0x1201 +#define PCI_DEVICE_ID_AMD_10H_NB_DRAM 0x1202 +#define PCI_DEVICE_ID_AMD_10H_NB_MISC 0x1203 +#define PCI_DEVICE_ID_AMD_10H_NB_LINK 0x1204 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 #define PCI_DEVICE_ID_AMD_SCSI 0x2020 -- cgit v1.2.3 From ee648bc77f11b57d15a68d336fc30e343198f893 Mon Sep 17 00:00:00 2001 From: Robert Richter Date: Tue, 22 Jul 2008 21:08:53 +0200 Subject: OProfile: add IBS code macros Signed-off-by: Robert Richter Cc: oprofile-list Cc: Barry Kasindorf Signed-off-by: Ingo Molnar --- include/linux/oprofile.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index 041bb31100f..bcb8f725427 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -36,6 +36,8 @@ #define XEN_ENTER_SWITCH_CODE 10 #define SPU_PROFILING_CODE 11 #define SPU_CTX_SWITCH_CODE 12 +#define IBS_FETCH_CODE 13 +#define IBS_OP_CODE 14 struct super_block; struct dentry; -- cgit v1.2.3 From 0af36739af81f152cc24a0fdfa0754ef657afe3d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 24 Jul 2008 17:27:57 -0700 Subject: usb: move ehci reg def prepare x86: usb debug port early console move ehci struct def to linux/usrb/ehci_def.h from host/ehci.h Signed-off-by: Yinghai Lu Acked-by: David Brownell Cc: Andrew Morton Cc: Andi Kleen Cc: "Arjan van de Ven" Cc: "Eric W. Biederman" Cc: "Greg KH" Signed-off-by: Ingo Molnar --- include/linux/usb/ehci_def.h | 160 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 include/linux/usb/ehci_def.h (limited to 'include/linux') diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h new file mode 100644 index 00000000000..5b88e36c910 --- /dev/null +++ b/include/linux/usb/ehci_def.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2001-2002 by David Brownell + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_USB_EHCI_DEF_H +#define __LINUX_USB_EHCI_DEF_H + +/* EHCI register interface, corresponds to EHCI Revision 0.95 specification */ + +/* Section 2.2 Host Controller Capability Registers */ +struct ehci_caps { + /* these fields are specified as 8 and 16 bit registers, + * but some hosts can't perform 8 or 16 bit PCI accesses. + */ + u32 hc_capbase; +#define HC_LENGTH(p) (((p)>>00)&0x00ff) /* bits 7:0 */ +#define HC_VERSION(p) (((p)>>16)&0xffff) /* bits 31:16 */ + u32 hcs_params; /* HCSPARAMS - offset 0x4 */ +#define HCS_DEBUG_PORT(p) (((p)>>20)&0xf) /* bits 23:20, debug port? */ +#define HCS_INDICATOR(p) ((p)&(1 << 16)) /* true: has port indicators */ +#define HCS_N_CC(p) (((p)>>12)&0xf) /* bits 15:12, #companion HCs */ +#define HCS_N_PCC(p) (((p)>>8)&0xf) /* bits 11:8, ports per CC */ +#define HCS_PORTROUTED(p) ((p)&(1 << 7)) /* true: port routing */ +#define HCS_PPC(p) ((p)&(1 << 4)) /* true: port power control */ +#define HCS_N_PORTS(p) (((p)>>0)&0xf) /* bits 3:0, ports on HC */ + + u32 hcc_params; /* HCCPARAMS - offset 0x8 */ +#define HCC_EXT_CAPS(p) (((p)>>8)&0xff) /* for pci extended caps */ +#define HCC_ISOC_CACHE(p) ((p)&(1 << 7)) /* true: can cache isoc frame */ +#define HCC_ISOC_THRES(p) (((p)>>4)&0x7) /* bits 6:4, uframes cached */ +#define HCC_CANPARK(p) ((p)&(1 << 2)) /* true: can park on async qh */ +#define HCC_PGM_FRAMELISTLEN(p) ((p)&(1 << 1)) /* true: periodic_size changes*/ +#define HCC_64BIT_ADDR(p) ((p)&(1)) /* true: can use 64-bit addr */ + u8 portroute [8]; /* nibbles for routing - offset 0xC */ +} __attribute__ ((packed)); + + +/* Section 2.3 Host Controller Operational Registers */ +struct ehci_regs { + + /* USBCMD: offset 0x00 */ + u32 command; +/* 23:16 is r/w intr rate, in microframes; default "8" == 1/msec */ +#define CMD_PARK (1<<11) /* enable "park" on async qh */ +#define CMD_PARK_CNT(c) (((c)>>8)&3) /* how many transfers to park for */ +#define CMD_LRESET (1<<7) /* partial reset (no ports, etc) */ +#define CMD_IAAD (1<<6) /* "doorbell" interrupt async advance */ +#define CMD_ASE (1<<5) /* async schedule enable */ +#define CMD_PSE (1<<4) /* periodic schedule enable */ +/* 3:2 is periodic frame list size */ +#define CMD_RESET (1<<1) /* reset HC not bus */ +#define CMD_RUN (1<<0) /* start/stop HC */ + + /* USBSTS: offset 0x04 */ + u32 status; +#define STS_ASS (1<<15) /* Async Schedule Status */ +#define STS_PSS (1<<14) /* Periodic Schedule Status */ +#define STS_RECL (1<<13) /* Reclamation */ +#define STS_HALT (1<<12) /* Not running (any reason) */ +/* some bits reserved */ + /* these STS_* flags are also intr_enable bits (USBINTR) */ +#define STS_IAA (1<<5) /* Interrupted on async advance */ +#define STS_FATAL (1<<4) /* such as some PCI access errors */ +#define STS_FLR (1<<3) /* frame list rolled over */ +#define STS_PCD (1<<2) /* port change detect */ +#define STS_ERR (1<<1) /* "error" completion (overflow, ...) */ +#define STS_INT (1<<0) /* "normal" completion (short, ...) */ + + /* USBINTR: offset 0x08 */ + u32 intr_enable; + + /* FRINDEX: offset 0x0C */ + u32 frame_index; /* current microframe number */ + /* CTRLDSSEGMENT: offset 0x10 */ + u32 segment; /* address bits 63:32 if needed */ + /* PERIODICLISTBASE: offset 0x14 */ + u32 frame_list; /* points to periodic list */ + /* ASYNCLISTADDR: offset 0x18 */ + u32 async_next; /* address of next async queue head */ + + u32 reserved [9]; + + /* CONFIGFLAG: offset 0x40 */ + u32 configured_flag; +#define FLAG_CF (1<<0) /* true: we'll support "high speed" */ + + /* PORTSC: offset 0x44 */ + u32 port_status [0]; /* up to N_PORTS */ +/* 31:23 reserved */ +#define PORT_WKOC_E (1<<22) /* wake on overcurrent (enable) */ +#define PORT_WKDISC_E (1<<21) /* wake on disconnect (enable) */ +#define PORT_WKCONN_E (1<<20) /* wake on connect (enable) */ +/* 19:16 for port testing */ +#define PORT_LED_OFF (0<<14) +#define PORT_LED_AMBER (1<<14) +#define PORT_LED_GREEN (2<<14) +#define PORT_LED_MASK (3<<14) +#define PORT_OWNER (1<<13) /* true: companion hc owns this port */ +#define PORT_POWER (1<<12) /* true: has power (see PPC) */ +#define PORT_USB11(x) (((x)&(3<<10)) == (1<<10)) /* USB 1.1 device */ +/* 11:10 for detecting lowspeed devices (reset vs release ownership) */ +/* 9 reserved */ +#define PORT_RESET (1<<8) /* reset port */ +#define PORT_SUSPEND (1<<7) /* suspend port */ +#define PORT_RESUME (1<<6) /* resume it */ +#define PORT_OCC (1<<5) /* over current change */ +#define PORT_OC (1<<4) /* over current active */ +#define PORT_PEC (1<<3) /* port enable change */ +#define PORT_PE (1<<2) /* port enable */ +#define PORT_CSC (1<<1) /* connect status change */ +#define PORT_CONNECT (1<<0) /* device connected */ +#define PORT_RWC_BITS (PORT_CSC | PORT_PEC | PORT_OCC) +} __attribute__ ((packed)); + +#define USBMODE 0x68 /* USB Device mode */ +#define USBMODE_SDIS (1<<3) /* Stream disable */ +#define USBMODE_BE (1<<2) /* BE/LE endianness select */ +#define USBMODE_CM_HC (3<<0) /* host controller mode */ +#define USBMODE_CM_IDLE (0<<0) /* idle state */ + +/* Appendix C, Debug port ... intended for use with special "debug devices" + * that can help if there's no serial console. (nonstandard enumeration.) + */ +struct ehci_dbg_port { + u32 control; +#define DBGP_OWNER (1<<30) +#define DBGP_ENABLED (1<<28) +#define DBGP_DONE (1<<16) +#define DBGP_INUSE (1<<10) +#define DBGP_ERRCODE(x) (((x)>>7)&0x07) +# define DBGP_ERR_BAD 1 +# define DBGP_ERR_SIGNAL 2 +#define DBGP_ERROR (1<<6) +#define DBGP_GO (1<<5) +#define DBGP_OUT (1<<4) +#define DBGP_LEN(x) (((x)>>0)&0x0f) + u32 pids; +#define DBGP_PID_GET(x) (((x)>>16)&0xff) +#define DBGP_PID_SET(data, tok) (((data)<<8)|(tok)) + u32 data03; + u32 data47; + u32 address; +#define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) +} __attribute__ ((packed)); + +#endif /* __LINUX_USB_EHCI_DEF_H */ -- cgit v1.2.3 From d974ae379a2fbe8948f01eabbc6b19c0a80f09bc Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 24 Jul 2008 16:27:46 -0700 Subject: generic, memparse(): constify argument memparse()'s first argument can be const, so it should be. Signed-off-by: Jeremy Fitzhardinge Cc: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index fdbbf72ca2e..7889c2f9b75 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -176,7 +176,7 @@ extern int vsscanf(const char *, const char *, va_list) extern int get_option(char **str, int *pint); extern char *get_options(const char *str, int nints, int *ints); -extern unsigned long long memparse(char *ptr, char **retptr); +extern unsigned long long memparse(const char *ptr, char **retptr); extern int core_kernel_text(unsigned long addr); extern int __kernel_text_address(unsigned long addr); -- cgit v1.2.3 From 6902c0bead4ce266226fc0c5b3828b850bdc884a Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 6 Jun 2008 01:33:22 -0400 Subject: Input: gameport - make gameport_register_driver() return errors Perform actual driver registration right in gameport_register_driver() instead of offloading it to kgameportd and return proper error code to callers if driver registration fails. Note that driver <-> port matching is still done by kgameportd. Signed-off-by: Dmitry Torokhov --- include/linux/gameport.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/gameport.h b/include/linux/gameport.h index f64e29c0ef3..5126125afd4 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -146,10 +146,11 @@ static inline void gameport_unpin_driver(struct gameport *gameport) mutex_unlock(&gameport->drv_mutex); } -void __gameport_register_driver(struct gameport_driver *drv, struct module *owner); -static inline void gameport_register_driver(struct gameport_driver *drv) +int __gameport_register_driver(struct gameport_driver *drv, + struct module *owner, const char *mod_name); +static inline int gameport_register_driver(struct gameport_driver *drv) { - __gameport_register_driver(drv, THIS_MODULE); + return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME); } void gameport_unregister_driver(struct gameport_driver *drv); -- cgit v1.2.3 From 8c4b3c29329eb7ffded3023e6d65bc415cb4e215 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Fri, 6 Jun 2008 01:33:51 -0400 Subject: Input: gameport - mark gameport_register_driver() __must_check Signed-off-by: Dmitry Torokhov --- include/linux/gameport.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 5126125afd4..0cd825f7363 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h @@ -148,7 +148,7 @@ static inline void gameport_unpin_driver(struct gameport *gameport) int __gameport_register_driver(struct gameport_driver *drv, struct module *owner, const char *mod_name); -static inline int gameport_register_driver(struct gameport_driver *drv) +static inline int __must_check gameport_register_driver(struct gameport_driver *drv) { return __gameport_register_driver(drv, THIS_MODULE, KBUILD_MODNAME); } -- cgit v1.2.3 From 03bac96fae0efdb25e2059e5accbe4f3ee6328dd Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 23 Jun 2008 10:47:34 -0400 Subject: Input: expand keycode space Expand the number of potential key codes from 512 to 768 since people are coming up with more and more keys. Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 2 +- include/linux/mod_devicetable.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index a5802c9c81a..7fae1dee356 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -579,7 +579,7 @@ struct input_absinfo { /* We avoid low common keys in module aliases so they don't get huge. */ #define KEY_MIN_INTERESTING KEY_MUTE -#define KEY_MAX 0x1ff +#define KEY_MAX 0x2ff #define KEY_CNT (KEY_MAX+1) /* diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index c4db5827963..0dddfa44ec1 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -274,7 +274,7 @@ struct pcmcia_device_id { /* Input */ #define INPUT_DEVICE_ID_EV_MAX 0x1f #define INPUT_DEVICE_ID_KEY_MIN_INTERESTING 0x71 -#define INPUT_DEVICE_ID_KEY_MAX 0x1ff +#define INPUT_DEVICE_ID_KEY_MAX 0x2ff #define INPUT_DEVICE_ID_REL_MAX 0x0f #define INPUT_DEVICE_ID_ABS_MAX 0x3f #define INPUT_DEVICE_ID_MSC_MAX 0x07 -- cgit v1.2.3 From 5a599a15182ed48e5bf54111feb3b21e425e194d Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Mon, 23 Jun 2008 10:47:53 -0400 Subject: Input: add keycodes for remote controls/phone keypads The new keys are separate from normal numeric keys and standard numeric keypads. The userspace should not attempt to apply modifiers like shift and NumLock to these so tey work properly regardless of the language mapping used. Signed-off-by: Dmitry Torokhov --- include/linux/input.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index 7fae1dee356..b86fb5581ce 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -577,6 +577,19 @@ struct input_absinfo { #define KEY_BRL_DOT9 0x1f9 #define KEY_BRL_DOT10 0x1fa +#define KEY_NUMERIC_0 0x200 /* used by phones, remote controls, */ +#define KEY_NUMERIC_1 0x201 /* and other keypads */ +#define KEY_NUMERIC_2 0x202 +#define KEY_NUMERIC_3 0x203 +#define KEY_NUMERIC_4 0x204 +#define KEY_NUMERIC_5 0x205 +#define KEY_NUMERIC_6 0x206 +#define KEY_NUMERIC_7 0x207 +#define KEY_NUMERIC_8 0x208 +#define KEY_NUMERIC_9 0x209 +#define KEY_NUMERIC_STAR 0x20a +#define KEY_NUMERIC_POUND 0x20b + /* We avoid low common keys in module aliases so they don't get huge. */ #define KEY_MIN_INTERESTING KEY_MUTE #define KEY_MAX 0x2ff -- cgit v1.2.3 From 64a76f667d987a559ad0726b4692c987800b22bc Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 29 Jul 2008 12:47:38 -0700 Subject: hpet: /dev/hpet - fixes and cleanup Minor /dev/hpet updates and bugfixes: * Remove dead code, mostly remnants of an incomplete/unusable kernel interface ... noted when addressing "sparse" warnings: + hpet_unregister() and a routine it calls + hpet_task and all references, including hpet_task_lock + hpet_data.hd_flags (and HPET_DATA_PLATFORM) * Correct and improve boot message: + displays *counter* (shared between comparators) bit width, not *timer* bit widths (which are often mixed) + relabel "timers" as "comparators"; this is less confusing, they are not independent like normal timers are (sigh) + display MHz not Hz; it's never less than 10 MHz. * Tighten and correct the userspace interface code + don't accidentally program comparators in 64-bit mode using 32-bit values ... always force comparators into 32-bit mode + provide the correct bit definition flagging comparators with periodic capability ... the ABI is unchanged * Update Documentation/hpet.txt + be more correct and current + expand description a bit + don't mention that now-gone kernel interface Plus, add a FIXME comment for something that could cause big trouble on systems with more capable HPETs than at least Intel seems to ship. It seems that few folk use this userspace interface; it's not very usable given the general lack of HPET IRQ routing. I'm told that the only real point of it any more is to mmap for fast timestamps; IMO that's handled better through the gettimeofday() vsyscall. Signed-off-by: David Brownell Acked-by: Clemens Ladisch Signed-off-by: Ingo Molnar --- include/linux/hpet.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hpet.h b/include/linux/hpet.h index 6d2626b63a9..79f63a27bce 100644 --- a/include/linux/hpet.h +++ b/include/linux/hpet.h @@ -92,23 +92,14 @@ struct hpet { * exported interfaces */ -struct hpet_task { - void (*ht_func) (void *); - void *ht_data; - void *ht_opaque; -}; - struct hpet_data { unsigned long hd_phys_address; void __iomem *hd_address; unsigned short hd_nirqs; - unsigned short hd_flags; unsigned int hd_state; /* timer allocated */ unsigned int hd_irq[HPET_MAX_TIMERS]; }; -#define HPET_DATA_PLATFORM 0x0001 /* platform call to hpet_alloc */ - static inline void hpet_reserve_timer(struct hpet_data *hd, int timer) { hd->hd_state |= (1 << timer); @@ -126,7 +117,7 @@ struct hpet_info { unsigned short hi_timer; }; -#define HPET_INFO_PERIODIC 0x0001 /* timer is periodic */ +#define HPET_INFO_PERIODIC 0x0010 /* periodic-capable comparator */ #define HPET_IE_ON _IO('h', 0x01) /* interrupt on */ #define HPET_IE_OFF _IO('h', 0x02) /* interrupt off */ -- cgit v1.2.3 From feb2f55db45919aa80731f8877b60cab454b7b94 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 1 Aug 2008 11:53:29 +0300 Subject: [MTD] [OneNAND] Add defines for HF and sync write Signed-off-by: Adrian Hunter Signed-off-by: David Woodhouse --- include/linux/mtd/onenand_regs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mtd/onenand_regs.h b/include/linux/mtd/onenand_regs.h index d1b310c92eb..0c6bbe28f38 100644 --- a/include/linux/mtd/onenand_regs.h +++ b/include/linux/mtd/onenand_regs.h @@ -152,6 +152,8 @@ #define ONENAND_SYS_CFG1_INT (1 << 6) #define ONENAND_SYS_CFG1_IOBE (1 << 5) #define ONENAND_SYS_CFG1_RDY_CONF (1 << 4) +#define ONENAND_SYS_CFG1_HF (1 << 2) +#define ONENAND_SYS_CFG1_SYNC_WRITE (1 << 1) /* * Controller Status Register F240h (R) -- cgit v1.2.3 From 2e489e077a6ad118c4f247faedf330117b107cce Mon Sep 17 00:00:00 2001 From: Alexey Korolev Date: Tue, 5 Aug 2008 16:39:42 +0100 Subject: [MTD] [NOR] Add qry_mode_on()/qry_omde_off() to deal with odd chips There are some CFI chips which require non standard procedures to get into QRY mode. The possible way to support them would be trying different modes till QRY will be read. This patch introduce two new functions qry_mode_on qry_mode_off. qry_mode_on tries different commands in order switch chip into QRY mode. So if we have one more "odd" chip - we just could add several lines to qry_mode_on. Also using these functions remove unnecessary code duplicaton in porbe procedure. Currently there are two "odd" cases 1. Some old intel chips which require 0xFF before 0x98 2. ST M29DW chip which requires 0x98 to be sent at 0x555 (according to CFI should be 0x55) This patch is partialy based on the patch from Uwe (see "[PATCH 2/4] [RFC][MTD] cfi_probe: remove Intel chip workaround" thread ) Signed-off-by: Alexey Korolev Signed-off-by: Alexander Belyakov Signed-off-by: David Woodhouse --- include/linux/mtd/cfi.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index d6fb115f5a0..3058917d7b9 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -12,6 +12,7 @@ #include #include #include +#include #ifdef CONFIG_MTD_CFI_I1 #define cfi_interleave(cfi) 1 @@ -430,7 +431,6 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t { map_word val; uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); - val = cfi_build_cmd(cmd, map, cfi); if (prev_val) @@ -483,6 +483,13 @@ static inline void cfi_udelay(int us) } } +int __xipram qry_present(struct map_info *map, __u32 base, + struct cfi_private *cfi); +int __xipram qry_mode_on(uint32_t base, struct map_info *map, + struct cfi_private *cfi); +void __xipram qry_mode_off(uint32_t base, struct map_info *map, + struct cfi_private *cfi); + struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, const char* name); struct cfi_fixup { -- cgit v1.2.3 From e93cafe45fd74935e0aca2b79e533f0e3ed9640f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Grafstr=C3=B6m?= Date: Tue, 5 Aug 2008 18:37:41 +0200 Subject: [MTD] [NOR] cfi_cmdset_0001: Timeouts for erase, write and unlock operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Timeouts are currently given by the typical operation time times 8. It works in the general well-behaved case but not when an erase block is failing. For erase operations, it seems that a failing erase block will keep the device state machine in erasing state until the vendor specified maximum timeout period has passed. By this time the driver would have long since timed out, left erasing state and attempted further operations which all fail. This patch implements timeouts using values from the CFI Query structure when available. The patch also sets a longer timeout for locking operations. The current value used for locking/unlocking given by 1000000/HZ microseconds is too short for devices like J3 and J5 Strataflash which have a typical clear lock-bits time of 0.5 seconds. Signed-off-by: Anders Grafström Signed-off-by: David Woodhouse --- include/linux/mtd/flashchip.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h index 08dd131301c..d4f38c5fd44 100644 --- a/include/linux/mtd/flashchip.h +++ b/include/linux/mtd/flashchip.h @@ -73,6 +73,10 @@ struct flchip { int buffer_write_time; int erase_time; + int word_write_time_max; + int buffer_write_time_max; + int erase_time_max; + void *priv; }; -- cgit v1.2.3 From c314dfdc358847eef0fc07ec8682e1acc8cadd00 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 7 Aug 2008 11:55:07 +0100 Subject: [MTD] [NOR] Rename and export new cfi_qry_*() functions They need to be exported, so let's give them less generic-sounding names while we're at it. Original export patch, along with the suggestion about the nomenclature, from Stephen Rothwell. Signed-off-by: David Woodhouse --- include/linux/mtd/cfi.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 3058917d7b9..ee5124ec319 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -483,12 +483,12 @@ static inline void cfi_udelay(int us) } } -int __xipram qry_present(struct map_info *map, __u32 base, - struct cfi_private *cfi); -int __xipram qry_mode_on(uint32_t base, struct map_info *map, - struct cfi_private *cfi); -void __xipram qry_mode_off(uint32_t base, struct map_info *map, - struct cfi_private *cfi); +int __xipram cfi_qry_present(struct map_info *map, __u32 base, + struct cfi_private *cfi); +int __xipram cfi_qry_mode_on(uint32_t base, struct map_info *map, + struct cfi_private *cfi); +void __xipram cfi_qry_mode_off(uint32_t base, struct map_info *map, + struct cfi_private *cfi); struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, const char* name); -- cgit v1.2.3 From 67182ae1c42206e516f7efb292b745e826497b24 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 10 Aug 2008 18:35:38 -0700 Subject: rcu, debug: detect stalled grace periods this is a diagnostic patch for Classic RCU. The approach is to record a timestamp at the beginning of the grace period (in rcu_start_batch()), then have rcu_check_callbacks() complain if: 1. it is running on a CPU that has holding up grace periods for a long time (say one second). This will identify the culprit assuming that the culprit has not disabled hardware irqs, instruction execution, or some such. 2. it is running on a CPU that is not holding up grace periods, but grace periods have been held up for an even longer time (say two seconds). It is enabled via the default-off CONFIG_DEBUG_RCU_STALL kernel parameter. Rather than exponential backoff, it backs off to once per 30 seconds. My feeling upon thinking on it was that if you have stalled RCU grace periods for that long, a few extra printk() messages are probably the least of your worries... Signed-off-by: Paul E. McKenney Cc: Peter Zijlstra Cc: Yinghai Lu Cc: David Witbrodt Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 04c728147be..16589958b40 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -46,6 +46,9 @@ struct rcu_ctrlblk { long cur; /* Current batch number. */ long completed; /* Number of the last completed batch */ long pending; /* Number of the last pending batch */ +#ifdef CONFIG_DEBUG_RCU_STALL + unsigned long gp_check; /* Time grace period should end, in seconds. */ +#endif /* #ifdef CONFIG_DEBUG_RCU_STALL */ int signaled; -- cgit v1.2.3 From b845b517b5e3706a3729f6ea83b88ab85f0725b0 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 8 Aug 2008 21:47:09 +0200 Subject: printk: robustify printk Avoid deadlocks against rq->lock and xtime_lock by deferring the klogd wakeup by polling from the timer tick. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index aaa998f65c7..113ac8d0425 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -200,6 +200,8 @@ extern struct ratelimit_state printk_ratelimit_state; extern int printk_ratelimit(void); extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, unsigned int interval_msec); +extern void printk_tick(void); +extern int printk_needs_cpu(int); #else static inline int vprintk(const char *s, va_list args) __attribute__ ((format (printf, 1, 0))); @@ -211,6 +213,8 @@ static inline int printk_ratelimit(void) { return 0; } static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ unsigned int interval_msec) \ { return false; } +static inline void printk_tick(void) { } +static inline int printk_needs_cpu(int) { return 0; } #endif extern void asmlinkage __attribute__((format(printf, 1, 2))) -- cgit v1.2.3 From ced9cd40ac14111befd6b0c73ec90106c22a3fd7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 11 Aug 2008 14:38:12 +0200 Subject: printk: robustify printk, fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: include/linux/kernel.h: In function ‘printk_needs_cpu': include/linux/kernel.h:217: error: parameter name omitted Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 113ac8d0425..3652a456412 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -200,8 +200,6 @@ extern struct ratelimit_state printk_ratelimit_state; extern int printk_ratelimit(void); extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, unsigned int interval_msec); -extern void printk_tick(void); -extern int printk_needs_cpu(int); #else static inline int vprintk(const char *s, va_list args) __attribute__ ((format (printf, 1, 0))); @@ -213,10 +211,11 @@ static inline int printk_ratelimit(void) { return 0; } static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \ unsigned int interval_msec) \ { return false; } -static inline void printk_tick(void) { } -static inline int printk_needs_cpu(int) { return 0; } #endif +extern int printk_needs_cpu(int cpu); +extern void printk_tick(void); + extern void asmlinkage __attribute__((format(printf, 1, 2))) early_printk(const char *fmt, ...); -- cgit v1.2.3 From bb0eb217c980d50c45f3e793b4dcc70ab9ee820d Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Tue, 12 Aug 2008 12:40:50 +0300 Subject: [MTD] Define and use MTD_FAIL_ADDR_UNKNOWN instead of 0xffffffff Signed-off-by: Adrian Hunter Signed-off-by: David Woodhouse --- include/linux/mtd/mtd.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 92263654855..eae26bb6430 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -25,8 +25,10 @@ #define MTD_ERASE_DONE 0x08 #define MTD_ERASE_FAILED 0x10 +#define MTD_FAIL_ADDR_UNKNOWN 0xffffffff + /* If the erase fails, fail_addr might indicate exactly which block failed. If - fail_addr = 0xffffffff, the failure was not at the device level or was not + fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not specific to any particular block. */ struct erase_info { struct mtd_info *mtd; -- cgit v1.2.3 From c1bc667e844c2677cdf927102ab384fe7b033762 Mon Sep 17 00:00:00 2001 From: Julius Volz Date: Thu, 7 Aug 2008 16:43:38 +0200 Subject: IPVS: Add genetlink interface definitions to ip_vs.h Add IPVS Generic Netlink interface definitions to include/linux/ip_vs.h. Signed-off-by: Julius Volz Signed-off-by: Simon Horman --- include/linux/ip_vs.h | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ip_vs.h b/include/linux/ip_vs.h index ec6eb49af2d..0f434a28fb5 100644 --- a/include/linux/ip_vs.h +++ b/include/linux/ip_vs.h @@ -242,4 +242,164 @@ struct ip_vs_daemon_user { int syncid; }; +/* + * + * IPVS Generic Netlink interface definitions + * + */ + +/* Generic Netlink family info */ + +#define IPVS_GENL_NAME "IPVS" +#define IPVS_GENL_VERSION 0x1 + +struct ip_vs_flags { + __be32 flags; + __be32 mask; +}; + +/* Generic Netlink command attributes */ +enum { + IPVS_CMD_UNSPEC = 0, + + IPVS_CMD_NEW_SERVICE, /* add service */ + IPVS_CMD_SET_SERVICE, /* modify service */ + IPVS_CMD_DEL_SERVICE, /* delete service */ + IPVS_CMD_GET_SERVICE, /* get service info */ + + IPVS_CMD_NEW_DEST, /* add destination */ + IPVS_CMD_SET_DEST, /* modify destination */ + IPVS_CMD_DEL_DEST, /* delete destination */ + IPVS_CMD_GET_DEST, /* get destination info */ + + IPVS_CMD_NEW_DAEMON, /* start sync daemon */ + IPVS_CMD_DEL_DAEMON, /* stop sync daemon */ + IPVS_CMD_GET_DAEMON, /* get sync daemon status */ + + IPVS_CMD_SET_CONFIG, /* set config settings */ + IPVS_CMD_GET_CONFIG, /* get config settings */ + + IPVS_CMD_SET_INFO, /* only used in GET_INFO reply */ + IPVS_CMD_GET_INFO, /* get general IPVS info */ + + IPVS_CMD_ZERO, /* zero all counters and stats */ + IPVS_CMD_FLUSH, /* flush services and dests */ + + __IPVS_CMD_MAX, +}; + +#define IPVS_CMD_MAX (__IPVS_CMD_MAX - 1) + +/* Attributes used in the first level of commands */ +enum { + IPVS_CMD_ATTR_UNSPEC = 0, + IPVS_CMD_ATTR_SERVICE, /* nested service attribute */ + IPVS_CMD_ATTR_DEST, /* nested destination attribute */ + IPVS_CMD_ATTR_DAEMON, /* nested sync daemon attribute */ + IPVS_CMD_ATTR_TIMEOUT_TCP, /* TCP connection timeout */ + IPVS_CMD_ATTR_TIMEOUT_TCP_FIN, /* TCP FIN wait timeout */ + IPVS_CMD_ATTR_TIMEOUT_UDP, /* UDP timeout */ + __IPVS_CMD_ATTR_MAX, +}; + +#define IPVS_CMD_ATTR_MAX (__IPVS_SVC_ATTR_MAX - 1) + +/* + * Attributes used to describe a service + * + * Used inside nested attribute IPVS_CMD_ATTR_SERVICE + */ +enum { + IPVS_SVC_ATTR_UNSPEC = 0, + IPVS_SVC_ATTR_AF, /* address family */ + IPVS_SVC_ATTR_PROTOCOL, /* virtual service protocol */ + IPVS_SVC_ATTR_ADDR, /* virtual service address */ + IPVS_SVC_ATTR_PORT, /* virtual service port */ + IPVS_SVC_ATTR_FWMARK, /* firewall mark of service */ + + IPVS_SVC_ATTR_SCHED_NAME, /* name of scheduler */ + IPVS_SVC_ATTR_FLAGS, /* virtual service flags */ + IPVS_SVC_ATTR_TIMEOUT, /* persistent timeout */ + IPVS_SVC_ATTR_NETMASK, /* persistent netmask */ + + IPVS_SVC_ATTR_STATS, /* nested attribute for service stats */ + __IPVS_SVC_ATTR_MAX, +}; + +#define IPVS_SVC_ATTR_MAX (__IPVS_SVC_ATTR_MAX - 1) + +/* + * Attributes used to describe a destination (real server) + * + * Used inside nested attribute IPVS_CMD_ATTR_DEST + */ +enum { + IPVS_DEST_ATTR_UNSPEC = 0, + IPVS_DEST_ATTR_ADDR, /* real server address */ + IPVS_DEST_ATTR_PORT, /* real server port */ + + IPVS_DEST_ATTR_FWD_METHOD, /* forwarding method */ + IPVS_DEST_ATTR_WEIGHT, /* destination weight */ + + IPVS_DEST_ATTR_U_THRESH, /* upper threshold */ + IPVS_DEST_ATTR_L_THRESH, /* lower threshold */ + + IPVS_DEST_ATTR_ACTIVE_CONNS, /* active connections */ + IPVS_DEST_ATTR_INACT_CONNS, /* inactive connections */ + IPVS_DEST_ATTR_PERSIST_CONNS, /* persistent connections */ + + IPVS_DEST_ATTR_STATS, /* nested attribute for dest stats */ + __IPVS_DEST_ATTR_MAX, +}; + +#define IPVS_DEST_ATTR_MAX (__IPVS_DEST_ATTR_MAX - 1) + +/* + * Attributes describing a sync daemon + * + * Used inside nested attribute IPVS_CMD_ATTR_DAEMON + */ +enum { + IPVS_DAEMON_ATTR_UNSPEC = 0, + IPVS_DAEMON_ATTR_STATE, /* sync daemon state (master/backup) */ + IPVS_DAEMON_ATTR_MCAST_IFN, /* multicast interface name */ + IPVS_DAEMON_ATTR_SYNC_ID, /* SyncID we belong to */ + __IPVS_DAEMON_ATTR_MAX, +}; + +#define IPVS_DAEMON_ATTR_MAX (__IPVS_DAEMON_ATTR_MAX - 1) + +/* + * Attributes used to describe service or destination entry statistics + * + * Used inside nested attributes IPVS_SVC_ATTR_STATS and IPVS_DEST_ATTR_STATS + */ +enum { + IPVS_STATS_ATTR_UNSPEC = 0, + IPVS_STATS_ATTR_CONNS, /* connections scheduled */ + IPVS_STATS_ATTR_INPKTS, /* incoming packets */ + IPVS_STATS_ATTR_OUTPKTS, /* outgoing packets */ + IPVS_STATS_ATTR_INBYTES, /* incoming bytes */ + IPVS_STATS_ATTR_OUTBYTES, /* outgoing bytes */ + + IPVS_STATS_ATTR_CPS, /* current connection rate */ + IPVS_STATS_ATTR_INPPS, /* current in packet rate */ + IPVS_STATS_ATTR_OUTPPS, /* current out packet rate */ + IPVS_STATS_ATTR_INBPS, /* current in byte rate */ + IPVS_STATS_ATTR_OUTBPS, /* current out byte rate */ + __IPVS_STATS_ATTR_MAX, +}; + +#define IPVS_STATS_ATTR_MAX (__IPVS_STATS_ATTR_MAX - 1) + +/* Attributes used in response to IPVS_CMD_GET_INFO command */ +enum { + IPVS_INFO_ATTR_UNSPEC = 0, + IPVS_INFO_ATTR_VERSION, /* IPVS version number */ + IPVS_INFO_ATTR_CONN_TAB_SIZE, /* size of connection hash table */ + __IPVS_INFO_ATTR_MAX, +}; + +#define IPVS_INFO_ATTR_MAX (__IPVS_INFO_ATTR_MAX - 1) + #endif /* _IP_VS_H */ -- cgit v1.2.3 From ff9cf2ce7afe76435d66c898cc9dacaa68e79d41 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 1 Aug 2008 14:10:02 -0700 Subject: rcu: fixes to include/linux/rcupreempt.h Hello! Compared tip/core/rcu to my latest patchset, and found the following issues: o the memory barrier in rcu_exit_nohz() somehow got out of place (it is correct in mainline as of 2.6.26-rc7). o There is a duplicate declaration of rcu_dyntick_sched. The attached patch fixes these. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/rcupreempt.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index 0967f03b070..addb5e282f3 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -111,7 +111,6 @@ extern struct rcupreempt_trace *rcupreempt_trace_cpu(int cpu); struct softirq_action; #ifdef CONFIG_NO_HZ -DECLARE_PER_CPU(struct rcu_dyntick_sched, rcu_dyntick_sched); static inline void rcu_enter_nohz(void) { @@ -126,8 +125,8 @@ static inline void rcu_exit_nohz(void) { static DEFINE_RATELIMIT_STATE(rs, 10 * HZ, 1); - smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ __get_cpu_var(rcu_dyntick_sched).dynticks++; + smp_mb(); /* CPUs seeing ++ must see later RCU read-side crit sects */ WARN_ON_RATELIMIT(!(__get_cpu_var(rcu_dyntick_sched).dynticks & 0x1), &rs); } -- cgit v1.2.3 From 34d7c2b38d124219b7034356716e3455c439acd3 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 1 Aug 2008 14:11:05 -0700 Subject: rcu: remove list_for_each_rcu() All of the in-tree uses of list_for_each_rcu() have been converted to list_for_each_entry_rcu(), so list_for_each_rcu() can now be removed. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/rculist.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rculist.h b/include/linux/rculist.h index eb4443c7e05..e649bd3f2c9 100644 --- a/include/linux/rculist.h +++ b/include/linux/rculist.h @@ -198,20 +198,6 @@ static inline void list_splice_init_rcu(struct list_head *list, at->prev = last; } -/** - * list_for_each_rcu - iterate over an rcu-protected list - * @pos: the &struct list_head to use as a loop cursor. - * @head: the head for your list. - * - * This list-traversal primitive may safely run concurrently with - * the _rcu list-mutation primitives such as list_add_rcu() - * as long as the traversal is guarded by rcu_read_lock(). - */ -#define list_for_each_rcu(pos, head) \ - for (pos = rcu_dereference((head)->next); \ - prefetch(pos->next), pos != (head); \ - pos = rcu_dereference(pos->next)) - #define __list_for_each_rcu(pos, head) \ for (pos = rcu_dereference((head)->next); \ pos != (head); \ -- cgit v1.2.3 From 07dd20e0324f4d3e33bde1944d4f7771a09c498c Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 1 Aug 2008 13:18:04 +0100 Subject: sched: reorder signal_struct to remove 8 bytes on 64 bit builds reorder structure to remove 8 bytes of padding on 64 bit builds Signed-off-by: Richard Kennedy Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index cfb0d87b99f..5a8058e44f5 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -451,8 +451,8 @@ struct signal_struct { * - everyone except group_exit_task is stopped during signal delivery * of fatal signals, group_exit_task processes the signal. */ - struct task_struct *group_exit_task; int notify_count; + struct task_struct *group_exit_task; /* thread group stop support, overloads group_exit_code too */ int group_stop_count; -- cgit v1.2.3 From bee367ed066e26c14263d808136fba8eec3bd70a Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 1 Aug 2008 13:24:08 +0100 Subject: sched: reorder struct sched_rt_entity to remove padding on 64 bit builds remove 8 bytes of padding on 64 bit builds (also removes 8 bytes from task_struct) Signed-off-by: Richard Kennedy Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 5a8058e44f5..08a87b5f29e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1010,8 +1010,8 @@ struct sched_entity { struct sched_rt_entity { struct list_head run_list; - unsigned int time_slice; unsigned long timeout; + unsigned int time_slice; int nr_cpus_allowed; struct sched_rt_entity *back; -- cgit v1.2.3 From 3fb669dd6ec11e14819c0114a0e68a9ddcec65e1 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Fri, 1 Aug 2008 13:36:28 +0100 Subject: reorder struct prop_local_single to remove padding on 64 bit builds reorder structure to remove 8 bytes of padding on 64 bit builds (also removes 8 bytes from task_struct) Signed-off-by: Richard Kennedy Cc: peterz@infradead.org Signed-off-by: Ingo Molnar --- include/linux/proportions.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/proportions.h b/include/linux/proportions.h index 5afc1b23346..cf793bbbd05 100644 --- a/include/linux/proportions.h +++ b/include/linux/proportions.h @@ -104,8 +104,8 @@ struct prop_local_single { * snapshot of the last seen global state * and a lock protecting this state */ - int shift; unsigned long period; + int shift; spinlock_t lock; /* protect the snapshot state */ }; -- cgit v1.2.3 From dd0078f4f04d939950a792c493d7d97d7ce663b8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 30 Jul 2008 14:20:54 -0400 Subject: rcu: just rename call_rcu_bh instead of making it a macro Seems that I found a box that has a config that passes call_rcu_bh as a function pointer (see net/sctp/sm_make_chunk.c), so declaring the call_rcu_bh has a macro function isn't good enough. This patch makes it just another name of call_rcu for rcupreempt. Signed-off-by: Steven Rostedt Reviewed-by: "Paul E. McKenney" Signed-off-by: Ingo Molnar --- include/linux/rcupreempt.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rcupreempt.h b/include/linux/rcupreempt.h index addb5e282f3..3e05c09b54a 100644 --- a/include/linux/rcupreempt.h +++ b/include/linux/rcupreempt.h @@ -57,7 +57,13 @@ static inline void rcu_qsctr_inc(int cpu) rdssp->sched_qs++; } #define rcu_bh_qsctr_inc(cpu) -#define call_rcu_bh(head, rcu) call_rcu(head, rcu) + +/* + * Someone might want to pass call_rcu_bh as a function pointer. + * So this needs to just be a rename and not a macro function. + * (no parentheses) + */ +#define call_rcu_bh call_rcu /** * call_rcu_sched - Queue RCU callback for invocation after sched grace period. -- cgit v1.2.3 From ded00a56e99555c3f4000ef3eebfd5fe0d574565 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Sun, 17 Aug 2008 12:50:36 -0700 Subject: rcu: remove redundant ACCESS_ONCE definition from rcupreempt.c Remove the redundant definition of ACCESS_ONCE() from rcupreempt.c in favor of the one in compiler.h. Also merge the comment header from rcupreempt.c's definition into that in compiler.h. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/compiler.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/compiler.h b/include/linux/compiler.h index c8bd2daf95e..8322141ee48 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -190,7 +190,9 @@ extern void __chk_io_ptr(const volatile void __iomem *); * ACCESS_ONCE() in different C statements. * * This macro does absolutely -nothing- to prevent the CPU from reordering, - * merging, or refetching absolutely anything at any time. + * merging, or refetching absolutely anything at any time. Its main intended + * use is to mediate communication between process-level code and irq/NMI + * handlers, all running on the same CPU. */ #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x)) -- cgit v1.2.3 From 1f7c14c62ce63805f9574664a6c6de3633d4a354 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Thu, 9 Oct 2008 12:50:59 -0400 Subject: percpu counter: clean up percpu_counter_sum_and_set() percpu_counter_sum_and_set() and percpu_counter_sum() is the same except the former updates the global counter after accounting. Since we are taking the fbc->lock to calculate the precise value of the counter in percpu_counter_sum() anyway, it should simply set fbc->count too, as the percpu_counter_sum_and_set() does. This patch merges these two interfaces into one. Signed-off-by: Mingming Cao Acked-by: Peter Zijlstra Cc: Signed-off-by: Andrew Morton Signed-off-by: "Theodore Ts'o" --- include/linux/percpu_counter.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 20838883535..9007ccdfc11 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -35,7 +35,7 @@ int percpu_counter_init_irq(struct percpu_counter *fbc, s64 amount); void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); -s64 __percpu_counter_sum(struct percpu_counter *fbc, int set); +s64 __percpu_counter_sum(struct percpu_counter *fbc); static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -44,19 +44,13 @@ static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) static inline s64 percpu_counter_sum_positive(struct percpu_counter *fbc) { - s64 ret = __percpu_counter_sum(fbc, 0); + s64 ret = __percpu_counter_sum(fbc); return ret < 0 ? 0 : ret; } -static inline s64 percpu_counter_sum_and_set(struct percpu_counter *fbc) -{ - return __percpu_counter_sum(fbc, 1); -} - - static inline s64 percpu_counter_sum(struct percpu_counter *fbc) { - return __percpu_counter_sum(fbc, 0); + return __percpu_counter_sum(fbc); } static inline s64 percpu_counter_read(struct percpu_counter *fbc) -- cgit v1.2.3 From 17c1d2be28e485c0c8b09661db39d5bf2605069d Mon Sep 17 00:00:00 2001 From: Alexey Korolev Date: Wed, 20 Aug 2008 22:32:08 +0100 Subject: [MTD] [NAND] Fix missing kernel-doc [Reported by Randy Dunlap] Signed-off-by: Alexey Korolev Signed-off-by: David Woodhouse --- include/linux/mtd/nand.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 81774e5facf..733d3f3b4eb 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -248,6 +248,7 @@ struct nand_hw_control { * @read_page_raw: function to read a raw page without ECC * @write_page_raw: function to write a raw page without ECC * @read_page: function to read a page according to the ecc generator requirements + * @read_subpage: function to read parts of the page covered by ECC. * @write_page: function to write a page according to the ecc generator requirements * @read_oob: function to read chip OOB data * @write_oob: function to write chip OOB data -- cgit v1.2.3 From d9105c2b01eedb620cae96073dde4f760367817f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Va=C5=A1ut?= Date: Sun, 3 Aug 2008 21:34:08 +0100 Subject: [ARM] 5184/1: Split ucb1400_ts into core and touchscreen This patch splits ucb1400_ts into ucb1400_ts and ucb1400_core. Since this chip supports more features than only touchscreen, it was necessary to prepare it for feature addition. The previous functionality is preserved by applying this patch. [Build fixes for non-ARM by Stephen Rothwell and Takashi Iwai] Signed-off-by: Marek Vasut Signed-off-by: Russell King --- include/linux/ucb1400.h | 161 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 include/linux/ucb1400.h (limited to 'include/linux') diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h new file mode 100644 index 00000000000..970473bf8d5 --- /dev/null +++ b/include/linux/ucb1400.h @@ -0,0 +1,161 @@ +/* + * Register definitions and functions for: + * Philips UCB1400 driver + * + * Based on ucb1400_ts: + * Author: Nicolas Pitre + * Created: September 25, 2006 + * Copyright: MontaVista Software, Inc. + * + * Spliting done by: Marek Vasut + * If something doesnt work and it worked before spliting, e-mail me, + * dont bother Nicolas please ;-) + * + * 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. + * + * This code is heavily based on ucb1x00-*.c copyrighted by Russell King + * covering the UCB1100, UCB1200 and UCB1300.. Support for the UCB1400 has + * been made separate from ucb1x00-core/ucb1x00-ts on Russell's request. + */ + +#ifndef _LINUX__UCB1400_H +#define _LINUX__UCB1400_H + +#include +#include +#include + +/* + * UCB1400 AC-link registers + */ + +#define UCB_IO_DATA 0x5a +#define UCB_IO_DIR 0x5c +#define UCB_IE_RIS 0x5e +#define UCB_IE_FAL 0x60 +#define UCB_IE_STATUS 0x62 +#define UCB_IE_CLEAR 0x62 +#define UCB_IE_ADC (1 << 11) +#define UCB_IE_TSPX (1 << 12) + +#define UCB_TS_CR 0x64 +#define UCB_TS_CR_TSMX_POW (1 << 0) +#define UCB_TS_CR_TSPX_POW (1 << 1) +#define UCB_TS_CR_TSMY_POW (1 << 2) +#define UCB_TS_CR_TSPY_POW (1 << 3) +#define UCB_TS_CR_TSMX_GND (1 << 4) +#define UCB_TS_CR_TSPX_GND (1 << 5) +#define UCB_TS_CR_TSMY_GND (1 << 6) +#define UCB_TS_CR_TSPY_GND (1 << 7) +#define UCB_TS_CR_MODE_INT (0 << 8) +#define UCB_TS_CR_MODE_PRES (1 << 8) +#define UCB_TS_CR_MODE_POS (2 << 8) +#define UCB_TS_CR_BIAS_ENA (1 << 11) +#define UCB_TS_CR_TSPX_LOW (1 << 12) +#define UCB_TS_CR_TSMX_LOW (1 << 13) + +#define UCB_ADC_CR 0x66 +#define UCB_ADC_SYNC_ENA (1 << 0) +#define UCB_ADC_VREFBYP_CON (1 << 1) +#define UCB_ADC_INP_TSPX (0 << 2) +#define UCB_ADC_INP_TSMX (1 << 2) +#define UCB_ADC_INP_TSPY (2 << 2) +#define UCB_ADC_INP_TSMY (3 << 2) +#define UCB_ADC_INP_AD0 (4 << 2) +#define UCB_ADC_INP_AD1 (5 << 2) +#define UCB_ADC_INP_AD2 (6 << 2) +#define UCB_ADC_INP_AD3 (7 << 2) +#define UCB_ADC_EXT_REF (1 << 5) +#define UCB_ADC_START (1 << 7) +#define UCB_ADC_ENA (1 << 15) + +#define UCB_ADC_DATA 0x68 +#define UCB_ADC_DAT_VALID (1 << 15) +#define UCB_ADC_DAT_MASK 0x3ff + +#define UCB_ID 0x7e +#define UCB_ID_1400 0x4304 + +struct ucb1400_ts { + struct input_dev *ts_idev; + struct task_struct *ts_task; + int id; + wait_queue_head_t ts_wait; + unsigned int ts_restart:1; + int irq; + unsigned int irq_pending; /* not bit field shared */ + struct snd_ac97 *ac97; +}; + +struct ucb1400 { + struct platform_device *ucb1400_ts; +}; + +static inline u16 ucb1400_reg_read(struct snd_ac97 *ac97, u16 reg) +{ + return ac97->bus->ops->read(ac97, reg); +} + +static inline void ucb1400_reg_write(struct snd_ac97 *ac97, u16 reg, u16 val) +{ + ac97->bus->ops->write(ac97, reg, val); +} + +static inline u16 ucb1400_gpio_get_value(struct snd_ac97 *ac97, u16 gpio) +{ + return ucb1400_reg_read(ac97, UCB_IO_DATA) & (1 << gpio); +} + +static inline void ucb1400_gpio_set_value(struct snd_ac97 *ac97, u16 gpio, + u16 val) +{ + ucb1400_reg_write(ac97, UCB_IO_DATA, val ? + ucb1400_reg_read(ac97, UCB_IO_DATA) | (1 << gpio) : + ucb1400_reg_read(ac97, UCB_IO_DATA) & ~(1 << gpio)); +} + +static inline u16 ucb1400_gpio_get_direction(struct snd_ac97 *ac97, u16 gpio) +{ + return ucb1400_reg_read(ac97, UCB_IO_DIR) & (1 << gpio); +} + +static inline void ucb1400_gpio_set_direction(struct snd_ac97 *ac97, u16 gpio, + u16 dir) +{ + ucb1400_reg_write(ac97, UCB_IO_DIR, dir ? + ucb1400_reg_read(ac97, UCB_IO_DIR) | (1 << gpio) : + ucb1400_reg_read(ac97, UCB_IO_DIR) & ~(1 << gpio)); +} + +static inline void ucb1400_adc_enable(struct snd_ac97 *ac97) +{ + ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA); +} + +static unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, + int adcsync) +{ + unsigned int val; + + if (adcsync) + adc_channel |= UCB_ADC_SYNC_ENA; + + ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); + ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | + UCB_ADC_START); + + while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA)) + & UCB_ADC_DAT_VALID)) + schedule_timeout_uninterruptible(1); + + return val & UCB_ADC_DAT_MASK; +} + +static inline void ucb1400_adc_disable(struct snd_ac97 *ac97) +{ + ucb1400_reg_write(ac97, UCB_ADC_CR, 0); +} + +#endif -- cgit v1.2.3 From 1aa5dfb751d275ae7117d3b73ac423b4a46f2a73 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 20 Aug 2008 16:37:28 -0700 Subject: clocksource: keep track of original clocksource frequency The clocksource frequency is represented by clocksource->mult/2^(clocksource->shift). Currently, when NTP makes adjustments to the clock frequency, they are made directly to the mult value. This has the drawback that once changed, we cannot know what the orignal mult value was, or how much adjustment has been applied. This property causes problems in calculating proper ntp intervals when switching back and forth between clocksources. This patch separates the current mult value into a mult and mult_orig pair. The mult_orig value stays constant, while the ntp clocksource adjustments are done only to the mult value. This allows for correct ntp interval calculation and additionally lays the groundwork for a new notion of time, what I'm calling the monotonic-raw time, which is introduced in a following patch. Signed-off-by: John Stultz Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/clocksource.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 55e434feec9..f0a7fb98441 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -45,7 +45,8 @@ struct clocksource; * @read: returns a cycle value * @mask: bitmask for two's complement * subtraction of non 64 bit counters - * @mult: cycle to nanosecond multiplier + * @mult: cycle to nanosecond multiplier (adjusted by NTP) + * @mult_orig: cycle to nanosecond multiplier (unadjusted by NTP) * @shift: cycle to nanosecond divisor (power of two) * @flags: flags describing special properties * @vread: vsyscall based read @@ -63,6 +64,7 @@ struct clocksource { cycle_t (*read)(void); cycle_t mask; u32 mult; + u32 mult_orig; u32 shift; unsigned long flags; cycle_t (*vread)(void); @@ -201,16 +203,17 @@ static inline void clocksource_calculate_interval(struct clocksource *c, { u64 tmp; - /* XXX - All of this could use a whole lot of optimization */ + /* Do the ns -> cycle conversion first, using original mult */ tmp = length_nsec; tmp <<= c->shift; - tmp += c->mult/2; - do_div(tmp, c->mult); + tmp += c->mult_orig/2; + do_div(tmp, c->mult_orig); c->cycle_interval = (cycle_t)tmp; if (c->cycle_interval == 0) c->cycle_interval = 1; + /* Go back from cycles -> shifted ns, this time use ntp adjused mult */ c->xtime_interval = (u64)c->cycle_interval * c->mult; } -- cgit v1.2.3 From 2d42244ae71d6c7b0884b5664cf2eda30fb2ae68 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Wed, 20 Aug 2008 16:37:30 -0700 Subject: clocksource: introduce CLOCK_MONOTONIC_RAW In talking with Josip Loncaric, and his work on clock synchronization (see btime.sf.net), he mentioned that for really close synchronization, it is useful to have access to "hardware time", that is a notion of time that is not in any way adjusted by the clock slewing done to keep close time sync. Part of the issue is if we are using the kernel's ntp adjusted representation of time in order to measure how we should correct time, we can run into what Paul McKenney aptly described as "Painting a road using the lines we're painting as the guide". I had been thinking of a similar problem, and was trying to come up with a way to give users access to a purely hardware based time representation that avoided users having to know the underlying frequency and mask values needed to deal with the wide variety of possible underlying hardware counters. My solution is to introduce CLOCK_MONOTONIC_RAW. This exposes a nanosecond based time value, that increments starting at bootup and has no frequency adjustments made to it what so ever. The time is accessed from userspace via the posix_clock_gettime() syscall, passing CLOCK_MONOTONIC_RAW as the clock_id. Signed-off-by: John Stultz Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/clocksource.h | 3 +++ include/linux/time.h | 2 ++ 2 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index f0a7fb98441..f88d32f8ff7 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -79,6 +79,7 @@ struct clocksource { /* timekeeping specific data, ignore */ cycle_t cycle_interval; u64 xtime_interval; + u32 raw_interval; /* * Second part is written at each timer interrupt * Keep it in a different cache line to dirty no @@ -87,6 +88,7 @@ struct clocksource { cycle_t cycle_last ____cacheline_aligned_in_smp; u64 xtime_nsec; s64 error; + struct timespec raw_time; #ifdef CONFIG_CLOCKSOURCE_WATCHDOG /* Watchdog related data, used by the framework */ @@ -215,6 +217,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c, /* Go back from cycles -> shifted ns, this time use ntp adjused mult */ c->xtime_interval = (u64)c->cycle_interval * c->mult; + c->raw_interval = ((u64)c->cycle_interval * c->mult_orig) >> c->shift; } diff --git a/include/linux/time.h b/include/linux/time.h index e15206a7e82..205f974b9eb 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -117,6 +117,7 @@ extern int do_setitimer(int which, struct itimerval *value, extern unsigned int alarm_setitimer(unsigned int seconds); extern int do_getitimer(int which, struct itimerval *value); extern void getnstimeofday(struct timespec *tv); +extern void getrawmonotonic(struct timespec *ts); extern void getboottime(struct timespec *ts); extern void monotonic_to_bootbased(struct timespec *ts); @@ -214,6 +215,7 @@ struct itimerval { #define CLOCK_MONOTONIC 1 #define CLOCK_PROCESS_CPUTIME_ID 2 #define CLOCK_THREAD_CPUTIME_ID 3 +#define CLOCK_MONOTONIC_RAW 4 /* * The IDs of various hardware clocks: -- cgit v1.2.3 From 916c7a855174e3b53d182b97a26b2e27a29726a1 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Wed, 20 Aug 2008 16:46:08 -0700 Subject: ntp: fix ADJ_OFFSET_SS_READ bug and do_adjtimex() cleanup Thanks to the review by Michael Kerrisk a bug in the recent ADJ_OFFSET_SS_READ option was discovered, where the ntp time_offset was inadvertently set by it. This fixes this by making the adjtime code more separate from the ntp_adjtime code (both of which really want to be separate syscalls). Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Acked-by: John Stultz Signed-off-by: Ingo Molnar --- include/linux/timex.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/timex.h b/include/linux/timex.h index fc6035d29d5..c00bcdd3ae4 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -141,8 +141,15 @@ struct timex { #define ADJ_MICRO 0x1000 /* select microsecond resolution */ #define ADJ_NANO 0x2000 /* select nanosecond resolution */ #define ADJ_TICK 0x4000 /* tick value */ + +#ifdef __KERNEL__ +#define ADJ_ADJTIME 0x8000 /* switch between adjtime/adjtimex modes */ +#define ADJ_OFFSET_SINGLESHOT 0x0001 /* old-fashioned adjtime */ +#define ADJ_OFFSET_READONLY 0x2000 /* read-only adjtime */ +#else #define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime */ -#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */ +#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime */ +#endif /* xntp 3.4 compatibility names */ #define MOD_OFFSET ADJ_OFFSET -- cgit v1.2.3 From 9961920199ec88d6b581d3e38502088935925c04 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 2 Aug 2008 15:10:58 -0300 Subject: rfkill: add default global states (v2) Add a second set of global states, "rfkill_default_states", to track the state that will be used when the first rfkill class of a given type is registered, and also to save "undo" information when rfkill_epo is called. Add a new exported function, rfkill_set_default(), which can be used by platform drivers to restore radio state saved by the platform across reboots or shutdown. Also, fix rfkill_epo to properly update rfkill_states, but still preserve a copy of the state so that we can undo the effect of rfkill_epo later if we want to. Add rfkill_restore_states() to restore rfkill_states from the copy. Signed-off-by: Henrique de Moraes Holschuh Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- include/linux/rfkill.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index 741d1a62cc3..aa3c7d5852f 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -116,6 +116,7 @@ int rfkill_register(struct rfkill *rfkill); void rfkill_unregister(struct rfkill *rfkill); int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state); +int rfkill_set_default(enum rfkill_type type, enum rfkill_state state); /** * rfkill_state_complement - return complementar state -- cgit v1.2.3 From 77fba13ccc3a2a3db100892a4a6cc5e2f8290cc7 Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 2 Aug 2008 15:10:59 -0300 Subject: rfkill: add __must_check annotations rfkill is not a small, mere detail in wireless support. Once it starts supporting rfkill and users start counting on that support, a wireless device is at risk of operating in dangerous conditions should rfkill support fail to properly activate. Therefore, add the required __must_check annotations on some key functions of the rfkill API, for which the wireless drivers absolutely MUST handle the failure mode safely in order to avoid a potentially dangerous situation where the wireless transmitter is left enabled when the user don't want it to. Signed-off-by: Henrique de Moraes Holschuh Acked-by: Ivo van Doorn Cc: Matthew Garrett Signed-off-by: John W. Linville --- include/linux/rfkill.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index aa3c7d5852f..e92d8e94bb8 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -110,9 +110,10 @@ struct rfkill { }; #define to_rfkill(d) container_of(d, struct rfkill, dev) -struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type); +struct rfkill * __must_check rfkill_allocate(struct device *parent, + enum rfkill_type type); void rfkill_free(struct rfkill *rfkill); -int rfkill_register(struct rfkill *rfkill); +int __must_check rfkill_register(struct rfkill *rfkill); void rfkill_unregister(struct rfkill *rfkill); int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state); -- cgit v1.2.3 From 96c87607ac8f9b0e641d11ba6e57f8ec0214ea1c Mon Sep 17 00:00:00 2001 From: Henrique de Moraes Holschuh Date: Sat, 2 Aug 2008 15:11:00 -0300 Subject: rfkill: introduce RFKILL_STATE_MAX While it is interesting to not add last-enum-markers because it allows gcc to warn us of switch() statements missing a valid state, we really should be handling memory corruption on a rfkill state with default clauses, anyway. So add RFKILL_STATE_MAX and use it where applicable. It makes for safer code in the long run. Signed-off-by: Henrique de Moraes Holschuh Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- include/linux/rfkill.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h index e92d8e94bb8..4cd64b0d982 100644 --- a/include/linux/rfkill.h +++ b/include/linux/rfkill.h @@ -49,6 +49,7 @@ enum rfkill_state { RFKILL_STATE_SOFT_BLOCKED = 0, /* Radio output blocked */ RFKILL_STATE_UNBLOCKED = 1, /* Radio output allowed */ RFKILL_STATE_HARD_BLOCKED = 2, /* Output blocked, non-overrideable */ + RFKILL_STATE_MAX, /* marker for last valid state */ }; /* -- cgit v1.2.3 From fef1643bf0cdd092a52dc3378479e4811fd65152 Mon Sep 17 00:00:00 2001 From: Jasper Bryant-Greene Date: Sun, 3 Aug 2008 11:30:55 +1200 Subject: move ETH_P_PAE from ieee80211_i.h to if_ether.h ETH_P_PAE belongs in if_ether.h with the other ETH_P_* definitions. This patch moves it there. Signed-off-by: Jasper Bryant-Greene Acked-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index e157c1399b6..5028e0b6082 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -74,6 +74,7 @@ #define ETH_P_ATMFATE 0x8884 /* Frame-based ATM Transport * over Ethernet */ +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ #define ETH_P_TIPC 0x88CA /* TIPC */ -- cgit v1.2.3 From 65eb3dc609dec17deea48dcd4de2e549d29a9824 Mon Sep 17 00:00:00 2001 From: Kevin Diggs Date: Tue, 26 Aug 2008 10:26:54 +0200 Subject: sched: add kernel doc for the completion, fix kernel-doc-nano-HOWTO.txt This patch adds kernel doc for the completion feature. An error in the split-man.pl PERL snippet in kernel-doc-nano-HOWTO.txt is also fixed. Signed-off-by: Kevin Diggs Signed-off-by: Ingo Molnar --- include/linux/completion.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include/linux') diff --git a/include/linux/completion.h b/include/linux/completion.h index 02ef8835999..4a6b604ef7e 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h @@ -10,6 +10,18 @@ #include +/** + * struct completion - structure used to maintain state for a "completion" + * + * This is the opaque structure used to maintain the state for a "completion". + * Completions currently use a FIFO to queue threads that have to wait for + * the "completion" event. + * + * See also: complete(), wait_for_completion() (and friends _timeout, + * _interruptible, _interruptible_timeout, and _killable), init_completion(), + * and macros DECLARE_COMPLETION(), DECLARE_COMPLETION_ONSTACK(), and + * INIT_COMPLETION(). + */ struct completion { unsigned int done; wait_queue_head_t wait; @@ -21,6 +33,14 @@ struct completion { #define COMPLETION_INITIALIZER_ONSTACK(work) \ ({ init_completion(&work); work; }) +/** + * DECLARE_COMPLETION: - declare and initialize a completion structure + * @work: identifier for the completion structure + * + * This macro declares and initializes a completion structure. Generally used + * for static declarations. You should use the _ONSTACK variant for automatic + * variables. + */ #define DECLARE_COMPLETION(work) \ struct completion work = COMPLETION_INITIALIZER(work) @@ -29,6 +49,13 @@ struct completion { * completions - so we use the _ONSTACK() variant for those that * are on the kernel stack: */ +/** + * DECLARE_COMPLETION_ONSTACK: - declare and initialize a completion structure + * @work: identifier for the completion structure + * + * This macro declares and initializes a completion structure on the kernel + * stack. + */ #ifdef CONFIG_LOCKDEP # define DECLARE_COMPLETION_ONSTACK(work) \ struct completion work = COMPLETION_INITIALIZER_ONSTACK(work) @@ -36,6 +63,13 @@ struct completion { # define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work) #endif +/** + * init_completion: - Initialize a dynamically allocated completion + * @x: completion structure that is to be initialized + * + * This inline function will initialize a dynamically created completion + * structure. + */ static inline void init_completion(struct completion *x) { x->done = 0; @@ -55,6 +89,13 @@ extern bool completion_done(struct completion *x); extern void complete(struct completion *); extern void complete_all(struct completion *); +/** + * INIT_COMPLETION: - reinitialize a completion structure + * @x: completion structure to be reinitialized + * + * This macro should be used to reinitialize a completion structure so it can + * be reused. This is especially important after complete_all() is used. + */ #define INIT_COMPLETION(x) ((x).done = 0) -- cgit v1.2.3 From da31894ed7b654e2e1741e7ac4ef6c15be0dd14b Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Fri, 22 Aug 2008 11:35:57 -0400 Subject: securityfs: do not depend on CONFIG_SECURITY Add a new Kconfig option SECURITYFS which will build securityfs support but does not require CONFIG_SECURITY. The only current user of securityfs does not depend on CONFIG_SECURITY and there is no reason the full LSM needs to be built to build this fs. Signed-off-by: Eric Paris Signed-off-by: James Morris --- include/linux/security.h | 54 +++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 24 deletions(-) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 80c4d002864..f5c4a51eb42 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1560,11 +1560,6 @@ struct security_operations { extern int security_init(void); extern int security_module_enable(struct security_operations *ops); extern int register_security(struct security_operations *ops); -extern struct dentry *securityfs_create_file(const char *name, mode_t mode, - struct dentry *parent, void *data, - const struct file_operations *fops); -extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent); -extern void securityfs_remove(struct dentry *dentry); /* Security operations */ int security_ptrace_may_access(struct task_struct *child, unsigned int mode); @@ -2424,25 +2419,6 @@ static inline int security_netlink_recv(struct sk_buff *skb, int cap) return cap_netlink_recv(skb, cap); } -static inline struct dentry *securityfs_create_dir(const char *name, - struct dentry *parent) -{ - return ERR_PTR(-ENODEV); -} - -static inline struct dentry *securityfs_create_file(const char *name, - mode_t mode, - struct dentry *parent, - void *data, - const struct file_operations *fops) -{ - return ERR_PTR(-ENODEV); -} - -static inline void securityfs_remove(struct dentry *dentry) -{ -} - static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) { return -EOPNOTSUPP; @@ -2806,5 +2782,35 @@ static inline void security_audit_rule_free(void *lsmrule) #endif /* CONFIG_SECURITY */ #endif /* CONFIG_AUDIT */ +#ifdef CONFIG_SECURITYFS + +extern struct dentry *securityfs_create_file(const char *name, mode_t mode, + struct dentry *parent, void *data, + const struct file_operations *fops); +extern struct dentry *securityfs_create_dir(const char *name, struct dentry *parent); +extern void securityfs_remove(struct dentry *dentry); + +#else /* CONFIG_SECURITYFS */ + +static inline struct dentry *securityfs_create_dir(const char *name, + struct dentry *parent) +{ + return ERR_PTR(-ENODEV); +} + +static inline struct dentry *securityfs_create_file(const char *name, + mode_t mode, + struct dentry *parent, + void *data, + const struct file_operations *fops) +{ + return ERR_PTR(-ENODEV); +} + +static inline void securityfs_remove(struct dentry *dentry) +{} + +#endif + #endif /* ! __LINUX_SECURITY_H */ -- cgit v1.2.3 From 0f8e0d9a317406612700426fad3efab0b7bbc467 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 6 Aug 2008 13:30:24 -0500 Subject: dlm: allow multiple lockspace creates Add a count for lockspace create and release so that create can be called multiple times to use the lockspace from different places. Also add the new flag DLM_LSFL_NEWEXCL to create a lockspace with the previous behavior of returning -EEXIST if the lockspace already exists. Signed-off-by: David Teigland --- include/linux/dlm.h | 5 ++++- include/linux/dlm_device.h | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dlm.h b/include/linux/dlm.h index 203a025e30e..b9cd38603fd 100644 --- a/include/linux/dlm.h +++ b/include/linux/dlm.h @@ -2,7 +2,7 @@ ******************************************************************************* ** ** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. ** ** This copyrighted material is made available to anyone wishing to use, ** modify, copy, or redistribute it subject to the terms and conditions @@ -65,9 +65,12 @@ struct dlm_lksb { char * sb_lvbptr; }; +/* dlm_new_lockspace() flags */ + #define DLM_LSFL_NODIR 0x00000001 #define DLM_LSFL_TIMEWARN 0x00000002 #define DLM_LSFL_FS 0x00000004 +#define DLM_LSFL_NEWEXCL 0x00000008 #ifdef __KERNEL__ diff --git a/include/linux/dlm_device.h b/include/linux/dlm_device.h index c6034508fed..3060783c419 100644 --- a/include/linux/dlm_device.h +++ b/include/linux/dlm_device.h @@ -26,7 +26,7 @@ /* Version of the device interface */ #define DLM_DEVICE_VERSION_MAJOR 6 #define DLM_DEVICE_VERSION_MINOR 0 -#define DLM_DEVICE_VERSION_PATCH 0 +#define DLM_DEVICE_VERSION_PATCH 1 /* struct passed to the lock write */ struct dlm_lock_params { -- cgit v1.2.3 From da7f033ddc9fdebb3223b0bf88a2a2ab5b797608 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 31 Jul 2008 17:08:25 +0800 Subject: crypto: cryptomgr - Add test infrastructure This patch moves the newly created alg_test infrastructure into cryptomgr. This shall allow us to use it for testing at algorithm registrations. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index c43dc47fdf7..7ea0a4bc4ce 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -515,6 +515,8 @@ struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags); struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask); void crypto_free_tfm(struct crypto_tfm *tfm); +int alg_test(const char *driver, const char *alg, u32 type, u32 mask); + /* * Transform helpers which query the underlying algorithm. */ -- cgit v1.2.3 From 73d3864a4823abda19ebc4387b6ddcbf416e3a77 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Aug 2008 21:15:23 +0800 Subject: crypto: api - Use test infrastructure This patch makes use of the new testing infrastructure by requiring algorithms to pass a run-time test before they're made available to users. Signed-off-by: Herbert Xu --- include/linux/crypto.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 7ea0a4bc4ce..81d994a3bda 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -60,6 +60,14 @@ */ #define CRYPTO_ALG_GENIV 0x00000200 +/* + * Set if the algorithm has passed automated run-time testing. Note that + * if there is no run-time testing for a given algorithm it is considered + * to have passed. + */ + +#define CRYPTO_ALG_TESTED 0x00000400 + /* * Transform masks and values (for crt_flags). */ -- cgit v1.2.3 From 17f0f4a47df9aea9ee26c939f8057c35e0be1847 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Thu, 14 Aug 2008 22:15:52 +1000 Subject: crypto: rng - RNG interface and implementation This patch adds a random number generator interface as well as a cryptographic pseudo-random number generator based on AES. It is meant to be used in cases where a deterministic CPRNG is required. One of the first applications will be as an input in the IPsec IV generation process. Signed-off-by: Neil Horman Signed-off-by: Herbert Xu --- include/linux/crypto.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 81d994a3bda..3d2317e4af2 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -38,6 +38,7 @@ #define CRYPTO_ALG_TYPE_DIGEST 0x00000008 #define CRYPTO_ALG_TYPE_HASH 0x00000009 #define CRYPTO_ALG_TYPE_AHASH 0x0000000a +#define CRYPTO_ALG_TYPE_RNG 0x0000000c #define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e #define CRYPTO_ALG_TYPE_AHASH_MASK 0x0000000c @@ -113,6 +114,7 @@ struct crypto_aead; struct crypto_blkcipher; struct crypto_hash; struct crypto_ahash; +struct crypto_rng; struct crypto_tfm; struct crypto_type; struct aead_givcrypt_request; @@ -298,6 +300,15 @@ struct compress_alg { unsigned int slen, u8 *dst, unsigned int *dlen); }; +struct rng_alg { + int (*rng_make_random)(struct crypto_rng *tfm, u8 *rdata, + unsigned int dlen); + int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); + + unsigned int seedsize; +}; + + #define cra_ablkcipher cra_u.ablkcipher #define cra_aead cra_u.aead #define cra_blkcipher cra_u.blkcipher @@ -306,6 +317,7 @@ struct compress_alg { #define cra_hash cra_u.hash #define cra_ahash cra_u.ahash #define cra_compress cra_u.compress +#define cra_rng cra_u.rng struct crypto_alg { struct list_head cra_list; @@ -333,6 +345,7 @@ struct crypto_alg { struct hash_alg hash; struct ahash_alg ahash; struct compress_alg compress; + struct rng_alg rng; } cra_u; int (*cra_init)(struct crypto_tfm *tfm); @@ -438,6 +451,12 @@ struct compress_tfm { u8 *dst, unsigned int *dlen); }; +struct rng_tfm { + int (*rng_gen_random)(struct crypto_rng *tfm, u8 *rdata, + unsigned int dlen); + int (*rng_reset)(struct crypto_rng *tfm, u8 *seed, unsigned int slen); +}; + #define crt_ablkcipher crt_u.ablkcipher #define crt_aead crt_u.aead #define crt_blkcipher crt_u.blkcipher @@ -445,6 +464,7 @@ struct compress_tfm { #define crt_hash crt_u.hash #define crt_ahash crt_u.ahash #define crt_compress crt_u.compress +#define crt_rng crt_u.rng struct crypto_tfm { @@ -458,6 +478,7 @@ struct crypto_tfm { struct hash_tfm hash; struct ahash_tfm ahash; struct compress_tfm compress; + struct rng_tfm rng; } crt_u; struct crypto_alg *__crt_alg; @@ -489,6 +510,10 @@ struct crypto_hash { struct crypto_tfm base; }; +struct crypto_rng { + struct crypto_tfm base; +}; + enum { CRYPTOA_UNSPEC, CRYPTOA_ALG, -- cgit v1.2.3 From 9f1ba9062e032fb7b395cd27fc564754fe4e9867 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 7 Aug 2008 20:07:01 +0300 Subject: mac80211/cfg80211: Add BSS configuration options for AP mode This change adds a new cfg80211 command, NL80211_CMD_SET_BSS, to allow AP mode BSS parameters to be changed from user space (e.g., hostapd). The drivers using mac80211 are expected to be modified with separate changes to use the new BSS info parameter for short slot time in the bss_info_changed() handler. Signed-off-by: Jouni Malinen Acked-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/nl80211.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 2be7c63bc0f..447c02a5190 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -89,6 +89,8 @@ * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC * or, if no MAC address given, all mesh paths, on the interface identified * by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by + * %NL80211_ATTR_IFINDEX. * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use @@ -127,6 +129,8 @@ enum nl80211_commands { NL80211_CMD_NEW_MPATH, NL80211_CMD_DEL_MPATH, + NL80211_CMD_SET_BSS, + /* add commands here */ /* used to define NL80211_CMD_MAX below */ @@ -134,6 +138,11 @@ enum nl80211_commands { NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 }; +/* + * Allow user space programs to use #ifdef on new commands by defining them + * here + */ +#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS /** * enum nl80211_attrs - nl80211 netlink attributes @@ -192,6 +201,12 @@ enum nl80211_commands { * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of * &enum nl80211_mntr_flags. * + * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled + * (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled + * (u8, 0 or 1) + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -235,6 +250,10 @@ enum nl80211_attrs { NL80211_ATTR_MPATH_NEXT_HOP, NL80211_ATTR_MPATH_INFO, + NL80211_ATTR_BSS_CTS_PROT, + NL80211_ATTR_BSS_SHORT_PREAMBLE, + NL80211_ATTR_BSS_SHORT_SLOT_TIME, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, -- cgit v1.2.3 From 18d7c65ba6628d2759bd650e7039d6307f2c99e9 Mon Sep 17 00:00:00 2001 From: Sujith Date: Thu, 14 Aug 2008 13:27:41 +0530 Subject: mac80211: Add an 802.11n definition This patch adds a HT Capability (DSSS/CCK Mode in 40MHz BSS) definition to ieee80211.h Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 7f4df7c7659..be456450cd2 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -714,6 +714,7 @@ struct ieee80211_ht_addt_info { #define IEEE80211_HT_CAP_SGI_40 0x0040 #define IEEE80211_HT_CAP_DELAY_BA 0x0400 #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 /* 802.11n HT capability AMPDU settings */ #define IEEE80211_HT_CAP_AMPDU_FACTOR 0x03 #define IEEE80211_HT_CAP_AMPDU_DENSITY 0x1C -- cgit v1.2.3 From 095f695cbb07281682462da0618fffabb499d0be Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 19 Aug 2008 12:50:31 -0500 Subject: ssb: Update for Rev. 5 SPROM Although a revision 5 SPROM has not been seen in the wild, the open-source portion of the MIPS driver 4.150.10.5 describes its layout, which is mostly inherited from revision 4. This patch implements the differences. Signed-off-by: Larry Finger Acked-by: Michael Buesch Signed-off-by: John W. Linville --- include/linux/ssb/ssb_regs.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index ebad0bac980..271bb4b6446 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -316,6 +316,21 @@ #define SSB_SPROM4_PA1B1 0x1090 #define SSB_SPROM4_PA1B2 0x1092 +/* SPROM Revision 5 (inherits most data from rev 4) */ +#define SSB_SPROM5_BFLLO 0x104A /* Boardflags (low 16 bits) */ +#define SSB_SPROM5_BFLHI 0x104C /* Board Flags Hi */ +#define SSB_SPROM5_IL0MAC 0x1052 /* 6 byte MAC address for a/b/g/n */ +#define SSB_SPROM5_CCODE 0x1044 /* Country Code (2 bytes) */ +#define SSB_SPROM5_GPIOA 0x1076 /* Gen. Purpose IO # 0 and 1 */ +#define SSB_SPROM5_GPIOA_P0 0x00FF /* Pin 0 */ +#define SSB_SPROM5_GPIOA_P1 0xFF00 /* Pin 1 */ +#define SSB_SPROM5_GPIOA_P1_SHIFT 8 +#define SSB_SPROM5_GPIOB 0x1078 /* Gen. Purpose IO # 2 and 3 */ +#define SSB_SPROM5_GPIOB_P2 0x00FF /* Pin 2 */ +#define SSB_SPROM5_GPIOB_P3 0xFF00 /* Pin 3 */ +#define SSB_SPROM5_GPIOB_P3_SHIFT 8 + + /* Values for SSB_SPROM1_BINF_CCODE */ enum { SSB_SPROM1CCODE_WORLD = 0, -- cgit v1.2.3 From 31ce12fb3ebf88b054deb99ad729e84888bf6125 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 20 Aug 2008 17:45:06 -0500 Subject: ssb: Clean up extraction of MAC addresses from SPROM Only rev 1 and 2 ssb SPROMs have fields named et0mac and et1mac; however, all of the extraction routines extract pseudo data for these fields from regions that are all 1's resulting in a hardware address of FF:FF:FF:FF:FF:FF. This patch forces such a fill at the beginning of the data extraction process, and only does the formal extraction if the SPROM rev is 1 or 2. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- include/linux/ssb/ssb_regs.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index 271bb4b6446..99a0f991e85 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -245,8 +245,6 @@ /* SPROM Revision 3 (inherits most data from rev 2) */ #define SSB_SPROM3_IL0MAC 0x104A /* 6 bytes MAC address for 802.11b/g */ -#define SSB_SPROM3_ET0MAC 0x1050 /* 6 bytes MAC address for Ethernet ?? */ -#define SSB_SPROM3_ET1MAC 0x1050 /* 6 bytes MAC address for 802.11a ?? */ #define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */ #define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */ #define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */ @@ -267,8 +265,6 @@ /* SPROM Revision 4 */ #define SSB_SPROM4_IL0MAC 0x104C /* 6 byte MAC address for a/b/g/n */ -#define SSB_SPROM4_ET0MAC 0x1018 /* 6 bytes MAC address for Ethernet ?? */ -#define SSB_SPROM4_ET1MAC 0x1018 /* 6 bytes MAC address for 802.11a ?? */ #define SSB_SPROM4_ETHPHY 0x105A /* Ethernet PHY settings ?? */ #define SSB_SPROM4_ETHPHY_ET0A 0x001F /* MII Address for enet0 */ #define SSB_SPROM4_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */ -- cgit v1.2.3 From 36aedc903ea11a4188de0a118d26c9f20afdd272 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 25 Aug 2008 11:58:58 +0300 Subject: mac80211/cfg80211: HT capabilities for NEW_STA Allow userspace (e.g., hostapd) to set HT capabilities for associated STAs. This is based on a patch from Zhu Yi (only the NL80211_ATTR_HT_CAPABILITY for NEW_STA part is included here). Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- include/linux/nl80211.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 447c02a5190..0c1147de3ec 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -207,6 +207,9 @@ enum nl80211_commands { * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled * (u8, 0 or 1) * + * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from + * association request when used with NL80211_CMD_NEW_STATION) + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -254,16 +257,25 @@ enum nl80211_attrs { NL80211_ATTR_BSS_SHORT_PREAMBLE, NL80211_ATTR_BSS_SHORT_SLOT_TIME, + NL80211_ATTR_HT_CAPABILITY, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 }; +/* + * Allow user space programs to use #ifdef on new attributes by defining them + * here + */ +#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY + #define NL80211_MAX_SUPP_RATES 32 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 +#define NL80211_HT_CAPABILITY_LEN 26 /** * enum nl80211_iftype - (virtual) interface types -- cgit v1.2.3 From 942ed161944b3476639916cf544e6975b29c985a Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 26 Aug 2008 21:09:59 +0100 Subject: power_supply: Add function to return system-wide power state Certain drivers benefit from knowing whether the system is on ac or battery, for instance when determining which backlight registers to read. This adds a simple call to determine whether there's an online power supply other than any batteries. Signed-off-by: Matthew Garrett Signed-off-by: Anton Vorontsov --- include/linux/power_supply.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/power_supply.h b/include/linux/power_supply.h index ea96ead1d39..f9348cba6dc 100644 --- a/include/linux/power_supply.h +++ b/include/linux/power_supply.h @@ -165,6 +165,12 @@ struct power_supply_info { extern void power_supply_changed(struct power_supply *psy); extern int power_supply_am_i_supplied(struct power_supply *psy); +#if defined(CONFIG_POWER_SUPPLY) || defined(CONFIG_POWER_SUPPLY_MODULE) +extern int power_supply_is_system_supplied(void); +#else +static inline int power_supply_is_system_supplied(void) { return -ENOSYS; } +#endif + extern int power_supply_register(struct device *parent, struct power_supply *psy); extern void power_supply_unregister(struct power_supply *psy); -- cgit v1.2.3 From 94fe7424a4c21940b4569200faaf0a0a5efd2924 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Wed, 3 Sep 2008 15:12:34 -0700 Subject: rtc-m48t59: add support for M48T02 and M48T59 chips Add support for two compatible RTC: - M48T08 which does not have alarm part, - M48T08 which does not have alarm part and has only 2KB of NVRAM These types covers all Mostek's RTC used in Sun UltraSparc workstations. Tested on Sun Ultra60 with M48T59 RTC. Signed-off-by: Krzysztof Helt Signed-off-by: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- include/linux/rtc/m48t59.h | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rtc/m48t59.h b/include/linux/rtc/m48t59.h index e8c7c21ceb1..41798505d15 100644 --- a/include/linux/rtc/m48t59.h +++ b/include/linux/rtc/m48t59.h @@ -18,40 +18,45 @@ /* * M48T59 Register Offset */ -#define M48T59_YEAR 0x1fff -#define M48T59_MONTH 0x1ffe -#define M48T59_MDAY 0x1ffd /* Day of Month */ -#define M48T59_WDAY 0x1ffc /* Day of Week */ +#define M48T59_YEAR 0xf +#define M48T59_MONTH 0xe +#define M48T59_MDAY 0xd /* Day of Month */ +#define M48T59_WDAY 0xc /* Day of Week */ #define M48T59_WDAY_CB 0x20 /* Century Bit */ #define M48T59_WDAY_CEB 0x10 /* Century Enable Bit */ -#define M48T59_HOUR 0x1ffb -#define M48T59_MIN 0x1ffa -#define M48T59_SEC 0x1ff9 -#define M48T59_CNTL 0x1ff8 +#define M48T59_HOUR 0xb +#define M48T59_MIN 0xa +#define M48T59_SEC 0x9 +#define M48T59_CNTL 0x8 #define M48T59_CNTL_READ 0x40 #define M48T59_CNTL_WRITE 0x80 -#define M48T59_WATCHDOG 0x1ff7 -#define M48T59_INTR 0x1ff6 +#define M48T59_WATCHDOG 0x7 +#define M48T59_INTR 0x6 #define M48T59_INTR_AFE 0x80 /* Alarm Interrupt Enable */ #define M48T59_INTR_ABE 0x20 -#define M48T59_ALARM_DATE 0x1ff5 -#define M48T59_ALARM_HOUR 0x1ff4 -#define M48T59_ALARM_MIN 0x1ff3 -#define M48T59_ALARM_SEC 0x1ff2 -#define M48T59_UNUSED 0x1ff1 -#define M48T59_FLAGS 0x1ff0 +#define M48T59_ALARM_DATE 0x5 +#define M48T59_ALARM_HOUR 0x4 +#define M48T59_ALARM_MIN 0x3 +#define M48T59_ALARM_SEC 0x2 +#define M48T59_UNUSED 0x1 +#define M48T59_FLAGS 0x0 #define M48T59_FLAGS_WDT 0x80 /* watchdog timer expired */ #define M48T59_FLAGS_AF 0x40 /* alarm */ #define M48T59_FLAGS_BF 0x10 /* low battery */ -#define M48T59_NVRAM_SIZE 0x1ff0 +#define M48T59RTC_TYPE_M48T59 0 /* to keep compatibility */ +#define M48T59RTC_TYPE_M48T02 1 +#define M48T59RTC_TYPE_M48T08 2 struct m48t59_plat_data { - /* The method to access M48T59 registers, - * NOTE: The 'ofs' should be 0x00~0x1fff - */ + /* The method to access M48T59 registers */ void (*write_byte)(struct device *dev, u32 ofs, u8 val); unsigned char (*read_byte)(struct device *dev, u32 ofs); + + int type; /* RTC model */ + + /* offset to RTC registers, automatically set according to the type */ + unsigned int offset; }; #endif /* _LINUX_RTC_M48T59_H_ */ -- cgit v1.2.3 From 64151ad5b3a03e236390d6d5160805ee4f4e7c67 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Wed, 3 Sep 2008 15:41:57 -0700 Subject: rtc-m48t59: allow externally mapped ioaddr Add support for externally mapped ioaddr. This is required on sparc32 as the ioaddr must be mapped with of_ioremap(). Signed-off-by: Krzysztof Helt Signed-off-by: David S. Miller --- include/linux/rtc/m48t59.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rtc/m48t59.h b/include/linux/rtc/m48t59.h index 41798505d15..6fc961459b4 100644 --- a/include/linux/rtc/m48t59.h +++ b/include/linux/rtc/m48t59.h @@ -55,6 +55,8 @@ struct m48t59_plat_data { int type; /* RTC model */ + /* ioaddr mapped externally */ + void __iomem *ioaddr; /* offset to RTC registers, automatically set according to the type */ unsigned int offset; }; -- cgit v1.2.3 From b4eec206370b7154dc354dc30f0a3f02ea8468b2 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Implement lookup table for feature-negotiation information A lookup table for feature-negotiation information, extracted from RFC 4340/42, is provided by this patch. All currently known features can be found in this table, along with their feature location, their default value, and type. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 6080449fbec..3978aff197d 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -176,19 +176,20 @@ enum { }; /* DCCP features (RFC 4340 section 6.4) */ -enum { +enum dccp_feature_numbers { DCCPF_RESERVED = 0, DCCPF_CCID = 1, - DCCPF_SHORT_SEQNOS = 2, /* XXX: not yet implemented */ + DCCPF_SHORT_SEQNOS = 2, DCCPF_SEQUENCE_WINDOW = 3, - DCCPF_ECN_INCAPABLE = 4, /* XXX: not yet implemented */ + DCCPF_ECN_INCAPABLE = 4, DCCPF_ACK_RATIO = 5, DCCPF_SEND_ACK_VECTOR = 6, DCCPF_SEND_NDP_COUNT = 7, DCCPF_MIN_CSUM_COVER = 8, - DCCPF_DATA_CHECKSUM = 9, /* XXX: not yet implemented */ + DCCPF_DATA_CHECKSUM = 9, /* 10-127 reserved */ DCCPF_MIN_CCID_SPECIFIC = 128, + DCCPF_SEND_LEV_RATE = 192, /* RFC 4342, sec. 8.4 */ DCCPF_MAX_CCID_SPECIFIC = 255, }; -- cgit v1.2.3 From 828755cee087e4a34f45d6c9db661ccd0631cc6d Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Per-socket initialisation of feature negotiation This provides feature-negotiation initialisation for both DCCP sockets and DCCP request_sockets, to support feature negotiation during connection setup. It also resolves a FIXME regarding the congestion control initialisation. Thanks to Wei Yongjun for help with the IPv6 side of this patch. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 3978aff197d..484b8a1fb02 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -412,6 +412,7 @@ extern void dccp_minisock_init(struct dccp_minisock *dmsk); * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1) * @dreq_isr: initial sequence number received on the Request * @dreq_service: service code present on the Request (there is just one) + * @dreq_featneg: feature negotiation options for this connection * The following two fields are analogous to the ones in dccp_sock: * @dreq_timestamp_echo: last received timestamp to echo (13.1) * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo @@ -421,6 +422,7 @@ struct dccp_request_sock { __u64 dreq_iss; __u64 dreq_isr; __be32 dreq_service; + struct list_head dreq_featneg; __u32 dreq_timestamp_echo; __u32 dreq_timestamp_time; }; @@ -498,6 +500,7 @@ struct dccp_ackvec; * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) * @dccps_minisock - associated minisock (accessed via dccp_msk) + * @dccps_featneg - tracks feature-negotiation state (mostly during handshake) * @dccps_hc_rx_ackvec - rx half connection ack vector * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection) @@ -535,6 +538,7 @@ struct dccp_sock { __u64 dccps_ndp_count:48; unsigned long dccps_rate_last; struct dccp_minisock dccps_minisock; + struct list_head dccps_featneg; struct dccp_ackvec *dccps_hc_rx_ackvec; struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; -- cgit v1.2.3 From 71bb49596bbf4e5a3328e1704d18604e822ba181 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Query supported CCIDs This provides a data structure to record which CCIDs are locally supported and three accessor functions: - a test function for internal use which is used to validate CCID requests made by the user; - a copy function so that the list can be used for feature-negotiation; - documented getsockopt() support so that the user can query capabilities. The data structure is a table which is filled in at compile-time with the list of available CCIDs (which in turn depends on the Kconfig choices). Using the copy function for cloning the list of supported CCIDs is useful for feature negotiation, since the negotiation is now with the full list of available CCIDs (e.g. {2, 3}) instead of the default value {2}. This means negotiation will not fail if the peer requests to use CCID3 instead of CCID2. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 484b8a1fb02..d3ac1bde60b 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -209,6 +209,7 @@ struct dccp_so_feat { #define DCCP_SOCKOPT_SERVER_TIMEWAIT 6 #define DCCP_SOCKOPT_SEND_CSCOV 10 #define DCCP_SOCKOPT_RECV_CSCOV 11 +#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 -- cgit v1.2.3 From 668144f7b41716a9efe1b398e15ead32a26cd101 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Deprecate old setsockopt framework The previous setsockopt interface, which passed socket options via struct dccp_so_feat, is complicated/difficult to use. Continuing to support it leads to ugly code since the old approach did not distinguish between NN and SP values. This patch removes the old setsockopt interface and replaces it with two new functions to register NN/SP values for feature negotiation. These are essentially wrappers around the internal __feat_register functions, with checking added to avoid * wrong usage (type); * changing values while the connection is in progress. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index d3ac1bde60b..6eaaca9b037 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -193,13 +193,6 @@ enum dccp_feature_numbers { DCCPF_MAX_CCID_SPECIFIC = 255, }; -/* this structure is argument to DCCP_SOCKOPT_CHANGE_X */ -struct dccp_so_feat { - __u8 dccpsf_feat; - __u8 __user *dccpsf_val; - __u8 dccpsf_len; -}; - /* DCCP socket options */ #define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */ #define DCCP_SOCKOPT_SERVICE 2 -- cgit v1.2.3 From 20f41eee82864e308a5499308a1722dc3181cc3a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Feature negotiation for minimum-checksum-coverage This provides feature negotiation for server minimum checksum coverage which so far has been missing. Since sender/receiver coverage values range only from 0...15, their type has also been reduced in size from u16 to u4. Feature-negotiation options are now generated for both sender and receiver coverage, i.e. when the peer has `forgotten' to enable partial coverage then feature negotiation will automatically enable (negotiate) the partial coverage value for this connection. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 6eaaca9b037..5a5a89935db 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -527,8 +527,8 @@ struct dccp_sock { __u32 dccps_timestamp_time; __u16 dccps_l_ack_ratio; __u16 dccps_r_ack_ratio; - __u16 dccps_pcslen; - __u16 dccps_pcrlen; + __u8 dccps_pcslen:4; + __u8 dccps_pcrlen:4; __u64 dccps_ndp_count:48; unsigned long dccps_rate_last; struct dccp_minisock dccps_minisock; -- cgit v1.2.3 From 17c30b40ed79e9f3955e884632c8f01e577b204a Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Deprecate Ack Ratio sysctl This patch deprecates the Ack Ratio sysctl, since * Ack Ratio is entirely ignored by CCID-3 and CCID-4, * Ack Ratio currently doesn't work in CCID-2 (i.e. is always set to 1); * even if it would work in CCID-2, there is no point for a user to change it: - Ack Ratio is constrained by cwnd (RFC 4341, 6.1.2), - if Ack Ratio > cwnd, the system resorts to spurious RTO timeouts (since waiting for Acks which will never arrive in this window), - cwnd is not a user-configurable value. The only reasonable place for Ack Ratio is to print it for debugging. It is planned to do this later on, as part of e.g. dccp_probe. With this patch Ack Ratio is now under full control of feature negotiation: * Ack Ratio is resolved as a dependency of the selected CCID; * if the chosen CCID supports it (i.e. CCID == CCID-2), Ack Ratio is set to the default of 2, following RFC 4340, 11.3 - "New connections start with Ack Ratio 2 for both endpoints"; * what happens then is part of another patch set, since it concerns the dynamic update of Ack Ratio while the connection is in full flight. Thanks to Tomasz Grobelny for discussion leading up to this patch. Signed-off-by: Gerrit Renker Acked-by: Arnaldo Carvalho de Melo --- include/linux/dccp.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 5a5a89935db..eda389ce04f 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -368,7 +368,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) * @dccpms_ccid - Congestion Control Id (CCID) (section 10) * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2) - * @dccpms_ack_ratio - Ack Ratio Feature (section 11.3) * @dccpms_pending - List of features being negotiated * @dccpms_conf - */ @@ -378,7 +377,6 @@ struct dccp_minisock { __u8 dccpms_tx_ccid; __u8 dccpms_send_ack_vector; __u8 dccpms_send_ndp_count; - __u8 dccpms_ack_ratio; struct list_head dccpms_pending; struct list_head dccpms_conf; }; -- cgit v1.2.3 From fade756f18d42694e3acb00e3471ab43002cba16 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Set per-connection CCIDs via socket options With this patch, TX/RX CCIDs can now be changed on a per-connection basis, which overrides the defaults set by the global sysctl variables for TX/RX CCIDs. To make full use of this facility, the remaining patches of this patch set are needed, which track dependencies and activate negotiated feature values. Note on the maximum number of CCIDs that can be registered: ----------------------------------------------------------- The maximum number of CCIDs that can be registered on the socket is constrained by the space in a Confirm/Change feature negotiation option. The space in these in turn depends on the size of header options as defined in RFC 4340, 5.8. Since this is a recurring constant, it has been moved from ackvec.h into linux/dccp.h, clarifying its purpose. Relative to this size, the maximum number of CCID identifiers that can be present in a Confirm option (which always consumes 1 byte more than a Change option, cf. 6.1) is 2 bytes less than the maximum TLV size: one for the CCID-feature-type and one for the selected value. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index eda389ce04f..6a72ff52a8a 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -168,6 +168,8 @@ enum { DCCPO_MIN_CCID_SPECIFIC = 128, DCCPO_MAX_CCID_SPECIFIC = 255, }; +/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ +#define DCCP_SINGLE_OPT_MAXLEN 253 /* DCCP CCIDS */ enum { @@ -203,6 +205,9 @@ enum dccp_feature_numbers { #define DCCP_SOCKOPT_SEND_CSCOV 10 #define DCCP_SOCKOPT_RECV_CSCOV 11 #define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 +#define DCCP_SOCKOPT_CCID 13 +#define DCCP_SOCKOPT_TX_CCID 14 +#define DCCP_SOCKOPT_RX_CCID 15 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 -- cgit v1.2.3 From 78673e24df27c76ec75565f4024d45c2c74ef148 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Remove obsolete parts of the old CCID interface The TX/RX CCIDs of the minisock are now redundant: similar to the Ack Vector case, their value equals initially that of the sysctl, but at the end of feature negotiation may be something different. The old interface removed by this patch thus has been replaced by the newer interface to dynamically query the currently loaded CCIDs earlier in this patch set. Also removed the constructors for the TX CCID and the RX CCID, since the switch rx/non-rx is done by the handler in minisocks.c (and the handler is the only place in the code where CCIDs are loaded). Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 6a72ff52a8a..46daea312d9 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -370,7 +370,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) * Will be used to pass the state from dccp_request_sock to dccp_sock. * * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) - * @dccpms_ccid - Congestion Control Id (CCID) (section 10) * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2) * @dccpms_pending - List of features being negotiated @@ -378,8 +377,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) */ struct dccp_minisock { __u64 dccpms_sequence_window; - __u8 dccpms_rx_ccid; - __u8 dccpms_tx_ccid; __u8 dccpms_send_ack_vector; __u8 dccpms_send_ndp_count; struct list_head dccpms_pending; -- cgit v1.2.3 From 68e074bfcef269bc61006c2740d7f89ccbbd93d7 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Remove manual influence on NDP Count feature Updating the NDP count feature is handled automatically now: * for CCID-2 it is disabled, since the code does not use NDP counts; * for CCID-3 it is enabled, as NDP counts are used to determine loss lengths. Allowing the user to change NDP values leads to unpredictable and failing behaviour, since it is then possible to disable NDP counts even when they are needed (e.g. in CCID-3). This means that only those user settings are sensible that agree with the values for Send NDP Count implied by the choice of CCID. But those settings are already activated by the feature negotiation (CCID dependency tracking), hence this form of support is redundant. At startup the initialisation of the NDP count feature is with the default value of 0, which is done implicitly by the zeroing-out of the socket when it is allocated. If the choice of CCID or feature negotiation enables NDP count, this will then be updated via the NDP activation handler. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 46daea312d9..60e94438ead 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -371,14 +371,12 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) * * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) - * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2) * @dccpms_pending - List of features being negotiated * @dccpms_conf - */ struct dccp_minisock { __u64 dccpms_sequence_window; __u8 dccpms_send_ack_vector; - __u8 dccpms_send_ndp_count; struct list_head dccpms_pending; struct list_head dccpms_conf; }; @@ -490,6 +488,7 @@ struct dccp_ackvec; * @dccps_r_ack_ratio - feature-remote Ack Ratio * @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) + * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) * @dccps_ndp_count - number of Non Data Packets since last data packet * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) @@ -529,6 +528,7 @@ struct dccp_sock { __u16 dccps_r_ack_ratio; __u8 dccps_pcslen:4; __u8 dccps_pcrlen:4; + __u8 dccps_send_ndp_count:1; __u64 dccps_ndp_count:48; unsigned long dccps_rate_last; struct dccp_minisock dccps_minisock; -- cgit v1.2.3 From b235dc4abbc1356284bd0dc730efa711f394e0e2 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp ccid-2: Phase out the use of boolean Ack Vector sysctl This removes the use of the sysctl and the minisock variable for the Send Ack Vector feature, which is now handled fully dynamically via feature negotiation; i.e. when CCID2 is enabled, Ack Vectors are automatically enabled (as per RFC 4341, 4.). Using a sysctl in parallel to this implementation would open the door to crashes, since much of the code relies on tests of the boolean minisock / sysctl variable. Thus, this patch replaces all tests of type if (dccp_msk(sk)->dccpms_send_ack_vector) /* ... */ with if (dp->dccps_hc_rx_ackvec != NULL) /* ... */ The dccps_hc_rx_ackvec is allocated by the dccp_hdlr_ackvec() when feature negotiation concluded that Ack Vectors are to be used on the half-connection. Otherwise, it is NULL (due to dccp_init_sock/dccp_create_openreq_child), so that the test is a valid one. The activation handler for Ack Vectors is called as soon as the feature negotiation has concluded at the * server when the Ack marking the transition RESPOND => OPEN arrives; * client after it has sent its ACK, marking the transition REQUEST => PARTOPEN. Adding the sequence number of the Response packet to the Ack Vector has been removed, since (a) connection establishment implies that the Response has been received; (b) the CCIDs only look at packets received in the (PART)OPEN state, i.e. this entry will always be ignored; (c) it can not be used for anything useful - to detect loss for instance, only packets received after the loss can serve as pseudo-dupacks. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 60e94438ead..61734e27abb 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -360,7 +360,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) #define DCCPF_INITIAL_SEQUENCE_WINDOW 100 #define DCCPF_INITIAL_ACK_RATIO 2 #define DCCPF_INITIAL_CCID DCCPC_CCID2 -#define DCCPF_INITIAL_SEND_ACK_VECTOR 1 /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 @@ -370,13 +369,11 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) * Will be used to pass the state from dccp_request_sock to dccp_sock. * * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) - * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) * @dccpms_pending - List of features being negotiated * @dccpms_conf - */ struct dccp_minisock { __u64 dccpms_sequence_window; - __u8 dccpms_send_ack_vector; struct list_head dccpms_pending; struct list_head dccpms_conf; }; -- cgit v1.2.3 From 5d3dac267a7fd0811ec777e76a81f97f5cdcb395 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Initialisation framework for feature negotiation This initialises feature negotiation from two tables, which are initialised from sysctls. As a novel feature, specifics of the implementation (e.g. currently short seqnos and ECN are not supported) are advertised for robustness. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 61734e27abb..990e97fa1f0 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -369,28 +369,9 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) * Will be used to pass the state from dccp_request_sock to dccp_sock. * * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) - * @dccpms_pending - List of features being negotiated - * @dccpms_conf - */ struct dccp_minisock { __u64 dccpms_sequence_window; - struct list_head dccpms_pending; - struct list_head dccpms_conf; -}; - -struct dccp_opt_conf { - __u8 *dccpoc_val; - __u8 dccpoc_len; -}; - -struct dccp_opt_pend { - struct list_head dccpop_node; - __u8 dccpop_type; - __u8 dccpop_feat; - __u8 *dccpop_val; - __u8 dccpop_len; - int dccpop_conf; - struct dccp_opt_conf *dccpop_sc; }; extern void dccp_minisock_init(struct dccp_minisock *dmsk); -- cgit v1.2.3 From 51c7d4fa2675c106a980ddcdbe308b54b5151945 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Implement both feature-local and feature-remote Sequence Window feature This adds full support for local/remote Sequence Window feature, from which the * sequence-number-validity (W) and * acknowledgment-number-validity (W') windows derive as specified in RFC 4340, 7.5.3. Specifically, the following changes are introduced: * integrated new socket fields into dccp_sk; * updated the update_gsr/gss routines with regard to these fields; * updated handler code: the Sequence Window feature is located at the TX side, so the local feature is meant if the handler-rx flag is false; * the initialisation of `rcv_wnd' in reqsk is removed, since - rcv_wnd is not used by the code anywhere; - sequence number checks are not done in the LISTEN state (cf. 7.5.3); - dccp_check_req checks the Ack number validity more rigorously; * the `struct dccp_minisock' became empty and is now removed. Until the handshake completes with activating negotiated values, the local/remote Sequence-Window values are undefined and thus can not reliably be estimated. This issue is addressed in a separate patch. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 990e97fa1f0..7a0502ab383 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -363,19 +363,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) /* FIXME: for now we're default to 1 but it should really be 0 */ #define DCCPF_INITIAL_SEND_NDP_COUNT 1 -/** - * struct dccp_minisock - Minimal DCCP connection representation - * - * Will be used to pass the state from dccp_request_sock to dccp_sock. - * - * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) - */ -struct dccp_minisock { - __u64 dccpms_sequence_window; -}; - -extern void dccp_minisock_init(struct dccp_minisock *dmsk); - /** * struct dccp_request_sock - represent DCCP-specific connection request * @dreq_inet_rsk: structure inherited from @@ -464,13 +451,14 @@ struct dccp_ackvec; * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo * @dccps_l_ack_ratio - feature-local Ack Ratio * @dccps_r_ack_ratio - feature-remote Ack Ratio + * @dccps_l_seq_win - local Sequence Window (influences ack number validity) + * @dccps_r_seq_win - remote Sequence Window (influences seq number validity) * @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) * @dccps_ndp_count - number of Non Data Packets since last data packet * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) - * @dccps_minisock - associated minisock (accessed via dccp_msk) * @dccps_featneg - tracks feature-negotiation state (mostly during handshake) * @dccps_hc_rx_ackvec - rx half connection ack vector * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) @@ -504,12 +492,13 @@ struct dccp_sock { __u32 dccps_timestamp_time; __u16 dccps_l_ack_ratio; __u16 dccps_r_ack_ratio; + __u64 dccps_l_seq_win:48; + __u64 dccps_r_seq_win:48; __u8 dccps_pcslen:4; __u8 dccps_pcrlen:4; __u8 dccps_send_ndp_count:1; __u64 dccps_ndp_count:48; unsigned long dccps_rate_last; - struct dccp_minisock dccps_minisock; struct list_head dccps_featneg; struct dccp_ackvec *dccps_hc_rx_ackvec; struct ccid *dccps_hc_rx_ccid; @@ -527,11 +516,6 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk) return (struct dccp_sock *)sk; } -static inline struct dccp_minisock *dccp_msk(const struct sock *sk) -{ - return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock; -} - static inline const char *dccp_role(const struct sock *sk) { switch (dccp_sk(sk)->dccps_role) { -- cgit v1.2.3 From 0a4822679d94e2b0117aeead06a19fad59533905 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Initialisation and type-checking of feature sysctls This patch takes care of initialising and type-checking sysctls related to feature negotiation. Type checking is important since some of the sysctls now directly act on the feature-negotiation process. The sysctls are initialised with the known default values for each feature. For the type-checking the value constraints from RFC 4340 are used: * Sequence Window uses the specified Wmin=32, the maximum is ulong (4 bytes), tested and confirmed that it works up to 4294967295 - for Gbps speed; * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer); * CCIDs are between 0 .. 255; * request_retries, retries1, retries2 also between 0..255 for good measure; * tx_qlen is checked to be non-negative; * sync_ratelimit remains as before. Further changes: ---------------- Performed s@sysctl_dccp_feat@sysctl_dccp@g since the sysctls are now in feat.c. Signed-off-by: Gerrit Renker Acked-by: Ian McDonald --- include/linux/dccp.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 7a0502ab383..7434a8353e2 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -355,14 +355,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) return __dccp_hdr_len(dccp_hdr(skb)); } - -/* initial values for each feature */ -#define DCCPF_INITIAL_SEQUENCE_WINDOW 100 -#define DCCPF_INITIAL_ACK_RATIO 2 -#define DCCPF_INITIAL_CCID DCCPC_CCID2 -/* FIXME: for now we're default to 1 but it should really be 0 */ -#define DCCPF_INITIAL_SEND_NDP_COUNT 1 - /** * struct dccp_request_sock - represent DCCP-specific connection request * @dreq_inet_rsk: structure inherited from -- cgit v1.2.3 From f10ecaee6dc2c6d56783462b2a82e98bc81b55f4 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Replace magic CCID-specific numbers by symbolic constants The constants DCCPO_{MIN,MAX}_CCID_SPECIFIC are nowhere used in the code, but instead for the CCID-specific options numbers are used. This patch unifies the use of CCID-specific option numbers, by adding symbolic names reflecting the definitions in RFC 4340, 10.3. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 7434a8353e2..7187bd8a75f 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -165,8 +165,10 @@ enum { DCCPO_TIMESTAMP_ECHO = 42, DCCPO_ELAPSED_TIME = 43, DCCPO_MAX = 45, - DCCPO_MIN_CCID_SPECIFIC = 128, - DCCPO_MAX_CCID_SPECIFIC = 255, + DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */ + DCCPO_MAX_RX_CCID_SPECIFIC = 191, + DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */ + DCCPO_MAX_TX_CCID_SPECIFIC = 255, }; /* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ #define DCCP_SINGLE_OPT_MAXLEN 253 -- cgit v1.2.3 From c2f42077bd06f300ae959204f3c007f820f5e769 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp ccid-2: Schedule Sync as out-of-band mechanism The problem with Ack Vectors is that i) their length is variable and can in principle grow quite large, ii) it is hard to predict exactly how large they will be. Due to the second point it seems not a good idea to reduce the MPS; in particular when on average there is enough room for the Ack Vector and an increase in length is momentarily due to some burst loss, after which the Ack Vector returns to its normal/average length. The solution taken by this patch is to subtract a minimum-expected Ack Vector length from the MPS (previous patch), and to defer any larger Ack Vectors onto a separate Sync - but only if indeed there is no space left on the skb. This patch provides the infrastructure to schedule Sync-packets for transporting (urgent) out-of-band data. Its signalling is quicker than scheduling an Ack, since it does not need to wait for new application data. It can thus serve other parts of the DCCP code as well. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 7187bd8a75f..83197b601a4 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -462,6 +462,7 @@ struct dccp_ackvec; * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) + * @dccps_sync_scheduled - flag which signals "send out-of-band message soon" * @dccps_xmit_timer - timer for when CCID is not ready to send * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) */ @@ -502,6 +503,7 @@ struct dccp_sock { __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; + __u8 dccps_sync_scheduled:1; struct timer_list dccps_xmit_timer; }; -- cgit v1.2.3 From e7937772d7a2b0127cc4cbc67bc594e139fdaf63 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Extend CCID packet dequeueing interface This extends the packet dequeuing interface of dccp_write_xmit() to allow 1. CCIDs to take care of timing when the next packet may be sent; 2. delayed sending (as before, with an inter-packet gap up to 65.535 seconds). The main purpose is to take CCID2 out of its polling mode (when it is network- limited, it tries every millisecond to send, without interruption). The interface can also be used to support other CCIDs. The mode of operation for (2) is as follows: * new packet is enqueued via dccp_sendmsg() => dccp_write_xmit(), * ccid_hc_tx_send_packet() detects that it may not send (e.g. window full), * it signals this condition via `CCID_PACKET_WILL_DEQUEUE_LATER', * dccp_write_xmit() returns without further action; * after some time the wait-condition for CCID becomes true, * that CCID schedules the tasklet, * tasklet function calls ccid_hc_tx_send_packet() via dccp_write_xmit(), * since the wait-condition is now true, ccid_hc_tx_packet() returns "send now", * packet is sent, and possibly more (since dccp_write_xmit() loops). Code reuse: the taskled function calls dccp_write_xmit(), the timer function reduces to a wrapper around the same code. If the tasklet finds that the socket is locked, it re-schedules the tasklet function (not the tasklet) after one jiffy. Changed DCCP_BUG to dccp_pr_debug when transmit_skb returns an error (e.g. when a local qdisc is used, NET_XMIT_DROP=1 can be returned for many packets). Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 83197b601a4..eed52bcd35d 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -463,7 +463,8 @@ struct dccp_ackvec; * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) * @dccps_sync_scheduled - flag which signals "send out-of-band message soon" - * @dccps_xmit_timer - timer for when CCID is not ready to send + * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets + * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) */ struct dccp_sock { @@ -504,6 +505,7 @@ struct dccp_sock { __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; __u8 dccps_sync_scheduled:1; + struct tasklet_struct dccps_xmitlet; struct timer_list dccps_xmit_timer; }; -- cgit v1.2.3 From d6da3511d6b558d0b017777b61dc08b8fbc06ea4 Mon Sep 17 00:00:00 2001 From: Tomasz Grobelny Date: Thu, 4 Sep 2008 07:30:19 +0200 Subject: dccp: Policy-based packet dequeueing infrastructure This patch adds a generic infrastructure for policy-based dequeueing of TX packets and provides two policies: * a simple FIFO policy (which is the default) and * a priority based policy (set via socket options). Both policies honour the tx_qlen sysctl for the maximum size of the write queue (can be overridden via socket options). The priority policy uses skb->priority internally to assign an u32 priority identifier, using the same ranking as SO_PRIORITY. The skb->priority field is set to 0 when the packet leaves DCCP. The priority is supplied as ancillary data using cmsg(3), the patch also provides the requisite parsing routines. Signed-off-by: Tomasz Grobelny Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index eed52bcd35d..010e2d87ed7 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -197,6 +197,21 @@ enum dccp_feature_numbers { DCCPF_MAX_CCID_SPECIFIC = 255, }; +/* DCCP socket control message types for cmsg */ +enum dccp_cmsg_type { + DCCP_SCM_PRIORITY = 1, + DCCP_SCM_QPOLICY_MAX = 0xFFFF, + /* ^-- Up to here reserved exclusively for qpolicy parameters */ + DCCP_SCM_MAX +}; + +/* DCCP priorities for outgoing/queued packets */ +enum dccp_packet_dequeueing_policy { + DCCPQ_POLICY_SIMPLE, + DCCPQ_POLICY_PRIO, + DCCPQ_POLICY_MAX +}; + /* DCCP socket options */ #define DCCP_SOCKOPT_PACKET_SIZE 1 /* XXX deprecated, without effect */ #define DCCP_SOCKOPT_SERVICE 2 @@ -210,6 +225,8 @@ enum dccp_feature_numbers { #define DCCP_SOCKOPT_CCID 13 #define DCCP_SOCKOPT_TX_CCID 14 #define DCCP_SOCKOPT_RX_CCID 15 +#define DCCP_SOCKOPT_QPOLICY_ID 16 +#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 @@ -458,6 +475,8 @@ struct dccp_ackvec; * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection) * @dccps_options_received - parsed set of retrieved options + * @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy + * @dccps_tx_qlen - maximum length of the TX queue * @dccps_role - role of this sock, one of %dccp_role * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending @@ -500,6 +519,8 @@ struct dccp_sock { struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; + __u8 dccps_qpolicy; + __u32 dccps_tx_qlen; enum dccp_role dccps_role:2; __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; -- cgit v1.2.3 From 8c5eb880585a6fa278aa49553dd53a25e1ac319d Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 3 Sep 2008 09:45:57 +0100 Subject: =?UTF-8?q?Use=20PCI=5FDEVICE=5FID=5F88ALP01=20for=20CAF=C3=89=20c?= =?UTF-8?q?hip,=20rather=20than=20PCI=5FDEVICE=5FID=5FCAFE.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Probably better to use the official designation. Signed-off-by: David Woodhouse Acked-by: Pierre Ossman --- include/linux/pci_ids.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f1624b39675..ef6ef64beb5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1521,7 +1521,7 @@ #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 -#define PCI_DEVICE_ID_MARVELL_CAFE_SD 0x4101 +#define PCI_DEVICE_ID_MARVELL_88ALP01_SD 0x4101 #define PCI_VENDOR_ID_V3 0x11b0 #define PCI_DEVICE_ID_V3_V960 0x0001 -- cgit v1.2.3 From 514fca4373d28522c0709fcdd439fc9e1e257bb6 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 3 Sep 2008 09:47:17 +0100 Subject: =?UTF-8?q?[MTD]=20[NAND]=20Define=20and=20use=20PCI=5FDEVICE=5FID?= =?UTF-8?q?=5FMARVELL=5F88ALP01=5FNAND=20for=20CAF=C3=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: David Woodhouse --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ef6ef64beb5..e6240b7cb40 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1521,6 +1521,7 @@ #define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 #define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 +#define PCI_DEVICE_ID_MARVELL_88ALP01_NAND 0x4100 #define PCI_DEVICE_ID_MARVELL_88ALP01_SD 0x4101 #define PCI_VENDOR_ID_V3 0x11b0 -- cgit v1.2.3 From aa7a7fb3990ffc74945494cbd2fc6e920825ee2c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 3 Sep 2008 09:49:20 +0100 Subject: =?UTF-8?q?Define=20and=20use=20PCI=5FDEVICE=5FID=5FMARVELL=5F88AL?= =?UTF-8?q?P01=5FCCIC=20for=20CAF=C3=89=20camera=20driver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, stop looking at the NAND controller (0x4100) and checking the device class. For a while during development, all three functions on the chip had the same ID. We made them fix that fairly promptly, and we can forget about it now. Signed-off-by: David Woodhouse Acked-by: Jonathan Corbet --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e6240b7cb40..6cf53f49b62 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1523,6 +1523,7 @@ #define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 #define PCI_DEVICE_ID_MARVELL_88ALP01_NAND 0x4100 #define PCI_DEVICE_ID_MARVELL_88ALP01_SD 0x4101 +#define PCI_DEVICE_ID_MARVELL_88ALP01_CCIC 0x4102 #define PCI_VENDOR_ID_V3 0x11b0 #define PCI_DEVICE_ID_V3_V960 0x0001 -- cgit v1.2.3 From 268364a0f48aee2f851f9d1ef8a6cda0f3039ef1 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 4 Sep 2008 21:02:44 +0200 Subject: IO resources: add reserve_region_with_split() add reserve_region_with_split() to not lose e820 reserved entries if they overlap with existing IO regions: with test case by extend 0xe0000000 - 0xeffffff to 0xdd800000 - we get: e0000000-efffffff : PCI MMCONFIG 0 e0000000-efffffff : reserved and in /proc/iomem we get: found conflict for reserved [dd800000, efffffff], try to reserve with split __reserve_region_with_split: (PCI Bus #80) [dd000000, ddffffff], res: (reserved) [dd800000, efffffff] __reserve_region_with_split: (PCI Bus #00) [de000000, dfffffff], res: (reserved) [de000000, efffffff] initcall pci_subsys_init+0x0/0x121 returned 0 after 381 msecs in dmesg various fixes and improvements suggested by Linus. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/ioport.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 8d3b7a9afd1..fded376b94e 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -108,6 +108,9 @@ extern struct resource iomem_resource; extern int request_resource(struct resource *root, struct resource *new); extern int release_resource(struct resource *new); +extern void reserve_region_with_split(struct resource *root, + resource_size_t start, resource_size_t end, + const char *name); extern int insert_resource(struct resource *parent, struct resource *new); extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); extern int allocate_resource(struct resource *root, struct resource *new, -- cgit v1.2.3 From f7981c1c67b53abb4a7d8a501e68585b9826179a Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 10:23:22 +0200 Subject: mv643xx_eth: require contiguous receive and transmit queue numbering Simplify receive and transmit queue handling by requiring the set of queue numbers to be contiguous starting from zero. Signed-off-by: Lennert Buytenhek --- include/linux/mv643xx_eth.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 12078577aef..eb78b00edcd 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -49,10 +49,10 @@ struct mv643xx_eth_platform_data { int duplex; /* - * Which RX/TX queues to use. + * How many RX/TX queues to use. */ - int rx_queue_mask; - int tx_queue_mask; + int rx_queue_count; + int tx_queue_count; /* * Override default RX/TX queue sizes if nonzero. -- cgit v1.2.3 From fc0eb9f226d8ecc8e3b563bf808bd6d61a6153a1 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 12:56:56 +0200 Subject: mv643xx_eth: smi sharing is a per-unit property, not a per-port one Which top-level unit's SMI interface to use should be a property of the top-level unit, not of the individual ports. This patch moves the ->shared_smi pointer from the per-port platform data to the global platform data. Signed-off-by: Lennert Buytenhek --- include/linux/mv643xx_eth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index eb78b00edcd..12339eb6570 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -17,6 +17,7 @@ struct mv643xx_eth_shared_platform_data { struct mbus_dram_target_info *dram; + struct platform_device *shared_smi; unsigned int t_clk; }; @@ -30,7 +31,6 @@ struct mv643xx_eth_platform_data { /* * Whether a PHY is present, and if yes, at which address. */ - struct platform_device *shared_smi; int force_phy_addr; int phy_addr; -- cgit v1.2.3 From ac840605f3b1d9b99e1e6629a54994f8e003ff91 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 14:06:47 +0200 Subject: mv643xx_eth: remove force_phy_addr field Currently, there are two different fields in the mv643xx_eth_platform_data struct that together describe the PHY address -- one field (phy_addr) has the address of the PHY, but if that address is zero, a second field (force_phy_addr) needs to be set to distinguish the actual address zero from a zero due to not having filled in the PHY address explicitly (which should mean 'use the default PHY address'). If we are a bit smarter about the encoding of the phy_addr field, we can avoid the need for a second field -- this patch does that. Signed-off-by: Lennert Buytenhek --- include/linux/mv643xx_eth.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h index 12339eb6570..cbbbe9bfeca 100644 --- a/include/linux/mv643xx_eth.h +++ b/include/linux/mv643xx_eth.h @@ -21,6 +21,10 @@ struct mv643xx_eth_shared_platform_data { unsigned int t_clk; }; +#define MV643XX_ETH_PHY_ADDR_DEFAULT 0 +#define MV643XX_ETH_PHY_ADDR(x) (0x80 | (x)) +#define MV643XX_ETH_PHY_NONE 0xff + struct mv643xx_eth_platform_data { /* * Pointer back to our parent instance, and our port number. @@ -31,7 +35,6 @@ struct mv643xx_eth_platform_data { /* * Whether a PHY is present, and if yes, at which address. */ - int force_phy_addr; int phy_addr; /* -- cgit v1.2.3 From ca1af29a733629b9158a4a32a927d16ff9009a95 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Tue, 2 Sep 2008 13:13:39 +0200 Subject: x86, pci: add northbridge pci ids for fam 0x11 processors The PCI device ids for AMD family 0x11 processors are missing in pci_ids.h. This patch adds them. Signed-off-by: Joerg Roedel Signed-off-by: Ingo Molnar --- include/linux/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 9ec2bcce8e8..0d0b314476c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -497,6 +497,11 @@ #define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP 0x1101 #define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL 0x1102 #define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 +#define PCI_DEVICE_ID_AMD_11H_NB_HT 0x1300 +#define PCI_DEVICE_ID_AMD_11H_NB_MAP 0x1301 +#define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 +#define PCI_DEVICE_ID_AMD_11H_NB_MISC 0x1303 +#define PCI_DEVICE_ID_AMD_11H_NB_LINK 0x1304 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 #define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 #define PCI_DEVICE_ID_AMD_SCSI 0x2020 -- cgit v1.2.3 From f59ac0481660e66cec67f1d6b024e78b9dc715fe Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Fri, 29 Aug 2008 16:26:43 -0700 Subject: cfg80211: keep track of supported interface modes It is obviously good for userspace to know up front which interface modes a given piece of hardware might support (even if adding such an interface might fail later because of concurrency issues), so let's make cfg80211 aware of that. For good measure, disallow adding interfaces in all other modes so drivers don't forget to announce support for one mode when they add it. Signed-off-by: Johannes Berg Signed-off-by: Stephen Blackheath Signed-off-by: Ivo van Doorn Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/linux/nl80211.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 0c1147de3ec..5e51f4e7600 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -210,6 +210,10 @@ enum nl80211_commands { * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from * association request when used with NL80211_CMD_NEW_STATION) * + * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all + * supported interface types, each a flag attribute with the number + * of the interface mode. + * * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use */ @@ -259,6 +263,8 @@ enum nl80211_attrs { NL80211_ATTR_HT_CAPABILITY, + NL80211_ATTR_SUPPORTED_IFTYPES, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, -- cgit v1.2.3 From 7bb67439bf6bd3782f07f1d7be1e63406453d5de Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 31 Aug 2008 08:05:58 -0700 Subject: select: Introduce a hrtimeout function This patch adds a schedule_hrtimeout() function, to be used by select() and poll() in a later patch. This function works similar to schedule_timeout() in most ways, but takes a timespec rather than jiffies. With a lot of contributions/fixes from Thomas Signed-off-by: Arjan van de Ven Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6d93dce61cb..becd17db1a1 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -346,6 +346,8 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *tsk); +extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); + /* Soft interrupt function to run the hrtimer queues: */ extern void hrtimer_run_queues(void); extern void hrtimer_run_pending(void); -- cgit v1.2.3 From df0cc0539b4127bd02f64de2c335b4af1fdb3845 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 31 Aug 2008 08:09:53 -0700 Subject: select: add a timespec_add_safe() function For the select() rework, it's important to be able to add timespec structures in an overflow-safe manner. This patch adds a timespec_add_safe() function for this which is similar in operation to ktime_add_safe(), but works on a struct timespec. Signed-off-by: Thomas Gleixner Signed-off-by: Arjan van de Ven --- include/linux/time.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/time.h b/include/linux/time.h index e15206a7e82..72697647848 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -38,6 +38,8 @@ struct timezone { #define NSEC_PER_SEC 1000000000L #define FSEC_PER_SEC 1000000000000000L +#define TIME_T_MAX (time_t)((1UL << ((sizeof(time_t) << 3) - 1)) - 1) + static inline int timespec_equal(const struct timespec *a, const struct timespec *b) { @@ -72,6 +74,8 @@ extern unsigned long mktime(const unsigned int year, const unsigned int mon, const unsigned int min, const unsigned int sec); extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec); +extern struct timespec timespec_add_safe(const struct timespec lhs, + const struct timespec rhs); /* * sub = lhs - rhs, in normalized form -- cgit v1.2.3 From b773ad40aca5bd755ba886620842f16e8fef6d75 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 31 Aug 2008 08:16:57 -0700 Subject: select: add poll_select_set_timeout() and poll_select_copy_remaining() helpers This patch adds 2 helpers that will be used for the hrtimer based select/poll: poll_select_set_timeout() is a helper that takes a timeout (as a second, nanosecond pair) and turns that into a "struct timespec" that represents the absolute end time. This is a common operation in the many select() and poll() variants and needs various, common, sanity checks. poll_select_copy_remaining() is a helper that takes care of copying the remaining time to userspace, as select(), pselect() and ppoll() do. This function comes in both a natural and a compat implementation (due to datastructure differences). Signed-off-by: Thomas Gleixner Signed-off-by: Arjan van de Ven --- include/linux/poll.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/poll.h b/include/linux/poll.h index ef453828877..f65de5128a9 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -120,6 +120,8 @@ extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s64 *timeout); +extern int poll_select_set_timeout(struct timespec *to, long sec, long nsec); + #endif /* KERNEL */ #endif /* _LINUX_POLL_H */ -- cgit v1.2.3 From be5dad20a55e054a35dac7f6f5f184dc72b379b4 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Sun, 31 Aug 2008 08:19:15 -0700 Subject: select: add a poll specific struct to the restart_block union with hrtimer poll/select, the signal restart data no longer is a single long representing a jiffies count, but it becomes a second/nanosecond pair that also needs to encode if there was a timeout at all or not. This patch adds a struct to the restart_block union for this purpose Signed-off-by: Thomas Gleixner Signed-off-by: Arjan van de Ven --- include/linux/thread_info.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 38a56477f27..e6b820f8b56 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -38,6 +38,14 @@ struct restart_block { #endif u64 expires; } nanosleep; + /* For poll */ + struct { + struct pollfd __user *ufds; + int nfds; + int has_timeout; + unsigned long tv_sec; + unsigned long tv_nsec; + } poll; }; }; -- cgit v1.2.3 From 8ff3e8e85fa6c312051134b3953e397feb639f51 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 31 Aug 2008 08:26:40 -0700 Subject: select: switch select() and poll() over to hrtimers With lots of help, input and cleanups from Thomas Gleixner This patch switches select() and poll() over to hrtimers. The core of the patch is replacing the "s64 timeout" with a "struct timespec end_time" in all the plumbing. But most of the diffstat comes from using the just introduced helpers: poll_select_set_timeout poll_select_copy_remaining timespec_add_safe which make manipulating the timespec easier and less error-prone. Signed-off-by: Arjan van de Ven Signed-off-by: Thomas Gleixner --- include/linux/poll.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/poll.h b/include/linux/poll.h index f65de5128a9..badd98ab06f 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -114,11 +114,11 @@ void zero_fd_set(unsigned long nr, unsigned long *fdset) #define MAX_INT64_SECONDS (((s64)(~((u64)0)>>1)/HZ)-1) -extern int do_select(int n, fd_set_bits *fds, s64 *timeout); +extern int do_select(int n, fd_set_bits *fds, struct timespec *end_time); extern int do_sys_poll(struct pollfd __user * ufds, unsigned int nfds, - s64 *timeout); + struct timespec *end_time); extern int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, s64 *timeout); + fd_set __user *exp, struct timespec *end_time); extern int poll_select_set_timeout(struct timespec *to, long sec, long nsec); -- cgit v1.2.3 From 63ca243b271f5b44e0b1057003cf498b6d0fadf7 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 1 Sep 2008 14:35:02 -0700 Subject: hrtimer: add abstraction functions for accessing the "expires" member In order to be able to turn hrtimers into range based, we need to provide accessor functions for getting to the "expires" ktime_t member of the struct hrtimer. This patch adds a set of accessors for this purpose: * hrtimer_set_expires * hrtimer_set_expires_tv64 * hrtimer_add_expires * hrtimer_add_expires_ns * hrtimer_get_expires * hrtimer_get_expires_tv64 * hrtimer_get_expires_ns * hrtimer_expires_remaining * hrtimer_start_expires No users of these new accessors are added yet; these follow in later patches. Hopefully this patch can even go into 2.6.27-rc so that the conversions will not have a bottleneck in -next Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index becd17db1a1..9900e998ea8 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -217,6 +217,45 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) return timer->base->cpu_base->hres_active; } +static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) +{ + timer->expires = time; +} +static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) +{ + timer->expires.tv64 = tv64; +} + +static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) +{ + timer->expires = ktime_add_safe(timer->expires, time); +} + +static inline void hrtimer_add_expires_ns(struct hrtimer *timer, unsigned long ns) +{ + timer->expires = ktime_add_ns(timer->expires, ns); +} + +static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) +{ + return timer->expires; +} + +static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) +{ + return timer->expires.tv64; +} + +static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) +{ + return ktime_to_ns(timer->expires); +} + +static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) +{ + return ktime_sub(timer->expires, timer->base->get_time()); +} + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an @@ -287,6 +326,12 @@ extern int hrtimer_start(struct hrtimer *timer, ktime_t tim, extern int hrtimer_cancel(struct hrtimer *timer); extern int hrtimer_try_to_cancel(struct hrtimer *timer); +static inline int hrtimer_start_expires(struct hrtimer *timer, + enum hrtimer_mode mode) +{ + return hrtimer_start(timer, hrtimer_get_expires(timer), mode); +} + static inline int hrtimer_restart(struct hrtimer *timer) { return hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); -- cgit v1.2.3 From 799b64de256ea68fbb5db63bb55f61c305870643 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 1 Sep 2008 15:27:58 -0700 Subject: hrtimer: rename the "expires" struct member to avoid accidental usage To catch code that still touches the "expires" memory directly, rename it to have the compiler complain rather than get nasty, hard to explain, runtime behavior Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 9900e998ea8..485a634fd6e 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -111,7 +111,7 @@ enum hrtimer_cb_mode { */ struct hrtimer { struct rb_node node; - ktime_t expires; + ktime_t _expires; enum hrtimer_restart (*function)(struct hrtimer *); struct hrtimer_clock_base *base; unsigned long state; @@ -219,41 +219,41 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) { - timer->expires = time; + timer->_expires = time; } static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) { - timer->expires.tv64 = tv64; + timer->_expires.tv64 = tv64; } static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) { - timer->expires = ktime_add_safe(timer->expires, time); + timer->_expires = ktime_add_safe(timer->_expires, time); } static inline void hrtimer_add_expires_ns(struct hrtimer *timer, unsigned long ns) { - timer->expires = ktime_add_ns(timer->expires, ns); + timer->_expires = ktime_add_ns(timer->_expires, ns); } static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) { - return timer->expires; + return timer->_expires; } static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) { - return timer->expires.tv64; + return timer->_expires.tv64; } static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) { - return ktime_to_ns(timer->expires); + return ktime_to_ns(timer->_expires); } static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) { - return ktime_sub(timer->expires, timer->base->get_time()); + return ktime_sub(timer->_expires, timer->base->get_time()); } /* @@ -334,7 +334,7 @@ static inline int hrtimer_start_expires(struct hrtimer *timer, static inline int hrtimer_restart(struct hrtimer *timer) { - return hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); + return hrtimer_start(timer, timer->_expires, HRTIMER_MODE_ABS); } /* Query timers: */ -- cgit v1.2.3 From 654c8e0b1c623b156c5b92f28d914ab38c9c2c90 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 1 Sep 2008 15:47:08 -0700 Subject: hrtimer: turn hrtimers into range timers this patch turns hrtimers into range timers; they have 2 expire points 1) the soft expire point 2) the hard expire point the kernel will do it's regular best effort attempt to get the timer run at the hard expire point. However, if some other time fires after the soft expire point, the kernel now has the freedom to fire this timer at this point, and thus grouping the events and preventing a power-expensive wakeup in the future. Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 485a634fd6e..28259c33667 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -112,6 +112,7 @@ enum hrtimer_cb_mode { struct hrtimer { struct rb_node node; ktime_t _expires; + ktime_t _softexpires; enum hrtimer_restart (*function)(struct hrtimer *); struct hrtimer_clock_base *base; unsigned long state; @@ -220,20 +221,37 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) { timer->_expires = time; + timer->_softexpires = time; } + +static inline void hrtimer_set_expires_range(struct hrtimer *timer, ktime_t time, ktime_t delta) +{ + timer->_softexpires = time; + timer->_expires = ktime_add_safe(time, delta); +} + +static inline void hrtimer_set_expires_range_ns(struct hrtimer *timer, ktime_t time, unsigned long delta) +{ + timer->_softexpires = time; + timer->_expires = ktime_add_safe(time, ns_to_ktime(delta)); +} + static inline void hrtimer_set_expires_tv64(struct hrtimer *timer, s64 tv64) { timer->_expires.tv64 = tv64; + timer->_softexpires.tv64 = tv64; } static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) { timer->_expires = ktime_add_safe(timer->_expires, time); + timer->_softexpires = ktime_add_safe(timer->_softexpires, time); } static inline void hrtimer_add_expires_ns(struct hrtimer *timer, unsigned long ns) { timer->_expires = ktime_add_ns(timer->_expires, ns); + timer->_softexpires = ktime_add_ns(timer->_softexpires, ns); } static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) @@ -241,10 +259,19 @@ static inline ktime_t hrtimer_get_expires(const struct hrtimer *timer) return timer->_expires; } +static inline ktime_t hrtimer_get_softexpires(const struct hrtimer *timer) +{ + return timer->_softexpires; +} + static inline s64 hrtimer_get_expires_tv64(const struct hrtimer *timer) { return timer->_expires.tv64; } +static inline s64 hrtimer_get_softexpires_tv64(const struct hrtimer *timer) +{ + return timer->_softexpires.tv64; +} static inline s64 hrtimer_get_expires_ns(const struct hrtimer *timer) { @@ -334,7 +361,7 @@ static inline int hrtimer_start_expires(struct hrtimer *timer, static inline int hrtimer_restart(struct hrtimer *timer) { - return hrtimer_start(timer, timer->_expires, HRTIMER_MODE_ABS); + return hrtimer_start_expires(timer, HRTIMER_MODE_ABS); } /* Query timers: */ @@ -391,6 +418,8 @@ extern long hrtimer_nanosleep_restart(struct restart_block *restart_block); extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, struct task_struct *tsk); +extern int schedule_hrtimeout_range(ktime_t *expires, unsigned long delta, + const enum hrtimer_mode mode); extern int schedule_hrtimeout(ktime_t *expires, const enum hrtimer_mode mode); /* Soft interrupt function to run the hrtimer queues: */ -- cgit v1.2.3 From 6976675d94042fbd446231d1bd8b7de71a980ada Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 1 Sep 2008 15:52:40 -0700 Subject: hrtimer: create a "timer_slack" field in the task struct We want to be able to control the default "rounding" that is used by select() and poll() and friends. This is a per process property (so that we can have a "nice" like program to start certain programs with a looser or stricter rounding) that can be set/get via a prctl(). For this purpose, a field called "timer_slack_ns" is added to the task struct. In addition, a field called "default_timer_slack"ns" is added so that tasks easily can temporarily to a more/less accurate slack and then back to the default. The default value of the slack is set to 50 usec; this is significantly less than 2.6.27's average select() and poll() timing error but still allows the kernel to group timers somewhat to preserve power behavior. Applications and admins can override this via the prctl() Signed-off-by: Arjan van de Ven --- include/linux/init_task.h | 1 + include/linux/prctl.h | 7 +++++++ include/linux/sched.h | 6 ++++++ 3 files changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 021d8e720c7..23fd8909b9e 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -170,6 +170,7 @@ extern struct group_info init_groups; .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ .fs_excl = ATOMIC_INIT(0), \ .pi_lock = __SPIN_LOCK_UNLOCKED(tsk.pi_lock), \ + .timer_slack_ns = 50000, /* 50 usec default slack */ \ .pids = { \ [PIDTYPE_PID] = INIT_PID_LINK(PIDTYPE_PID), \ [PIDTYPE_PGID] = INIT_PID_LINK(PIDTYPE_PGID), \ diff --git a/include/linux/prctl.h b/include/linux/prctl.h index 5ad79198d6f..48d887e3c6e 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -78,4 +78,11 @@ #define PR_GET_SECUREBITS 27 #define PR_SET_SECUREBITS 28 +/* + * Get/set the timerslack as used by poll/select/nanosleep + * A value of 0 means "use default" + */ +#define PR_SET_TIMERSLACK 29 +#define PR_GET_TIMERSLACK 30 + #endif /* _LINUX_PRCTL_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 3d9120c5ad1..dcc03fd5a7f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1301,6 +1301,12 @@ struct task_struct { int latency_record_count; struct latency_record latency_record[LT_SAVECOUNT]; #endif + /* + * time slack values; these are used to round up poll() and + * select() etc timeout values. These are in nanoseconds. + */ + unsigned long timer_slack_ns; + unsigned long default_timer_slack_ns; }; /* -- cgit v1.2.3 From 584fb4a76413ec9215741e075e0dfb69173b213f Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 6 Sep 2008 08:32:57 -0700 Subject: hrtimer: fix build bug found by Ingo in some randconfig configurations, hrtimers are used even though the hrtimer config if off; and it broke the build due to some of the new functions being on the wrong side of the ifdef. This patch moves the functions to the other side of the ifdef, fixing the build bug. Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 28259c33667..c407b33ef84 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -198,13 +198,6 @@ struct hrtimer_cpu_base { #endif }; -#ifdef CONFIG_HIGH_RES_TIMERS -struct clock_event_device; - -extern void clock_was_set(void); -extern void hres_timers_resume(void); -extern void hrtimer_interrupt(struct clock_event_device *dev); - /* * In high resolution mode the time reference must be read accurate */ @@ -283,6 +276,13 @@ static inline ktime_t hrtimer_expires_remaining(const struct hrtimer *timer) return ktime_sub(timer->_expires, timer->base->get_time()); } +#ifdef CONFIG_HIGH_RES_TIMERS +struct clock_event_device; + +extern void clock_was_set(void); +extern void hres_timers_resume(void); +extern void hrtimer_interrupt(struct clock_event_device *dev); + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an -- cgit v1.2.3 From 2ec02270c00f94b08fddfb68c37510a9fb47ac7c Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 6 Sep 2008 09:36:56 -0700 Subject: hrtimer: another build fix More randconfig testing Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index c407b33ef84..4c1a834b984 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -198,19 +198,6 @@ struct hrtimer_cpu_base { #endif }; -/* - * In high resolution mode the time reference must be read accurate - */ -static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) -{ - return timer->base->get_time(); -} - -static inline int hrtimer_is_hres_active(struct hrtimer *timer) -{ - return timer->base->cpu_base->hres_active; -} - static inline void hrtimer_set_expires(struct hrtimer *timer, ktime_t time) { timer->_expires = time; @@ -283,6 +270,19 @@ extern void clock_was_set(void); extern void hres_timers_resume(void); extern void hrtimer_interrupt(struct clock_event_device *dev); +/* + * In high resolution mode the time reference must be read accurate + */ +static inline ktime_t hrtimer_cb_get_time(struct hrtimer *timer) +{ + return timer->base->get_time(); +} + +static inline int hrtimer_is_hres_active(struct hrtimer *timer) +{ + return timer->base->cpu_base->hres_active; +} + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an -- cgit v1.2.3 From 978b0116cd225682a29e3d1d5010319bf2de32c2 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 6 Sep 2008 20:04:36 +0200 Subject: softirq: allocate less vectors We don't need whole 32 of them, only NR_SOFTIRQS. Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 58ff4e74b2f..54b3623434e 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -252,6 +252,8 @@ enum HRTIMER_SOFTIRQ, #endif RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */ + + NR_SOFTIRQS }; /* softirq mask and active fields moved to irq_cpustat_t in -- cgit v1.2.3 From 5394f80f92642c61fc2a95385be85f2fdcfb5adb Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 7 Sep 2008 01:51:32 -0700 Subject: x86: check for and defend against BIOS memory corruption Some BIOSes have been observed to corrupt memory in the low 64k. This change: - Reserves all memory which does not have to be in that area, to prevent it from being used as general memory by the kernel. Things like the SMP trampoline are still in the memory, however. - Clears the reserved memory so we can observe changes to it. - Adds a function check_for_bios_corruption() which checks and reports on memory becoming unexpectedly non-zero. Currently it's called in the x86 fault handler, and the powermanagement debug output. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2651f805ba6..8017129e6b6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -240,6 +240,18 @@ extern const char *print_tainted(void); extern void add_taint(unsigned); extern int root_mountflags; +#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION +/* + * This is obviously not a great place for this, but we want to be + * able to scatter it around anywhere in the kernel. + */ +void check_for_bios_corruption(void); +#else +static inline void check_for_bios_corruption(void) +{ +} +#endif + /* Values used for system_state */ extern enum system_states { SYSTEM_BOOTING, -- cgit v1.2.3 From bb577f980ef35e2b0d00aeed566724e5032aa5eb Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sun, 7 Sep 2008 01:51:33 -0700 Subject: x86: add periodic corruption check Perodically check for corruption in low phusical memory. Don't bother checking at fault time, since it won't show anything useful. Signed-off-by: Hugh Dickins Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 8017129e6b6..00bb251c645 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -246,6 +246,7 @@ extern int root_mountflags; * able to scatter it around anywhere in the kernel. */ void check_for_bios_corruption(void); +void start_periodic_check_for_corruption(void); #else static inline void check_for_bios_corruption(void) { -- cgit v1.2.3 From b0dbcf511c4bd10350902e79a1bdd4f5dcca66b6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 4 Sep 2008 21:13:37 +0100 Subject: [NET] smc91x: provide configurable leds This patch provides a mechanism for platforms to be able to supply the LED configuration via platform data, rather than having to hard code it in smc91x.h. Acked-by: Eric Miao Acked-by: Nicolas Pitre Acked-by: Jeff Garzik Signed-off-by: Russell King --- include/linux/smc91x.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h index 3827b922ba1..ed25483d25d 100644 --- a/include/linux/smc91x.h +++ b/include/linux/smc91x.h @@ -18,6 +18,8 @@ struct smc91x_platdata { unsigned long flags; + unsigned char leda; + unsigned char ledb; }; #endif /* __SMC91X_H__ */ -- cgit v1.2.3 From da8f2e170ea94cc20f8ebbc8ee8d127edb8f12f1 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 7 Sep 2008 10:47:46 -0700 Subject: hrtimer: add a hrtimer_start_range() function this patch adds a _range version of hrtimer_start() so that range timers can be created; the hrtimer_start() function is just a wrapper around this. In addition, hrtimer_start_expires() will now preserve existing ranges. Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 4c1a834b984..1c0473e8ecb 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -350,13 +350,20 @@ static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } /* Basic timer operations: */ extern int hrtimer_start(struct hrtimer *timer, ktime_t tim, const enum hrtimer_mode mode); +extern int hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim, + unsigned long range_ns, const enum hrtimer_mode mode); extern int hrtimer_cancel(struct hrtimer *timer); extern int hrtimer_try_to_cancel(struct hrtimer *timer); static inline int hrtimer_start_expires(struct hrtimer *timer, enum hrtimer_mode mode) { - return hrtimer_start(timer, hrtimer_get_expires(timer), mode); + unsigned long delta; + ktime_t soft, hard; + soft = hrtimer_get_softexpires(timer); + hard = hrtimer_get_expires(timer); + delta = ktime_to_ns(ktime_sub(hard, soft)); + return hrtimer_start_range_ns(timer, hrtimer_get_expires(timer), delta, mode); } static inline int hrtimer_restart(struct hrtimer *timer) -- cgit v1.2.3 From 4ce105d30e08fb8a1783c55a0e48aa3fa200c455 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 7 Sep 2008 15:31:39 -0700 Subject: hrtimer: incorporate feedback from Peter Zijlstra (based on lkml review) * use rt_task() * task_nice() has a sign Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 1c0473e8ecb..95db11f62ff 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -363,7 +363,7 @@ static inline int hrtimer_start_expires(struct hrtimer *timer, soft = hrtimer_get_softexpires(timer); hard = hrtimer_get_expires(timer); delta = ktime_to_ns(ktime_sub(hard, soft)); - return hrtimer_start_range_ns(timer, hrtimer_get_expires(timer), delta, mode); + return hrtimer_start_range_ns(timer, soft, delta, mode); } static inline int hrtimer_restart(struct hrtimer *timer) -- cgit v1.2.3 From 05496769e5da83ce22ed97345afd9c7b71d6bd24 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 16 Sep 2008 14:36:17 -0400 Subject: jbd2: clean up how the journal device name is printed Calculate the journal device name once and stash it away in the journal_s structure. This avoids needing to call bdevname() everywhere and reduces stack usage by not needing to allocate an on-stack buffer. In addition, we eliminate the '/' that can appear in device names (e.g. "cciss/c0d0p9" --- see kernel bugzilla #11321) that can cause problems when creating proc directory names, and include the inode number to support ocfs2 which creates multiple journals with different inode numbers. Signed-off-by: "Theodore Ts'o" --- include/linux/jbd2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 3dd20900709..66c3499478b 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -850,7 +850,8 @@ struct journal_s */ struct block_device *j_dev; int j_blocksize; - unsigned long long j_blk_offset; + unsigned long long j_blk_offset; + char j_devname[BDEVNAME_SIZE+24]; /* * Device which holds the client fs. For internal journal this will be -- cgit v1.2.3 From e545a6140b698b2494daf0b32107bdcc5e901390 Mon Sep 17 00:00:00 2001 From: Manfred Spraul Date: Sun, 7 Sep 2008 16:57:22 +0200 Subject: kernel/cpu.c: create a CPU_STARTING cpu_chain notifier Right now, there is no notifier that is called on a new cpu, before the new cpu begins processing interrupts/softirqs. Various kernel function would need that notification, e.g. kvm works around by calling smp_call_function_single(), rcu polls cpu_online_map. The patch adds a CPU_STARTING notification. It also adds a helper function that sends the message to all cpu_chain handlers. Tested on x86-64. All other archs are untested. Especially on sparc, I'm not sure if I got it right. Signed-off-by: Manfred Spraul Signed-off-by: Ingo Molnar --- include/linux/cpu.h | 1 + include/linux/notifier.h | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/cpu.h b/include/linux/cpu.h index d7faf880849..c2747ac2ae4 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -69,6 +69,7 @@ static inline void unregister_cpu_notifier(struct notifier_block *nb) #endif int cpu_up(unsigned int cpu); +void notify_cpu_starting(unsigned int cpu); extern void cpu_hotplug_init(void); extern void cpu_maps_update_begin(void); extern void cpu_maps_update_done(void); diff --git a/include/linux/notifier.h b/include/linux/notifier.h index da2698b0fdd..b86fa2ffca0 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h @@ -213,9 +213,16 @@ static inline int notifier_to_errno(int ret) #define CPU_DOWN_FAILED 0x0006 /* CPU (unsigned)v NOT going down */ #define CPU_DEAD 0x0007 /* CPU (unsigned)v dead */ #define CPU_DYING 0x0008 /* CPU (unsigned)v not running any task, - * not handling interrupts, soon dead */ + * not handling interrupts, soon dead. + * Called on the dying cpu, interrupts + * are already disabled. Must not + * sleep, must not fail */ #define CPU_POST_DEAD 0x0009 /* CPU (unsigned)v dead, cpu_hotplug * lock is dropped */ +#define CPU_STARTING 0x000A /* CPU (unsigned)v soon running. + * Called on the new cpu, just before + * enabling interrupts. Must not sleep, + * must not fail */ /* Used for CPU hotplug events occuring while tasks are frozen due to a suspend * operation in progress @@ -229,6 +236,7 @@ static inline int notifier_to_errno(int ret) #define CPU_DOWN_FAILED_FROZEN (CPU_DOWN_FAILED | CPU_TASKS_FROZEN) #define CPU_DEAD_FROZEN (CPU_DEAD | CPU_TASKS_FROZEN) #define CPU_DYING_FROZEN (CPU_DYING | CPU_TASKS_FROZEN) +#define CPU_STARTING_FROZEN (CPU_STARTING | CPU_TASKS_FROZEN) /* Hibernation and suspend events */ #define PM_HIBERNATION_PREPARE 0x0001 /* Going to hibernate */ -- cgit v1.2.3 From 9c3254ad42e7925c3a3907a072185273705bd7b2 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sun, 7 Sep 2008 14:54:41 -0700 Subject: x86: fix compile error with corruption checking disabled Fix compile error: arch/x86/mm/init_32.c: In function 'mem_init': arch/x86/mm/init_32.c:908: error: implicit declaration of function 'start_periodic_check_for_corruption' Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 00bb251c645..50873b21178 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -251,6 +251,10 @@ void start_periodic_check_for_corruption(void); static inline void check_for_bios_corruption(void) { } + +static inline void start_periodic_check_for_corruption(void) +{ +} #endif /* Values used for system_state */ -- cgit v1.2.3 From 410e27a49bb98bc7fa3ff5fc05cc313817b9f253 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Tue, 9 Sep 2008 13:27:22 +0200 Subject: This reverts "Merge branch 'dccp' of git://eden-feed.erg.abdn.ac.uk/dccp_exp" as it accentally contained the wrong set of patches. These will be submitted separately. Signed-off-by: Gerrit Renker --- include/linux/dccp.h | 122 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 51 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dccp.h b/include/linux/dccp.h index 010e2d87ed7..6080449fbec 100644 --- a/include/linux/dccp.h +++ b/include/linux/dccp.h @@ -165,13 +165,9 @@ enum { DCCPO_TIMESTAMP_ECHO = 42, DCCPO_ELAPSED_TIME = 43, DCCPO_MAX = 45, - DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */ - DCCPO_MAX_RX_CCID_SPECIFIC = 191, - DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */ - DCCPO_MAX_TX_CCID_SPECIFIC = 255, + DCCPO_MIN_CCID_SPECIFIC = 128, + DCCPO_MAX_CCID_SPECIFIC = 255, }; -/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ -#define DCCP_SINGLE_OPT_MAXLEN 253 /* DCCP CCIDS */ enum { @@ -180,36 +176,27 @@ enum { }; /* DCCP features (RFC 4340 section 6.4) */ -enum dccp_feature_numbers { +enum { DCCPF_RESERVED = 0, DCCPF_CCID = 1, - DCCPF_SHORT_SEQNOS = 2, + DCCPF_SHORT_SEQNOS = 2, /* XXX: not yet implemented */ DCCPF_SEQUENCE_WINDOW = 3, - DCCPF_ECN_INCAPABLE = 4, + DCCPF_ECN_INCAPABLE = 4, /* XXX: not yet implemented */ DCCPF_ACK_RATIO = 5, DCCPF_SEND_ACK_VECTOR = 6, DCCPF_SEND_NDP_COUNT = 7, DCCPF_MIN_CSUM_COVER = 8, - DCCPF_DATA_CHECKSUM = 9, + DCCPF_DATA_CHECKSUM = 9, /* XXX: not yet implemented */ /* 10-127 reserved */ DCCPF_MIN_CCID_SPECIFIC = 128, - DCCPF_SEND_LEV_RATE = 192, /* RFC 4342, sec. 8.4 */ DCCPF_MAX_CCID_SPECIFIC = 255, }; -/* DCCP socket control message types for cmsg */ -enum dccp_cmsg_type { - DCCP_SCM_PRIORITY = 1, - DCCP_SCM_QPOLICY_MAX = 0xFFFF, - /* ^-- Up to here reserved exclusively for qpolicy parameters */ - DCCP_SCM_MAX -}; - -/* DCCP priorities for outgoing/queued packets */ -enum dccp_packet_dequeueing_policy { - DCCPQ_POLICY_SIMPLE, - DCCPQ_POLICY_PRIO, - DCCPQ_POLICY_MAX +/* this structure is argument to DCCP_SOCKOPT_CHANGE_X */ +struct dccp_so_feat { + __u8 dccpsf_feat; + __u8 __user *dccpsf_val; + __u8 dccpsf_len; }; /* DCCP socket options */ @@ -221,12 +208,6 @@ enum dccp_packet_dequeueing_policy { #define DCCP_SOCKOPT_SERVER_TIMEWAIT 6 #define DCCP_SOCKOPT_SEND_CSCOV 10 #define DCCP_SOCKOPT_RECV_CSCOV 11 -#define DCCP_SOCKOPT_AVAILABLE_CCIDS 12 -#define DCCP_SOCKOPT_CCID 13 -#define DCCP_SOCKOPT_TX_CCID 14 -#define DCCP_SOCKOPT_RX_CCID 15 -#define DCCP_SOCKOPT_QPOLICY_ID 16 -#define DCCP_SOCKOPT_QPOLICY_TXQLEN 17 #define DCCP_SOCKOPT_CCID_RX_INFO 128 #define DCCP_SOCKOPT_CCID_TX_INFO 192 @@ -374,13 +355,62 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) return __dccp_hdr_len(dccp_hdr(skb)); } + +/* initial values for each feature */ +#define DCCPF_INITIAL_SEQUENCE_WINDOW 100 +#define DCCPF_INITIAL_ACK_RATIO 2 +#define DCCPF_INITIAL_CCID DCCPC_CCID2 +#define DCCPF_INITIAL_SEND_ACK_VECTOR 1 +/* FIXME: for now we're default to 1 but it should really be 0 */ +#define DCCPF_INITIAL_SEND_NDP_COUNT 1 + +/** + * struct dccp_minisock - Minimal DCCP connection representation + * + * Will be used to pass the state from dccp_request_sock to dccp_sock. + * + * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2) + * @dccpms_ccid - Congestion Control Id (CCID) (section 10) + * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5) + * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2) + * @dccpms_ack_ratio - Ack Ratio Feature (section 11.3) + * @dccpms_pending - List of features being negotiated + * @dccpms_conf - + */ +struct dccp_minisock { + __u64 dccpms_sequence_window; + __u8 dccpms_rx_ccid; + __u8 dccpms_tx_ccid; + __u8 dccpms_send_ack_vector; + __u8 dccpms_send_ndp_count; + __u8 dccpms_ack_ratio; + struct list_head dccpms_pending; + struct list_head dccpms_conf; +}; + +struct dccp_opt_conf { + __u8 *dccpoc_val; + __u8 dccpoc_len; +}; + +struct dccp_opt_pend { + struct list_head dccpop_node; + __u8 dccpop_type; + __u8 dccpop_feat; + __u8 *dccpop_val; + __u8 dccpop_len; + int dccpop_conf; + struct dccp_opt_conf *dccpop_sc; +}; + +extern void dccp_minisock_init(struct dccp_minisock *dmsk); + /** * struct dccp_request_sock - represent DCCP-specific connection request * @dreq_inet_rsk: structure inherited from * @dreq_iss: initial sequence number sent on the Response (RFC 4340, 7.1) * @dreq_isr: initial sequence number received on the Request * @dreq_service: service code present on the Request (there is just one) - * @dreq_featneg: feature negotiation options for this connection * The following two fields are analogous to the ones in dccp_sock: * @dreq_timestamp_echo: last received timestamp to echo (13.1) * @dreq_timestamp_echo: the time of receiving the last @dreq_timestamp_echo @@ -390,7 +420,6 @@ struct dccp_request_sock { __u64 dreq_iss; __u64 dreq_isr; __be32 dreq_service; - struct list_head dreq_featneg; __u32 dreq_timestamp_echo; __u32 dreq_timestamp_time; }; @@ -462,28 +491,21 @@ struct dccp_ackvec; * @dccps_timestamp_time - time of receiving latest @dccps_timestamp_echo * @dccps_l_ack_ratio - feature-local Ack Ratio * @dccps_r_ack_ratio - feature-remote Ack Ratio - * @dccps_l_seq_win - local Sequence Window (influences ack number validity) - * @dccps_r_seq_win - remote Sequence Window (influences seq number validity) * @dccps_pcslen - sender partial checksum coverage (via sockopt) * @dccps_pcrlen - receiver partial checksum coverage (via sockopt) - * @dccps_send_ndp_count - local Send NDP Count feature (7.7.2) * @dccps_ndp_count - number of Non Data Packets since last data packet * @dccps_mss_cache - current value of MSS (path MTU minus header sizes) * @dccps_rate_last - timestamp for rate-limiting DCCP-Sync (RFC 4340, 7.5.4) - * @dccps_featneg - tracks feature-negotiation state (mostly during handshake) + * @dccps_minisock - associated minisock (accessed via dccp_msk) * @dccps_hc_rx_ackvec - rx half connection ack vector * @dccps_hc_rx_ccid - CCID used for the receiver (or receiving half-connection) * @dccps_hc_tx_ccid - CCID used for the sender (or sending half-connection) * @dccps_options_received - parsed set of retrieved options - * @dccps_qpolicy - TX dequeueing policy, one of %dccp_packet_dequeueing_policy - * @dccps_tx_qlen - maximum length of the TX queue * @dccps_role - role of this sock, one of %dccp_role * @dccps_hc_rx_insert_options - receiver wants to add options when acking * @dccps_hc_tx_insert_options - sender wants to add options when sending * @dccps_server_timewait - server holds timewait state on close (RFC 4340, 8.3) - * @dccps_sync_scheduled - flag which signals "send out-of-band message soon" - * @dccps_xmitlet - tasklet scheduled by the TX CCID to dequeue data packets - * @dccps_xmit_timer - used by the TX CCID to delay sending (rate-based pacing) + * @dccps_xmit_timer - timer for when CCID is not ready to send * @dccps_syn_rtt - RTT sample from Request/Response exchange (in usecs) */ struct dccp_sock { @@ -507,26 +529,19 @@ struct dccp_sock { __u32 dccps_timestamp_time; __u16 dccps_l_ack_ratio; __u16 dccps_r_ack_ratio; - __u64 dccps_l_seq_win:48; - __u64 dccps_r_seq_win:48; - __u8 dccps_pcslen:4; - __u8 dccps_pcrlen:4; - __u8 dccps_send_ndp_count:1; + __u16 dccps_pcslen; + __u16 dccps_pcrlen; __u64 dccps_ndp_count:48; unsigned long dccps_rate_last; - struct list_head dccps_featneg; + struct dccp_minisock dccps_minisock; struct dccp_ackvec *dccps_hc_rx_ackvec; struct ccid *dccps_hc_rx_ccid; struct ccid *dccps_hc_tx_ccid; struct dccp_options_received dccps_options_received; - __u8 dccps_qpolicy; - __u32 dccps_tx_qlen; enum dccp_role dccps_role:2; __u8 dccps_hc_rx_insert_options:1; __u8 dccps_hc_tx_insert_options:1; __u8 dccps_server_timewait:1; - __u8 dccps_sync_scheduled:1; - struct tasklet_struct dccps_xmitlet; struct timer_list dccps_xmit_timer; }; @@ -535,6 +550,11 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk) return (struct dccp_sock *)sk; } +static inline struct dccp_minisock *dccp_msk(const struct sock *sk) +{ + return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock; +} + static inline const char *dccp_role(const struct sock *sk) { switch (dccp_sk(sk)->dccps_role) { -- cgit v1.2.3 From fb683f1627745e937ef199edd3428ac4b2ef1e08 Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Fri, 22 Aug 2008 16:36:28 +0200 Subject: Export smc91x led definitions Now that we can configure smc91x leds from its platform data, it seems rather useful to move the led definitions to the externally visible header file. Signed-off-by: Marc Zyngier --- include/linux/smc91x.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/smc91x.h b/include/linux/smc91x.h index ed25483d25d..bc21db598c0 100644 --- a/include/linux/smc91x.h +++ b/include/linux/smc91x.h @@ -16,6 +16,15 @@ #define SMC91X_USE_DMA (1 << 6) +#define RPC_LED_100_10 (0x00) /* LED = 100Mbps OR's with 10Mbps link detect */ +#define RPC_LED_RES (0x01) /* LED = Reserved */ +#define RPC_LED_10 (0x02) /* LED = 10Mbps link detect */ +#define RPC_LED_FD (0x03) /* LED = Full Duplex Mode */ +#define RPC_LED_TX_RX (0x04) /* LED = TX or RX packet occurred */ +#define RPC_LED_100 (0x05) /* LED = 100Mbps link dectect */ +#define RPC_LED_TX (0x06) /* LED = TX packet occurred */ +#define RPC_LED_RX (0x07) /* LED = RX packet occurred */ + struct smc91x_platdata { unsigned long flags; unsigned char leda; -- cgit v1.2.3 From 636dc67cbf8c481a996faf6c23f0532d0f02ebad Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Wed, 10 Sep 2008 01:06:46 +0900 Subject: add is_buffer_dma_capable helper function is_buffer_dma_capable helper function is to see if a memory region is DMA-capable or not. The arugments are the dma_mask (or coherent_dma_mask) of a device and the address and size of a memory region. Signed-off-by: FUJITA Tomonori Acked-by: Joerg Roedel Signed-off-by: Ingo Molnar --- include/linux/dma-mapping.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 952e0f857ac..6ed50c1642f 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -48,6 +48,11 @@ static inline int is_device_dma_capable(struct device *dev) return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE; } +static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) +{ + return addr + size <= mask; +} + #ifdef CONFIG_HAS_DMA #include #else -- cgit v1.2.3 From f7d0b926ac8c8ec0c7a83ee69409bd2e6bb39f81 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 9 Sep 2008 15:43:22 -0700 Subject: mm: define USE_SPLIT_PTLOCKS rather than repeating expression Define USE_SPLIT_PTLOCKS as a constant expression rather than repeating "NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS" all over the place. Signed-off-by: Jeremy Fitzhardinge Acked-by: Hugh Dickins Signed-off-by: Ingo Molnar --- include/linux/mm.h | 6 +++--- include/linux/mm_types.h | 10 ++++++---- include/linux/sched.h | 6 +++--- 3 files changed, 12 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 72a15dc26bb..4194bf8e4f6 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -919,7 +919,7 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a } #endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */ -#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS +#if USE_SPLIT_PTLOCKS /* * We tuck a spinlock to guard each pagetable page into its struct page, * at page->private, with BUILD_BUG_ON to make sure that this will not @@ -932,14 +932,14 @@ static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long a } while (0) #define pte_lock_deinit(page) ((page)->mapping = NULL) #define pte_lockptr(mm, pmd) ({(void)(mm); __pte_lockptr(pmd_page(*(pmd)));}) -#else +#else /* !USE_SPLIT_PTLOCKS */ /* * We use mm->page_table_lock to guard all pagetable pages of the mm. */ #define pte_lock_init(page) do {} while (0) #define pte_lock_deinit(page) do {} while (0) #define pte_lockptr(mm, pmd) ({(void)(pmd); &(mm)->page_table_lock;}) -#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ +#endif /* USE_SPLIT_PTLOCKS */ static inline void pgtable_page_ctor(struct page *page) { diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index bf334138c7c..9d49fa36bbe 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -21,11 +21,13 @@ struct address_space; -#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS +#define USE_SPLIT_PTLOCKS (NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS) + +#if USE_SPLIT_PTLOCKS typedef atomic_long_t mm_counter_t; -#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ +#else /* !USE_SPLIT_PTLOCKS */ typedef unsigned long mm_counter_t; -#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ +#endif /* !USE_SPLIT_PTLOCKS */ /* * Each physical page in the system has a struct page associated with @@ -65,7 +67,7 @@ struct page { * see PAGE_MAPPING_ANON below. */ }; -#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS +#if USE_SPLIT_PTLOCKS spinlock_t ptl; #endif struct kmem_cache *slab; /* SLUB: Pointer to slab */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 3d9120c5ad1..272c35309df 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -352,7 +352,7 @@ arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, extern void arch_unmap_area(struct mm_struct *, unsigned long); extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); -#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS +#if USE_SPLIT_PTLOCKS /* * The mm counters are not protected by its page_table_lock, * so must be incremented atomically. @@ -363,7 +363,7 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); #define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) #define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) -#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ +#else /* !USE_SPLIT_PTLOCKS */ /* * The mm counters are protected by its page_table_lock, * so can be incremented directly. @@ -374,7 +374,7 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long); #define inc_mm_counter(mm, member) (mm)->_##member++ #define dec_mm_counter(mm, member) (mm)->_##member-- -#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ +#endif /* !USE_SPLIT_PTLOCKS */ #define get_mm_rss(mm) \ (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) -- cgit v1.2.3 From 4d5975e5016a9025814b92981de21eaf9203caa6 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 10 Sep 2008 12:06:15 -0400 Subject: Input: ads7846 - introduce .gpio_pendown to get pendown state The GPIO connected to ADS7846 nPENIRQ signal is usually used to get the pendown state as well. Introduce a .gpio_pendown, and use this to decide the pendown state if .get_pendown_state is NULL. Signed-off-by: Eric Miao Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index daf744017a3..05eab2f11e6 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -43,6 +43,9 @@ struct ads7846_platform_data { u16 debounce_tol; /* tolerance used for filtering */ u16 debounce_rep; /* additional consecutive good readings * required after the first two */ + int gpio_pendown; /* the GPIO used to decide the pendown + * state if get_pendown_state == NULL + */ int (*get_pendown_state)(void); int (*filter_init) (struct ads7846_platform_data *pdata, void **filter_data); -- cgit v1.2.3 From 271bff7afbb2cbaa81e744006ad2fff1f3e10b1b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Sep 2008 04:48:58 -0700 Subject: net: Add DMA mapping tokens to skb_shared_info. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 90992371783..4b2be23903c 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -146,8 +146,14 @@ struct skb_shared_info { unsigned short gso_segs; unsigned short gso_type; __be32 ip6_frag_id; +#ifdef CONFIG_HAS_DMA + unsigned int num_dma_maps; +#endif struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; +#ifdef CONFIG_HAS_DMA + dma_addr_t dma_maps[MAX_SKB_FRAGS + 1]; +#endif }; /* We divide dataref into two halves. The higher 16 bits hold references -- cgit v1.2.3 From a40c24a13366e324bc0ff8c3bb107db89312c984 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 11 Sep 2008 04:51:14 -0700 Subject: net: Add SKB DMA mapping helper functions. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4b2be23903c..aa80ad9cbc8 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -359,6 +359,14 @@ struct sk_buff { #include +#ifdef CONFIG_HAS_DMA +#include +extern int skb_dma_map(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir); +extern void skb_dma_unmap(struct device *dev, struct sk_buff *skb, + enum dma_data_direction dir); +#endif + extern void kfree_skb(struct sk_buff *skb); extern void __kfree_skb(struct sk_buff *skb); extern struct sk_buff *__alloc_skb(unsigned int size, -- cgit v1.2.3 From 2e94d1f71f7e4404d997e6fb4f1618aa147d76f9 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Wed, 10 Sep 2008 16:06:00 -0700 Subject: hrtimer: peek at the timer queue just before going idle As part of going idle, we already look at the time of the next timer event to determine which C-state to select etc. This patch adds functionality that causes the timers that are past their soft expire time, to fire at this time, before we calculate the next wakeup time. This functionality will thus avoid wakeups by running timers before going idle rather than specially waking up for it. Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 95db11f62ff..d93b1e1dc16 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -326,6 +326,11 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) extern ktime_t ktime_get(void); extern ktime_t ktime_get_real(void); + +DECLARE_PER_CPU(struct tick_device, tick_cpu_device); +extern void hrtimer_peek_ahead_timers(void); + + /* Exported timer functions: */ /* Initialize timers: */ -- cgit v1.2.3 From 00c5ae2fa0f8191a1b204e71f0ee11359e3b2c06 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Wed, 3 Sep 2008 11:26:42 +0800 Subject: mac80211: change MIMO_PS to SM_PS This patch follows 11n spec naming more rigorously replacing MIMO_PS with SM_PS (Spatial Multiplexing Power Save). (Originally submitted as 4 patches, "mac80211: change MIMO_PS to SM_PS", "iwlwifi: change MIMO_PS to SM_PS", "ath9k: change MIMO_PS to SM_PS", and "iwlwifi: remove double definition of SM PS". -- JWL) Signed-off-by: Ron Rindjunsky Signed-off-by: Tomas Winkler Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index be456450cd2..333d3ae7688 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -708,7 +708,7 @@ struct ieee80211_ht_addt_info { /* 802.11n HT capabilities masks */ #define IEEE80211_HT_CAP_SUP_WIDTH 0x0002 -#define IEEE80211_HT_CAP_MIMO_PS 0x000C +#define IEEE80211_HT_CAP_SM_PS 0x000C #define IEEE80211_HT_CAP_GRN_FLD 0x0010 #define IEEE80211_HT_CAP_SGI_20 0x0020 #define IEEE80211_HT_CAP_SGI_40 0x0040 @@ -737,11 +737,11 @@ struct ieee80211_ht_addt_info { #define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 #define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 -/* MIMO Power Save Modes */ -#define WLAN_HT_CAP_MIMO_PS_STATIC 0 -#define WLAN_HT_CAP_MIMO_PS_DYNAMIC 1 -#define WLAN_HT_CAP_MIMO_PS_INVALID 2 -#define WLAN_HT_CAP_MIMO_PS_DISABLED 3 +/* Spatial Multiplexing Power Save Modes */ +#define WLAN_HT_CAP_SM_PS_STATIC 0 +#define WLAN_HT_CAP_SM_PS_DYNAMIC 1 +#define WLAN_HT_CAP_SM_PS_INVALID 2 +#define WLAN_HT_CAP_SM_PS_DISABLED 3 /* Authentication algorithms */ #define WLAN_AUTH_OPEN 0 -- cgit v1.2.3 From 44d414dbff9d5bf46fc09f2e68567b5848cbbfd3 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 8 Sep 2008 17:44:28 +0200 Subject: mac80211: move some HT code out of mlme.c Some of the HT code in mlme.c is misplaced: * constants/definitions belong to the ieee80211.h header * code being used in other modes as well shouldn't be there Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 333d3ae7688..abc1abc63bf 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -643,6 +643,9 @@ struct ieee80211_mgmt { } u; } __attribute__ ((packed)); +/* mgmt header + 1 byte category code */ +#define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) + /* Control frames */ struct ieee80211_rts { @@ -737,6 +740,21 @@ struct ieee80211_ht_addt_info { #define IEEE80211_HT_IE_NON_GF_STA_PRSNT 0x0004 #define IEEE80211_HT_IE_NON_HT_STA_PRSNT 0x0010 +/* block-ack parameters */ +#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 +#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C +#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 +#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 +#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 + +/* + * A-PMDU buffer sizes + * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) + */ +#define IEEE80211_MIN_AMPDU_BUF 0x8 +#define IEEE80211_MAX_AMPDU_BUF 0x40 + + /* Spatial Multiplexing Power Save Modes */ #define WLAN_HT_CAP_SM_PS_STATIC 0 #define WLAN_HT_CAP_SM_PS_DYNAMIC 1 -- cgit v1.2.3 From 92651940ab00dbe64722e908f70d816713d677b7 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 12 Sep 2008 16:29:34 -0700 Subject: pkt_sched: Add multiqueue scheduler support This patch is intended to add a qdisc to support the new tx multiqueue architecture by providing a band for each hardware queue. By doing this it is possible to support a different qdisc per physical hardware queue. This qdisc uses the skb->queue_mapping to select which band to place the traffic onto. It then uses a round robin w/ a check to see if the subqueue is stopped to determine which band to dequeue the packet from. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- include/linux/pkt_sched.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index e5de421ac7b..5d921fa91a5 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -123,6 +123,13 @@ struct tc_prio_qopt __u8 priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */ }; +/* MULTIQ section */ + +struct tc_multiq_qopt { + __u16 bands; /* Number of bands */ + __u16 max_bands; /* Maximum number of queues */ +}; + /* TBF section */ struct tc_tbf_qopt -- cgit v1.2.3 From ca9b0e27e072be4cef2f5f0cbc0b0fd94eae3520 Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Fri, 12 Sep 2008 16:30:20 -0700 Subject: pkt_action: add new action skbedit This new action will have the ability to change the priority and/or queue_mapping fields on an sk_buff. Signed-off-by: Alexander Duyck Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- include/linux/tc_act/Kbuild | 1 + include/linux/tc_act/tc_skbedit.h | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 include/linux/tc_act/tc_skbedit.h (limited to 'include/linux') diff --git a/include/linux/tc_act/Kbuild b/include/linux/tc_act/Kbuild index 6dac0d7365c..76990937f4c 100644 --- a/include/linux/tc_act/Kbuild +++ b/include/linux/tc_act/Kbuild @@ -3,3 +3,4 @@ header-y += tc_ipt.h header-y += tc_mirred.h header-y += tc_pedit.h header-y += tc_nat.h +header-y += tc_skbedit.h diff --git a/include/linux/tc_act/tc_skbedit.h b/include/linux/tc_act/tc_skbedit.h new file mode 100644 index 00000000000..a14e461a7af --- /dev/null +++ b/include/linux/tc_act/tc_skbedit.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2008, Intel Corporation. + * + * 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., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Author: Alexander Duyck + */ + +#ifndef __LINUX_TC_SKBEDIT_H +#define __LINUX_TC_SKBEDIT_H + +#include + +#define TCA_ACT_SKBEDIT 11 + +#define SKBEDIT_F_PRIORITY 0x1 +#define SKBEDIT_F_QUEUE_MAPPING 0x2 + +struct tc_skbedit { + tc_gen; +}; + +enum { + TCA_SKBEDIT_UNSPEC, + TCA_SKBEDIT_TM, + TCA_SKBEDIT_PARMS, + TCA_SKBEDIT_PRIORITY, + TCA_SKBEDIT_QUEUE_MAPPING, + __TCA_SKBEDIT_MAX +}; +#define TCA_SKBEDIT_MAX (__TCA_SKBEDIT_MAX - 1) + +#endif -- cgit v1.2.3 From f06febc96ba8e0af80bcc3eaec0a109e88275fac Mon Sep 17 00:00:00 2001 From: Frank Mayhar Date: Fri, 12 Sep 2008 09:54:39 -0700 Subject: timers: fix itimer/many thread hang Overview This patch reworks the handling of POSIX CPU timers, including the ITIMER_PROF, ITIMER_VIRT timers and rlimit handling. It was put together with the help of Roland McGrath, the owner and original writer of this code. The problem we ran into, and the reason for this rework, has to do with using a profiling timer in a process with a large number of threads. It appears that the performance of the old implementation of run_posix_cpu_timers() was at least O(n*3) (where "n" is the number of threads in a process) or worse. Everything is fine with an increasing number of threads until the time taken for that routine to run becomes the same as or greater than the tick time, at which point things degrade rather quickly. This patch fixes bug 9906, "Weird hang with NPTL and SIGPROF." Code Changes This rework corrects the implementation of run_posix_cpu_timers() to make it run in constant time for a particular machine. (Performance may vary between one machine and another depending upon whether the kernel is built as single- or multiprocessor and, in the latter case, depending upon the number of running processors.) To do this, at each tick we now update fields in signal_struct as well as task_struct. The run_posix_cpu_timers() function uses those fields to make its decisions. We define a new structure, "task_cputime," to contain user, system and scheduler times and use these in appropriate places: struct task_cputime { cputime_t utime; cputime_t stime; unsigned long long sum_exec_runtime; }; This is included in the structure "thread_group_cputime," which is a new substructure of signal_struct and which varies for uniprocessor versus multiprocessor kernels. For uniprocessor kernels, it uses "task_cputime" as a simple substructure, while for multiprocessor kernels it is a pointer: struct thread_group_cputime { struct task_cputime totals; }; struct thread_group_cputime { struct task_cputime *totals; }; We also add a new task_cputime substructure directly to signal_struct, to cache the earliest expiration of process-wide timers, and task_cputime also replaces the it_*_expires fields of task_struct (used for earliest expiration of thread timers). The "thread_group_cputime" structure contains process-wide timers that are updated via account_user_time() and friends. In the non-SMP case the structure is a simple aggregator; unfortunately in the SMP case that simplicity was not achievable due to cache-line contention between CPUs (in one measured case performance was actually _worse_ on a 16-cpu system than the same test on a 4-cpu system, due to this contention). For SMP, the thread_group_cputime counters are maintained as a per-cpu structure allocated using alloc_percpu(). The timer functions update only the timer field in the structure corresponding to the running CPU, obtained using per_cpu_ptr(). We define a set of inline functions in sched.h that we use to maintain the thread_group_cputime structure and hide the differences between UP and SMP implementations from the rest of the kernel. The thread_group_cputime_init() function initializes the thread_group_cputime structure for the given task. The thread_group_cputime_alloc() is a no-op for UP; for SMP it calls the out-of-line function thread_group_cputime_alloc_smp() to allocate and fill in the per-cpu structures and fields. The thread_group_cputime_free() function, also a no-op for UP, in SMP frees the per-cpu structures. The thread_group_cputime_clone_thread() function (also a UP no-op) for SMP calls thread_group_cputime_alloc() if the per-cpu structures haven't yet been allocated. The thread_group_cputime() function fills the task_cputime structure it is passed with the contents of the thread_group_cputime fields; in UP it's that simple but in SMP it must also safely check that tsk->signal is non-NULL (if it is it just uses the appropriate fields of task_struct) and, if so, sums the per-cpu values for each online CPU. Finally, the three functions account_group_user_time(), account_group_system_time() and account_group_exec_runtime() are used by timer functions to update the respective fields of the thread_group_cputime structure. Non-SMP operation is trivial and will not be mentioned further. The per-cpu structure is always allocated when a task creates its first new thread, via a call to thread_group_cputime_clone_thread() from copy_signal(). It is freed at process exit via a call to thread_group_cputime_free() from cleanup_signal(). All functions that formerly summed utime/stime/sum_sched_runtime values from from all threads in the thread group now use thread_group_cputime() to snapshot the values in the thread_group_cputime structure or the values in the task structure itself if the per-cpu structure hasn't been allocated. Finally, the code in kernel/posix-cpu-timers.c has changed quite a bit. The run_posix_cpu_timers() function has been split into a fast path and a slow path; the former safely checks whether there are any expired thread timers and, if not, just returns, while the slow path does the heavy lifting. With the dedicated thread group fields, timers are no longer "rebalanced" and the process_timer_rebalance() function and related code has gone away. All summing loops are gone and all code that used them now uses the thread_group_cputime() inline. When process-wide timers are set, the new task_cputime structure in signal_struct is used to cache the earliest expiration; this is checked in the fast path. Performance The fix appears not to add significant overhead to existing operations. It generally performs the same as the current code except in two cases, one in which it performs slightly worse (Case 5 below) and one in which it performs very significantly better (Case 2 below). Overall it's a wash except in those two cases. I've since done somewhat more involved testing on a dual-core Opteron system. Case 1: With no itimer running, for a test with 100,000 threads, the fixed kernel took 1428.5 seconds, 513 seconds more than the unfixed system, all of which was spent in the system. There were twice as many voluntary context switches with the fix as without it. Case 2: With an itimer running at .01 second ticks and 4000 threads (the most an unmodified kernel can handle), the fixed kernel ran the test in eight percent of the time (5.8 seconds as opposed to 70 seconds) and had better tick accuracy (.012 seconds per tick as opposed to .023 seconds per tick). Case 3: A 4000-thread test with an initial timer tick of .01 second and an interval of 10,000 seconds (i.e. a timer that ticks only once) had very nearly the same performance in both cases: 6.3 seconds elapsed for the fixed kernel versus 5.5 seconds for the unfixed kernel. With fewer threads (eight in these tests), the Case 1 test ran in essentially the same time on both the modified and unmodified kernels (5.2 seconds versus 5.8 seconds). The Case 2 test ran in about the same time as well, 5.9 seconds versus 5.4 seconds but again with much better tick accuracy, .013 seconds per tick versus .025 seconds per tick for the unmodified kernel. Since the fix affected the rlimit code, I also tested soft and hard CPU limits. Case 4: With a hard CPU limit of 20 seconds and eight threads (and an itimer running), the modified kernel was very slightly favored in that while it killed the process in 19.997 seconds of CPU time (5.002 seconds of wall time), only .003 seconds of that was system time, the rest was user time. The unmodified kernel killed the process in 20.001 seconds of CPU (5.014 seconds of wall time) of which .016 seconds was system time. Really, though, the results were too close to call. The results were essentially the same with no itimer running. Case 5: With a soft limit of 20 seconds and a hard limit of 2000 seconds (where the hard limit would never be reached) and an itimer running, the modified kernel exhibited worse tick accuracy than the unmodified kernel: .050 seconds/tick versus .028 seconds/tick. Otherwise, performance was almost indistinguishable. With no itimer running this test exhibited virtually identical behavior and times in both cases. In times past I did some limited performance testing. those results are below. On a four-cpu Opteron system without this fix, a sixteen-thread test executed in 3569.991 seconds, of which user was 3568.435s and system was 1.556s. On the same system with the fix, user and elapsed time were about the same, but system time dropped to 0.007 seconds. Performance with eight, four and one thread were comparable. Interestingly, the timer ticks with the fix seemed more accurate: The sixteen-thread test with the fix received 149543 ticks for 0.024 seconds per tick, while the same test without the fix received 58720 for 0.061 seconds per tick. Both cases were configured for an interval of 0.01 seconds. Again, the other tests were comparable. Each thread in this test computed the primes up to 25,000,000. I also did a test with a large number of threads, 100,000 threads, which is impossible without the fix. In this case each thread computed the primes only up to 10,000 (to make the runtime manageable). System time dominated, at 1546.968 seconds out of a total 2176.906 seconds (giving a user time of 629.938s). It received 147651 ticks for 0.015 seconds per tick, still quite accurate. There is obviously no comparable test without the fix. Signed-off-by: Frank Mayhar Cc: Roland McGrath Cc: Alexey Dobriyan Cc: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/posix-timers.h | 2 + include/linux/sched.h | 257 ++++++++++++++++++++++++++++++++++++++++--- include/linux/time.h | 3 + 3 files changed, 249 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index a7dd38f30ad..f9d8e9e94e9 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -115,4 +115,6 @@ void set_process_cpu_timer(struct task_struct *task, unsigned int clock_idx, long clock_nanosleep_restart(struct restart_block *restart_block); +void update_rlimit_cpu(unsigned long rlim_new); + #endif diff --git a/include/linux/sched.h b/include/linux/sched.h index 3d9120c5ad1..26d7a5f2d0b 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -425,6 +425,45 @@ struct pacct_struct { unsigned long ac_minflt, ac_majflt; }; +/** + * struct task_cputime - collected CPU time counts + * @utime: time spent in user mode, in &cputime_t units + * @stime: time spent in kernel mode, in &cputime_t units + * @sum_exec_runtime: total time spent on the CPU, in nanoseconds + * + * This structure groups together three kinds of CPU time that are + * tracked for threads and thread groups. Most things considering + * CPU time want to group these counts together and treat all three + * of them in parallel. + */ +struct task_cputime { + cputime_t utime; + cputime_t stime; + unsigned long long sum_exec_runtime; +}; +/* Alternate field names when used to cache expirations. */ +#define prof_exp stime +#define virt_exp utime +#define sched_exp sum_exec_runtime + +/** + * struct thread_group_cputime - thread group interval timer counts + * @totals: thread group interval timers; substructure for + * uniprocessor kernel, per-cpu for SMP kernel. + * + * This structure contains the version of task_cputime, above, that is + * used for thread group CPU clock calculations. + */ +#ifdef CONFIG_SMP +struct thread_group_cputime { + struct task_cputime *totals; +}; +#else +struct thread_group_cputime { + struct task_cputime totals; +}; +#endif + /* * NOTE! "signal_struct" does not have it's own * locking, because a shared signal_struct always @@ -470,6 +509,17 @@ struct signal_struct { cputime_t it_prof_expires, it_virt_expires; cputime_t it_prof_incr, it_virt_incr; + /* + * Thread group totals for process CPU clocks. + * See thread_group_cputime(), et al, for details. + */ + struct thread_group_cputime cputime; + + /* Earliest-expiration cache. */ + struct task_cputime cputime_expires; + + struct list_head cpu_timers[3]; + /* job control IDs */ /* @@ -500,7 +550,7 @@ struct signal_struct { * Live threads maintain their own counters and add to these * in __exit_signal, except for the group leader. */ - cputime_t utime, stime, cutime, cstime; + cputime_t cutime, cstime; cputime_t gtime; cputime_t cgtime; unsigned long nvcsw, nivcsw, cnvcsw, cnivcsw; @@ -508,14 +558,6 @@ struct signal_struct { unsigned long inblock, oublock, cinblock, coublock; struct task_io_accounting ioac; - /* - * Cumulative ns of scheduled CPU time for dead threads in the - * group, not including a zombie group leader. (This only differs - * from jiffies_to_ns(utime + stime) if sched_clock uses something - * other than jiffies.) - */ - unsigned long long sum_sched_runtime; - /* * We don't bother to synchronize most readers of this at all, * because there is no reader checking a limit that actually needs @@ -527,8 +569,6 @@ struct signal_struct { */ struct rlimit rlim[RLIM_NLIMITS]; - struct list_head cpu_timers[3]; - /* keep the process-shared keyrings here so that they do the right * thing in threads created with CLONE_THREAD */ #ifdef CONFIG_KEYS @@ -1134,8 +1174,7 @@ struct task_struct { /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ unsigned long min_flt, maj_flt; - cputime_t it_prof_expires, it_virt_expires; - unsigned long long it_sched_expires; + struct task_cputime cputime_expires; struct list_head cpu_timers[3]; /* process credentials */ @@ -1585,6 +1624,7 @@ extern unsigned long long cpu_clock(int cpu); extern unsigned long long task_sched_runtime(struct task_struct *task); +extern unsigned long long thread_group_sched_runtime(struct task_struct *task); /* sched_exec is called by processes performing an exec */ #ifdef CONFIG_SMP @@ -2081,6 +2121,197 @@ static inline int spin_needbreak(spinlock_t *lock) #endif } +/* + * Thread group CPU time accounting. + */ +#ifdef CONFIG_SMP + +extern int thread_group_cputime_alloc_smp(struct task_struct *); +extern void thread_group_cputime_smp(struct task_struct *, struct task_cputime *); + +static inline void thread_group_cputime_init(struct signal_struct *sig) +{ + sig->cputime.totals = NULL; +} + +static inline int thread_group_cputime_clone_thread(struct task_struct *curr, + struct task_struct *new) +{ + if (curr->signal->cputime.totals) + return 0; + return thread_group_cputime_alloc_smp(curr); +} + +static inline void thread_group_cputime_free(struct signal_struct *sig) +{ + free_percpu(sig->cputime.totals); +} + +/** + * thread_group_cputime - Sum the thread group time fields across all CPUs. + * + * This is a wrapper for the real routine, thread_group_cputime_smp(). See + * that routine for details. + */ +static inline void thread_group_cputime( + struct task_struct *tsk, + struct task_cputime *times) +{ + thread_group_cputime_smp(tsk, times); +} + +/** + * thread_group_cputime_account_user - Maintain utime for a thread group. + * + * @tgtimes: Pointer to thread_group_cputime structure. + * @cputime: Time value by which to increment the utime field of that + * structure. + * + * If thread group time is being maintained, get the structure for the + * running CPU and update the utime field there. + */ +static inline void thread_group_cputime_account_user( + struct thread_group_cputime *tgtimes, + cputime_t cputime) +{ + if (tgtimes->totals) { + struct task_cputime *times; + + times = per_cpu_ptr(tgtimes->totals, get_cpu()); + times->utime = cputime_add(times->utime, cputime); + put_cpu_no_resched(); + } +} + +/** + * thread_group_cputime_account_system - Maintain stime for a thread group. + * + * @tgtimes: Pointer to thread_group_cputime structure. + * @cputime: Time value by which to increment the stime field of that + * structure. + * + * If thread group time is being maintained, get the structure for the + * running CPU and update the stime field there. + */ +static inline void thread_group_cputime_account_system( + struct thread_group_cputime *tgtimes, + cputime_t cputime) +{ + if (tgtimes->totals) { + struct task_cputime *times; + + times = per_cpu_ptr(tgtimes->totals, get_cpu()); + times->stime = cputime_add(times->stime, cputime); + put_cpu_no_resched(); + } +} + +/** + * thread_group_cputime_account_exec_runtime - Maintain exec runtime for a + * thread group. + * + * @tgtimes: Pointer to thread_group_cputime structure. + * @ns: Time value by which to increment the sum_exec_runtime field + * of that structure. + * + * If thread group time is being maintained, get the structure for the + * running CPU and update the sum_exec_runtime field there. + */ +static inline void thread_group_cputime_account_exec_runtime( + struct thread_group_cputime *tgtimes, + unsigned long long ns) +{ + if (tgtimes->totals) { + struct task_cputime *times; + + times = per_cpu_ptr(tgtimes->totals, get_cpu()); + times->sum_exec_runtime += ns; + put_cpu_no_resched(); + } +} + +#else /* CONFIG_SMP */ + +static inline void thread_group_cputime_init(struct signal_struct *sig) +{ + sig->cputime.totals.utime = cputime_zero; + sig->cputime.totals.stime = cputime_zero; + sig->cputime.totals.sum_exec_runtime = 0; +} + +static inline int thread_group_cputime_alloc(struct task_struct *tsk) +{ + return 0; +} + +static inline void thread_group_cputime_free(struct signal_struct *sig) +{ +} + +static inline int thread_group_cputime_clone_thread(struct task_struct *curr, + struct task_struct *tsk) +{ +} + +static inline void thread_group_cputime(struct task_struct *tsk, + struct task_cputime *cputime) +{ + *cputime = tsk->signal->cputime.totals; +} + +static inline void thread_group_cputime_account_user( + struct thread_group_cputime *tgtimes, + cputime_t cputime) +{ + tgtimes->totals->utime = cputime_add(tgtimes->totals->utime, cputime); +} + +static inline void thread_group_cputime_account_system( + struct thread_group_cputime *tgtimes, + cputime_t cputime) +{ + tgtimes->totals->stime = cputime_add(tgtimes->totals->stime, cputime); +} + +static inline void thread_group_cputime_account_exec_runtime( + struct thread_group_cputime *tgtimes, + unsigned long long ns) +{ + tgtimes->totals->sum_exec_runtime += ns; +} + +#endif /* CONFIG_SMP */ + +static inline void account_group_user_time(struct task_struct *tsk, + cputime_t cputime) +{ + struct signal_struct *sig; + + sig = tsk->signal; + if (likely(sig)) + thread_group_cputime_account_user(&sig->cputime, cputime); +} + +static inline void account_group_system_time(struct task_struct *tsk, + cputime_t cputime) +{ + struct signal_struct *sig; + + sig = tsk->signal; + if (likely(sig)) + thread_group_cputime_account_system(&sig->cputime, cputime); +} + +static inline void account_group_exec_runtime(struct task_struct *tsk, + unsigned long long ns) +{ + struct signal_struct *sig; + + sig = tsk->signal; + if (likely(sig)) + thread_group_cputime_account_exec_runtime(&sig->cputime, ns); +} + /* * Reevaluate whether the task has signals pending delivery. * Wake the task if so. diff --git a/include/linux/time.h b/include/linux/time.h index e15206a7e82..1b70b3c293e 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -125,6 +125,9 @@ extern int timekeeping_valid_for_hres(void); extern void update_wall_time(void); extern void update_xtime_cache(u64 nsec); +struct tms; +extern void do_sys_times(struct tms *); + /** * timespec_to_ns - Convert timespec to nanoseconds * @ts: pointer to the timespec variable to be converted -- cgit v1.2.3 From eecfffc154ffbfe70686a9905c090b488778c28e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 12 Sep 2008 19:42:33 +0900 Subject: iommu: add iommu_device_max_index IOMMU helper function This function helps IOMMUs to know the highest address that a device can access to. Signed-off-by: FUJITA Tomonori Signed-off-by: Ingo Molnar --- include/linux/iommu-helper.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index c975caf7538..58f41107e4a 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h @@ -1,3 +1,13 @@ +static inline unsigned long iommu_device_max_index(unsigned long size, + unsigned long offset, + u64 dma_mask) +{ + if (size + offset > dma_mask) + return dma_mask - offset + 1; + else + return size; +} + extern int iommu_is_span_boundary(unsigned int index, unsigned int nr, unsigned long shift, unsigned long boundary_size); -- cgit v1.2.3 From 589fc9a6e2102b498978f6350581ec7fa5aeb032 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 12 Sep 2008 19:42:34 +0900 Subject: iommu: add dma_get_mask helper function Several IOMMUs do the same thing to get the dma_mask of a device. This adds a helper function to do the same thing to sweep them. Signed-off-by: FUJITA Tomonori Signed-off-by: Ingo Molnar --- include/linux/dma-mapping.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 6ed50c1642f..0dba7433af1 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -63,6 +63,13 @@ static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) #define dma_sync_single dma_sync_single_for_cpu #define dma_sync_sg dma_sync_sg_for_cpu +static inline u64 dma_get_mask(struct device *dev) +{ + if (dev->dma_mask && *dev->dma_mask) + return *dev->dma_mask; + return DMA_32BIT_MASK; +} + extern u64 dma_get_required_mask(struct device *dev); static inline unsigned int dma_get_max_seg_size(struct device *dev) -- cgit v1.2.3 From 0a8eaa4f9b58759595a1bfe13a1295fdc25ba026 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Sep 2008 17:03:52 +0200 Subject: timers: fix itimer/many thread hang, fix #2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix the UP build: In file included from arch/x86/kernel/asm-offsets_32.c:9, from arch/x86/kernel/asm-offsets.c:3: include/linux/sched.h: In function ‘thread_group_cputime_clone_thread’: include/linux/sched.h:2272: warning: no return statement in function returning non-void include/linux/sched.h: In function ‘thread_group_cputime_account_user’: include/linux/sched.h:2284: error: invalid type argument of ‘->’ (have ‘struct task_cputime’) include/linux/sched.h:2284: error: invalid type argument of ‘->’ (have ‘struct task_cputime’) include/linux/sched.h: In function ‘thread_group_cputime_account_system’: include/linux/sched.h:2291: error: invalid type argument of ‘->’ (have ‘struct task_cputime’) include/linux/sched.h:2291: error: invalid type argument of ‘->’ (have ‘struct task_cputime’) include/linux/sched.h: In function ‘thread_group_cputime_account_exec_runtime’: include/linux/sched.h:2298: error: invalid type argument of ‘->’ (have ‘struct task_cputime’) distcc[14501] ERROR: compile arch/x86/kernel/asm-offsets.c on a/30 failed make[1]: *** [arch/x86/kernel/asm-offsets.s] Error 1 Signed-off-by: Ingo Molnar --- include/linux/sched.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 26d7a5f2d0b..ed355f02d32 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2251,6 +2251,7 @@ static inline void thread_group_cputime_free(struct signal_struct *sig) static inline int thread_group_cputime_clone_thread(struct task_struct *curr, struct task_struct *tsk) { + return 0; } static inline void thread_group_cputime(struct task_struct *tsk, @@ -2263,21 +2264,21 @@ static inline void thread_group_cputime_account_user( struct thread_group_cputime *tgtimes, cputime_t cputime) { - tgtimes->totals->utime = cputime_add(tgtimes->totals->utime, cputime); + tgtimes->totals.utime = cputime_add(tgtimes->totals.utime, cputime); } static inline void thread_group_cputime_account_system( struct thread_group_cputime *tgtimes, cputime_t cputime) { - tgtimes->totals->stime = cputime_add(tgtimes->totals->stime, cputime); + tgtimes->totals.stime = cputime_add(tgtimes->totals.stime, cputime); } static inline void thread_group_cputime_account_exec_runtime( struct thread_group_cputime *tgtimes, unsigned long long ns) { - tgtimes->totals->sum_exec_runtime += ns; + tgtimes->totals.sum_exec_runtime += ns; } #endif /* CONFIG_SMP */ -- cgit v1.2.3 From 5ce73a4a5a4893a1aa4cdeed1b1a5a6de42c43b6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 14 Sep 2008 17:11:46 +0200 Subject: timers: fix itimer/many thread hang, cleanups Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index ed355f02d32..7ce8d4e5356 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -430,7 +430,7 @@ struct pacct_struct { * @utime: time spent in user mode, in &cputime_t units * @stime: time spent in kernel mode, in &cputime_t units * @sum_exec_runtime: total time spent on the CPU, in nanoseconds - * + * * This structure groups together three kinds of CPU time that are * tracked for threads and thread groups. Most things considering * CPU time want to group these counts together and treat all three -- cgit v1.2.3 From 600715dcdf567c86f8b2c6173fcfb4b873e25a19 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 11 Sep 2008 01:31:45 -0700 Subject: generic: add phys_addr_t for holding physical addresses Add a kernel-wide "phys_addr_t" which is guaranteed to be able to hold any physical address. By default it equals the word size of the architecture, but a 32-bit architecture can set ARCH_PHYS_ADDR_T_64BIT if it needs a 64-bit phys_addr_t. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/types.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/types.h b/include/linux/types.h index d4a9ce6e276..022c668496d 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -197,6 +197,12 @@ typedef u64 resource_size_t; typedef u32 resource_size_t; #endif +#ifdef CONFIG_PHYS_ADDR_T_64BIT +typedef u64 phys_addr_t; +#else +typedef u32 phys_addr_t; +#endif + struct ustat { __kernel_daddr_t f_tfree; __kernel_ino_t f_tinode; -- cgit v1.2.3 From 947d0496cf3e12ebfa70b3eaf561c25403247ce9 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 11 Sep 2008 01:31:48 -0700 Subject: generic: make PFN_PHYS explicitly return phys_addr_t PFN_PHYS, as its name suggests, turns a pfn into a physical address. However, it is a macro which just operates on its argument without modifying its type. pfns are typed unsigned long, but an unsigned long may not be long enough to hold a physical address (32-bit systems with more than 32 bits of physcial address). Make sure we cast to phys_addr_t to return a complete result. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/pfn.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pfn.h b/include/linux/pfn.h index bb01f8b92b5..7646637221f 100644 --- a/include/linux/pfn.h +++ b/include/linux/pfn.h @@ -1,9 +1,13 @@ #ifndef _LINUX_PFN_H_ #define _LINUX_PFN_H_ +#ifndef __ASSEMBLY__ +#include +#endif + #define PFN_ALIGN(x) (((unsigned long)(x) + (PAGE_SIZE - 1)) & PAGE_MASK) #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#define PFN_PHYS(x) ((phys_addr_t)(x) << PAGE_SHIFT) #endif -- cgit v1.2.3 From 8308c54d7e312f7a03e2ce2057d0837e6fe3843f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Thu, 11 Sep 2008 01:31:50 -0700 Subject: generic: redefine resource_size_t as phys_addr_t There's no good reason why a resource_size_t shouldn't just be a physical address, so simply redefine it in terms of phys_addr_t. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Ingo Molnar --- include/linux/types.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/types.h b/include/linux/types.h index 022c668496d..f24f7beb47d 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -191,18 +191,14 @@ typedef __u32 __bitwise __wsum; #ifdef __KERNEL__ typedef unsigned __bitwise__ gfp_t; -#ifdef CONFIG_RESOURCES_64BIT -typedef u64 resource_size_t; -#else -typedef u32 resource_size_t; -#endif - #ifdef CONFIG_PHYS_ADDR_T_64BIT typedef u64 phys_addr_t; #else typedef u32 phys_addr_t; #endif +typedef phys_addr_t resource_size_t; + struct ustat { __kernel_daddr_t f_tfree; __kernel_ino_t f_tinode; -- cgit v1.2.3 From b2e1b30290539b344cbaff0d9da38012e03aa347 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 9 Sep 2008 23:19:48 -0700 Subject: cfg80211: Add new wireless regulatory infrastructure This adds the new wireless regulatory infrastructure. The main motiviation behind this was to centralize regulatory code as each driver was implementing their own regulatory solution, and to replace the initial centralized code we have where: * only 3 regulatory domains are supported: US, JP and EU * regulatory domains can only be changed through module parameter * all rules were built statically in the kernel We now have support for regulatory domains for many countries and regulatory domains are now queried through a userspace agent through udev allowing distributions to update regulatory rules without updating the kernel. Each driver can regulatory_hint() a regulatory domain based on either their EEPROM mapped regulatory domain value to a respective ISO/IEC 3166-1 country code or pass an internally built regulatory domain. We also add support to let the user set the regulatory domain through userspace in case of faulty EEPROMs to further help compliance. Support for world roaming will be added soon for cards capable of this. For more information see: http://wireless.kernel.org/en/developers/Regulatory/CRDA For now we leave an option to enable the old module parameter, ieee80211_regdom, and to build the 3 old regdomains statically (US, JP and EU). This option is CONFIG_WIRELESS_OLD_REGULATORY. These old static definitions and the module parameter is being scheduled for removal for 2.6.29. Note that if you use this you won't make use of a world regulatory domain as its pointless. If you leave this option enabled and if CRDA is present and you use US or JP we will try to ask CRDA to update us a regulatory domain for us. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/linux/nl80211.h | 96 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index 5e51f4e7600..9bad65400fb 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h @@ -92,6 +92,20 @@ * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by * %NL80211_ATTR_IFINDEX. * + * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command + * after being queried by the kernel. CRDA replies by sending a regulatory + * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our + * current alpha2 if it found a match. It also provides + * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each + * regulatory rule is a nested set of attributes given by + * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and + * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by + * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and + * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. + * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain + * to the the specified ISO/IEC 3166-1 alpha2 country code. The core will + * store this as a valid request and then query userspace for it. + * * @NL80211_CMD_MAX: highest used command number * @__NL80211_CMD_AFTER_LAST: internal use */ @@ -131,7 +145,10 @@ enum nl80211_commands { NL80211_CMD_SET_BSS, - /* add commands here */ + NL80211_CMD_SET_REG, + NL80211_CMD_REQ_SET_REG, + + /* add new commands above here */ /* used to define NL80211_CMD_MAX below */ __NL80211_CMD_AFTER_LAST, @@ -197,10 +214,21 @@ enum nl80211_commands { * info given for %NL80211_CMD_GET_MPATH, nested attribute described at * &enum nl80211_mpath_info. * - * * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of * &enum nl80211_mntr_flags. * + * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the + * current regulatory domain should be set to or is already set to. + * For example, 'CR', for Costa Rica. This attribute is used by the kernel + * to query the CRDA to retrieve one regulatory domain. This attribute can + * also be used by userspace to query the kernel for the currently set + * regulatory domain. We chose an alpha2 as that is also used by the + * IEEE-802.11d country information element to identify a country. + * Users can also simply ask the wireless core to set regulatory domain + * to a specific alpha2. + * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory + * rules. + * * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled * (u8, 0 or 1) @@ -265,6 +293,9 @@ enum nl80211_attrs { NL80211_ATTR_SUPPORTED_IFTYPES, + NL80211_ATTR_REG_ALPHA2, + NL80211_ATTR_REG_RULES, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, @@ -278,6 +309,7 @@ enum nl80211_attrs { #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY #define NL80211_MAX_SUPP_RATES 32 +#define NL80211_MAX_SUPP_REG_RULES 32 #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 @@ -472,6 +504,66 @@ enum nl80211_bitrate_attr { NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 }; +/** + * enum nl80211_reg_rule_attr - regulatory rule attributes + * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional + * considerations for a given frequency range. These are the + * &enum nl80211_reg_rule_flags. + * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory + * rule in KHz. This is not a center of frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule + * in KHz. This is not a center a frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this + * frequency range, in KHz. + * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain + * for a given frequency range. The value is in mBi (100 * dBi). + * If you don't have one then don't send this. + * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for + * a given frequency range. The value is in mBm (100 * dBm). + */ +enum nl80211_reg_rule_attr { + __NL80211_REG_RULE_ATTR_INVALID, + NL80211_ATTR_REG_RULE_FLAGS, + + NL80211_ATTR_FREQ_RANGE_START, + NL80211_ATTR_FREQ_RANGE_END, + NL80211_ATTR_FREQ_RANGE_MAX_BW, + + NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, + NL80211_ATTR_POWER_RULE_MAX_EIRP, + + /* keep last */ + __NL80211_REG_RULE_ATTR_AFTER_LAST, + NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_reg_rule_flags - regulatory rule flags + * + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_NO_CCK: CCK modulation not allowed + * @NL80211_RRF_NO_INDOOR: indoor operation not allowed + * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed + * @NL80211_RRF_DFS: DFS support is required to be used + * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links + * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links + * @NL80211_RRF_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is allowed + */ +enum nl80211_reg_rule_flags { + NL80211_RRF_NO_OFDM = 1<<0, + NL80211_RRF_NO_CCK = 1<<1, + NL80211_RRF_NO_INDOOR = 1<<2, + NL80211_RRF_NO_OUTDOOR = 1<<3, + NL80211_RRF_DFS = 1<<4, + NL80211_RRF_PTP_ONLY = 1<<5, + NL80211_RRF_PTMP_ONLY = 1<<6, + NL80211_RRF_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + /** * enum nl80211_mntr_flags - monitor configuration flags * -- cgit v1.2.3 From ccbe329bcd87924baed96474ec0a6725e3957897 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 17 Sep 2008 16:34:03 +0100 Subject: bitmap: add bitmap_copy_le() bitmap_copy_le() copies a bitmap, putting the bits into little-endian order (i.e., each unsigned long word in the bitmap is put into little-endian order). The UWB stack used bitmaps to manage Medium Access Slot availability, and these bitmaps need to be written to the hardware in LE order. Signed-off-by: David Vrabel --- include/linux/bitmap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 89781fd4885..5379913aca5 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -130,6 +130,7 @@ extern void bitmap_fold(unsigned long *dst, const unsigned long *orig, extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order); extern void bitmap_release_region(unsigned long *bitmap, int pos, int order); extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); +extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); #define BITMAP_LAST_WORD_MASK(nbits) \ ( \ -- cgit v1.2.3 From 34e95e41f1fd751e33a7eb3fa66594903b81f13d Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Wed, 17 Sep 2008 16:34:05 +0100 Subject: uwb: add the uwb include files Signed-off-by: David Vrabel --- include/linux/uwb.h | 761 ++++++++++++++++++++++++++++++++++++++++++ include/linux/uwb/debug-cmd.h | 57 ++++ include/linux/uwb/debug.h | 82 +++++ include/linux/uwb/spec.h | 727 ++++++++++++++++++++++++++++++++++++++++ include/linux/wlp.h | 735 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 2362 insertions(+) create mode 100644 include/linux/uwb.h create mode 100644 include/linux/uwb/debug-cmd.h create mode 100644 include/linux/uwb/debug.h create mode 100644 include/linux/uwb/spec.h create mode 100644 include/linux/wlp.h (limited to 'include/linux') diff --git a/include/linux/uwb.h b/include/linux/uwb.h new file mode 100644 index 00000000000..0cd35937e12 --- /dev/null +++ b/include/linux/uwb.h @@ -0,0 +1,761 @@ +/* + * Ultra Wide Band + * UWB API + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: doc: overview of the API, different parts and pointers + */ + +#ifndef __LINUX__UWB_H__ +#define __LINUX__UWB_H__ + +#include +#include +#include +#include +#include +#include + +struct uwb_dev; +struct uwb_beca_e; +struct uwb_rc; +struct uwb_rsv; +struct uwb_dbg; + +/** + * struct uwb_dev - a UWB Device + * @rc: UWB Radio Controller that discovered the device (kind of its + * parent). + * @bce: a beacon cache entry for this device; or NULL if the device + * is a local radio controller. + * @mac_addr: the EUI-48 address of this device. + * @dev_addr: the current DevAddr used by this device. + * @beacon_slot: the slot number the beacon is using. + * @streams: bitmap of streams allocated to reservations targeted at + * this device. For an RC, this is the streams allocated for + * reservations targeted at DevAddrs. + * + * A UWB device may either by a neighbor or part of a local radio + * controller. + */ +struct uwb_dev { + struct mutex mutex; + struct list_head list_node; + struct device dev; + struct uwb_rc *rc; /* radio controller */ + struct uwb_beca_e *bce; /* Beacon Cache Entry */ + + struct uwb_mac_addr mac_addr; + struct uwb_dev_addr dev_addr; + int beacon_slot; + DECLARE_BITMAP(streams, UWB_NUM_STREAMS); +}; +#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev) + +/** + * UWB HWA/WHCI Radio Control {Command|Event} Block context IDs + * + * RC[CE]Bs have a 'context ID' field that matches the command with + * the event received to confirm it. + * + * Maximum number of context IDs + */ +enum { UWB_RC_CTX_MAX = 256 }; + + +/** Notification chain head for UWB generated events to listeners */ +struct uwb_notifs_chain { + struct list_head list; + struct mutex mutex; +}; + +/** + * struct uwb_mas_bm - a bitmap of all MAS in a superframe + * @bm: a bitmap of length #UWB_NUM_MAS + */ +struct uwb_mas_bm { + DECLARE_BITMAP(bm, UWB_NUM_MAS); +}; + +/** + * uwb_rsv_state - UWB Reservation state. + * + * NONE - reservation is not active (no DRP IE being transmitted). + * + * Owner reservation states: + * + * INITIATED - owner has sent an initial DRP request. + * PENDING - target responded with pending Reason Code. + * MODIFIED - reservation manager is modifying an established + * reservation with a different MAS allocation. + * ESTABLISHED - the reservation has been successfully negotiated. + * + * Target reservation states: + * + * DENIED - request is denied. + * ACCEPTED - request is accepted. + * PENDING - PAL has yet to make a decision to whether to accept or + * deny. + * + * FIXME: further target states TBD. + */ +enum uwb_rsv_state { + UWB_RSV_STATE_NONE, + UWB_RSV_STATE_O_INITIATED, + UWB_RSV_STATE_O_PENDING, + UWB_RSV_STATE_O_MODIFIED, + UWB_RSV_STATE_O_ESTABLISHED, + UWB_RSV_STATE_T_ACCEPTED, + UWB_RSV_STATE_T_DENIED, + UWB_RSV_STATE_T_PENDING, + + UWB_RSV_STATE_LAST, +}; + +enum uwb_rsv_target_type { + UWB_RSV_TARGET_DEV, + UWB_RSV_TARGET_DEVADDR, +}; + +/** + * struct uwb_rsv_target - the target of a reservation. + * + * Reservations unicast and targeted at a single device + * (UWB_RSV_TARGET_DEV); or (e.g., in the case of WUSB) targeted at a + * specific (private) DevAddr (UWB_RSV_TARGET_DEVADDR). + */ +struct uwb_rsv_target { + enum uwb_rsv_target_type type; + union { + struct uwb_dev *dev; + struct uwb_dev_addr devaddr; + }; +}; + +/* + * Number of streams reserved for reservations targeted at DevAddrs. + */ +#define UWB_NUM_GLOBAL_STREAMS 1 + +typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv); + +/** + * struct uwb_rsv - a DRP reservation + * + * Data structure management: + * + * @rc: the radio controller this reservation is for + * (as target or owner) + * @rc_node: a list node for the RC + * @pal_node: a list node for the PAL + * + * Owner and target parameters: + * + * @owner: the UWB device owning this reservation + * @target: the target UWB device + * @type: reservation type + * + * Owner parameters: + * + * @max_mas: maxiumum number of MAS + * @min_mas: minimum number of MAS + * @sparsity: owner selected sparsity + * @is_multicast: true iff multicast + * + * @callback: callback function when the reservation completes + * @pal_priv: private data for the PAL making the reservation + * + * Reservation status: + * + * @status: negotiation status + * @stream: stream index allocated for this reservation + * @mas: reserved MAS + * @drp_ie: the DRP IE + * @ie_valid: true iff the DRP IE matches the reservation parameters + * + * DRP reservations are uniquely identified by the owner, target and + * stream index. However, when using a DevAddr as a target (e.g., for + * a WUSB cluster reservation) the responses may be received from + * devices with different DevAddrs. In this case, reservations are + * uniquely identified by just the stream index. A number of stream + * indexes (UWB_NUM_GLOBAL_STREAMS) are reserved for this. + */ +struct uwb_rsv { + struct uwb_rc *rc; + struct list_head rc_node; + struct list_head pal_node; + + struct uwb_dev *owner; + struct uwb_rsv_target target; + enum uwb_drp_type type; + int max_mas; + int min_mas; + int sparsity; + bool is_multicast; + + uwb_rsv_cb_f callback; + void *pal_priv; + + enum uwb_rsv_state state; + u8 stream; + struct uwb_mas_bm mas; + struct uwb_ie_drp *drp_ie; + bool ie_valid; + struct timer_list timer; + bool expired; +}; + +static const +struct uwb_mas_bm uwb_mas_bm_zero = { .bm = { 0 } }; + +static inline void uwb_mas_bm_copy_le(void *dst, const struct uwb_mas_bm *mas) +{ + bitmap_copy_le(dst, mas->bm, UWB_NUM_MAS); +} + +/** + * struct uwb_drp_avail - a radio controller's view of MAS usage + * @global: MAS unused by neighbors (excluding reservations targetted + * or owned by the local radio controller) or the beaon period + * @local: MAS unused by local established reservations + * @pending: MAS unused by local pending reservations + * @ie: DRP Availability IE to be included in the beacon + * @ie_valid: true iff @ie is valid and does not need to regenerated from + * @global and @local + * + * Each radio controller maintains a view of MAS usage or + * availability. MAS available for a new reservation are determined + * from the intersection of @global, @local, and @pending. + * + * The radio controller must transmit a DRP Availability IE that's the + * intersection of @global and @local. + * + * A set bit indicates the MAS is unused and available. + * + * rc->rsvs_mutex should be held before accessing this data structure. + * + * [ECMA-368] section 17.4.3. + */ +struct uwb_drp_avail { + DECLARE_BITMAP(global, UWB_NUM_MAS); + DECLARE_BITMAP(local, UWB_NUM_MAS); + DECLARE_BITMAP(pending, UWB_NUM_MAS); + struct uwb_ie_drp_avail ie; + bool ie_valid; +}; + + +const char *uwb_rsv_state_str(enum uwb_rsv_state state); +const char *uwb_rsv_type_str(enum uwb_drp_type type); + +struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb, + void *pal_priv); +void uwb_rsv_destroy(struct uwb_rsv *rsv); + +int uwb_rsv_establish(struct uwb_rsv *rsv); +int uwb_rsv_modify(struct uwb_rsv *rsv, + int max_mas, int min_mas, int sparsity); +void uwb_rsv_terminate(struct uwb_rsv *rsv); + +void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv); + +/** + * Radio Control Interface instance + * + * + * Life cycle rules: those of the UWB Device. + * + * @index: an index number for this radio controller, as used in the + * device name. + * @version: version of protocol supported by this device + * @priv: Backend implementation; rw with uwb_dev.dev.sem taken. + * @cmd: Backend implementation to execute commands; rw and call + * only with uwb_dev.dev.sem taken. + * @reset: Hardware reset of radio controller and any PAL controllers. + * @filter: Backend implementation to manipulate data to and from device + * to be compliant to specification assumed by driver (WHCI + * 0.95). + * + * uwb_dev.dev.mutex is used to execute commands and update + * the corresponding structures; can't use a spinlock + * because rc->cmd() can sleep. + * @ies: This is a dynamically allocated array cacheing the + * IEs (settable by the host) that the beacon of this + * radio controller is currently sending. + * + * In reality, we store here the full command we set to + * the radio controller (which is basically a command + * prefix followed by all the IEs the beacon currently + * contains). This way we don't have to realloc and + * memcpy when setting it. + * + * We set this up in uwb_rc_ie_setup(), where we alloc + * this struct, call get_ie() [so we know which IEs are + * currently being sent, if any]. + * + * @ies_capacity:Amount of space (in bytes) allocated in @ies. The + * amount used is given by sizeof(*ies) plus ies->wIELength + * (which is a little endian quantity all the time). + * @ies_mutex: protect the IE cache + * @dbg: information for the debug interface + */ +struct uwb_rc { + struct uwb_dev uwb_dev; + int index; + u16 version; + + struct module *owner; + void *priv; + int (*start)(struct uwb_rc *rc); + void (*stop)(struct uwb_rc *rc); + int (*cmd)(struct uwb_rc *, const struct uwb_rccb *, size_t); + int (*reset)(struct uwb_rc *rc); + int (*filter_cmd)(struct uwb_rc *, struct uwb_rccb **, size_t *); + int (*filter_event)(struct uwb_rc *, struct uwb_rceb **, const size_t, + size_t *, size_t *); + + spinlock_t neh_lock; /* protects neh_* and ctx_* */ + struct list_head neh_list; /* Open NE handles */ + unsigned long ctx_bm[UWB_RC_CTX_MAX / 8 / sizeof(unsigned long)]; + u8 ctx_roll; + + int beaconing; /* Beaconing state [channel number] */ + int scanning; + enum uwb_scan_type scan_type:3; + unsigned ready:1; + struct uwb_notifs_chain notifs_chain; + + struct uwb_drp_avail drp_avail; + struct list_head reservations; + struct mutex rsvs_mutex; + struct workqueue_struct *rsv_workq; + struct work_struct rsv_update_work; + + struct mutex ies_mutex; + struct uwb_rc_cmd_set_ie *ies; + size_t ies_capacity; + + spinlock_t pal_lock; + struct list_head pals; + + struct uwb_dbg *dbg; +}; + + +/** + * struct uwb_pal - a UWB PAL + * @new_rsv: called when a peer requests a reservation (may be NULL if + * the PAL cannot accept reservation requests). + * + * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB + * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP). + * + * The PALs using a radio controller must register themselves to + * permit the UWB stack to coordinate usage of the radio between the + * various PALs or to allow PALs to response to certain requests from + * peers. + * + * A struct uwb_pal should be embedded in a containing structure + * belonging to the PAL and initialized with uwb_pal_init()). Fields + * should be set appropriately by the PAL before registering the PAL + * with uwb_pal_register(). + */ +struct uwb_pal { + struct list_head node; + + void (*new_rsv)(struct uwb_rsv *rsv); +}; + +void uwb_pal_init(struct uwb_pal *pal); +int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal); +void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal); + +/* + * General public API + * + * This API can be used by UWB device drivers or by those implementing + * UWB Radio Controllers + */ +struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc, + const struct uwb_dev_addr *devaddr); +struct uwb_dev *uwb_dev_get_by_rc(struct uwb_dev *, struct uwb_rc *); +static inline void uwb_dev_get(struct uwb_dev *uwb_dev) +{ + get_device(&uwb_dev->dev); +} +static inline void uwb_dev_put(struct uwb_dev *uwb_dev) +{ + put_device(&uwb_dev->dev); +} +struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev); + +/** + * Callback function for 'uwb_{dev,rc}_foreach()'. + * + * @dev: Linux device instance + * 'uwb_dev = container_of(dev, struct uwb_dev, dev)' + * @priv: Data passed by the caller to 'uwb_{dev,rc}_foreach()'. + * + * @returns: 0 to continue the iterations, any other val to stop + * iterating and return the value to the caller of + * _foreach(). + */ +typedef int (*uwb_dev_for_each_f)(struct device *dev, void *priv); +int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f func, void *priv); + +struct uwb_rc *uwb_rc_alloc(void); +struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *); +struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *); +void uwb_rc_put(struct uwb_rc *rc); + +typedef void (*uwb_rc_cmd_cb_f)(struct uwb_rc *rc, void *arg, + struct uwb_rceb *reply, ssize_t reply_size); + +int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + u8 expected_type, u16 expected_event, + uwb_rc_cmd_cb_f cb, void *arg); +ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + struct uwb_rceb *reply, size_t reply_size); +ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name, + struct uwb_rccb *cmd, size_t cmd_size, + u8 expected_type, u16 expected_event, + struct uwb_rceb **preply); +ssize_t uwb_rc_get_ie(struct uwb_rc *, struct uwb_rc_evt_get_ie **); +int uwb_bg_joined(struct uwb_rc *rc); + +size_t __uwb_addr_print(char *, size_t, const unsigned char *, int); + +int uwb_rc_dev_addr_set(struct uwb_rc *, const struct uwb_dev_addr *); +int uwb_rc_dev_addr_get(struct uwb_rc *, struct uwb_dev_addr *); +int uwb_rc_mac_addr_set(struct uwb_rc *, const struct uwb_mac_addr *); +int uwb_rc_mac_addr_get(struct uwb_rc *, struct uwb_mac_addr *); +int __uwb_mac_addr_assigned_check(struct device *, void *); +int __uwb_dev_addr_assigned_check(struct device *, void *); + +/* Print in @buf a pretty repr of @addr */ +static inline size_t uwb_dev_addr_print(char *buf, size_t buf_size, + const struct uwb_dev_addr *addr) +{ + return __uwb_addr_print(buf, buf_size, addr->data, 0); +} + +/* Print in @buf a pretty repr of @addr */ +static inline size_t uwb_mac_addr_print(char *buf, size_t buf_size, + const struct uwb_mac_addr *addr) +{ + return __uwb_addr_print(buf, buf_size, addr->data, 1); +} + +/* @returns 0 if device addresses @addr2 and @addr1 are equal */ +static inline int uwb_dev_addr_cmp(const struct uwb_dev_addr *addr1, + const struct uwb_dev_addr *addr2) +{ + return memcmp(addr1, addr2, sizeof(*addr1)); +} + +/* @returns 0 if MAC addresses @addr2 and @addr1 are equal */ +static inline int uwb_mac_addr_cmp(const struct uwb_mac_addr *addr1, + const struct uwb_mac_addr *addr2) +{ + return memcmp(addr1, addr2, sizeof(*addr1)); +} + +/* @returns !0 if a MAC @addr is a broadcast address */ +static inline int uwb_mac_addr_bcast(const struct uwb_mac_addr *addr) +{ + struct uwb_mac_addr bcast = { + .data = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } + }; + return !uwb_mac_addr_cmp(addr, &bcast); +} + +/* @returns !0 if a MAC @addr is all zeroes*/ +static inline int uwb_mac_addr_unset(const struct uwb_mac_addr *addr) +{ + struct uwb_mac_addr unset = { + .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }; + return !uwb_mac_addr_cmp(addr, &unset); +} + +/* @returns !0 if the address is in use. */ +static inline unsigned __uwb_dev_addr_assigned(struct uwb_rc *rc, + struct uwb_dev_addr *addr) +{ + return uwb_dev_for_each(rc, __uwb_dev_addr_assigned_check, addr); +} + +/* + * UWB Radio Controller API + * + * This API is used (in addition to the general API) to implement UWB + * Radio Controllers. + */ +void uwb_rc_init(struct uwb_rc *); +int uwb_rc_add(struct uwb_rc *, struct device *dev, void *rc_priv); +void uwb_rc_rm(struct uwb_rc *); +void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t); +void uwb_rc_neh_error(struct uwb_rc *, int); +void uwb_rc_reset_all(struct uwb_rc *rc); + +/** + * uwb_rsv_is_owner - is the owner of this reservation the RC? + * @rsv: the reservation + */ +static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv) +{ + return rsv->owner == &rsv->rc->uwb_dev; +} + +/** + * Events generated by UWB that can be passed to any listeners + * + * Higher layers can register callback functions with the radio + * controller using uwb_notifs_register(). The radio controller + * maintains a list of all registered handlers and will notify all + * nodes when an event occurs. + */ +enum uwb_notifs { + UWB_NOTIF_BG_JOIN = 0, /* radio controller joined a beacon group */ + UWB_NOTIF_BG_LEAVE = 1, /* radio controller left a beacon group */ + UWB_NOTIF_ONAIR, + UWB_NOTIF_OFFAIR, +}; + +/* Callback function registered with UWB */ +struct uwb_notifs_handler { + struct list_head list_node; + void (*cb)(void *, struct uwb_dev *, enum uwb_notifs); + void *data; +}; + +int uwb_notifs_register(struct uwb_rc *, struct uwb_notifs_handler *); +int uwb_notifs_deregister(struct uwb_rc *, struct uwb_notifs_handler *); + + +/** + * UWB radio controller Event Size Entry (for creating entry tables) + * + * WUSB and WHCI define events and notifications, and they might have + * fixed or variable size. + * + * Each event/notification has a size which is not necessarily known + * in advance based on the event code. As well, vendor specific + * events/notifications will have a size impossible to determine + * unless we know about the device's specific details. + * + * It was way too smart of the spec writers not to think that it would + * be impossible for a generic driver to skip over vendor specific + * events/notifications if there are no LENGTH fields in the HEADER of + * each message...the transaction size cannot be counted on as the + * spec does not forbid to pack more than one event in a single + * transaction. + * + * Thus, we guess sizes with tables (or for events, when you know the + * size ahead of time you can use uwb_rc_neh_extra_size*()). We + * register tables with the known events and their sizes, and then we + * traverse those tables. For those with variable length, we provide a + * way to lookup the size inside the event/notification's + * payload. This allows device-specific event size tables to be + * registered. + * + * @size: Size of the payload + * + * @offset: if != 0, at offset @offset-1 starts a field with a length + * that has to be added to @size. The format of the field is + * given by @type. + * + * @type: Type and length of the offset field. Most common is LE 16 + * bits (that's why that is zero); others are there mostly to + * cover for bugs and weirdos. + */ +struct uwb_est_entry { + size_t size; + unsigned offset; + enum { UWB_EST_16 = 0, UWB_EST_8 = 1 } type; +}; + +int uwb_est_register(u8 type, u8 code_high, u16 vendor, u16 product, + const struct uwb_est_entry *, size_t entries); +int uwb_est_unregister(u8 type, u8 code_high, u16 vendor, u16 product, + const struct uwb_est_entry *, size_t entries); +ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb, + size_t len); + +/* -- Misc */ + +enum { + EDC_MAX_ERRORS = 10, + EDC_ERROR_TIMEFRAME = HZ, +}; + +/* error density counter */ +struct edc { + unsigned long timestart; + u16 errorcount; +}; + +static inline +void edc_init(struct edc *edc) +{ + edc->timestart = jiffies; +} + +/* Called when an error occured. + * This is way to determine if the number of acceptable errors per time + * period has been exceeded. It is not accurate as there are cases in which + * this scheme will not work, for example if there are periodic occurences + * of errors that straddle updates to the start time. This scheme is + * sufficient for our usage. + * + * @returns 1 if maximum acceptable errors per timeframe has been exceeded. + */ +static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe) +{ + unsigned long now; + + now = jiffies; + if (now - err_hist->timestart > timeframe) { + err_hist->errorcount = 1; + err_hist->timestart = now; + } else if (++err_hist->errorcount > max_err) { + err_hist->errorcount = 0; + err_hist->timestart = now; + return 1; + } + return 0; +} + + +/* Information Element handling */ + +/* For representing the state of writing to a buffer when iterating */ +struct uwb_buf_ctx { + char *buf; + size_t bytes, size; +}; + +typedef int (*uwb_ie_f)(struct uwb_dev *, const struct uwb_ie_hdr *, + size_t, void *); +struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); +ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data, + const void *buf, size_t size); +int uwb_ie_dump_hex(struct uwb_dev *, const struct uwb_ie_hdr *, + size_t, void *); +int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *); +struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len); + + +/* + * Transmission statistics + * + * UWB uses LQI and RSSI (one byte values) for reporting radio signal + * strength and line quality indication. We do quick and dirty + * averages of those. They are signed values, btw. + * + * For 8 bit quantities, we keep the min, the max, an accumulator + * (@sigma) and a # of samples. When @samples gets to 255, we compute + * the average (@sigma / @samples), place it in @sigma and reset + * @samples to 1 (so we use it as the first sample). + * + * Now, statistically speaking, probably I am kicking the kidneys of + * some books I have in my shelves collecting dust, but I just want to + * get an approx, not the Nobel. + * + * LOCKING: there is no locking per se, but we try to keep a lockless + * schema. Only _add_samples() modifies the values--as long as you + * have other locking on top that makes sure that no two calls of + * _add_sample() happen at the same time, then we are fine. Now, for + * resetting the values we just set @samples to 0 and that makes the + * next _add_sample() to start with defaults. Reading the values in + * _show() currently can race, so you need to make sure the calls are + * under the same lock that protects calls to _add_sample(). FIXME: + * currently unlocked (It is not ultraprecise but does the trick. Bite + * me). + */ +struct stats { + s8 min, max; + s16 sigma; + atomic_t samples; +}; + +static inline +void stats_init(struct stats *stats) +{ + atomic_set(&stats->samples, 0); + wmb(); +} + +static inline +void stats_add_sample(struct stats *stats, s8 sample) +{ + s8 min, max; + s16 sigma; + unsigned samples = atomic_read(&stats->samples); + if (samples == 0) { /* it was zero before, so we initialize */ + min = 127; + max = -128; + sigma = 0; + } else { + min = stats->min; + max = stats->max; + sigma = stats->sigma; + } + + if (sample < min) /* compute new values */ + min = sample; + else if (sample > max) + max = sample; + sigma += sample; + + stats->min = min; /* commit */ + stats->max = max; + stats->sigma = sigma; + if (atomic_add_return(1, &stats->samples) > 255) { + /* wrapped around! reset */ + stats->sigma = sigma / 256; + atomic_set(&stats->samples, 1); + } +} + +static inline ssize_t stats_show(struct stats *stats, char *buf) +{ + int min, max, avg; + int samples = atomic_read(&stats->samples); + if (samples == 0) + min = max = avg = 0; + else { + min = stats->min; + max = stats->max; + avg = stats->sigma / samples; + } + return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", min, max, avg); +} + +static inline ssize_t stats_store(struct stats *stats, const char *buf, + size_t size) +{ + stats_init(stats); + return size; +} + +#endif /* #ifndef __LINUX__UWB_H__ */ diff --git a/include/linux/uwb/debug-cmd.h b/include/linux/uwb/debug-cmd.h new file mode 100644 index 00000000000..1141f41bab5 --- /dev/null +++ b/include/linux/uwb/debug-cmd.h @@ -0,0 +1,57 @@ +/* + * Ultra Wide Band + * Debug interface commands + * + * Copyright (C) 2008 Cambridge Silicon Radio Ltd. + * + * 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. + * + * 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, see . + */ +#ifndef __LINUX__UWB__DEBUG_CMD_H__ +#define __LINUX__UWB__DEBUG_CMD_H__ + +#include + +/* + * Debug interface commands + * + * UWB_DBG_CMD_RSV_ESTABLISH: Establish a new unicast reservation. + * + * UWB_DBG_CMD_RSV_TERMINATE: Terminate the Nth reservation. + */ + +enum uwb_dbg_cmd_type { + UWB_DBG_CMD_RSV_ESTABLISH = 1, + UWB_DBG_CMD_RSV_TERMINATE = 2, +}; + +struct uwb_dbg_cmd_rsv_establish { + __u8 target[6]; + __u8 type; + __u16 max_mas; + __u16 min_mas; + __u8 sparsity; +}; + +struct uwb_dbg_cmd_rsv_terminate { + int index; +}; + +struct uwb_dbg_cmd { + __u32 type; + union { + struct uwb_dbg_cmd_rsv_establish rsv_establish; + struct uwb_dbg_cmd_rsv_terminate rsv_terminate; + }; +}; + +#endif /* #ifndef __LINUX__UWB__DEBUG_CMD_H__ */ diff --git a/include/linux/uwb/debug.h b/include/linux/uwb/debug.h new file mode 100644 index 00000000000..a86a73fe303 --- /dev/null +++ b/include/linux/uwb/debug.h @@ -0,0 +1,82 @@ +/* + * Ultra Wide Band + * Debug Support + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: doc + * Invoke like: + * + * #define D_LOCAL 4 + * #include + * + * At the end of your include files. + */ +#include + +struct device; +extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize); + +/* Master debug switch; !0 enables, 0 disables */ +#define D_MASTER (!0) + +/* Local (per-file) debug switch; #define before #including */ +#ifndef D_LOCAL +#define D_LOCAL 0 +#endif + +#undef __d_printf +#undef d_fnstart +#undef d_fnend +#undef d_printf +#undef d_dump + +#define __d_printf(l, _tag, _dev, f, a...) \ +do { \ + struct device *__dev = (_dev); \ + if (D_MASTER && D_LOCAL >= (l)) { \ + char __head[64] = ""; \ + if (_dev != NULL) { \ + if ((unsigned long)__dev < 4096) \ + printk(KERN_ERR "E: Corrupt dev %p\n", \ + __dev); \ + else \ + snprintf(__head, sizeof(__head), \ + "%s %s: ", \ + dev_driver_string(__dev), \ + __dev->bus_id); \ + } \ + printk(KERN_ERR "%s%s" _tag ": " f, __head, \ + __func__, ## a); \ + } \ +} while (0 && _dev) + +#define d_fnstart(l, _dev, f, a...) \ + __d_printf(l, " FNSTART", _dev, f, ## a) +#define d_fnend(l, _dev, f, a...) \ + __d_printf(l, " FNEND", _dev, f, ## a) +#define d_printf(l, _dev, f, a...) \ + __d_printf(l, "", _dev, f, ## a) +#define d_dump(l, _dev, ptr, size) \ +do { \ + struct device *__dev = _dev; \ + if (D_MASTER && D_LOCAL >= (l)) \ + dump_bytes(__dev, ptr, size); \ +} while (0 && _dev) +#define d_test(l) (D_MASTER && D_LOCAL >= (l)) diff --git a/include/linux/uwb/spec.h b/include/linux/uwb/spec.h new file mode 100644 index 00000000000..198c15f8e25 --- /dev/null +++ b/include/linux/uwb/spec.h @@ -0,0 +1,727 @@ +/* + * Ultra Wide Band + * UWB Standard definitions + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * All these definitions are based on the ECMA-368 standard. + * + * Note all definitions are Little Endian in the wire, and we will + * convert them to host order before operating on the bitfields (that + * yes, we use extensively). + */ + +#ifndef __LINUX__UWB_SPEC_H__ +#define __LINUX__UWB_SPEC_H__ + +#include +#include + +#define i1480_FW 0x00000303 +/* #define i1480_FW 0x00000302 */ + +/** + * Number of Medium Access Slots in a superframe. + * + * UWB divides time in SuperFrames, each one divided in 256 pieces, or + * Medium Access Slots. See MBOA MAC[5.4.5] for details. The MAS is the + * basic bandwidth allocation unit in UWB. + */ +enum { UWB_NUM_MAS = 256 }; + +/** + * Number of Zones in superframe. + * + * UWB divides the superframe into zones with numbering starting from BPST. + * See MBOA MAC[16.8.6] + */ +enum { UWB_NUM_ZONES = 16 }; + +/* + * Number of MAS in a zone. + */ +#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES) + +/* + * Number of streams per DRP reservation between a pair of devices. + * + * [ECMA-368] section 16.8.6. + */ +enum { UWB_NUM_STREAMS = 8 }; + +/* + * mMasLength + * + * The length of a MAS in microseconds. + * + * [ECMA-368] section 17.16. + */ +enum { UWB_MAS_LENGTH_US = 256 }; + +/* + * mBeaconSlotLength + * + * The length of the beacon slot in microseconds. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_BEACON_SLOT_LENGTH_US = 85 }; + +/* + * mMaxLostBeacons + * + * The number beacons missing in consecutive superframes before a + * device can be considered as unreachable. + * + * [ECMA-368] section 17.16 + */ +enum { UWB_MAX_LOST_BEACONS = 3 }; + +/* + * Length of a superframe in microseconds. + */ +#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS) + +/** + * UWB MAC address + * + * It is *imperative* that this struct is exactly 6 packed bytes (as + * it is also used to define headers sent down and up the wire/radio). + */ +struct uwb_mac_addr { + u8 data[6]; +} __attribute__((packed)); + + +/** + * UWB device address + * + * It is *imperative* that this struct is exactly 6 packed bytes (as + * it is also used to define headers sent down and up the wire/radio). + */ +struct uwb_dev_addr { + u8 data[2]; +} __attribute__((packed)); + + +/** + * Types of UWB addresses + * + * Order matters (by size). + */ +enum uwb_addr_type { + UWB_ADDR_DEV = 0, + UWB_ADDR_MAC = 1, +}; + + +/** Size of a char buffer for printing a MAC/device address */ +enum { UWB_ADDR_STRSIZE = 32 }; + + +/** UWB WiMedia protocol IDs. */ +enum uwb_prid { + UWB_PRID_WLP_RESERVED = 0x0000, + UWB_PRID_WLP = 0x0001, + UWB_PRID_WUSB_BOT = 0x0010, + UWB_PRID_WUSB = 0x0010, + UWB_PRID_WUSB_TOP = 0x001F, +}; + + +/** PHY Rate (MBOA MAC[7.8.12, Table 61]) */ +enum uwb_phy_rate { + UWB_PHY_RATE_53 = 0, + UWB_PHY_RATE_80, + UWB_PHY_RATE_106, + UWB_PHY_RATE_160, + UWB_PHY_RATE_200, + UWB_PHY_RATE_320, + UWB_PHY_RATE_400, + UWB_PHY_RATE_480, + UWB_PHY_RATE_INVALID +}; + + +/** + * Different ways to scan (MBOA MAC[6.2.2, Table 8], WUSB[Table 8-78]) + */ +enum uwb_scan_type { + UWB_SCAN_ONLY = 0, + UWB_SCAN_OUTSIDE_BP, + UWB_SCAN_WHILE_INACTIVE, + UWB_SCAN_DISABLED, + UWB_SCAN_ONLY_STARTTIME, + UWB_SCAN_TOP +}; + + +/** ACK Policy types (MBOA MAC[7.2.1.3]) */ +enum uwb_ack_pol { + UWB_ACK_NO = 0, + UWB_ACK_INM = 1, + UWB_ACK_B = 2, + UWB_ACK_B_REQ = 3, +}; + + +/** DRP reservation types ([ECMA-368 table 106) */ +enum uwb_drp_type { + UWB_DRP_TYPE_ALIEN_BP = 0, + UWB_DRP_TYPE_HARD, + UWB_DRP_TYPE_SOFT, + UWB_DRP_TYPE_PRIVATE, + UWB_DRP_TYPE_PCA, +}; + + +/** DRP Reason Codes ([ECMA-368] table 107) */ +enum uwb_drp_reason { + UWB_DRP_REASON_ACCEPTED = 0, + UWB_DRP_REASON_CONFLICT, + UWB_DRP_REASON_PENDING, + UWB_DRP_REASON_DENIED, + UWB_DRP_REASON_MODIFIED, +}; + +/** + * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9]) + */ +enum uwb_drp_notif_reason { + UWB_DRP_NOTIF_DRP_IE_RCVD = 0, + UWB_DRP_NOTIF_CONFLICT, + UWB_DRP_NOTIF_TERMINATE, +}; + + +/** Allocation of MAS slots in a DRP request MBOA MAC[7.8.7] */ +struct uwb_drp_alloc { + __le16 zone_bm; + __le16 mas_bm; +} __attribute__((packed)); + + +/** General MAC Header format (ECMA-368[16.2]) */ +struct uwb_mac_frame_hdr { + __le16 Frame_Control; + struct uwb_dev_addr DestAddr; + struct uwb_dev_addr SrcAddr; + __le16 Sequence_Control; + __le16 Access_Information; +} __attribute__((packed)); + + +/** + * uwb_beacon_frame - a beacon frame including MAC headers + * + * [ECMA] section 16.3. + */ +struct uwb_beacon_frame { + struct uwb_mac_frame_hdr hdr; + struct uwb_mac_addr Device_Identifier; /* may be a NULL EUI-48 */ + u8 Beacon_Slot_Number; + u8 Device_Control; + u8 IEData[]; +} __attribute__((packed)); + + +/** Information Element codes (MBOA MAC[T54]) */ +enum uwb_ie { + UWB_PCA_AVAILABILITY = 2, + UWB_IE_DRP_AVAILABILITY = 8, + UWB_IE_DRP = 9, + UWB_BP_SWITCH_IE = 11, + UWB_MAC_CAPABILITIES_IE = 12, + UWB_PHY_CAPABILITIES_IE = 13, + UWB_APP_SPEC_PROBE_IE = 15, + UWB_IDENTIFICATION_IE = 19, + UWB_MASTER_KEY_ID_IE = 20, + UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */ + UWB_APP_SPEC_IE = 255, +}; + + +/** + * Header common to all Information Elements (IEs) + */ +struct uwb_ie_hdr { + u8 element_id; /* enum uwb_ie */ + u8 length; +} __attribute__((packed)); + + +/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.6]) */ +struct uwb_ie_drp { + struct uwb_ie_hdr hdr; + __le16 drp_control; + struct uwb_dev_addr dev_addr; + struct uwb_drp_alloc allocs[]; +} __attribute__((packed)); + +static inline int uwb_ie_drp_type(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 0) & 0x7; +} + +static inline int uwb_ie_drp_stream_index(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 3) & 0x7; +} + +static inline int uwb_ie_drp_reason_code(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 6) & 0x7; +} + +static inline int uwb_ie_drp_status(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 9) & 0x1; +} + +static inline int uwb_ie_drp_owner(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 10) & 0x1; +} + +static inline int uwb_ie_drp_tiebreaker(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 11) & 0x1; +} + +static inline int uwb_ie_drp_unsafe(struct uwb_ie_drp *ie) +{ + return (le16_to_cpu(ie->drp_control) >> 12) & 0x1; +} + +static inline void uwb_ie_drp_set_type(struct uwb_ie_drp *ie, enum uwb_drp_type type) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x7 << 0)) | (type << 0); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_stream_index(struct uwb_ie_drp *ie, int stream_index) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x7 << 3)) | (stream_index << 3); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_reason_code(struct uwb_ie_drp *ie, + enum uwb_drp_reason reason_code) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (ie->drp_control & ~(0x7 << 6)) | (reason_code << 6); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_status(struct uwb_ie_drp *ie, int status) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 9)) | (status << 9); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_owner(struct uwb_ie_drp *ie, int owner) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 10)) | (owner << 10); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_tiebreaker(struct uwb_ie_drp *ie, int tiebreaker) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 11)) | (tiebreaker << 11); + ie->drp_control = cpu_to_le16(drp_control); +} + +static inline void uwb_ie_drp_set_unsafe(struct uwb_ie_drp *ie, int unsafe) +{ + u16 drp_control = le16_to_cpu(ie->drp_control); + drp_control = (drp_control & ~(0x1 << 12)) | (unsafe << 12); + ie->drp_control = cpu_to_le16(drp_control); +} + +/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.7]) */ +struct uwb_ie_drp_avail { + struct uwb_ie_hdr hdr; + DECLARE_BITMAP(bmp, UWB_NUM_MAS); +} __attribute__((packed)); + +/** + * The Vendor ID is set to an OUI that indicates the vendor of the device. + * ECMA-368 [16.8.10] + */ +struct uwb_vendor_id { + u8 data[3]; +} __attribute__((packed)); + +/** + * The device type ID + * FIXME: clarify what this means + * ECMA-368 [16.8.10] + */ +struct uwb_device_type_id { + u8 data[3]; +} __attribute__((packed)); + + +/** + * UWB device information types + * ECMA-368 [16.8.10] + */ +enum uwb_dev_info_type { + UWB_DEV_INFO_VENDOR_ID = 0, + UWB_DEV_INFO_VENDOR_TYPE, + UWB_DEV_INFO_NAME, +}; + +/** + * UWB device information found in Identification IE + * ECMA-368 [16.8.10] + */ +struct uwb_dev_info { + u8 type; /* enum uwb_dev_info_type */ + u8 length; + u8 data[]; +} __attribute__((packed)); + +/** + * UWB Identification IE + * ECMA-368 [16.8.10] + */ +struct uwb_identification_ie { + struct uwb_ie_hdr hdr; + struct uwb_dev_info info[]; +} __attribute__((packed)); + +/* + * UWB Radio Controller + * + * These definitions are common to the Radio Control layers as + * exported by the WUSB1.0 HWA and WHCI interfaces. + */ + +/** Radio Control Command Block (WUSB1.0[Table 8-65] and WHCI 0.95) */ +struct uwb_rccb { + u8 bCommandType; /* enum hwa_cet */ + __le16 wCommand; /* Command code */ + u8 bCommandContext; /* Context ID */ +} __attribute__((packed)); + + +/** Radio Control Event Block (WUSB[table 8-66], WHCI 0.95) */ +struct uwb_rceb { + u8 bEventType; /* enum hwa_cet */ + __le16 wEvent; /* Event code */ + u8 bEventContext; /* Context ID */ +} __attribute__((packed)); + + +enum { + UWB_RC_CET_GENERAL = 0, /* General Command/Event type */ + UWB_RC_CET_EX_TYPE_1 = 1, /* Extended Type 1 Command/Event type */ +}; + +/* Commands to the radio controller */ +enum uwb_rc_cmd { + UWB_RC_CMD_CHANNEL_CHANGE = 16, + UWB_RC_CMD_DEV_ADDR_MGMT = 17, /* Device Address Management */ + UWB_RC_CMD_GET_IE = 18, /* GET Information Elements */ + UWB_RC_CMD_RESET = 19, + UWB_RC_CMD_SCAN = 20, /* Scan management */ + UWB_RC_CMD_SET_BEACON_FILTER = 21, + UWB_RC_CMD_SET_DRP_IE = 22, /* Dynamic Reservation Protocol IEs */ + UWB_RC_CMD_SET_IE = 23, /* Information Element management */ + UWB_RC_CMD_SET_NOTIFICATION_FILTER = 24, + UWB_RC_CMD_SET_TX_POWER = 25, + UWB_RC_CMD_SLEEP = 26, + UWB_RC_CMD_START_BEACON = 27, + UWB_RC_CMD_STOP_BEACON = 28, + UWB_RC_CMD_BP_MERGE = 29, + UWB_RC_CMD_SEND_COMMAND_FRAME = 30, + UWB_RC_CMD_SET_ASIE_NOTIF = 31, +}; + +/* Notifications from the radio controller */ +enum uwb_rc_evt { + UWB_RC_EVT_IE_RCV = 0, + UWB_RC_EVT_BEACON = 1, + UWB_RC_EVT_BEACON_SIZE = 2, + UWB_RC_EVT_BPOIE_CHANGE = 3, + UWB_RC_EVT_BP_SLOT_CHANGE = 4, + UWB_RC_EVT_BP_SWITCH_IE_RCV = 5, + UWB_RC_EVT_DEV_ADDR_CONFLICT = 6, + UWB_RC_EVT_DRP_AVAIL = 7, + UWB_RC_EVT_DRP = 8, + UWB_RC_EVT_BP_SWITCH_STATUS = 9, + UWB_RC_EVT_CMD_FRAME_RCV = 10, + UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV = 11, + /* Events (command responses) use the same code as the command */ + UWB_RC_EVT_UNKNOWN_CMD_RCV = 65535, +}; + +enum uwb_rc_extended_type_1_cmd { + UWB_RC_SET_DAA_ENERGY_MASK = 32, + UWB_RC_SET_NOTIFICATION_FILTER_EX = 33, +}; + +enum uwb_rc_extended_type_1_evt { + UWB_RC_DAA_ENERGY_DETECTED = 0, +}; + +/* Radio Control Result Code. [WHCI] table 3-3. */ +enum { + UWB_RC_RES_SUCCESS = 0, + UWB_RC_RES_FAIL, + UWB_RC_RES_FAIL_HARDWARE, + UWB_RC_RES_FAIL_NO_SLOTS, + UWB_RC_RES_FAIL_BEACON_TOO_LARGE, + UWB_RC_RES_FAIL_INVALID_PARAMETER, + UWB_RC_RES_FAIL_UNSUPPORTED_PWR_LEVEL, + UWB_RC_RES_FAIL_INVALID_IE_DATA, + UWB_RC_RES_FAIL_BEACON_SIZE_EXCEEDED, + UWB_RC_RES_FAIL_CANCELLED, + UWB_RC_RES_FAIL_INVALID_STATE, + UWB_RC_RES_FAIL_INVALID_SIZE, + UWB_RC_RES_FAIL_ACK_NOT_RECEIVED, + UWB_RC_RES_FAIL_NO_MORE_ASIE_NOTIF, + UWB_RC_RES_FAIL_TIME_OUT = 255, +}; + +/* Confirm event. [WHCI] section 3.1.3.1 etc. */ +struct uwb_rc_evt_confirm { + struct uwb_rceb rceb; + u8 bResultCode; +} __attribute__((packed)); + +/* Device Address Management event. [WHCI] section 3.1.3.2. */ +struct uwb_rc_evt_dev_addr_mgmt { + struct uwb_rceb rceb; + u8 baAddr[6]; + u8 bResultCode; +} __attribute__((packed)); + + +/* Get IE Event. [WHCI] section 3.1.3.3. */ +struct uwb_rc_evt_get_ie { + struct uwb_rceb rceb; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Set DRP IE Event. [WHCI] section 3.1.3.7. */ +struct uwb_rc_evt_set_drp_ie { + struct uwb_rceb rceb; + __le16 wRemainingSpace; + u8 bResultCode; +} __attribute__((packed)); + +/* Set IE Event. [WHCI] section 3.1.3.8. */ +struct uwb_rc_evt_set_ie { + struct uwb_rceb rceb; + __le16 RemainingSpace; + u8 bResultCode; +} __attribute__((packed)); + +/* Scan command. [WHCI] 3.1.3.5. */ +struct uwb_rc_cmd_scan { + struct uwb_rccb rccb; + u8 bChannelNumber; + u8 bScanState; + __le16 wStartTime; +} __attribute__((packed)); + +/* Set DRP IE command. [WHCI] section 3.1.3.7. */ +struct uwb_rc_cmd_set_drp_ie { + struct uwb_rccb rccb; + __le16 wIELength; + struct uwb_ie_drp IEData[]; +} __attribute__((packed)); + +/* Set IE command. [WHCI] section 3.1.3.8. */ +struct uwb_rc_cmd_set_ie { + struct uwb_rccb rccb; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Set DAA Energy Mask event. [WHCI 0.96] section 3.1.3.17. */ +struct uwb_rc_evt_set_daa_energy_mask { + struct uwb_rceb rceb; + __le16 wLength; + u8 result; +} __attribute__((packed)); + +/* Set Notification Filter Extended event. [WHCI 0.96] section 3.1.3.18. */ +struct uwb_rc_evt_set_notification_filter_ex { + struct uwb_rceb rceb; + __le16 wLength; + u8 result; +} __attribute__((packed)); + +/* IE Received notification. [WHCI] section 3.1.4.1. */ +struct uwb_rc_evt_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr SrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* Type of the received beacon. [WHCI] section 3.1.4.2. */ +enum uwb_rc_beacon_type { + UWB_RC_BEACON_TYPE_SCAN = 0, + UWB_RC_BEACON_TYPE_NEIGHBOR, + UWB_RC_BEACON_TYPE_OL_ALIEN, + UWB_RC_BEACON_TYPE_NOL_ALIEN, +}; + +/* Beacon received notification. [WHCI] 3.1.4.2. */ +struct uwb_rc_evt_beacon { + struct uwb_rceb rceb; + u8 bChannelNumber; + u8 bBeaconType; + __le16 wBPSTOffset; + u8 bLQI; + u8 bRSSI; + __le16 wBeaconInfoLength; + u8 BeaconInfo[]; +} __attribute__((packed)); + + +/* Beacon Size Change notification. [WHCI] section 3.1.4.3 */ +struct uwb_rc_evt_beacon_size { + struct uwb_rceb rceb; + __le16 wNewBeaconSize; +} __attribute__((packed)); + + +/* BPOIE Change notification. [WHCI] section 3.1.4.4. */ +struct uwb_rc_evt_bpoie_change { + struct uwb_rceb rceb; + __le16 wBPOIELength; + u8 BPOIE[]; +} __attribute__((packed)); + + +/* Beacon Slot Change notification. [WHCI] section 3.1.4.5. */ +struct uwb_rc_evt_bp_slot_change { + struct uwb_rceb rceb; + u8 slot_info; +} __attribute__((packed)); + +static inline int uwb_rc_evt_bp_slot_change_slot_num( + const struct uwb_rc_evt_bp_slot_change *evt) +{ + return evt->slot_info & 0x7f; +} + +static inline int uwb_rc_evt_bp_slot_change_no_slot( + const struct uwb_rc_evt_bp_slot_change *evt) +{ + return (evt->slot_info & 0x80) >> 7; +} + +/* BP Switch IE Received notification. [WHCI] section 3.1.4.6. */ +struct uwb_rc_evt_bp_switch_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr wSrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* DevAddr Conflict notification. [WHCI] section 3.1.4.7. */ +struct uwb_rc_evt_dev_addr_conflict { + struct uwb_rceb rceb; +} __attribute__((packed)); + +/* DRP notification. [WHCI] section 3.1.4.9. */ +struct uwb_rc_evt_drp { + struct uwb_rceb rceb; + struct uwb_dev_addr src_addr; + u8 reason; + u8 beacon_slot_number; + __le16 ie_length; + u8 ie_data[]; +} __attribute__((packed)); + +static inline enum uwb_drp_notif_reason uwb_rc_evt_drp_reason(struct uwb_rc_evt_drp *evt) +{ + return evt->reason & 0x0f; +} + + +/* DRP Availability Change notification. [WHCI] section 3.1.4.8. */ +struct uwb_rc_evt_drp_avail { + struct uwb_rceb rceb; + DECLARE_BITMAP(bmp, UWB_NUM_MAS); +} __attribute__((packed)); + +/* BP switch status notification. [WHCI] section 3.1.4.10. */ +struct uwb_rc_evt_bp_switch_status { + struct uwb_rceb rceb; + u8 status; + u8 slot_offset; + __le16 bpst_offset; + u8 move_countdown; +} __attribute__((packed)); + +/* Command Frame Received notification. [WHCI] section 3.1.4.11. */ +struct uwb_rc_evt_cmd_frame_rcv { + struct uwb_rceb rceb; + __le16 receive_time; + struct uwb_dev_addr wSrcAddr; + struct uwb_dev_addr wDstAddr; + __le16 control; + __le16 reserved; + __le16 dataLength; + u8 data[]; +} __attribute__((packed)); + +/* Channel Change IE Received notification. [WHCI] section 3.1.4.12. */ +struct uwb_rc_evt_channel_change_ie_rcv { + struct uwb_rceb rceb; + struct uwb_dev_addr wSrcAddr; + __le16 wIELength; + u8 IEData[]; +} __attribute__((packed)); + +/* DAA Energy Detected notification. [WHCI 0.96] section 3.1.4.14. */ +struct uwb_rc_evt_daa_energy_detected { + struct uwb_rceb rceb; + __le16 wLength; + u8 bandID; + u8 reserved; + u8 toneBmp[16]; +} __attribute__((packed)); + + +/** + * Radio Control Interface Class Descriptor + * + * WUSB 1.0 [8.6.1.2] + */ +struct uwb_rc_control_intf_class_desc { + u8 bLength; + u8 bDescriptorType; + __le16 bcdRCIVersion; +} __attribute__((packed)); + +#endif /* #ifndef __LINUX__UWB_SPEC_H__ */ diff --git a/include/linux/wlp.h b/include/linux/wlp.h new file mode 100644 index 00000000000..033545e145c --- /dev/null +++ b/include/linux/wlp.h @@ -0,0 +1,735 @@ +/* + * WiMedia Logical Link Control Protocol (WLP) + * + * Copyright (C) 2005-2006 Intel Corporation + * Reinette Chatre + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * + * - Does not (yet) include support for WLP control frames + * WLP Draft 0.99 [6.5]. + * + * A visual representation of the data structures. + * + * wssidB wssidB + * ^ ^ + * | | + * wssidA wssidA + * wlp interface { ^ ^ + * ... | | + * ... ... wssid wssid ... + * wlp --- ... | | + * }; neighbors --> neighbA --> neighbB + * ... + * wss + * ... + * eda cache --> neighborA --> neighborB --> neighborC ... + */ + +#ifndef __LINUX__WLP_H_ +#define __LINUX__WLP_H_ + +#include +#include +#include +#include + +/** + * WLP Protocol ID + * WLP Draft 0.99 [6.2] + * + * The MUX header for all WLP frames + */ +#define WLP_PROTOCOL_ID 0x0100 + +/** + * WLP Version + * WLP version placed in the association frames (WLP 0.99 [6.6]) + */ +#define WLP_VERSION 0x10 + +/** + * Bytes needed to print UUID as string + */ +#define WLP_WSS_UUID_STRSIZE 48 + +/** + * Bytes needed to print nonce as string + */ +#define WLP_WSS_NONCE_STRSIZE 48 + + +/** + * Size used for WLP name size + * + * The WSS name is set to 65 bytes, 1 byte larger than the maximum + * allowed by the WLP spec. This is to have a null terminated string + * for display to the user. A maximum of 64 bytes will still be used + * when placing the WSS name field in association frames. + */ +#define WLP_WSS_NAME_SIZE 65 + +/** + * Number of bytes added by WLP to data frame + * + * A data frame transmitted from a host will be placed in a Standard or + * Abbreviated WLP frame. These have an extra 4 bytes of header (struct + * wlp_frame_std_abbrv_hdr). + * When the stack sends this data frame for transmission it needs to ensure + * there is enough headroom for this header. + */ +#define WLP_DATA_HLEN 4 + +/** + * State of device regarding WLP Service Set + * + * WLP_WSS_STATE_NONE: the host does not participate in any WSS + * WLP_WSS_STATE_PART_ENROLLED: used as part of the enrollment sequence + * ("Partial Enroll"). This state is used to + * indicate the first part of enrollment that is + * unsecure. If the WSS is unsecure then the + * state will promptly go to WLP_WSS_STATE_ENROLLED, + * if the WSS is not secure then the enrollment + * procedure is a few more steps before we are + * enrolled. + * WLP_WSS_STATE_ENROLLED: the host is enrolled in a WSS + * WLP_WSS_STATE_ACTIVE: WSS is activated + * WLP_WSS_STATE_CONNECTED: host is connected to neighbor in WSS + * + */ +enum wlp_wss_state { + WLP_WSS_STATE_NONE = 0, + WLP_WSS_STATE_PART_ENROLLED, + WLP_WSS_STATE_ENROLLED, + WLP_WSS_STATE_ACTIVE, + WLP_WSS_STATE_CONNECTED, +}; + +/** + * WSS Secure status + * WLP 0.99 Table 6 + * + * Set to one if the WSS is secure, zero if it is not secure + */ +enum wlp_wss_sec_status { + WLP_WSS_UNSECURE = 0, + WLP_WSS_SECURE, +}; + +/** + * WLP frame type + * WLP Draft 0.99 [6.2 Table 1] + */ +enum wlp_frame_type { + WLP_FRAME_STANDARD = 0, + WLP_FRAME_ABBREVIATED, + WLP_FRAME_CONTROL, + WLP_FRAME_ASSOCIATION, +}; + +/** + * WLP Association Message Type + * WLP Draft 0.99 [6.6.1.2 Table 8] + */ +enum wlp_assoc_type { + WLP_ASSOC_D1 = 2, + WLP_ASSOC_D2 = 3, + WLP_ASSOC_M1 = 4, + WLP_ASSOC_M2 = 5, + WLP_ASSOC_M3 = 7, + WLP_ASSOC_M4 = 8, + WLP_ASSOC_M5 = 9, + WLP_ASSOC_M6 = 10, + WLP_ASSOC_M7 = 11, + WLP_ASSOC_M8 = 12, + WLP_ASSOC_F0 = 14, + WLP_ASSOC_E1 = 32, + WLP_ASSOC_E2 = 33, + WLP_ASSOC_C1 = 34, + WLP_ASSOC_C2 = 35, + WLP_ASSOC_C3 = 36, + WLP_ASSOC_C4 = 37, +}; + +/** + * WLP Attribute Type + * WLP Draft 0.99 [6.6.1 Table 6] + */ +enum wlp_attr_type { + WLP_ATTR_AUTH = 0x1005, /* Authenticator */ + WLP_ATTR_DEV_NAME = 0x1011, /* Device Name */ + WLP_ATTR_DEV_PWD_ID = 0x1012, /* Device Password ID */ + WLP_ATTR_E_HASH1 = 0x1014, /* E-Hash1 */ + WLP_ATTR_E_HASH2 = 0x1015, /* E-Hash2 */ + WLP_ATTR_E_SNONCE1 = 0x1016, /* E-SNonce1 */ + WLP_ATTR_E_SNONCE2 = 0x1017, /* E-SNonce2 */ + WLP_ATTR_ENCR_SET = 0x1018, /* Encrypted Settings */ + WLP_ATTR_ENRL_NONCE = 0x101A, /* Enrollee Nonce */ + WLP_ATTR_KEYWRAP_AUTH = 0x101E, /* Key Wrap Authenticator */ + WLP_ATTR_MANUF = 0x1021, /* Manufacturer */ + WLP_ATTR_MSG_TYPE = 0x1022, /* Message Type */ + WLP_ATTR_MODEL_NAME = 0x1023, /* Model Name */ + WLP_ATTR_MODEL_NR = 0x1024, /* Model Number */ + WLP_ATTR_PUB_KEY = 0x1032, /* Public Key */ + WLP_ATTR_REG_NONCE = 0x1039, /* Registrar Nonce */ + WLP_ATTR_R_HASH1 = 0x103D, /* R-Hash1 */ + WLP_ATTR_R_HASH2 = 0x103E, /* R-Hash2 */ + WLP_ATTR_R_SNONCE1 = 0x103F, /* R-SNonce1 */ + WLP_ATTR_R_SNONCE2 = 0x1040, /* R-SNonce2 */ + WLP_ATTR_SERIAL = 0x1042, /* Serial number */ + WLP_ATTR_UUID_E = 0x1047, /* UUID-E */ + WLP_ATTR_UUID_R = 0x1048, /* UUID-R */ + WLP_ATTR_PRI_DEV_TYPE = 0x1054, /* Primary Device Type */ + WLP_ATTR_SEC_DEV_TYPE = 0x1055, /* Secondary Device Type */ + WLP_ATTR_PORT_DEV = 0x1056, /* Portable Device */ + WLP_ATTR_APP_EXT = 0x1058, /* Application Extension */ + WLP_ATTR_WLP_VER = 0x2000, /* WLP Version */ + WLP_ATTR_WSSID = 0x2001, /* WSSID */ + WLP_ATTR_WSS_NAME = 0x2002, /* WSS Name */ + WLP_ATTR_WSS_SEC_STAT = 0x2003, /* WSS Secure Status */ + WLP_ATTR_WSS_BCAST = 0x2004, /* WSS Broadcast Address */ + WLP_ATTR_WSS_M_KEY = 0x2005, /* WSS Master Key */ + WLP_ATTR_ACC_ENRL = 0x2006, /* Accepting Enrollment */ + WLP_ATTR_WSS_INFO = 0x2007, /* WSS Information */ + WLP_ATTR_WSS_SEL_MTHD = 0x2008, /* WSS Selection Method */ + WLP_ATTR_ASSC_MTHD_LIST = 0x2009, /* Association Methods List */ + WLP_ATTR_SEL_ASSC_MTHD = 0x200A, /* Selected Association Method */ + WLP_ATTR_ENRL_HASH_COMM = 0x200B, /* Enrollee Hash Commitment */ + WLP_ATTR_WSS_TAG = 0x200C, /* WSS Tag */ + WLP_ATTR_WSS_VIRT = 0x200D, /* WSS Virtual EUI-48 */ + WLP_ATTR_WLP_ASSC_ERR = 0x200E, /* WLP Association Error */ + WLP_ATTR_VNDR_EXT = 0x200F, /* Vendor Extension */ +}; + +/** + * WLP Category ID of primary/secondary device + * WLP Draft 0.99 [6.6.1.8 Table 12] + */ +enum wlp_dev_category_id { + WLP_DEV_CAT_COMPUTER = 1, + WLP_DEV_CAT_INPUT, + WLP_DEV_CAT_PRINT_SCAN_FAX_COPIER, + WLP_DEV_CAT_CAMERA, + WLP_DEV_CAT_STORAGE, + WLP_DEV_CAT_INFRASTRUCTURE, + WLP_DEV_CAT_DISPLAY, + WLP_DEV_CAT_MULTIM, + WLP_DEV_CAT_GAMING, + WLP_DEV_CAT_TELEPHONE, + WLP_DEV_CAT_OTHER = 65535, +}; + +/** + * WLP WSS selection method + * WLP Draft 0.99 [6.6.1.6 Table 10] + */ +enum wlp_wss_sel_mthd { + WLP_WSS_ENRL_SELECT = 1, /* Enrollee selects */ + WLP_WSS_REG_SELECT, /* Registrar selects */ +}; + +/** + * WLP association error values + * WLP Draft 0.99 [6.6.1.5 Table 9] + */ +enum wlp_assc_error { + WLP_ASSOC_ERROR_NONE, + WLP_ASSOC_ERROR_AUTH, /* Authenticator Failure */ + WLP_ASSOC_ERROR_ROGUE, /* Rogue activity suspected */ + WLP_ASSOC_ERROR_BUSY, /* Device busy */ + WLP_ASSOC_ERROR_LOCK, /* Setup Locked */ + WLP_ASSOC_ERROR_NOT_READY, /* Registrar not ready */ + WLP_ASSOC_ERROR_INV, /* Invalid WSS selection */ + WLP_ASSOC_ERROR_MSG_TIME, /* Message timeout */ + WLP_ASSOC_ERROR_ENR_TIME, /* Enrollment session timeout */ + WLP_ASSOC_ERROR_PW, /* Device password invalid */ + WLP_ASSOC_ERROR_VER, /* Unsupported version */ + WLP_ASSOC_ERROR_INT, /* Internal error */ + WLP_ASSOC_ERROR_UNDEF, /* Undefined error */ + WLP_ASSOC_ERROR_NUM, /* Numeric comparison failure */ + WLP_ASSOC_ERROR_WAIT, /* Waiting for user input */ +}; + +/** + * WLP Parameters + * WLP 0.99 [7.7] + */ +enum wlp_parameters { + WLP_PER_MSG_TIMEOUT = 15, /* Seconds to wait for response to + association message. */ +}; + +/** + * WLP IE + * + * The WLP IE should be included in beacons by all devices. + * + * The driver can set only a few of the fields in this information element, + * most fields are managed by the device self. When the driver needs to set + * a field it will only provide values for the fields of interest, the rest + * will be filled with zeroes. The fields of interest are: + * + * Element ID + * Length + * Capabilities (only to include WSSID Hash list length) + * WSSID Hash List fields + * + * WLP 0.99 [6.7] + * + * Only the fields that will be used are detailed in this structure, rest + * are not detailed or marked as "notused". + */ +struct wlp_ie { + struct uwb_ie_hdr hdr; + __le16 capabilities; + __le16 cycle_param; + __le16 acw_anchor_addr; + u8 wssid_hash_list[]; +} __attribute__((packed)); + +static inline int wlp_ie_hash_length(struct wlp_ie *ie) +{ + return (le16_to_cpu(ie->capabilities) >> 12) & 0xf; +} + +static inline void wlp_ie_set_hash_length(struct wlp_ie *ie, int hash_length) +{ + u16 caps = le16_to_cpu(ie->capabilities); + caps = (caps & ~(0xf << 12)) | (hash_length << 12); + ie->capabilities = cpu_to_le16(caps); +} + +/** + * WLP nonce + * WLP Draft 0.99 [6.6.1 Table 6] + * + * A 128-bit random number often used (E-SNonce1, E-SNonce2, Enrollee + * Nonce, Registrar Nonce, R-SNonce1, R-SNonce2). It is passed to HW so + * it is packed. + */ +struct wlp_nonce { + u8 data[16]; +} __attribute__((packed)); + +/** + * WLP UUID + * WLP Draft 0.99 [6.6.1 Table 6] + * + * Universally Unique Identifier (UUID) encoded as an octet string in the + * order the octets are shown in string representation in RFC4122. A UUID + * is often used (UUID-E, UUID-R, WSSID). It is passed to HW so it is packed. + */ +struct wlp_uuid { + u8 data[16]; +} __attribute__((packed)); + + +/** + * Primary and secondary device type attributes + * WLP Draft 0.99 [6.6.1.8] + */ +struct wlp_dev_type { + enum wlp_dev_category_id category:16; + u8 OUI[3]; + u8 OUIsubdiv; + __le16 subID; +} __attribute__((packed)); + +/** + * WLP frame header + * WLP Draft 0.99 [6.2] + */ +struct wlp_frame_hdr { + __le16 mux_hdr; /* WLP_PROTOCOL_ID */ + enum wlp_frame_type type:8; +} __attribute__((packed)); + +/** + * WLP attribute field header + * WLP Draft 0.99 [6.6.1] + * + * Header of each attribute found in an association frame + */ +struct wlp_attr_hdr { + __le16 type; + __le16 length; +} __attribute__((packed)); + +/** + * Device information commonly used together + * + * Each of these device information elements has a specified range in which it + * should fit (WLP 0.99 [Table 6]). This range provided in the spec does not + * include the termination null '\0' character (when used in the + * association protocol the attribute fields are accompanied + * with a "length" field so the full range from the spec can be used for + * the value). We thus allocate an extra byte to be able to store a string + * of max length with a terminating '\0'. + */ +struct wlp_device_info { + char name[33]; + char model_name[33]; + char manufacturer[65]; + char model_nr[33]; + char serial[33]; + struct wlp_dev_type prim_dev_type; +}; + +/** + * Macros for the WLP attributes + * + * There are quite a few attributes (total is 43). The attribute layout can be + * in one of three categories: one value, an array, an enum forced to 8 bits. + * These macros help with their definitions. + */ +#define wlp_attr(type, name) \ +struct wlp_attr_##name { \ + struct wlp_attr_hdr hdr; \ + type name; \ +} __attribute__((packed)); + +#define wlp_attr_array(type, name) \ +struct wlp_attr_##name { \ + struct wlp_attr_hdr hdr; \ + type name[]; \ +} __attribute__((packed)); + +/** + * WLP association attribute fields + * WLP Draft 0.99 [6.6.1 Table 6] + * + * Attributes appear in same order as the Table in the spec + * FIXME Does not define all attributes yet + */ + +/* Device name: Friendly name of sending device */ +wlp_attr_array(u8, dev_name) + +/* Enrollee Nonce: Random number generated by enrollee for an enrollment + * session */ +wlp_attr(struct wlp_nonce, enonce) + +/* Manufacturer name: Name of manufacturer of the sending device */ +wlp_attr_array(u8, manufacturer) + +/* WLP Message Type */ +wlp_attr(u8, msg_type) + +/* WLP Model name: Model name of sending device */ +wlp_attr_array(u8, model_name) + +/* WLP Model number: Model number of sending device */ +wlp_attr_array(u8, model_nr) + +/* Registrar Nonce: Random number generated by registrar for an enrollment + * session */ +wlp_attr(struct wlp_nonce, rnonce) + +/* Serial number of device */ +wlp_attr_array(u8, serial) + +/* UUID of enrollee */ +wlp_attr(struct wlp_uuid, uuid_e) + +/* UUID of registrar */ +wlp_attr(struct wlp_uuid, uuid_r) + +/* WLP Primary device type */ +wlp_attr(struct wlp_dev_type, prim_dev_type) + +/* WLP Secondary device type */ +wlp_attr(struct wlp_dev_type, sec_dev_type) + +/* WLP protocol version */ +wlp_attr(u8, version) + +/* WLP service set identifier */ +wlp_attr(struct wlp_uuid, wssid) + +/* WLP WSS name */ +wlp_attr_array(u8, wss_name) + +/* WLP WSS Secure Status */ +wlp_attr(u8, wss_sec_status) + +/* WSS Broadcast Address */ +wlp_attr(struct uwb_mac_addr, wss_bcast) + +/* WLP Accepting Enrollment */ +wlp_attr(u8, accept_enrl) + +/** + * WSS information attributes + * WLP Draft 0.99 [6.6.3 Table 15] + */ +struct wlp_wss_info { + struct wlp_attr_wssid wssid; + struct wlp_attr_wss_name name; + struct wlp_attr_accept_enrl accept; + struct wlp_attr_wss_sec_status sec_stat; + struct wlp_attr_wss_bcast bcast; +} __attribute__((packed)); + +/* WLP WSS Information */ +wlp_attr_array(struct wlp_wss_info, wss_info) + +/* WLP WSS Selection method */ +wlp_attr(u8, wss_sel_mthd) + +/* WLP WSS tag */ +wlp_attr(u8, wss_tag) + +/* WSS Virtual Address */ +wlp_attr(struct uwb_mac_addr, wss_virt) + +/* WLP association error */ +wlp_attr(u8, wlp_assc_err) + +/** + * WLP standard and abbreviated frames + * + * WLP Draft 0.99 [6.3] and [6.4] + * + * The difference between the WLP standard frame and the WLP + * abbreviated frame is that the standard frame includes the src + * and dest addresses from the Ethernet header, the abbreviated frame does + * not. + * The src/dest (as well as the type/length and client data) are already + * defined as part of the Ethernet header, we do not do this here. + * From this perspective the standard and abbreviated frames appear the + * same - they will be treated differently though. + * + * The size of this header is also captured in WLP_DATA_HLEN to enable + * interfaces to prepare their headroom. + */ +struct wlp_frame_std_abbrv_hdr { + struct wlp_frame_hdr hdr; + u8 tag; +} __attribute__((packed)); + +/** + * WLP association frames + * + * WLP Draft 0.99 [6.6] + */ +struct wlp_frame_assoc { + struct wlp_frame_hdr hdr; + enum wlp_assoc_type type:8; + struct wlp_attr_version version; + struct wlp_attr_msg_type msg_type; + u8 attr[]; +} __attribute__((packed)); + +/* Ethernet to dev address mapping */ +struct wlp_eda { + spinlock_t lock; + struct list_head cache; /* Eth<->Dev Addr cache */ +}; + +/** + * WSS information temporary storage + * + * This information is only stored temporarily during discovery. It should + * not be stored unless the device is enrolled in the advertised WSS. This + * is done mainly because we follow the letter of the spec in this regard. + * See WLP 0.99 [7.2.3]. + * When the device does become enrolled in a WSS the WSS information will + * be stored as part of the more comprehensive struct wlp_wss. + */ +struct wlp_wss_tmp_info { + char name[WLP_WSS_NAME_SIZE]; + u8 accept_enroll; + u8 sec_status; + struct uwb_mac_addr bcast; +}; + +struct wlp_wssid_e { + struct list_head node; + struct wlp_uuid wssid; + struct wlp_wss_tmp_info *info; +}; + +/** + * A cache entry of WLP neighborhood + * + * @node: head of list is wlp->neighbors + * @wssid: list of wssids of this neighbor, element is wlp_wssid_e + * @info: temporary storage for information learned during discovery. This + * storage is used together with the wssid_e temporary storage + * during discovery. + */ +struct wlp_neighbor_e { + struct list_head node; + struct wlp_uuid uuid; + struct uwb_dev *uwb_dev; + struct list_head wssid; /* Elements are wlp_wssid_e */ + struct wlp_device_info *info; +}; + +struct wlp; +/** + * Information for an association session in progress. + * + * @exp_message: The type of the expected message. Both this message and a + * F0 message (which can be sent in response to any + * association frame) will be accepted as a valid message for + * this session. + * @cb: The function that will be called upon receipt of this + * message. + * @cb_priv: Private data of callback + * @data: Data used in association process (always a sk_buff?) + * @neighbor: Address of neighbor with which association session is in + * progress. + */ +struct wlp_session { + enum wlp_assoc_type exp_message; + void (*cb)(struct wlp *); + void *cb_priv; + void *data; + struct uwb_dev_addr neighbor_addr; +}; + +/** + * WLP Service Set + * + * @mutex: used to protect entire WSS structure. + * + * @name: The WSS name is set to 65 bytes, 1 byte larger than the maximum + * allowed by the WLP spec. This is to have a null terminated string + * for display to the user. A maximum of 64 bytes will still be used + * when placing the WSS name field in association frames. + * + * @accept_enroll: Accepting enrollment: Set to one if registrar is + * accepting enrollment in WSS, or zero otherwise. + * + * Global and local information for each WSS in which we are enrolled. + * WLP 0.99 Section 7.2.1 and Section 7.2.2 + */ +struct wlp_wss { + struct mutex mutex; + struct kobject kobj; + /* Global properties. */ + struct wlp_uuid wssid; + u8 hash; + char name[WLP_WSS_NAME_SIZE]; + struct uwb_mac_addr bcast; + u8 secure_status:1; + u8 master_key[16]; + /* Local properties. */ + u8 tag; + struct uwb_mac_addr virtual_addr; + /* Extra */ + u8 accept_enroll:1; + enum wlp_wss_state state; +}; + +/** + * WLP main structure + * @mutex: protect changes to WLP structure. We only allow changes to the + * uuid, so currently this mutex only protects this field. + */ +struct wlp { + struct mutex mutex; + struct uwb_rc *rc; /* UWB radio controller */ + struct uwb_pal pal; + struct wlp_eda eda; + struct wlp_uuid uuid; + struct wlp_session *session; + struct wlp_wss wss; + struct mutex nbmutex; /* Neighbor mutex protects neighbors list */ + struct list_head neighbors; /* Elements are wlp_neighbor_e */ + struct uwb_notifs_handler uwb_notifs_handler; + struct wlp_device_info *dev_info; + void (*fill_device_info)(struct wlp *wlp, struct wlp_device_info *info); + int (*xmit_frame)(struct wlp *, struct sk_buff *, + struct uwb_dev_addr *); + void (*stop_queue)(struct wlp *); + void (*start_queue)(struct wlp *); +}; + +/* sysfs */ + + +struct wlp_wss_attribute { + struct attribute attr; + ssize_t (*show)(struct wlp_wss *wss, char *buf); + ssize_t (*store)(struct wlp_wss *wss, const char *buf, size_t count); +}; + +#define WSS_ATTR(_name, _mode, _show, _store) \ +static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \ + _show, _store) + +extern int wlp_setup(struct wlp *, struct uwb_rc *); +extern void wlp_remove(struct wlp *); +extern ssize_t wlp_neighborhood_show(struct wlp *, char *); +extern int wlp_wss_setup(struct net_device *, struct wlp_wss *); +extern void wlp_wss_remove(struct wlp_wss *); +extern ssize_t wlp_wss_activate_show(struct wlp_wss *, char *); +extern ssize_t wlp_wss_activate_store(struct wlp_wss *, const char *, size_t); +extern ssize_t wlp_eda_show(struct wlp *, char *); +extern ssize_t wlp_eda_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_uuid_show(struct wlp *, char *); +extern ssize_t wlp_uuid_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_name_show(struct wlp *, char *); +extern ssize_t wlp_dev_name_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_manufacturer_show(struct wlp *, char *); +extern ssize_t wlp_dev_manufacturer_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_model_name_show(struct wlp *, char *); +extern ssize_t wlp_dev_model_name_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_model_nr_show(struct wlp *, char *); +extern ssize_t wlp_dev_model_nr_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_serial_show(struct wlp *, char *); +extern ssize_t wlp_dev_serial_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_prim_category_show(struct wlp *, char *); +extern ssize_t wlp_dev_prim_category_store(struct wlp *, const char *, + size_t); +extern ssize_t wlp_dev_prim_OUI_show(struct wlp *, char *); +extern ssize_t wlp_dev_prim_OUI_store(struct wlp *, const char *, size_t); +extern ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *, char *); +extern ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *, const char *, + size_t); +extern ssize_t wlp_dev_prim_subcat_show(struct wlp *, char *); +extern ssize_t wlp_dev_prim_subcat_store(struct wlp *, const char *, + size_t); +extern int wlp_receive_frame(struct device *, struct wlp *, struct sk_buff *, + struct uwb_dev_addr *); +extern int wlp_prepare_tx_frame(struct device *, struct wlp *, + struct sk_buff *, struct uwb_dev_addr *); +void wlp_reset_all(struct wlp *wlp); + +/** + * Initialize WSS + */ +static inline +void wlp_wss_init(struct wlp_wss *wss) +{ + mutex_init(&wss->mutex); +} + +static inline +void wlp_init(struct wlp *wlp) +{ + INIT_LIST_HEAD(&wlp->neighbors); + mutex_init(&wlp->mutex); + mutex_init(&wlp->nbmutex); + wlp_wss_init(&wlp->wss); +} + + +#endif /* #ifndef __LINUX__WLP_H_ */ -- cgit v1.2.3 From da389eac31be24556a71dd59ea6539ae4cba5c15 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 17 Sep 2008 16:34:12 +0100 Subject: uwb: add the umc bus The UMC bus is used for the capabilities exposed by a UWB Multi-interface Controller as described in the WHCI specification. Signed-off-by: David Vrabel --- include/linux/uwb/umc.h | 194 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 include/linux/uwb/umc.h (limited to 'include/linux') diff --git a/include/linux/uwb/umc.h b/include/linux/uwb/umc.h new file mode 100644 index 00000000000..36a39e34f8d --- /dev/null +++ b/include/linux/uwb/umc.h @@ -0,0 +1,194 @@ +/* + * UWB Multi-interface Controller support. + * + * Copyright (C) 2007 Cambridge Silicon Radio Ltd. + * + * This file is released under the GPLv2 + * + * UMC (UWB Multi-interface Controller) capabilities (e.g., radio + * controller, host controller) are presented as devices on the "umc" + * bus. + * + * The radio controller is not strictly a UMC capability but it's + * useful to present it as such. + * + * References: + * + * [WHCI] Wireless Host Controller Interface Specification for + * Certified Wireless Universal Serial Bus, revision 0.95. + * + * How this works is kind of convoluted but simple. The whci.ko driver + * loads when WHCI devices are detected. These WHCI devices expose + * many devices in the same PCI function (they couldn't have reused + * functions, no), so for each PCI function that exposes these many + * devices, whci ceates a umc_dev [whci_probe() -> whci_add_cap()] + * with umc_device_create() and adds it to the bus with + * umc_device_register(). + * + * umc_device_register() calls device_register() which will push the + * bus management code to load your UMC driver's somehting_probe() + * that you have registered for that capability code. + * + * Now when the WHCI device is removed, whci_remove() will go over + * each umc_dev assigned to each of the PCI function's capabilities + * and through whci_del_cap() call umc_device_unregister() each + * created umc_dev. Of course, if you are bound to the device, your + * driver's something_remove() will be called. + */ + +#ifndef _LINUX_UWB_UMC_H_ +#define _LINUX_UWB_UMC_H_ + +#include +#include + +/* + * UMC capability IDs. + * + * 0x00 is reserved so use it for the radio controller device. + * + * [WHCI] table 2-8 + */ +#define UMC_CAP_ID_WHCI_RC 0x00 /* radio controller */ +#define UMC_CAP_ID_WHCI_WUSB_HC 0x01 /* WUSB host controller */ + +/** + * struct umc_dev - UMC capability device + * + * @version: version of the specification this capability conforms to. + * @cap_id: capability ID. + * @bar: PCI Bar (64 bit) where the resource lies + * @resource: register space resource. + * @irq: interrupt line. + */ +struct umc_dev { + u16 version; + u8 cap_id; + u8 bar; + struct resource resource; + unsigned irq; + struct device dev; +}; + +#define to_umc_dev(d) container_of(d, struct umc_dev, dev) + +/** + * struct umc_driver - UMC capability driver + * @cap_id: supported capability ID. + * @match: driver specific capability matching function. + * @match_data: driver specific data for match() (e.g., a + * table of pci_device_id's if umc_match_pci_id() is used). + */ +struct umc_driver { + char *name; + u8 cap_id; + int (*match)(struct umc_driver *, struct umc_dev *); + const void *match_data; + + int (*probe)(struct umc_dev *); + void (*remove)(struct umc_dev *); + int (*suspend)(struct umc_dev *, pm_message_t state); + int (*resume)(struct umc_dev *); + + struct device_driver driver; +}; + +#define to_umc_driver(d) container_of(d, struct umc_driver, driver) + +extern struct bus_type umc_bus_type; + +struct umc_dev *umc_device_create(struct device *parent, int n); +int __must_check umc_device_register(struct umc_dev *umc); +void umc_device_unregister(struct umc_dev *umc); + +int __must_check __umc_driver_register(struct umc_driver *umc_drv, + struct module *mod, + const char *mod_name); + +/** + * umc_driver_register - register a UMC capabiltity driver. + * @umc_drv: pointer to the driver. + */ +static inline int __must_check umc_driver_register(struct umc_driver *umc_drv) +{ + return __umc_driver_register(umc_drv, THIS_MODULE, KBUILD_MODNAME); +} +void umc_driver_unregister(struct umc_driver *umc_drv); + +/* + * Utility function you can use to match (umc_driver->match) against a + * null-terminated array of 'struct pci_device_id' in + * umc_driver->match_data. + */ +int umc_match_pci_id(struct umc_driver *umc_drv, struct umc_dev *umc); + +/** + * umc_parent_pci_dev - return the UMC's parent PCI device or NULL if none + * @umc_dev: UMC device whose parent PCI device we are looking for + * + * DIRTY!!! DON'T RELY ON THIS + * + * FIXME: This is as dirty as it gets, but we need some way to check + * the correct type of umc_dev->parent (so that for example, we can + * cast to pci_dev). Casting to pci_dev is necesary because at some + * point we need to request resources from the device. Mapping is + * easily over come (ioremap and stuff are bus agnostic), but hooking + * up to some error handlers (such as pci error handlers) might need + * this. + * + * THIS might (probably will) be removed in the future, so don't count + * on it. + */ +static inline struct pci_dev *umc_parent_pci_dev(struct umc_dev *umc_dev) +{ + struct pci_dev *pci_dev = NULL; + if (umc_dev->dev.parent->bus == &pci_bus_type) + pci_dev = to_pci_dev(umc_dev->dev.parent); + return pci_dev; +} + +/** + * umc_dev_get() - reference a UMC device. + * @umc_dev: Pointer to UMC device. + * + * NOTE: we are assuming in this whole scheme that the parent device + * is referenced at _probe() time and unreferenced at _remove() + * time by the parent's subsystem. + */ +static inline struct umc_dev *umc_dev_get(struct umc_dev *umc_dev) +{ + get_device(&umc_dev->dev); + return umc_dev; +} + +/** + * umc_dev_put() - unreference a UMC device. + * @umc_dev: Pointer to UMC device. + */ +static inline void umc_dev_put(struct umc_dev *umc_dev) +{ + put_device(&umc_dev->dev); +} + +/** + * umc_set_drvdata - set UMC device's driver data. + * @umc_dev: Pointer to UMC device. + * @data: Data to set. + */ +static inline void umc_set_drvdata(struct umc_dev *umc_dev, void *data) +{ + dev_set_drvdata(&umc_dev->dev, data); +} + +/** + * umc_get_drvdata - recover UMC device's driver data. + * @umc_dev: Pointer to UMC device. + */ +static inline void *umc_get_drvdata(struct umc_dev *umc_dev) +{ + return dev_get_drvdata(&umc_dev->dev); +} + +int umc_controller_reset(struct umc_dev *umc); + +#endif /* #ifndef _LINUX_UWB_UMC_H_ */ -- cgit v1.2.3 From 8f1b678ab900c2bda1620dfb6e1f1f02604fc3a2 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 17 Sep 2008 16:34:13 +0100 Subject: uwb: add the driver to enumerate WHCI capabilities This enumerates the capabilties of a WHCI device, adding a umc device for each one. Signed-off-by: David Vrabel --- include/linux/uwb/whci.h | 117 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 include/linux/uwb/whci.h (limited to 'include/linux') diff --git a/include/linux/uwb/whci.h b/include/linux/uwb/whci.h new file mode 100644 index 00000000000..915ec23042d --- /dev/null +++ b/include/linux/uwb/whci.h @@ -0,0 +1,117 @@ +/* + * Wireless Host Controller Interface for Ultra-Wide-Band and Wireless USB + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * + * References: + * [WHCI] Wireless Host Controller Interface Specification for + * Certified Wireless Universal Serial Bus, revision 0.95. + */ +#ifndef _LINUX_UWB_WHCI_H_ +#define _LINUX_UWB_WHCI_H_ + +#include + +/* + * UWB interface capability registers (offsets from UWBBASE) + * + * [WHCI] section 2.2 + */ +#define UWBCAPINFO 0x00 /* == UWBCAPDATA(0) */ +# define UWBCAPINFO_TO_N_CAPS(c) (((c) >> 0) & 0xFull) +#define UWBCAPDATA(n) (8*(n)) +# define UWBCAPDATA_TO_VERSION(c) (((c) >> 32) & 0xFFFFull) +# define UWBCAPDATA_TO_OFFSET(c) (((c) >> 18) & 0x3FFFull) +# define UWBCAPDATA_TO_BAR(c) (((c) >> 16) & 0x3ull) +# define UWBCAPDATA_TO_SIZE(c) ((((c) >> 8) & 0xFFull) * sizeof(u32)) +# define UWBCAPDATA_TO_CAP_ID(c) (((c) >> 0) & 0xFFull) + +/* Size of the WHCI capability data (including the RC capability) for + a device with n capabilities. */ +#define UWBCAPDATA_SIZE(n) (8 + 8*(n)) + + +/* + * URC registers (offsets from URCBASE) + * + * [WHCI] section 2.3 + */ +#define URCCMD 0x00 +# define URCCMD_RESET (1 << 31) /* UMC Hardware reset */ +# define URCCMD_RS (1 << 30) /* Run/Stop */ +# define URCCMD_EARV (1 << 29) /* Event Address Register Valid */ +# define URCCMD_ACTIVE (1 << 15) /* Command is active */ +# define URCCMD_IWR (1 << 14) /* Interrupt When Ready */ +# define URCCMD_SIZE_MASK 0x00000fff /* Command size mask */ +#define URCSTS 0x04 +# define URCSTS_EPS (1 << 17) /* Event Processing Status */ +# define URCSTS_HALTED (1 << 16) /* RC halted */ +# define URCSTS_HSE (1 << 10) /* Host System Error...fried */ +# define URCSTS_ER (1 << 9) /* Event Ready */ +# define URCSTS_RCI (1 << 8) /* Ready for Command Interrupt */ +# define URCSTS_INT_MASK 0x00000700 /* URC interrupt sources */ +# define URCSTS_ISI 0x000000ff /* Interrupt Source Identification */ +#define URCINTR 0x08 +# define URCINTR_EN_ALL 0x000007ff /* Enable all interrupt sources */ +#define URCCMDADDR 0x10 +#define URCEVTADDR 0x18 +# define URCEVTADDR_OFFSET_MASK 0xfff /* Event pointer offset mask */ + + +/** Write 32 bit @value to little endian register at @addr */ +static inline +void le_writel(u32 value, void __iomem *addr) +{ + iowrite32(value, addr); +} + + +/** Read from 32 bit little endian register at @addr */ +static inline +u32 le_readl(void __iomem *addr) +{ + return ioread32(addr); +} + + +/** Write 64 bit @value to little endian register at @addr */ +static inline +void le_writeq(u64 value, void __iomem *addr) +{ + iowrite32(value, addr); + iowrite32(value >> 32, addr + 4); +} + + +/** Read from 64 bit little endian register at @addr */ +static inline +u64 le_readq(void __iomem *addr) +{ + u64 value; + value = ioread32(addr); + value |= (u64)ioread32(addr + 4) << 32; + return value; +} + +extern int whci_wait_for(struct device *dev, u32 __iomem *reg, + u32 mask, u32 result, + unsigned long max_ms, const char *tag); + +#endif /* #ifndef _LINUX_UWB_WHCI_H_ */ -- cgit v1.2.3 From c7f736484f8ecde4dc1bc8459179c4d65f2ccbe4 Mon Sep 17 00:00:00 2001 From: Inaky Perez-Gonzalez Date: Wed, 17 Sep 2008 16:34:22 +0100 Subject: wusb: add the Wireless USB include files. Common header files derived from the WUSB 1.0 specification. Signed-off-by: David Vrabel --- include/linux/usb/wusb-wa.h | 271 +++++++++++++++++++++++++++++++ include/linux/usb/wusb.h | 376 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 647 insertions(+) create mode 100644 include/linux/usb/wusb-wa.h create mode 100644 include/linux/usb/wusb.h (limited to 'include/linux') diff --git a/include/linux/usb/wusb-wa.h b/include/linux/usb/wusb-wa.h new file mode 100644 index 00000000000..a102561e702 --- /dev/null +++ b/include/linux/usb/wusb-wa.h @@ -0,0 +1,271 @@ +/* + * Wireless USB Wire Adapter constants and structures. + * + * Copyright (C) 2005-2006 Intel Corporation. + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + * + * References: + * [WUSB] Wireless Universal Serial Bus Specification, revision 1.0, ch8 + */ +#ifndef __LINUX_USB_WUSB_WA_H +#define __LINUX_USB_WUSB_WA_H + +/** + * Radio Command Request for the Radio Control Interface + * + * Radio Control Interface command and event codes are the same as + * WHCI, and listed in include/linux/uwb.h:UWB_RC_{CMD,EVT}_* + */ +enum { + WA_EXEC_RC_CMD = 40, /* Radio Control command Request */ +}; + +/* Wireless Adapter Requests ([WUSB] table 8-51) */ +enum { + WUSB_REQ_ADD_MMC_IE = 20, + WUSB_REQ_REMOVE_MMC_IE = 21, + WUSB_REQ_SET_NUM_DNTS = 22, + WUSB_REQ_SET_CLUSTER_ID = 23, + WUSB_REQ_SET_DEV_INFO = 24, + WUSB_REQ_GET_TIME = 25, + WUSB_REQ_SET_STREAM_IDX = 26, + WUSB_REQ_SET_WUSB_MAS = 27, +}; + + +/* Wireless Adapter WUSB Channel Time types ([WUSB] table 8-52) */ +enum { + WUSB_TIME_ADJ = 0, + WUSB_TIME_BPST = 1, + WUSB_TIME_WUSB = 2, +}; + +enum { + WA_ENABLE = 0x01, + WA_RESET = 0x02, + RPIPE_PAUSE = 0x1, +}; + +/* Responses from Get Status request ([WUSB] section 8.3.1.6) */ +enum { + WA_STATUS_ENABLED = 0x01, + WA_STATUS_RESETTING = 0x02 +}; + +enum rpipe_crs { + RPIPE_CRS_CTL = 0x01, + RPIPE_CRS_ISO = 0x02, + RPIPE_CRS_BULK = 0x04, + RPIPE_CRS_INTR = 0x08 +}; + +/** + * RPipe descriptor ([WUSB] section 8.5.2.11) + * + * FIXME: explain rpipes + */ +struct usb_rpipe_descriptor { + u8 bLength; + u8 bDescriptorType; + __le16 wRPipeIndex; + __le16 wRequests; + __le16 wBlocks; /* rw if 0 */ + __le16 wMaxPacketSize; /* rw? */ + u8 bHSHubAddress; /* reserved: 0 */ + u8 bHSHubPort; /* ??? FIXME ??? */ + u8 bSpeed; /* rw: xfer rate 'enum uwb_phy_rate' */ + u8 bDeviceAddress; /* rw: Target device address */ + u8 bEndpointAddress; /* rw: Target EP address */ + u8 bDataSequence; /* ro: Current Data sequence */ + __le32 dwCurrentWindow; /* ro */ + u8 bMaxDataSequence; /* ro?: max supported seq */ + u8 bInterval; /* rw: */ + u8 bOverTheAirInterval; /* rw: */ + u8 bmAttribute; /* ro? */ + u8 bmCharacteristics; /* ro? enum rpipe_attr, supported xsactions */ + u8 bmRetryOptions; /* rw? */ + __le16 wNumTransactionErrors; /* rw */ +} __attribute__ ((packed)); + +/** + * Wire Adapter Notification types ([WUSB] sections 8.4.5 & 8.5.4) + * + * These are the notifications coming on the notification endpoint of + * an HWA and a DWA. + */ +enum wa_notif_type { + DWA_NOTIF_RWAKE = 0x91, + DWA_NOTIF_PORTSTATUS = 0x92, + WA_NOTIF_TRANSFER = 0x93, + HWA_NOTIF_BPST_ADJ = 0x94, + HWA_NOTIF_DN = 0x95, +}; + +/** + * Wire Adapter notification header + * + * Notifications coming from a wire adapter use a common header + * defined in [WUSB] sections 8.4.5 & 8.5.4. + */ +struct wa_notif_hdr { + u8 bLength; + u8 bNotifyType; /* enum wa_notif_type */ +} __attribute__((packed)); + +/** + * HWA DN Received notification [(WUSB] section 8.5.4.2) + * + * The DNData is specified in WUSB1.0[7.6]. For each device + * notification we received, we just need to dispatch it. + * + * @dndata: this is really an array of notifications, but all start + * with the same header. + */ +struct hwa_notif_dn { + struct wa_notif_hdr hdr; + u8 bSourceDeviceAddr; /* from errata 2005/07 */ + u8 bmAttributes; + struct wusb_dn_hdr dndata[]; +} __attribute__((packed)); + +/* [WUSB] section 8.3.3 */ +enum wa_xfer_type { + WA_XFER_TYPE_CTL = 0x80, + WA_XFER_TYPE_BI = 0x81, /* bulk/interrupt */ + WA_XFER_TYPE_ISO = 0x82, + WA_XFER_RESULT = 0x83, + WA_XFER_ABORT = 0x84, +}; + +/* [WUSB] section 8.3.3 */ +struct wa_xfer_hdr { + u8 bLength; /* 0x18 */ + u8 bRequestType; /* 0x80 WA_REQUEST_TYPE_CTL */ + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ + __le32 dwTransferLength; /* Length of data to xfer */ + u8 bTransferSegment; +} __attribute__((packed)); + +struct wa_xfer_ctl { + struct wa_xfer_hdr hdr; + u8 bmAttribute; + __le16 wReserved; + struct usb_ctrlrequest baSetupData; +} __attribute__((packed)); + +struct wa_xfer_bi { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wReserved; +} __attribute__((packed)); + +struct wa_xfer_hwaiso { + struct wa_xfer_hdr hdr; + u8 bReserved; + __le16 wPresentationTime; + __le32 dwNumOfPackets; + /* FIXME: u8 pktdata[]? */ +} __attribute__((packed)); + +/* [WUSB] section 8.3.3.5 */ +struct wa_xfer_abort { + u8 bLength; + u8 bRequestType; + __le16 wRPipe; /* RPipe index */ + __le32 dwTransferID; /* Host-assigned ID */ +} __attribute__((packed)); + +/** + * WA Transfer Complete notification ([WUSB] section 8.3.3.3) + * + */ +struct wa_notif_xfer { + struct wa_notif_hdr hdr; + u8 bEndpoint; + u8 Reserved; +} __attribute__((packed)); + +/** Transfer result basic codes [WUSB] table 8-15 */ +enum { + WA_XFER_STATUS_SUCCESS, + WA_XFER_STATUS_HALTED, + WA_XFER_STATUS_DATA_BUFFER_ERROR, + WA_XFER_STATUS_BABBLE, + WA_XFER_RESERVED, + WA_XFER_STATUS_NOT_FOUND, + WA_XFER_STATUS_INSUFFICIENT_RESOURCE, + WA_XFER_STATUS_TRANSACTION_ERROR, + WA_XFER_STATUS_ABORTED, + WA_XFER_STATUS_RPIPE_NOT_READY, + WA_XFER_INVALID_FORMAT, + WA_XFER_UNEXPECTED_SEGMENT_NUMBER, + WA_XFER_STATUS_RPIPE_TYPE_MISMATCH, +}; + +/** [WUSB] section 8.3.3.4 */ +struct wa_xfer_result { + struct wa_notif_hdr hdr; + __le32 dwTransferID; + __le32 dwTransferLength; + u8 bTransferSegment; + u8 bTransferStatus; + __le32 dwNumOfPackets; +} __attribute__((packed)); + +/** + * Wire Adapter Class Descriptor ([WUSB] section 8.5.2.7). + * + * NOTE: u16 fields are read Little Endian from the hardware. + * + * @bNumPorts is the original max number of devices that the host can + * connect; we might chop this so the stack can handle + * it. In case you need to access it, use wusbhc->ports_max + * if it is a Wireless USB WA. + */ +struct usb_wa_descriptor { + u8 bLength; + u8 bDescriptorType; + u16 bcdWAVersion; + u8 bNumPorts; /* don't use!! */ + u8 bmAttributes; /* Reserved == 0 */ + u16 wNumRPipes; + u16 wRPipeMaxBlock; + u8 bRPipeBlockSize; + u8 bPwrOn2PwrGood; + u8 bNumMMCIEs; + u8 DeviceRemovable; /* FIXME: in DWA this is up to 16 bytes */ +} __attribute__((packed)); + +/** + * HWA Device Information Buffer (WUSB1.0[T8.54]) + */ +struct hwa_dev_info { + u8 bmDeviceAvailability[32]; /* FIXME: ignored for now */ + u8 bDeviceAddress; + __le16 wPHYRates; + u8 bmDeviceAttribute; +} __attribute__((packed)); + +#endif /* #ifndef __LINUX_USB_WUSB_WA_H */ diff --git a/include/linux/usb/wusb.h b/include/linux/usb/wusb.h new file mode 100644 index 00000000000..5f401b644ed --- /dev/null +++ b/include/linux/usb/wusb.h @@ -0,0 +1,376 @@ +/* + * Wireless USB Standard Definitions + * Event Size Tables + * + * Copyright (C) 2005-2006 Intel Corporation + * Inaky Perez-Gonzalez + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * + * FIXME: docs + * FIXME: organize properly, group logically + * + * All the event structures are defined in uwb/spec.h, as they are + * common to the WHCI and WUSB radio control interfaces. + */ + +#ifndef __WUSB_H__ +#define __WUSB_H__ + +#include +#include +#include +#include +#include + +/** + * WUSB Information Element header + * + * I don't know why, they decided to make it different to the MBOA MAC + * IE Header; beats me. + */ +struct wuie_hdr { + u8 bLength; + u8 bIEIdentifier; +} __attribute__((packed)); + +enum { + WUIE_ID_WCTA = 0x80, + WUIE_ID_CONNECTACK, + WUIE_ID_HOST_INFO, + WUIE_ID_CHANGE_ANNOUNCE, + WUIE_ID_DEVICE_DISCONNECT, + WUIE_ID_HOST_DISCONNECT, + WUIE_ID_KEEP_ALIVE = 0x89, + WUIE_ID_ISOCH_DISCARD, + WUIE_ID_RESET_DEVICE, +}; + +/** + * Maximum number of array elements in a WUSB IE. + * + * WUSB1.0[7.5 before table 7-38] says that in WUSB IEs that + * are "arrays" have to limited to 4 elements. So we define it + * like that to ease up and submit only the neeed size. + */ +#define WUIE_ELT_MAX 4 + +/** + * Wrapper for the data that defines a CHID, a CDID or a CK + * + * WUSB defines that CHIDs, CDIDs and CKs are a 16 byte string of + * data. In order to avoid confusion and enforce types, we wrap it. + * + * Make it packed, as we use it in some hw defintions. + */ +struct wusb_ckhdid { + u8 data[16]; +} __attribute__((packed)); + +const static +struct wusb_ckhdid wusb_ckhdid_zero = { .data = { 0 } }; + +#define WUSB_CKHDID_STRSIZE (3 * sizeof(struct wusb_ckhdid) + 1) + +/** + * WUSB IE: Host Information (WUSB1.0[7.5.2]) + * + * Used to provide information about the host to the Wireless USB + * devices in range (CHID can be used as an ASCII string). + */ +struct wuie_host_info { + struct wuie_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CHID; +} __attribute__((packed)); + +/** + * WUSB IE: Connect Ack (WUSB1.0[7.5.1]) + * + * Used to acknowledge device connect requests. See note for + * WUIE_ELT_MAX. + */ +struct wuie_connect_ack { + struct wuie_hdr hdr; + struct { + struct wusb_ckhdid CDID; + u8 bDeviceAddress; /* 0 means unused */ + u8 bReserved; + } blk[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE Host Information Element, Connect Availability + * + * WUSB1.0[7.5.2], bmAttributes description + */ +enum { + WUIE_HI_CAP_RECONNECT = 0, + WUIE_HI_CAP_LIMITED, + WUIE_HI_CAP_RESERVED, + WUIE_HI_CAP_ALL, +}; + +/** + * WUSB IE: Channel Stop (WUSB1.0[7.5.8]) + * + * Tells devices the host is going to stop sending MMCs and will dissapear. + */ +struct wuie_channel_stop { + struct wuie_hdr hdr; + u8 attributes; + u8 timestamp[3]; +} __attribute__((packed)); + +/** + * WUSB IE: Keepalive (WUSB1.0[7.5.9]) + * + * Ask device(s) to send keepalives. + */ +struct wuie_keep_alive { + struct wuie_hdr hdr; + u8 bDeviceAddress[WUIE_ELT_MAX]; +} __attribute__((packed)); + +/** + * WUSB IE: Reset device (WUSB1.0[7.5.11]) + * + * Tell device to reset; in all truth, we can fit 4 CDIDs, but we only + * use it for one at the time... + * + * In any case, this request is a wee bit silly: why don't they target + * by address?? + */ +struct wuie_reset { + struct wuie_hdr hdr; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +/** + * WUSB IE: Disconnect device (WUSB1.0[7.5.11]) + * + * Tell device to disconnect; we can fit 4 addresses, but we only use + * it for one at the time... + */ +struct wuie_disconnect { + struct wuie_hdr hdr; + u8 bDeviceAddress; + u8 padding; +} __attribute__((packed)); + +/** + * WUSB IE: Host disconnect ([WUSB] section 7.5.5) + * + * Tells all connected devices to disconnect. + */ +struct wuie_host_disconnect { + struct wuie_hdr hdr; +} __attribute__((packed)); + +/** + * WUSB Device Notification header (WUSB1.0[7.6]) + */ +struct wusb_dn_hdr { + u8 bType; + u8 notifdata[]; +} __attribute__((packed)); + +/** Device Notification codes (WUSB1.0[Table 7-54]) */ +enum WUSB_DN { + WUSB_DN_CONNECT = 0x01, + WUSB_DN_DISCONNECT = 0x02, + WUSB_DN_EPRDY = 0x03, + WUSB_DN_MASAVAILCHANGED = 0x04, + WUSB_DN_RWAKE = 0x05, + WUSB_DN_SLEEP = 0x06, + WUSB_DN_ALIVE = 0x07, +}; + +/** WUSB Device Notification Connect */ +struct wusb_dn_connect { + struct wusb_dn_hdr hdr; + __le16 attributes; + struct wusb_ckhdid CDID; +} __attribute__((packed)); + +static inline int wusb_dn_connect_prev_dev_addr(const struct wusb_dn_connect *dn) +{ + return le16_to_cpu(dn->attributes) & 0xff; +} + +static inline int wusb_dn_connect_new_connection(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 8) & 0x1; +} + +static inline int wusb_dn_connect_beacon_behavior(const struct wusb_dn_connect *dn) +{ + return (le16_to_cpu(dn->attributes) >> 9) & 0x03; +} + +/** Device is alive (aka: pong) (WUSB1.0[7.6.7]) */ +struct wusb_dn_alive { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/** Device is disconnecting (WUSB1.0[7.6.2]) */ +struct wusb_dn_disconnect { + struct wusb_dn_hdr hdr; +} __attribute__((packed)); + +/* General constants */ +enum { + WUSB_TRUST_TIMEOUT_MS = 4000, /* [WUSB] section 4.15.1 */ +}; + +static inline size_t ckhdid_printf(char *pr_ckhdid, size_t size, + const struct wusb_ckhdid *ckhdid) +{ + return scnprintf(pr_ckhdid, size, + "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx " + "%02hx %02hx %02hx %02hx %02hx %02hx %02hx %02hx", + ckhdid->data[0], ckhdid->data[1], + ckhdid->data[2], ckhdid->data[3], + ckhdid->data[4], ckhdid->data[5], + ckhdid->data[6], ckhdid->data[7], + ckhdid->data[8], ckhdid->data[9], + ckhdid->data[10], ckhdid->data[11], + ckhdid->data[12], ckhdid->data[13], + ckhdid->data[14], ckhdid->data[15]); +} + +/* + * WUSB Crypto stuff (WUSB1.0[6]) + */ + +extern const char *wusb_et_name(u8); + +/** + * WUSB key index WUSB1.0[7.3.2.4], for usage when setting keys for + * the host or the device. + */ +static inline u8 wusb_key_index(int index, int type, int originator) +{ + return (originator << 6) | (type << 4) | index; +} + +#define WUSB_KEY_INDEX_TYPE_PTK 0 /* for HWA only */ +#define WUSB_KEY_INDEX_TYPE_ASSOC 1 +#define WUSB_KEY_INDEX_TYPE_GTK 2 +#define WUSB_KEY_INDEX_ORIGINATOR_HOST 0 +#define WUSB_KEY_INDEX_ORIGINATOR_DEVICE 1 + +/* A CCM Nonce, defined in WUSB1.0[6.4.1] */ +struct aes_ccm_nonce { + u8 sfn[6]; /* Little Endian */ + u8 tkid[3]; /* LE */ + struct uwb_dev_addr dest_addr; + struct uwb_dev_addr src_addr; +} __attribute__((packed)); + +/* A CCM operation label, defined on WUSB1.0[6.5.x] */ +struct aes_ccm_label { + u8 data[14]; +} __attribute__((packed)); + +/* + * Input to the key derivation sequence defined in + * WUSB1.0[6.5.1]. Rest of the data is in the CCM Nonce passed to the + * PRF function. + */ +struct wusb_keydvt_in { + u8 hnonce[16]; + u8 dnonce[16]; +} __attribute__((packed)); + +/* + * Output from the key derivation sequence defined in + * WUSB1.0[6.5.1]. + */ +struct wusb_keydvt_out { + u8 kck[16]; + u8 ptk[16]; +} __attribute__((packed)); + +/* Pseudo Random Function WUSB1.0[6.5] */ +extern int wusb_crypto_init(void); +extern void wusb_crypto_exit(void); +extern ssize_t wusb_prf(void *out, size_t out_size, + const u8 key[16], const struct aes_ccm_nonce *_n, + const struct aes_ccm_label *a, + const void *b, size_t blen, size_t len); + +static inline int wusb_prf_64(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 64); +} + +static inline int wusb_prf_128(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 128); +} + +static inline int wusb_prf_256(void *out, size_t out_size, const u8 key[16], + const struct aes_ccm_nonce *n, + const struct aes_ccm_label *a, + const void *b, size_t blen) +{ + return wusb_prf(out, out_size, key, n, a, b, blen, 256); +} + +/* Key derivation WUSB1.0[6.5.1] */ +static inline int wusb_key_derive(struct wusb_keydvt_out *keydvt_out, + const u8 key[16], + const struct aes_ccm_nonce *n, + const struct wusb_keydvt_in *keydvt_in) +{ + const struct aes_ccm_label a = { .data = "Pair-wise keys" }; + return wusb_prf_256(keydvt_out, sizeof(*keydvt_out), key, n, &a, + keydvt_in, sizeof(*keydvt_in)); +} + +/* + * Out-of-band MIC Generation WUSB1.0[6.5.2] + * + * Compute the MIC over @key, @n and @hs and place it in @mic_out. + * + * @mic_out: Where to place the 8 byte MIC tag + * @key: KCK from the derivation process + * @n: CCM nonce, n->sfn == 0, TKID as established in the + * process. + * @hs: Handshake struct for phase 2 of the 4-way. + * hs->bStatus and hs->bReserved are zero. + * hs->bMessageNumber is 2 (WUSB1.0[7.3.2.5.2] + * hs->dest_addr is the device's USB address padded with 0 + * hs->src_addr is the hosts's UWB device address + * hs->mic is ignored (as we compute that value). + */ +static inline int wusb_oob_mic(u8 mic_out[8], const u8 key[16], + const struct aes_ccm_nonce *n, + const struct usb_handshake *hs) +{ + const struct aes_ccm_label a = { .data = "out-of-bandMIC" }; + return wusb_prf_64(mic_out, 8, key, n, &a, + hs, sizeof(*hs) - sizeof(hs->MIC)); +} + +#endif /* #ifndef __WUSB_H__ */ -- cgit v1.2.3 From b60066c141997ac2e4ef08459b75638ae86ae781 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Wed, 17 Sep 2008 16:34:40 +0100 Subject: uwb: add symlinks in sysfs between radio controllers and PALs Add a facility for PALs to have symlinks to their radio controller (and vice-versa) and make WUSB host controllers use this. Signed-off-by: David Vrabel --- include/linux/uwb.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/uwb.h b/include/linux/uwb.h index 0cd35937e12..f9ccbd9a2ce 100644 --- a/include/linux/uwb.h +++ b/include/linux/uwb.h @@ -361,6 +361,9 @@ struct uwb_rc { /** * struct uwb_pal - a UWB PAL + * @name: descriptive name for this PAL (wushc, wlp, etc.). + * @device: a device for the PAL. Used to link the PAL and the radio + * controller in sysfs. * @new_rsv: called when a peer requests a reservation (may be NULL if * the PAL cannot accept reservation requests). * @@ -379,7 +382,8 @@ struct uwb_rc { */ struct uwb_pal { struct list_head node; - + const char *name; + struct device *device; void (*new_rsv)(struct uwb_rsv *rsv); }; -- cgit v1.2.3 From 6ae19b04ab41a4db0f0c48ec0b78950f6b028823 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 10 Sep 2008 12:06:15 -0400 Subject: Input: ads7846 - introduce .gpio_pendown to get pendown state The GPIO connected to ADS7846 nPENIRQ signal is usually used to get the pendown state as well. Introduce a .gpio_pendown, and use this to decide the pendown state if .get_pendown_state is NULL. Signed-off-by: Eric Miao Signed-off-by: Dmitry Torokhov --- include/linux/spi/ads7846.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index daf744017a3..05eab2f11e6 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h @@ -43,6 +43,9 @@ struct ads7846_platform_data { u16 debounce_tol; /* tolerance used for filtering */ u16 debounce_rep; /* additional consecutive good readings * required after the first two */ + int gpio_pendown; /* the GPIO used to decide the pendown + * state if get_pendown_state == NULL + */ int (*get_pendown_state)(void); int (*filter_init) (struct ads7846_platform_data *pdata, void **filter_data); -- cgit v1.2.3 From 452c1ce218a68b5dbd626397ecfc65ca89dd3cbb Mon Sep 17 00:00:00 2001 From: Chris Snook Date: Sun, 14 Sep 2008 19:56:10 -0500 Subject: atl2: add atl2 driver Driver for Atheros L2 10/100 network device. Includes necessary changes for Kconfig, Makefile, and pci_ids.h. Signed-off-by: Chris Snook Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f1624b39675..90a132ab84a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2213,6 +2213,7 @@ #define PCI_VENDOR_ID_ATTANSIC 0x1969 #define PCI_DEVICE_ID_ATTANSIC_L1 0x1048 +#define PCI_DEVICE_ID_ATTANSIC_L2 0x2048 #define PCI_VENDOR_ID_JMICRON 0x197B #define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 -- cgit v1.2.3 From 01f2e4ead2c51226ed1283ef6a8388ca6f4cff8f Mon Sep 17 00:00:00 2001 From: Scott Feldman Date: Mon, 15 Sep 2008 09:17:11 -0700 Subject: enic: add Cisco 10G Ethernet NIC driver Signed-off-by: Scott Feldman Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 90a132ab84a..6f4276d461c 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1411,6 +1411,8 @@ #define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013 #define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014 +#define PCI_VENDOR_ID_CISCO 0x1137 + #define PCI_VENDOR_ID_ZIATECH 0x1138 #define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 -- cgit v1.2.3 From 4fd5f812c23c7deee6425f4a318e85c317cd1d6c Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 13:08:46 +0200 Subject: phylib: allow incremental scanning of an mii bus This patch splits the bus scanning code in mdiobus_register() off into a separate function, and makes this function available for calling from external code. This allows incrementally scanning an mii bus, e.g. as information about which addresses are 'safe' to scan becomes available. Signed-off-by: Lennert Buytenhek Acked-by: Andy Fleming --- include/linux/phy.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phy.h b/include/linux/phy.h index 7224c4099a2..5f170f5b1a3 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -410,6 +410,8 @@ int phy_start_aneg(struct phy_device *phydev); int mdiobus_register(struct mii_bus *bus); void mdiobus_unregister(struct mii_bus *bus); +struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); + void phy_sanitize_settings(struct phy_device *phydev); int phy_stop_interrupts(struct phy_device *phydev); int phy_enable_interrupts(struct phy_device *phydev); -- cgit v1.2.3 From 07a2c01a0c2a0cb4581a67d50d4f17cb4d2457c4 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 19 Sep 2008 02:02:05 +0900 Subject: convert swiotlb to use dma_get_mask swiotlb can use dma_get_mask() instead of the homegrown function. Signed-off-by: FUJITA Tomonori Cc: tony.luck@intel.com Signed-off-by: Ingo Molnar --- include/linux/dma-mapping.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 0dba7433af1..ba9114ec5d3 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -65,7 +65,7 @@ static inline int is_buffer_dma_capable(u64 mask, dma_addr_t addr, size_t size) static inline u64 dma_get_mask(struct device *dev) { - if (dev->dma_mask && *dev->dma_mask) + if (dev && dev->dma_mask && *dev->dma_mask) return *dev->dma_mask; return DMA_32BIT_MASK; } -- cgit v1.2.3 From 006f582c73f4eda35e06fd323193c3df43fb3459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Sat, 20 Sep 2008 21:20:20 -0700 Subject: tcp: convert retransmit_cnt_hint to seqno MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Main benefit in this is that we can then freely point the retransmit_skb_hint to anywhere we want to because there's no longer need to know what would be the count changes involve, and since this is really used only as a terminator, unnecessary work is one time walk at most, and if some retransmissions are necessary after that point later on, the walk is not full waste of time anyway. Since retransmit_high must be kept valid, all lost markers must ensure that. Now I also have learned how those "holes" in the rexmittable skbs can appear, mtu probe does them. So I removed the misleading comment as well. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 2e2557388e3..d7637c4b284 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -358,7 +358,7 @@ struct tcp_sock { */ int lost_cnt_hint; - int retransmit_cnt_hint; + u32 retransmit_high; /* L-bits may be on up to this seqno */ u32 lost_retrans_low; /* Sent seq after any rxmit (lowest) */ -- cgit v1.2.3 From 0e1c54c2a405494281e0639aacc90db03b50ae77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Sat, 20 Sep 2008 21:24:21 -0700 Subject: tcp: reorganize retransmit code loops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both loops are quite similar, so they can be combined with little effort. As a result, forward_skb_hint becomes obsolete as well. Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index d7637c4b284..76729062829 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -342,7 +342,6 @@ struct tcp_sock { struct sk_buff* lost_skb_hint; struct sk_buff *scoreboard_skb_hint; struct sk_buff *retransmit_skb_hint; - struct sk_buff *forward_skb_hint; struct sk_buff_head out_of_order_queue; /* Out of order segments go here */ -- cgit v1.2.3 From 67fed45930fa31e92c11beb3a3dbf83a1a92a58d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 21 Sep 2008 22:36:24 -0700 Subject: net: Add new interfaces for SKB list light-weight init and splicing. This will be used by subsequent changesets. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index aa80ad9cbc8..027b06170b4 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -660,6 +660,22 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) return list_->qlen; } +/** + * __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head + * @list: queue to initialize + * + * This initializes only the list and queue length aspects of + * an sk_buff_head object. This allows to initialize the list + * aspects of an sk_buff_head without reinitializing things like + * the spinlock. It can also be used for on-stack sk_buff_head + * objects where the spinlock is known to not be used. + */ +static inline void __skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = list->next = (struct sk_buff *)list; + list->qlen = 0; +} + /* * This function creates a split out lock class for each invocation; * this is needed for now since a whole lot of users of the skb-queue @@ -671,8 +687,7 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) static inline void skb_queue_head_init(struct sk_buff_head *list) { spin_lock_init(&list->lock); - list->prev = list->next = (struct sk_buff *)list; - list->qlen = 0; + __skb_queue_head_init(list); } static inline void skb_queue_head_init_class(struct sk_buff_head *list, @@ -699,6 +714,83 @@ static inline void __skb_insert(struct sk_buff *newsk, list->qlen++; } +static inline void __skb_queue_splice(const struct sk_buff_head *list, + struct sk_buff *prev, + struct sk_buff *next) +{ + struct sk_buff *first = list->next; + struct sk_buff *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * skb_queue_splice - join two skb lists, this is designed for stacks + * @list: the new list to add + * @head: the place to add it in the first list + */ +static inline void skb_queue_splice(const struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, (struct sk_buff *) head, head->next); + head->qlen = list->qlen; + } +} + +/** + * skb_queue_splice - join two skb lists and reinitialise the emptied list + * @list: the new list to add + * @head: the place to add it in the first list + * + * The list at @list is reinitialised + */ +static inline void skb_queue_splice_init(struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, (struct sk_buff *) head, head->next); + head->qlen = list->qlen; + __skb_queue_head_init(list); + } +} + +/** + * skb_queue_splice_tail - join two skb lists, each list being a queue + * @list: the new list to add + * @head: the place to add it in the first list + */ +static inline void skb_queue_splice_tail(const struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, head->prev, (struct sk_buff *) head); + head->qlen = list->qlen; + } +} + +/** + * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list + * @list: the new list to add + * @head: the place to add it in the first list + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void skb_queue_splice_tail_init(struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, head->prev, (struct sk_buff *) head); + head->qlen = list->qlen; + __skb_queue_head_init(list); + } +} + /** * __skb_queue_after - queue a buffer at the list head * @list: list to use -- cgit v1.2.3 From 6d80c39f9155e289fe8037a8b6352931ff916ceb Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 22 Sep 2008 07:29:31 +0100 Subject: GFS2: Add UUID to GFS2 sb This patch adds a UUID to the GFS2 sb structure. This field is not actually referenced from kernel space at all, but is added for completeness and due to the userland tools which get their on-disk structure information from the gfs2_ondisk.h header file. Since we have to be backwards compatible, we will assume that any GFS2 sb for which the UUID is all 0 does not have a UUID as such. We should then be (after some userland changes) able to support the -U mount option. This addresses Fedora bugzilla #242689 Signed-off-by: Steven Whitehouse --- include/linux/gfs2_ondisk.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h index c3c19f926e6..14d0df0b574 100644 --- a/include/linux/gfs2_ondisk.h +++ b/include/linux/gfs2_ondisk.h @@ -118,7 +118,11 @@ struct gfs2_sb { char sb_lockproto[GFS2_LOCKNAME_LEN]; char sb_locktable[GFS2_LOCKNAME_LEN]; - /* In gfs1, quota and license dinodes followed */ + + struct gfs2_inum __pad3; /* Was quota inode in gfs1 */ + struct gfs2_inum __pad4; /* Was licence inode in gfs1 */ +#define GFS2_HAS_UUID 1 + __u8 sb_uuid[16]; /* The UUID, maybe 0 for backwards compat */ }; /* -- cgit v1.2.3 From 38783e671399b5405f1fd177d602c400a9577ae6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 22 Sep 2008 01:15:02 -0700 Subject: isdn: isdn_ppp: Use SKB list facilities instead of home-grown implementation. Signed-off-by: David S. Miller --- include/linux/isdn_ppp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/isdn_ppp.h b/include/linux/isdn_ppp.h index 8687a7dc063..4c218ee7587 100644 --- a/include/linux/isdn_ppp.h +++ b/include/linux/isdn_ppp.h @@ -157,7 +157,7 @@ typedef struct { typedef struct { int mp_mrru; /* unused */ - struct sk_buff * frags; /* fragments sl list -- use skb->next */ + struct sk_buff_head frags; /* fragments sl list */ long frames; /* number of frames in the frame list */ unsigned int seq; /* last processed packet seq #: any packets * with smaller seq # will be dropped -- cgit v1.2.3 From d7cfb60c5cf904ecf1e0ae23ec178175b86f0d4a Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 19 Sep 2008 13:13:44 +0100 Subject: hrtimer: remove hrtimer_clock_base::get_softirq_time() Peter Zijlstra noticed this 8 months ago and I just noticed it again. hrtimer_clock_base::get_softirq_time() is currently unused in the entire tree. In fact, looking at the logs, it appears as if it was never used. Remove it. Signed-off-by: Mark McLoughlin Signed-off-by: Ingo Molnar --- include/linux/hrtimer.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6d93dce61cb..1b079bd29c3 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -145,7 +145,6 @@ struct hrtimer_sleeper { * @first: pointer to the timer node which expires first * @resolution: the resolution of the clock, in nanoseconds * @get_time: function to retrieve the current time of the clock - * @get_softirq_time: function to retrieve the current time from the softirq * @softirq_time: the time when running the hrtimer queue in the softirq * @offset: offset of this clock to the monotonic base * @reprogram: function to reprogram the timer event @@ -157,7 +156,6 @@ struct hrtimer_clock_base { struct rb_node *first; ktime_t resolution; ktime_t (*get_time)(void); - ktime_t (*get_softirq_time)(void); ktime_t softirq_time; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t offset; -- cgit v1.2.3 From b91c4996df56fcd201f85c392a1de7bc3f6641f5 Mon Sep 17 00:00:00 2001 From: Mark McLoughlin Date: Fri, 19 Sep 2008 13:13:48 +0100 Subject: hrtimer: remove hrtimer_clock_base::reprogram() hrtimer_clock_base::reprogram() also appears to never have been used, so remove it. Signed-off-by: Mark McLoughlin Signed-off-by: Ingo Molnar --- include/linux/hrtimer.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 1b079bd29c3..68b0196d869 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -147,7 +147,6 @@ struct hrtimer_sleeper { * @get_time: function to retrieve the current time of the clock * @softirq_time: the time when running the hrtimer queue in the softirq * @offset: offset of this clock to the monotonic base - * @reprogram: function to reprogram the timer event */ struct hrtimer_clock_base { struct hrtimer_cpu_base *cpu_base; @@ -159,9 +158,6 @@ struct hrtimer_clock_base { ktime_t softirq_time; #ifdef CONFIG_HIGH_RES_TIMERS ktime_t offset; - int (*reprogram)(struct hrtimer *t, - struct hrtimer_clock_base *b, - ktime_t n); #endif }; -- cgit v1.2.3 From 15afe09bf496ae10c989e1a375a6b5da7bd3e16e Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Sat, 20 Sep 2008 23:38:02 +0200 Subject: sched: wakeup preempt when small overlap Lin Ming reported a 10% OLTP regression against 2.6.27-rc4. The difference seems to come from different preemption agressiveness, which affects the cache footprint of the workload and its effective cache trashing. Aggresively preempt a task if its avg overlap is very small, this should avoid the task going to sleep and find it still running when we schedule back to it - saving a wakeup. Reported-by: Lin Ming Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/sched.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b3b7a8f3247..d8e699b5585 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -897,7 +897,7 @@ struct sched_class { void (*yield_task) (struct rq *rq); int (*select_task_rq)(struct task_struct *p, int sync); - void (*check_preempt_curr) (struct rq *rq, struct task_struct *p); + void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync); struct task_struct * (*pick_next_task) (struct rq *rq); void (*put_prev_task) (struct rq *rq, struct task_struct *p); -- cgit v1.2.3 From d26dbc5cf94b0a28acc947285c3b54814a73cb2e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 22 Sep 2008 22:35:07 +0900 Subject: iommu: export iommu_area_reserve helper function x86 has set_bit_string() that does the exact same thing that set_bit_area() in lib/iommu-helper.c does. This patch exports set_bit_area() in lib/iommu-helper.c as iommu_area_reserve(), converts GART, Calgary, and AMD IOMMU to use it. Signed-off-by: FUJITA Tomonori Acked-by: Joerg Roedel Signed-off-by: Ingo Molnar --- include/linux/iommu-helper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index 58f41107e4a..786539e432d 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h @@ -11,6 +11,7 @@ static inline unsigned long iommu_device_max_index(unsigned long size, extern int iommu_is_span_boundary(unsigned int index, unsigned int nr, unsigned long shift, unsigned long boundary_size); +extern void iommu_area_reserve(unsigned long *map, unsigned long i, int len); extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, unsigned long start, unsigned int nr, unsigned long shift, -- cgit v1.2.3 From a0ad05c75aa362c91f4d9cd91ff375a739574dd8 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 1 Sep 2008 14:27:02 +0200 Subject: Introduce FW_BUG, FW_WARN and FW_INFO to consistenly tell users about BIOS bugs The idea is to add this to printk after the severity: printk(KERN_ERR FW_BUG "This is not our fault, BIOS developer: fix it by simply add ...\n"); If a Firmware issue should be hidden, because it is work-arounded, but you still want to see something popping up e.g. for info only: printk(KERN_INFO FW_INFO "This is done stupid, we can handle it, but it should better be avoided in future\n"); or on the Linuxfirmwarekit to tell vendors that they did something stupid or wrong without bothering the user: printk(KERN_INFO FW_BUG "This is done stupid, we can handle it, but it should better be avoided in future\n"); Some use cases: - If a user sees a [Firmware Bug] message in the kernel he should first update the BIOS before wasting time with debugging and submiting on old firmware code to mailing lists. - The linuxfirmwarekit (http://www.linuxfirmwarekit.org) tries to detect firmware bugs. It currently is doing that in userspace which results in: - Huge test scripts that could be a one liner in the kernel - A lot of BIOS bugs are already absorbed by the kernel What do we need such a stupid linuxfirmwarekit for? - Vendors: Can test their BIOSes for Linux compatibility. There will be the time when vendors realize that the test utils on Linux are more strict and using them increases the qualitity and stability of their products. - Vendors: Can easily fix up their BIOSes and be more Linux compatible by: dmesg |grep "Firmware Bug" and send the result to their BIOS developer colleagues who should know what the messages are about and how to fix them, without the need of studying kernel code. - Distributions: can do a first automated HW/BIOS checks. This can then be done without the need of asking kernel developers who need to dig down the code and explain the details. Certification can/will just be rejected until dmesg |grep "Firmware Bug" is empty. - Thus this can be used as an instrument to enforce cleaner BIOS code. Currently every stupid Windows ACPI bug is re-implemented in Linux which is a rather unfortunate situation. We already have the power to avoid this in e.g. memory or cpu hot-plug ACPI implementations, because Linux certification is a must for most vendors in the server area. Working towards being able to do that in the laptop area (vendors are starting to look at Linux here also and will use this tool) is the goal. At least provide them a tool to make it as easy for this guys (e.g. not needing to browse kernel code) as possible. - The ordinary Linux user: can go into the next shop, boots the firmwarekit on his most preferred machines. He chooses one without BIOS bugs. Unsupported HW is ok, he likes to try out latest projects which might support them or likes to dig on it on his own, but he hates to workaround broken BIOSes like hell. I double checked with the firmwarekit. There they have: So the mapping generally is (also depending on how likely the BIOS is to blame, this could sometimes be difficult): FW_INFO = INFO FW_WARN = WARN FW_BUG = FAIL For more info about the linuxfirmwarekit and why this is needed can be found here: http://www.linuxfirmwarekit.org While severity matches with the firmwarekit, it might be tricky to hide messages from the user. E.g. we recently found out that on HP BIOSes negative temperatures are returned, which seem to indicate that the thermal zone is invalid. We can work around that gracefully by ignoring the thermal zone and we do not want to bother the ordinary user with a frightening message: Firmware Bug: thermal management absolutely broken but want to hide it from the user. But in the linuxfirmwarekit this should be shown as a real show stopper (the temperatures could really be wrong, broken thermal management is one of the worst things that can happen and the BIOS guys of the machine must implement this properly). It is intended to do that (hide it from the user with KERN_INFO msg, but still print it as a BIOS bug) by: printk(KERN_INFO FW_BUG "Negativ temperature values detected. Try to workarounded, BIOS must get fixed\n"); Hope that works out..., no idea how to better hide it as printk is the only way to easily provide this functionality. Signed-off-by: Thomas Renninger Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- include/linux/kernel.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2651f805ba6..0b19848e380 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -190,6 +190,30 @@ extern int kernel_text_address(unsigned long addr); struct pid; extern struct pid *session_of_pgrp(struct pid *pgrp); +/* + * FW_BUG + * Add this to a message where you are sure the firmware is buggy or behaves + * really stupid or out of spec. Be aware that the responsible BIOS developer + * should be able to fix this issue or at least get a concrete idea of the + * problem by reading your message without the need of looking at the kernel + * code. + * + * Use it for definite and high priority BIOS bugs. + * + * FW_WARN + * Use it for not that clear (e.g. could the kernel messed up things already?) + * and medium priority BIOS bugs. + * + * FW_INFO + * Use this one if you want to tell the user or vendor about something + * suspicious, but generally harmless related to the firmware. + * + * Use it for information or very low priority BIOS bugs. + */ +#define FW_BUG "[Firmware Bug]: " +#define FW_WARN "[Firmware Warn]: " +#define FW_INFO "[Firmware Info]: " + #ifdef CONFIG_PRINTK asmlinkage int vprintk(const char *fmt, va_list args) __attribute__ ((format (printf, 1, 0))); -- cgit v1.2.3 From 5c1824587f0797373c95719a196f6098f7c6d20c Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 22 Sep 2008 19:48:19 -0700 Subject: ipsec: Fix xfrm_state_walk race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discovered by Timo Teräs, the currently xfrm_state_walk scheme is racy because if a second dump finishes before the first, we may free xfrm states that the first dump would walk over later. This patch fixes this by storing the dumps in a list in order to calculate the correct completion counter which cures this problem. I've expanded netlink_cb in order to accomodate the extra state related to this. It shouldn't be a big deal since netlink_cb is kmalloced for each dump and we're just increasing it by 4 or 8 bytes. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 9ff1b54908f..cbba7760545 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -220,7 +220,7 @@ struct netlink_callback int (*dump)(struct sk_buff * skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); int family; - long args[6]; + long args[7]; }; struct netlink_notify -- cgit v1.2.3 From bce7b15426cac3000bf6a9cf59d9356ef0be2dec Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Mon, 22 Sep 2008 19:51:15 -0700 Subject: Phonet: global definitions Signed-off-by: Remi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + include/linux/if_phonet.h | 14 ++++++ include/linux/phonet.h | 125 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/rtnetlink.h | 4 ++ include/linux/socket.h | 4 +- 5 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 include/linux/if_phonet.h create mode 100644 include/linux/phonet.h (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 5028e0b6082..723a1c5fbc6 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -100,6 +100,7 @@ #define ETH_P_ECONET 0x0018 /* Acorn Econet */ #define ETH_P_HDLC 0x0019 /* HDLC frames */ #define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ +#define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ /* * This is an Ethernet frame header. diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h new file mode 100644 index 00000000000..22df25fbc4e --- /dev/null +++ b/include/linux/if_phonet.h @@ -0,0 +1,14 @@ +/* + * File: if_phonet.h + * + * Phonet interface kernel definitions + * + * Copyright (C) 2008 Nokia Corporation. All rights reserved. + */ + +#define PHONET_HEADER_LEN 8 /* Phonet header length */ + +#define PHONET_MIN_MTU 6 +/* 6 bytes header + 65535 bytes payload */ +#define PHONET_MAX_MTU 65541 +#define PHONET_DEV_MTU PHONET_MAX_MTU diff --git a/include/linux/phonet.h b/include/linux/phonet.h new file mode 100644 index 00000000000..6a764f8584a --- /dev/null +++ b/include/linux/phonet.h @@ -0,0 +1,125 @@ +/** + * file phonet.h + * + * Phonet sockets kernel interface + * + * Copyright (C) 2008 Nokia Corporation. All rights reserved. + * + * 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. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ + +#ifndef LINUX_PHONET_H +#define LINUX_PHONET_H + +/* Automatic protocol selection */ +#define PN_PROTO_TRANSPORT 0 +/* Phonet datagram socket */ +#define PN_PROTO_PHONET 1 +#define PHONET_NPROTO 2 + +#define PNADDR_ANY 0 +#define PNPORT_RESOURCE_ROUTING 0 + +/* Phonet protocol header */ +struct phonethdr { + __u8 pn_rdev; + __u8 pn_sdev; + __u8 pn_res; + __be16 pn_length; + __u8 pn_robj; + __u8 pn_sobj; +} __attribute__((packed)); + +/* Phonet socket address structure */ +struct sockaddr_pn { + sa_family_t spn_family; + __u8 spn_obj; + __u8 spn_dev; + __u8 spn_resource; + __u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3]; +} __attribute__ ((packed)); + +static inline __u16 pn_object(__u8 addr, __u16 port) +{ + return (addr << 8) | (port & 0x3ff); +} + +static inline __u8 pn_obj(__u16 handle) +{ + return handle & 0xff; +} + +static inline __u8 pn_dev(__u16 handle) +{ + return handle >> 8; +} + +static inline __u16 pn_port(__u16 handle) +{ + return handle & 0x3ff; +} + +static inline __u8 pn_addr(__u16 handle) +{ + return (handle >> 8) & 0xfc; +} + +static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, __u8 addr) +{ + spn->spn_dev &= 0x03; + spn->spn_dev |= addr & 0xfc; +} + +static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn, __u16 port) +{ + spn->spn_dev &= 0xfc; + spn->spn_dev |= (port >> 8) & 0x03; + spn->spn_obj = port & 0xff; +} + +static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn, + __u16 handle) +{ + spn->spn_dev = pn_dev(handle); + spn->spn_obj = pn_obj(handle); +} + +static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn, + __u8 resource) +{ + spn->spn_resource = resource; +} + +static inline __u8 pn_sockaddr_get_addr(const struct sockaddr_pn *spn) +{ + return spn->spn_dev & 0xfc; +} + +static inline __u16 pn_sockaddr_get_port(const struct sockaddr_pn *spn) +{ + return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj; +} + +static inline __u16 pn_sockaddr_get_object(const struct sockaddr_pn *spn) +{ + return pn_object(spn->spn_dev, spn->spn_obj); +} + +static inline __u8 pn_sockaddr_get_resource(const struct sockaddr_pn *spn) +{ + return spn->spn_resource; +} + +#endif diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index ca643b13b02..2b3d51c6ec9 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -582,6 +582,10 @@ enum rtnetlink_groups { #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE RTNLGRP_ND_USEROPT, #define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT + RTNLGRP_PHONET_IFADDR, +#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR + RTNLGRP_PHONET_ROUTE, +#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE __RTNLGRP_MAX }; #define RTNLGRP_MAX (__RTNLGRP_MAX - 1) diff --git a/include/linux/socket.h b/include/linux/socket.h index dc5086fe773..818ca33bf79 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -190,7 +190,8 @@ struct ucred { #define AF_IUCV 32 /* IUCV sockets */ #define AF_RXRPC 33 /* RxRPC sockets */ #define AF_ISDN 34 /* mISDN sockets */ -#define AF_MAX 35 /* For now.. */ +#define AF_PHONET 35 /* Phonet sockets */ +#define AF_MAX 36 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -227,6 +228,7 @@ struct ucred { #define PF_IUCV AF_IUCV #define PF_RXRPC AF_RXRPC #define PF_ISDN AF_ISDN +#define PF_PHONET AF_PHONET #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ -- cgit v1.2.3 From ba113a94b7503ee23ffe819e7045134b0c1d31de Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Mon, 22 Sep 2008 20:05:19 -0700 Subject: Phonet: common socket glue This provides the socket API for the Phonet protocols family. Signed-off-by: Remi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 6a764f8584a..001c0e67909 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -32,6 +32,9 @@ #define PNADDR_ANY 0 #define PNPORT_RESOURCE_ROUTING 0 +/* ioctls */ +#define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) + /* Phonet protocol header */ struct phonethdr { __u8 pn_rdev; -- cgit v1.2.3 From 5f77076d75d35c9f5619e1f9d7e7428a627f65e6 Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Mon, 22 Sep 2008 20:08:04 -0700 Subject: Phonet: provide MAC header operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/if_phonet.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h index 22df25fbc4e..7e989216ec1 100644 --- a/include/linux/if_phonet.h +++ b/include/linux/if_phonet.h @@ -12,3 +12,7 @@ /* 6 bytes header + 65535 bytes payload */ #define PHONET_MAX_MTU 65541 #define PHONET_DEV_MTU PHONET_MAX_MTU + +#ifdef __KERNEL__ +extern struct header_ops phonet_header_ops; +#endif -- cgit v1.2.3 From be0c52bfed7f7828494fa00060efd5d758e92580 Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Mon, 22 Sep 2008 20:09:13 -0700 Subject: Phonet: emit errors when a packet cannot be delivered locally When there is no listener socket for a received packet, send an error back to the sender. Signed-off-by: Remi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 001c0e67909..3a027f588a4 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -45,6 +45,38 @@ struct phonethdr { __u8 pn_sobj; } __attribute__((packed)); +/* Common Phonet payload header */ +struct phonetmsg { + __u8 pn_trans_id; /* transaction ID */ + __u8 pn_msg_id; /* message type */ + union { + struct { + __u8 pn_submsg_id; /* message subtype */ + __u8 pn_data[5]; + } base; + struct { + __u16 pn_e_res_id; /* extended resource ID */ + __u8 pn_e_submsg_id; /* message subtype */ + __u8 pn_e_data[3]; + } ext; + } pn_msg_u; +}; +#define PN_COMMON_MESSAGE 0xF0 +#define PN_PREFIX 0xE0 /* resource for extended messages */ +#define pn_submsg_id pn_msg_u.base.pn_submsg_id +#define pn_e_submsg_id pn_msg_u.ext.pn_e_submsg_id +#define pn_e_res_id pn_msg_u.ext.pn_e_res_id +#define pn_data pn_msg_u.base.pn_data +#define pn_e_data pn_msg_u.ext.pn_e_data + +/* data for unreachable errors */ +#define PN_COMM_SERVICE_NOT_IDENTIFIED_RESP 0x01 +#define PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP 0x14 +#define pn_orig_msg_id pn_data[0] +#define pn_status pn_data[1] +#define pn_e_orig_msg_id pn_e_data[0] +#define pn_e_status pn_e_data[1] + /* Phonet socket address structure */ struct sockaddr_pn { sa_family_t spn_family; -- cgit v1.2.3 From 0b815a1a6d43ab498674b8430c8c35ab08487a16 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 22 Sep 2008 21:28:11 -0700 Subject: net: network device name ifalias support This patch add support for keeping an additional character alias associated with an network interface. This is useful for maintaining the SNMP ifAlias value which is a user defined value. Routers use this to hold information like which circuit or line it is connected to. It is just an arbitrary text label on the network device. There are two exposed interfaces with this patch, the value can be read/written either via netlink or sysfs. This could be maintained just by the snmp daemon, but it is more generally useful for other management tools, and the kernel is good place to act as an agreed upon interface to store it. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/if.h | 1 + include/linux/if_link.h | 1 + include/linux/netdevice.h | 3 +++ 3 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if.h b/include/linux/if.h index 5c9d1fa93fe..65246846c84 100644 --- a/include/linux/if.h +++ b/include/linux/if.h @@ -24,6 +24,7 @@ #include /* for "__user" et al */ #define IFNAMSIZ 16 +#define IFALIASZ 256 #include /* Standard interface flags (netdevice->flags). */ diff --git a/include/linux/if_link.h b/include/linux/if_link.h index 84c3492ae5c..f9032c88716 100644 --- a/include/linux/if_link.h +++ b/include/linux/if_link.h @@ -79,6 +79,7 @@ enum IFLA_LINKINFO, #define IFLA_LINKINFO IFLA_LINKINFO IFLA_NET_NS_PID, + IFLA_IFALIAS, __IFLA_MAX }; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 488c56e649b..d675df08b94 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -471,6 +471,8 @@ struct net_device char name[IFNAMSIZ]; /* device name hash chain */ struct hlist_node name_hlist; + /* snmp alias */ + char *ifalias; /* * I/O specific fields @@ -1224,6 +1226,7 @@ extern int dev_ethtool(struct net *net, struct ifreq *); extern unsigned dev_get_flags(const struct net_device *); extern int dev_change_flags(struct net_device *, unsigned); extern int dev_change_name(struct net_device *, char *); +extern int dev_set_alias(struct net_device *, const char *, size_t); extern int dev_change_net_namespace(struct net_device *, struct net *, const char *); extern int dev_set_mtu(struct net_device *, int); -- cgit v1.2.3 From 1d4a31dde95af56edac4dee268249a29a21fa7c0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 22 Sep 2008 21:57:21 -0700 Subject: net: Fix bus in SKB queue splicing interfaces. Handle the case of head being non-empty, by adding list->qlen to head->qlen instead of using direct assignment. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 027b06170b4..4a144e8d053 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -738,7 +738,7 @@ static inline void skb_queue_splice(const struct sk_buff_head *list, { if (!skb_queue_empty(list)) { __skb_queue_splice(list, (struct sk_buff *) head, head->next); - head->qlen = list->qlen; + head->qlen += list->qlen; } } @@ -754,7 +754,7 @@ static inline void skb_queue_splice_init(struct sk_buff_head *list, { if (!skb_queue_empty(list)) { __skb_queue_splice(list, (struct sk_buff *) head, head->next); - head->qlen = list->qlen; + head->qlen += list->qlen; __skb_queue_head_init(list); } } @@ -769,7 +769,7 @@ static inline void skb_queue_splice_tail(const struct sk_buff_head *list, { if (!skb_queue_empty(list)) { __skb_queue_splice(list, head->prev, (struct sk_buff *) head); - head->qlen = list->qlen; + head->qlen += list->qlen; } } @@ -786,7 +786,7 @@ static inline void skb_queue_splice_tail_init(struct sk_buff_head *list, { if (!skb_queue_empty(list)) { __skb_queue_splice(list, head->prev, (struct sk_buff *) head); - head->qlen = list->qlen; + head->qlen += list->qlen; __skb_queue_head_init(list); } } -- cgit v1.2.3 From fc7ebb212d3e51d1188948d975aa93dbb0f58b25 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 23 Sep 2008 00:34:07 -0700 Subject: net: Add skb_queue_is_last(). Several bits of code want to know "is this the last SKB in a queue", and all of them implement this by hand. Provide an common interface to make this check. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 4a144e8d053..3a5838da160 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -472,6 +472,19 @@ static inline int skb_queue_empty(const struct sk_buff_head *list) return list->next == (struct sk_buff *)list; } +/** + * skb_queue_is_last - check if skb is the last entry in the queue + * @list: queue head + * @skb: buffer + * + * Returns true if @skb is the last buffer on the list. + */ +static inline bool skb_queue_is_last(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + return (skb->next == (struct sk_buff *) list); +} + /** * skb_get - reference buffer * @skb: buffer to reference -- cgit v1.2.3 From 249c8b42c7e5e6f33d0ff983041f08278b137e53 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 23 Sep 2008 00:44:42 -0700 Subject: net: Add skb_queue_next(). A lot of code wants to iterate over an SKB queue at the top level using it's own control structure and iterator scheme. Provide skb_queue_next(), which is only valid to invoke if skb_queue_is_last() returns false. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 3a5838da160..d2f1778877d 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -485,6 +485,24 @@ static inline bool skb_queue_is_last(const struct sk_buff_head *list, return (skb->next == (struct sk_buff *) list); } +/** + * skb_queue_next - return the next packet in the queue + * @list: queue head + * @skb: current buffer + * + * Return the next packet in @list after @skb. It is only valid to + * call this if skb_queue_is_last() evaluates to false. + */ +static inline struct sk_buff *skb_queue_next(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + /* This BUG_ON may seem severe, but if we just return then we + * are going to dereference garbage. + */ + BUG_ON(skb_queue_is_last(list, skb)); + return skb->next; +} + /** * skb_get - reference buffer * @skb: buffer to reference -- cgit v1.2.3 From 1164f52a244204830c7625b3c22812781996d7b4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 23 Sep 2008 00:49:44 -0700 Subject: net: Add skb_queue_walk_from() and skb_queue_walk_from_safe(). These will be used by TCP write queue handling and elsewhere. Signed-off-by: David S. Miller --- include/linux/skbuff.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index d2f1778877d..a19ea43fea0 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1571,6 +1571,15 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len) skb != (struct sk_buff *)(queue); \ skb = tmp, tmp = skb->next) +#define skb_queue_walk_from(queue, skb) \ + for (; prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ + skb = skb->next) + +#define skb_queue_walk_from_safe(queue, skb, tmp) \ + for (tmp = skb->next; \ + skb != (struct sk_buff *)(queue); \ + skb = tmp, tmp = skb->next) + #define skb_queue_reverse_walk(queue, skb) \ for (skb = (queue)->prev; \ prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \ -- cgit v1.2.3 From bb34d92f643086d546b49cef680f6f305ed84414 Mon Sep 17 00:00:00 2001 From: Frank Mayhar Date: Fri, 12 Sep 2008 09:54:39 -0700 Subject: timers: fix itimer/many thread hang, v2 This is the second resubmission of the posix timer rework patch, posted a few days ago. This includes the changes from the previous resubmittion, which addressed Oleg Nesterov's comments, removing the RCU stuff from the patch and un-inlining the thread_group_cputime() function for SMP. In addition, per Ingo Molnar it simplifies the UP code, consolidating much of it with the SMP version and depending on lower-level SMP/UP handling to take care of the differences. It also cleans up some UP compile errors, moves the scheduler stats-related macros into kernel/sched_stats.h, cleans up a merge error in kernel/fork.c and has a few other minor fixes and cleanups as suggested by Oleg and Ingo. Thanks for the review, guys. Signed-off-by: Frank Mayhar Cc: Roland McGrath Cc: Alexey Dobriyan Cc: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/kernel_stat.h | 1 + include/linux/sched.h | 183 ++------------------------------------------ 2 files changed, 6 insertions(+), 178 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index cf9f40a91c9..cac3750cd65 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -52,6 +52,7 @@ static inline int kstat_irqs(int irq) return sum; } +extern unsigned long long task_delta_exec(struct task_struct *); extern void account_user_time(struct task_struct *, cputime_t); extern void account_user_time_scaled(struct task_struct *, cputime_t); extern void account_system_time(struct task_struct *, int, cputime_t); diff --git a/include/linux/sched.h b/include/linux/sched.h index 7ce8d4e5356..b982fb48c8f 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -454,15 +454,9 @@ struct task_cputime { * This structure contains the version of task_cputime, above, that is * used for thread group CPU clock calculations. */ -#ifdef CONFIG_SMP struct thread_group_cputime { struct task_cputime *totals; }; -#else -struct thread_group_cputime { - struct task_cputime totals; -}; -#endif /* * NOTE! "signal_struct" does not have it's own @@ -2124,193 +2118,26 @@ static inline int spin_needbreak(spinlock_t *lock) /* * Thread group CPU time accounting. */ -#ifdef CONFIG_SMP -extern int thread_group_cputime_alloc_smp(struct task_struct *); -extern void thread_group_cputime_smp(struct task_struct *, struct task_cputime *); +extern int thread_group_cputime_alloc(struct task_struct *); +extern void thread_group_cputime(struct task_struct *, struct task_cputime *); static inline void thread_group_cputime_init(struct signal_struct *sig) { sig->cputime.totals = NULL; } -static inline int thread_group_cputime_clone_thread(struct task_struct *curr, - struct task_struct *new) +static inline int thread_group_cputime_clone_thread(struct task_struct *curr) { if (curr->signal->cputime.totals) return 0; - return thread_group_cputime_alloc_smp(curr); + return thread_group_cputime_alloc(curr); } -static inline void thread_group_cputime_free(struct signal_struct *sig) -{ - free_percpu(sig->cputime.totals); -} - -/** - * thread_group_cputime - Sum the thread group time fields across all CPUs. - * - * This is a wrapper for the real routine, thread_group_cputime_smp(). See - * that routine for details. - */ -static inline void thread_group_cputime( - struct task_struct *tsk, - struct task_cputime *times) -{ - thread_group_cputime_smp(tsk, times); -} - -/** - * thread_group_cputime_account_user - Maintain utime for a thread group. - * - * @tgtimes: Pointer to thread_group_cputime structure. - * @cputime: Time value by which to increment the utime field of that - * structure. - * - * If thread group time is being maintained, get the structure for the - * running CPU and update the utime field there. - */ -static inline void thread_group_cputime_account_user( - struct thread_group_cputime *tgtimes, - cputime_t cputime) -{ - if (tgtimes->totals) { - struct task_cputime *times; - - times = per_cpu_ptr(tgtimes->totals, get_cpu()); - times->utime = cputime_add(times->utime, cputime); - put_cpu_no_resched(); - } -} - -/** - * thread_group_cputime_account_system - Maintain stime for a thread group. - * - * @tgtimes: Pointer to thread_group_cputime structure. - * @cputime: Time value by which to increment the stime field of that - * structure. - * - * If thread group time is being maintained, get the structure for the - * running CPU and update the stime field there. - */ -static inline void thread_group_cputime_account_system( - struct thread_group_cputime *tgtimes, - cputime_t cputime) -{ - if (tgtimes->totals) { - struct task_cputime *times; - - times = per_cpu_ptr(tgtimes->totals, get_cpu()); - times->stime = cputime_add(times->stime, cputime); - put_cpu_no_resched(); - } -} - -/** - * thread_group_cputime_account_exec_runtime - Maintain exec runtime for a - * thread group. - * - * @tgtimes: Pointer to thread_group_cputime structure. - * @ns: Time value by which to increment the sum_exec_runtime field - * of that structure. - * - * If thread group time is being maintained, get the structure for the - * running CPU and update the sum_exec_runtime field there. - */ -static inline void thread_group_cputime_account_exec_runtime( - struct thread_group_cputime *tgtimes, - unsigned long long ns) -{ - if (tgtimes->totals) { - struct task_cputime *times; - - times = per_cpu_ptr(tgtimes->totals, get_cpu()); - times->sum_exec_runtime += ns; - put_cpu_no_resched(); - } -} - -#else /* CONFIG_SMP */ - -static inline void thread_group_cputime_init(struct signal_struct *sig) -{ - sig->cputime.totals.utime = cputime_zero; - sig->cputime.totals.stime = cputime_zero; - sig->cputime.totals.sum_exec_runtime = 0; -} - -static inline int thread_group_cputime_alloc(struct task_struct *tsk) -{ - return 0; -} static inline void thread_group_cputime_free(struct signal_struct *sig) { -} - -static inline int thread_group_cputime_clone_thread(struct task_struct *curr, - struct task_struct *tsk) -{ - return 0; -} - -static inline void thread_group_cputime(struct task_struct *tsk, - struct task_cputime *cputime) -{ - *cputime = tsk->signal->cputime.totals; -} - -static inline void thread_group_cputime_account_user( - struct thread_group_cputime *tgtimes, - cputime_t cputime) -{ - tgtimes->totals.utime = cputime_add(tgtimes->totals.utime, cputime); -} - -static inline void thread_group_cputime_account_system( - struct thread_group_cputime *tgtimes, - cputime_t cputime) -{ - tgtimes->totals.stime = cputime_add(tgtimes->totals.stime, cputime); -} - -static inline void thread_group_cputime_account_exec_runtime( - struct thread_group_cputime *tgtimes, - unsigned long long ns) -{ - tgtimes->totals.sum_exec_runtime += ns; -} - -#endif /* CONFIG_SMP */ - -static inline void account_group_user_time(struct task_struct *tsk, - cputime_t cputime) -{ - struct signal_struct *sig; - - sig = tsk->signal; - if (likely(sig)) - thread_group_cputime_account_user(&sig->cputime, cputime); -} - -static inline void account_group_system_time(struct task_struct *tsk, - cputime_t cputime) -{ - struct signal_struct *sig; - - sig = tsk->signal; - if (likely(sig)) - thread_group_cputime_account_system(&sig->cputime, cputime); -} - -static inline void account_group_exec_runtime(struct task_struct *tsk, - unsigned long long ns) -{ - struct signal_struct *sig; - - sig = tsk->signal; - if (likely(sig)) - thread_group_cputime_account_exec_runtime(&sig->cputime, ns); + free_percpu(sig->cputime.totals); } /* -- cgit v1.2.3 From faa312da9cd0b044bdc84483162c6ee10b9c83c0 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 29 Aug 2008 04:18:43 +0800 Subject: lcd: allow lcd device to handle mode change events Some LCD panels are capable of different resolutions, and is allowed to change at run-time, so to make "struct lcd_device" to be able to handle mode change events here. Signed-off-by: Eric Miao Acked-by: Krzysztof Helt Signed-off-by: Russell King --- include/linux/lcd.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/lcd.h b/include/linux/lcd.h index 173febac665..c67fecafff9 100644 --- a/include/linux/lcd.h +++ b/include/linux/lcd.h @@ -11,6 +11,7 @@ #include #include #include +#include /* Notes on locking: * @@ -45,6 +46,8 @@ struct lcd_ops { int (*get_contrast)(struct lcd_device *); /* Set LCD panel contrast */ int (*set_contrast)(struct lcd_device *, int contrast); + /* Set LCD panel mode (resolutions ...) */ + int (*set_mode)(struct lcd_device *, struct fb_videomode *); /* Check if given framebuffer device is the one LCD is bound to; return 0 if not, !=0 if it is. If NULL, lcd always matches the fb. */ int (*check_fb)(struct lcd_device *, struct fb_info *); -- cgit v1.2.3 From b18250a8f66050bd2a52287cd543fb93100e8ee0 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 29 Aug 2008 04:21:44 +0800 Subject: lcd: add SPI-based LCD and backlight driver for SHARP corgi/spitz The driver is based on different source files including corgi_ssp.c, corgi_lcd.c and corgi_bl.c, previously authored by Richard Purdie and many others. The LCD and Backlight device actually share the same SPI device, so they are made into this single driver. Signed-off-by: Eric Miao Cc: Richard Purdie Signed-off-by: Russell King --- include/linux/spi/corgi_lcd.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/linux/spi/corgi_lcd.h (limited to 'include/linux') diff --git a/include/linux/spi/corgi_lcd.h b/include/linux/spi/corgi_lcd.h new file mode 100644 index 00000000000..3c53ac26c8d --- /dev/null +++ b/include/linux/spi/corgi_lcd.h @@ -0,0 +1,16 @@ +#ifndef __LINUX_SPI_CORGI_LCD_H +#define __LINUX_SPI_CORGI_LCD_H + +#define CORGI_LCD_MODE_QVGA 1 +#define CORGI_LCD_MODE_VGA 2 + +struct corgi_lcd_platform_data { + int init_mode; + int max_intensity; + int default_intensity; + + void (*notify)(int intensity); + void (*kick_battery)(void); +}; + +#endif /* __LINUX_SPI_CORGI_LCD_H */ -- cgit v1.2.3 From bfdcaa3b6899bbfc6ba633aff3f5f2422486c8c1 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Fri, 29 Aug 2008 05:57:20 +0800 Subject: lcd: add corgibl_limit_intensity() to corgi_lcd This is not generic enough, added here for backward compatibility. And make this an individual commit so future revert will be a bit easier. Signed-off-by: Eric Miao Cc: Richard Purdie Signed-off-by: Russell King --- include/linux/spi/corgi_lcd.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/spi/corgi_lcd.h b/include/linux/spi/corgi_lcd.h index 3c53ac26c8d..b6161aae275 100644 --- a/include/linux/spi/corgi_lcd.h +++ b/include/linux/spi/corgi_lcd.h @@ -8,6 +8,7 @@ struct corgi_lcd_platform_data { int init_mode; int max_intensity; int default_intensity; + int limit_mask; void (*notify)(int intensity); void (*kick_battery)(void); -- cgit v1.2.3 From 5a9fa73072854981a5c05eb7ba18a96d49c2804f Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 22 Sep 2008 14:42:50 -0700 Subject: posix-timers: kill ->it_sigev_signo and ->it_sigev_value With the recent changes ->it_sigev_signo and ->it_sigev_value are only used in sys_timer_create(), kill them. Signed-off-by: Oleg Nesterov Cc: mingo@elte.hu Cc: Roland McGrath Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/posix-timers.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index f9d8e9e94e9..a7c72135554 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -45,8 +45,6 @@ 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 */ - int it_sigev_signo; /* signo word of sigevent struct */ - sigval_t it_sigev_value; /* value word of sigevent struct */ struct task_struct *it_process; /* process to send signal to */ struct sigqueue *sigq; /* signal queue entry. */ union { -- cgit v1.2.3 From 1b02469088ac7a13d7e622b618b7410d0f1ce5ec Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Mon, 22 Sep 2008 14:42:43 -0700 Subject: hrtimer: reorder struct hrtimer to save 8 bytes on 64bit builds reorder struct hrtimer to save 8 bytes on 64 bit builds when CONFIG_TIMER_STATS selected. (also removes 8 bytes from signal_struct) Signed-off-by: Richard Kennedy Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 68b0196d869..8730b60c943 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -115,12 +115,12 @@ struct hrtimer { enum hrtimer_restart (*function)(struct hrtimer *); struct hrtimer_clock_base *base; unsigned long state; - enum hrtimer_cb_mode cb_mode; struct list_head cb_entry; + enum hrtimer_cb_mode cb_mode; #ifdef CONFIG_TIMER_STATS + int start_pid; void *start_site; char start_comm[16]; - int start_pid; #endif }; -- cgit v1.2.3 From d40e944c25fb4642adb2a4c580a48218a9f3f824 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Mon, 22 Sep 2008 14:42:44 -0700 Subject: ntp: improve adjtimex frequency rounding Change PPM_SCALE_INV_SHIFT so that it doesn't throw away any input bits (19 is the amount of the factor 2 in PPM_SCALE), the output frequency can then be calculated back to its input value, as the inverse divide produce a slightly larger value, which is then correctly rounded by the final shift. Reported-by: Martin Ziegler Signed-off-by: Roman Zippel Cc: John Stultz Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner --- include/linux/timex.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/timex.h b/include/linux/timex.h index c00bcdd3ae4..9007313b5b7 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h @@ -82,7 +82,7 @@ */ #define SHIFT_USEC 16 /* frequency offset scale (shift) */ #define PPM_SCALE (NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC)) -#define PPM_SCALE_INV_SHIFT 20 +#define PPM_SCALE_INV_SHIFT 19 #define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \ PPM_SCALE + 1) -- cgit v1.2.3 From 79617deeebb9cf089e2bc2aad19743b1209043f6 Mon Sep 17 00:00:00 2001 From: YanBo Date: Mon, 22 Sep 2008 13:30:32 +0800 Subject: mac80211: mesh portal functionality support Currently the mesh code doesn't support bridging mesh point interfaces with wired ethernet or AP to construct an MPP or MAP. This patch adds code to support the "6 address frame format packet" functionality to mesh point interfaces. Now the mesh network can be used as backhaul for end to end communication. Signed-off-by: Li YanBo Signed-off-by: John W. Linville --- include/linux/ieee80211.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index abc1abc63bf..14126bc3664 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h @@ -471,6 +471,11 @@ struct ieee80211s_hdr { u8 eaddr3[6]; } __attribute__ ((packed)); +/* Mesh flags */ +#define MESH_FLAGS_AE_A4 0x1 +#define MESH_FLAGS_AE_A5_A6 0x2 +#define MESH_FLAGS_PS_DEEP 0x4 + /** * struct ieee80211_quiet_ie * -- cgit v1.2.3 From 040dec3b37e4b9ec15b359bf5744f1ceba39fe3e Mon Sep 17 00:00:00 2001 From: Dhananjay Phadke Date: Fri, 12 Sep 2008 06:55:14 -0700 Subject: netxen: add pci ids Define old and new pci vendor and device ids. Signed-off-by: Dhananjay Phadke Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 6f4276d461c..a65b082a888 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2247,6 +2247,16 @@ #define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 +#define PCI_VENDOR_ID_NETXEN 0x4040 +#define PCI_DEVICE_ID_NX2031_10GXSR 0x0001 +#define PCI_DEVICE_ID_NX2031_10GCX4 0x0002 +#define PCI_DEVICE_ID_NX2031_4GCU 0x0003 +#define PCI_DEVICE_ID_NX2031_IMEZ 0x0004 +#define PCI_DEVICE_ID_NX2031_HMEZ 0x0005 +#define PCI_DEVICE_ID_NX2031_XG_MGMT 0x0024 +#define PCI_DEVICE_ID_NX2031_XG_MGMT2 0x0025 +#define PCI_DEVICE_ID_NX3031 0x0100 + #define PCI_VENDOR_ID_AKS 0x416c #define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100 -- cgit v1.2.3 From ff7a4c7130c0ad97d55f7ab3f0a35fbc1f41b376 Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Sun, 7 Sep 2008 11:30:06 +0800 Subject: [ARM] corgi_lcd: use GPIO API for BACKLIGHT_ON and BACKLIGHT_CONT Signed-off-by: Eric Miao Signed-off-by: Russell King --- include/linux/spi/corgi_lcd.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/spi/corgi_lcd.h b/include/linux/spi/corgi_lcd.h index b6161aae275..6692b3418cc 100644 --- a/include/linux/spi/corgi_lcd.h +++ b/include/linux/spi/corgi_lcd.h @@ -10,6 +10,9 @@ struct corgi_lcd_platform_data { int default_intensity; int limit_mask; + int gpio_backlight_on; /* -1 if n/a */ + int gpio_backlight_cont; /* -1 if n/a */ + void (*notify)(int intensity); void (*kick_battery)(void); }; -- cgit v1.2.3 From 379daf6290814e41f14880094b7b773640df2461 Mon Sep 17 00:00:00 2001 From: Suresh Siddha Date: Thu, 25 Sep 2008 18:43:34 -0700 Subject: IO resources, x86: ioremap sanity check to catch mapping requests exceeding the BAR sizes Go through the iomem resource tree to check if any of the ioremap() requests span more than any slot in the iomem resource tree and do a WARN_ON() if we hit this check. This will raise a red-flag, if some driver is mapping more than what is needed. And hopefully identify possible corruptions much earlier. Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar --- include/linux/ioport.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ioport.h b/include/linux/ioport.h index fded376b94e..01712cf1a38 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -169,6 +169,7 @@ extern struct resource * __devm_request_region(struct device *dev, extern void __devm_release_region(struct device *dev, struct resource *parent, resource_size_t start, resource_size_t n); +extern int iomem_map_sanity_check(resource_size_t addr, unsigned long size); #endif /* __ASSEMBLY__ */ #endif /* _LINUX_IOPORT_H */ -- cgit v1.2.3 From e416de5e61e1a9b7f987804cbb67230b5f5293c6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 23 Sep 2008 17:25:10 +0100 Subject: Export the ROM enable/disable helpers .... so that they can be used by MTD map drivers. Lets us close #9420 Signed-off-by: Alan Cox Signed-off-by: David Woodhouse --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index c0e14008a3c..7a4cee00c1d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -631,6 +631,8 @@ int __must_check pci_assign_resource(struct pci_dev *dev, int i); int pci_select_bars(struct pci_dev *dev, unsigned long flags); /* ROM control related routines */ +int pci_enable_rom(struct pci_dev *pdev); +void pci_disable_rom(struct pci_dev *pdev); void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); size_t pci_get_rom_size(void __iomem *rom, size_t size); -- cgit v1.2.3 From 7086efe1c1536f6bc160e7d60a9bfd645b91f279 Mon Sep 17 00:00:00 2001 From: Frank Mayhar Date: Fri, 12 Sep 2008 09:54:39 -0700 Subject: timers: fix itimer/many thread hang, v3 - fix UP lockup - another set of UP/SMP cleanups and simplifications Signed-off-by: Frank Mayhar Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b982fb48c8f..23d9d546454 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2134,7 +2134,6 @@ static inline int thread_group_cputime_clone_thread(struct task_struct *curr) return thread_group_cputime_alloc(curr); } - static inline void thread_group_cputime_free(struct signal_struct *sig) { free_percpu(sig->cputime.totals); -- cgit v1.2.3 From 82ef04fb4c82542b3eda81cca461f0594ce9cd0b Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 31 Jul 2008 17:02:40 +0900 Subject: libata: make SCR access ops per-link Logically, SCR access ops should take @link; however, there was no compelling reason to convert all SCR access ops when adding @link abstraction as there's one-to-one mapping between a port and a non-PMP link. However, that assumption won't hold anymore with the scheduled addition of slave link. Make SCR access ops per-link. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 225bfc5bd9e..ffd622fa319 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -772,8 +772,8 @@ struct ata_port_operations { /* * Optional features */ - int (*scr_read)(struct ata_port *ap, unsigned int sc_reg, u32 *val); - int (*scr_write)(struct ata_port *ap, unsigned int sc_reg, u32 val); + int (*scr_read)(struct ata_link *link, unsigned int sc_reg, u32 *val); + int (*scr_write)(struct ata_link *link, unsigned int sc_reg, u32 val); void (*pmp_attach)(struct ata_port *ap); void (*pmp_detach)(struct ata_port *ap); int (*enable_pm)(struct ata_port *ap, enum link_pm policy); -- cgit v1.2.3 From aadffb682cc5572f48cc24883681db65530bd284 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 31 Jul 2008 17:02:41 +0900 Subject: libata: reimplement link iterator Implement __ata_port_next_link() and reimplement __ata_port_for_each_link() and ata_port_for_each_link() using it. This removes relatively large inlined code and makes iteration easier to extend. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ffd622fa319..3eaca347ce2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1265,34 +1265,17 @@ static inline int ata_link_active(struct ata_link *link) return ata_tag_valid(link->active_tag) || link->sactive; } -static inline struct ata_link *ata_port_first_link(struct ata_port *ap) -{ - if (sata_pmp_attached(ap)) - return ap->pmp_link; - return &ap->link; -} - -static inline struct ata_link *ata_port_next_link(struct ata_link *link) -{ - struct ata_port *ap = link->ap; - - if (ata_is_host_link(link)) { - if (!sata_pmp_attached(ap)) - return NULL; - return ap->pmp_link; - } - - if (++link < ap->nr_pmp_links + ap->pmp_link) - return link; - return NULL; -} +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(lk, ap) \ - for ((lk) = &(ap)->link; (lk); (lk) = ata_port_next_link(lk)) +#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_first_link(ap); (link); \ - (link) = ata_port_next_link(link)) + 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; \ -- cgit v1.2.3 From b5b3fa386b8f96c7fa92e507e5deddc2637924b4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 31 Jul 2008 17:02:42 +0900 Subject: libata: misc updates to prepare for slave link * Add ATA_EH_ALL_ACTIONS. * Make sata_link_{on|off}_line() return bool instead of int. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 3eaca347ce2..0c7e6f3c28e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -321,6 +321,8 @@ enum { ATA_EH_LPM = (1 << 4), /* link power management action */ ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, + ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | + ATA_EH_ENABLE_LINK | ATA_EH_LPM, /* ata_eh_info->flags */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ @@ -920,8 +922,8 @@ extern int sata_scr_valid(struct ata_link *link); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val); extern int sata_scr_write_flush(struct ata_link *link, int reg, u32 val); -extern int ata_link_online(struct ata_link *link); -extern int ata_link_offline(struct ata_link *link); +extern bool ata_link_online(struct ata_link *link); +extern bool ata_link_offline(struct ata_link *link); #ifdef CONFIG_PM extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); -- cgit v1.2.3 From b1c72916abbdd0a55015c87358536ca0ebaf6735 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 31 Jul 2008 17:02:43 +0900 Subject: libata: implement slave_link Explanation taken from the comment of ata_slave_link_init(). In libata, a port contains links and a link contains devices. There is single host link but if a PMP is attached to it, there can be multiple fan-out links. On SATA, there's usually a single device connected to a link but PATA and SATA controllers emulating TF based interface can have two - master and slave. However, there are a few controllers which don't fit into this abstraction too well - SATA controllers which emulate TF interface with both master and slave devices but also have separate SCR register sets for each device. These controllers need separate links for physical link handling (e.g. onlineness, link speed) but should be treated like a traditional M/S controller for everything else (e.g. command issue, softreset). slave_link is libata's way of handling this class of controllers without impacting core layer too much. For anything other than physical link handling, the default host link is used for both master and slave. For physical link handling, separate @ap->slave_link is used. All dirty details are implemented inside libata core layer. From LLD's POV, the only difference is that prereset, hardreset and postreset are called once more for the slave link, so the reset sequence looks like the following. prereset(M) -> prereset(S) -> hardreset(M) -> hardreset(S) -> softreset(M) -> postreset(M) -> postreset(S) Note that softreset is called only for the master. Softreset resets both M/S by definition, so SRST on master should handle both (the standard method will work just fine). As slave_link excludes PMP support and only code paths which deal with the attributes of physical link are affected, all the changes are localized to libata.h, libata-core.c and libata-eh.c. * ata_is_host_link() updated so that slave_link is considered as host link too. * iterator extended to iterate over the slave_link when using the underbarred version. * force param handling updated such that devno 16 is mapped to the slave link/device. * ata_link_on/offline() updated to return the combined result from master and slave link. ata_phys_link_on/offline() are the direct versions. * EH autopsy and report are performed separately for master slave links. Reset is udpated to implement the above described reset sequence. Except for reset update, most changes are minor, many of them just modifying dev->link to ata_dev_phys_link(dev) or using phys online test instead. After this update, LLDs can take full advantage of per-dev SCR registers by simply turning on slave link. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0c7e6f3c28e..244ff601559 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -690,7 +690,8 @@ struct ata_port { unsigned int qc_active; int nr_active_links; /* #links with active qcs */ - struct ata_link link; /* host default link */ + struct ata_link link; /* host default link */ + struct ata_link *slave_link; /* see ata_slave_link_init() */ int nr_pmp_links; /* nr of available PMP links */ struct ata_link *pmp_link; /* array of PMP links */ @@ -897,6 +898,7 @@ extern void ata_port_disable(struct ata_port *); extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports); extern struct ata_host *ata_host_alloc_pinfo(struct device *dev, const struct ata_port_info * const * ppi, int n_ports); +extern int ata_slave_link_init(struct ata_port *ap); extern int ata_host_start(struct ata_host *host); extern int ata_host_register(struct ata_host *host, struct scsi_host_template *sht); @@ -1136,7 +1138,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap) static inline int ata_is_host_link(const struct ata_link *link) { - return link == &link->ap->link; + return link == &link->ap->link || link == link->ap->slave_link; } #else /* CONFIG_SATA_PMP */ static inline bool sata_pmp_supported(struct ata_port *ap) @@ -1169,7 +1171,7 @@ static inline int sata_srst_pmp(struct ata_link *link) printk("%sata%u: "fmt, lv, (ap)->print_id , ##args) #define ata_link_printk(link, lv, fmt, args...) do { \ - if (sata_pmp_attached((link)->ap)) \ + if (sata_pmp_attached((link)->ap) || (link)->ap->slave_link) \ printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \ (link)->pmp , ##args); \ else \ -- cgit v1.2.3 From ea6ce53cd5d005455ec0a3cc1d45d3af0cb90919 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Fri, 19 Sep 2008 23:46:01 +0200 Subject: [libata] Introduce ata_id_has_unload() Add a function to check an ATA device's id for head unload support as specified in ATA-7. Signed-off-by: Elias Oltmanns Signed-off-by: Jeff Garzik --- include/linux/ata.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 8a12d718c16..a26ebd25bac 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -667,6 +667,15 @@ static inline int ata_id_has_dword_io(const u16 *id) return 0; } +static inline int ata_id_has_unload(const u16 *id) +{ + if (ata_id_major_version(id) >= 7 && + (id[ATA_ID_CFSSE] & 0xC000) == 0x4000 && + id[ATA_ID_CFSSE] & (1 << 13)) + return 1; + return 0; +} + static inline int ata_id_current_chs_valid(const u16 *id) { /* For ATA-1 devices, if the INITIALIZE DEVICE PARAMETERS command -- cgit v1.2.3 From 45fabbb77bd95adff7a80bde1c7a0ace1075fde6 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Sun, 21 Sep 2008 11:54:08 +0200 Subject: libata: Implement disk shock protection support On user request (through sysfs), the IDLE IMMEDIATE command with UNLOAD FEATURE as specified in ATA-7 is issued to the device and processing of the request queue is stopped thereafter until the specified timeout expires or user space asks to resume normal operation. This is supposed to prevent the heads of a hard drive from accidentally crashing onto the platter when a heavy shock is anticipated (like a falling laptop expected to hit the floor). In fact, the whole port stops processing commands until the timeout has expired in order to avoid any resets due to failed commands on another device. Signed-off-by: Elias Oltmanns Signed-off-by: Jeff Garzik --- include/linux/libata.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 244ff601559..1f44cfb847e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -146,6 +146,7 @@ enum { ATA_DFLAG_SPUNDOWN = (1 << 14), /* XXX: for spindown_compat */ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ + ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ ATA_DFLAG_INIT_MASK = (1 << 24) - 1, ATA_DFLAG_DETACH = (1 << 24), @@ -244,6 +245,7 @@ enum { ATA_TMOUT_BOOT = 30000, /* heuristic */ ATA_TMOUT_BOOT_QUICK = 7000, /* heuristic */ ATA_TMOUT_INTERNAL_QUICK = 5000, + ATA_TMOUT_MAX_PARK = 30000, /* FIXME: GoVault needs 2s but we can't afford that without * parallel probing. 800ms is enough for iVDR disk @@ -319,8 +321,9 @@ enum { ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_ENABLE_LINK = (1 << 3), ATA_EH_LPM = (1 << 4), /* link power management action */ + ATA_EH_PARK = (1 << 5), /* unload heads and stop I/O */ - ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, + ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE | ATA_EH_PARK, ATA_EH_ALL_ACTIONS = ATA_EH_REVALIDATE | ATA_EH_RESET | ATA_EH_ENABLE_LINK | ATA_EH_LPM, @@ -454,6 +457,7 @@ enum link_pm { MEDIUM_POWER, }; extern struct device_attribute dev_attr_link_power_management_policy; +extern struct device_attribute dev_attr_unload_heads; extern struct device_attribute dev_attr_em_message_type; extern struct device_attribute dev_attr_em_message; extern struct device_attribute dev_attr_sw_activity; @@ -566,6 +570,7 @@ struct ata_device { /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ + unsigned long unpark_deadline; u8 pio_mode; u8 dma_mode; @@ -623,6 +628,7 @@ struct ata_eh_context { [ATA_EH_CMD_TIMEOUT_TABLE_SIZE]; unsigned int classes[ATA_MAX_DEVICES]; unsigned int did_probe_mask; + unsigned int unloaded_mask; unsigned int saved_ncq_enabled; u8 saved_xfer_mode[ATA_MAX_DEVICES]; /* timestamp for the last reset attempt or success */ @@ -712,6 +718,7 @@ struct ata_port { struct list_head eh_done_q; wait_queue_head_t eh_wait_q; int eh_tries; + struct completion park_req_pending; pm_message_t pm_mesg; int *pm_result; @@ -1102,6 +1109,7 @@ extern void ata_std_error_handler(struct ata_port *ap); */ extern const struct ata_port_operations ata_base_port_ops; extern const struct ata_port_operations sata_port_ops; +extern struct device_attribute *ata_common_sdev_attrs[]; #define ATA_BASE_SHT(drv_name) \ .module = THIS_MODULE, \ @@ -1116,7 +1124,8 @@ extern const struct ata_port_operations sata_port_ops; .proc_name = drv_name, \ .slave_configure = ata_scsi_slave_config, \ .slave_destroy = ata_scsi_slave_destroy, \ - .bios_param = ata_std_bios_param + .bios_param = ata_std_bios_param, \ + .sdev_attrs = ata_common_sdev_attrs #define ATA_NCQ_SHT(drv_name) \ ATA_BASE_SHT(drv_name), \ -- cgit v1.2.3 From 6866e7bc83f13a1bc6de59099930e9db1ab0042f Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Mon, 22 Sep 2008 14:47:13 -0700 Subject: libata: reorder ata_device to remove 8 bytes of padding on 64 bits reduce size by 8 bytes from 1160 to 1152 allowing it to fit in 1 fewer cachelines. Signed-off-by: Richard Kennedy Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 1f44cfb847e..947cf84e555 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -560,8 +560,8 @@ struct ata_ering { struct ata_device { struct ata_link *link; unsigned int devno; /* 0 or 1 */ - unsigned long flags; /* ATA_DFLAG_xxx */ unsigned int horkage; /* List of broken features */ + unsigned long flags; /* ATA_DFLAG_xxx */ struct scsi_device *sdev; /* attached SCSI device */ #ifdef CONFIG_ATA_ACPI acpi_handle acpi_handle; -- cgit v1.2.3 From b00c1a99e7758f794923c61e5cd55268d61c9469 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 29 Sep 2008 15:44:46 +0200 Subject: hrtimer: mark migration state Impact: during migration active hrtimers can be seen as inactive The migration code removes the hrtimers from the queues of the dead CPU and sets the state temporary to INACTIVE. The enqueue code sets it to ACTIVE/PENDING again. Prevent that the wrong state can be seen by using a separate migration state bit. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 6d93dce61cb..bdd88df1b4e 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -67,9 +67,10 @@ enum hrtimer_cb_mode { * 0x02 callback function running * 0x04 callback pending (high resolution mode) * - * Special case: + * Special cases: * 0x03 callback function running and enqueued * (was requeued on another CPU) + * 0x09 timer was migrated on CPU hotunplug * The "callback function running and enqueued" status is only possible on * SMP. It happens for example when a posix timer expired and the callback * queued a signal. Between dropping the lock which protects the posix timer @@ -87,6 +88,7 @@ enum hrtimer_cb_mode { #define HRTIMER_STATE_ENQUEUED 0x01 #define HRTIMER_STATE_CALLBACK 0x02 #define HRTIMER_STATE_PENDING 0x04 +#define HRTIMER_STATE_MIGRATE 0x08 /** * struct hrtimer - the basic hrtimer structure -- cgit v1.2.3 From ccc7dadf736639da86f3e0c86832c11a66fc8221 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 29 Sep 2008 15:47:42 +0200 Subject: hrtimer: prevent migration of per CPU hrtimers Impact: per CPU hrtimers can be migrated from a dead CPU The hrtimer code has no knowledge about per CPU timers, but we need to prevent the migration of such timers and warn when such a timer is active at migration time. Explicitely mark the timers as per CPU and use a more understandable mode descriptor for the interrupts safe unlocked callback mode, which is used by hrtimer_sleeper and the scheduler code. Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index bdd88df1b4e..2f245fe63bd 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -47,14 +47,22 @@ enum hrtimer_restart { * HRTIMER_CB_IRQSAFE: Callback may run in hardirq context * HRTIMER_CB_IRQSAFE_NO_RESTART: Callback may run in hardirq context and * does not restart the timer - * HRTIMER_CB_IRQSAFE_NO_SOFTIRQ: Callback must run in hardirq context - * Special mode for tick emultation + * 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, HRTIMER_CB_IRQSAFE_NO_RESTART, - HRTIMER_CB_IRQSAFE_NO_SOFTIRQ, + HRTIMER_CB_IRQSAFE_PERCPU, + HRTIMER_CB_IRQSAFE_UNLOCKED, }; /* -- cgit v1.2.3 From e851db5b05408b89b9a9429a66814b79fabee2a1 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 30 Jun 2008 18:45:30 -0400 Subject: SUNRPC: Add address family field to svc_serv data structure Introduce and initialize an address family field in the svc_serv structure. This field will determine what family to use for the service's listener sockets and what families are advertised via the local rpcbind daemon. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index dc69068d94c..23143f38b12 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -66,6 +66,7 @@ struct svc_serv { struct list_head sv_tempsocks; /* all temporary sockets */ int sv_tmpcnt; /* count of temporary sockets */ struct timer_list sv_temptimer; /* timer for aging temporary sockets */ + sa_family_t sv_family; /* listener's address family */ char * sv_name; /* service name */ @@ -381,14 +382,14 @@ struct svc_procedure { /* * Function prototypes. */ -struct svc_serv * svc_create(struct svc_program *, unsigned int, - void (*shutdown)(struct svc_serv*)); +struct svc_serv *svc_create(struct svc_program *, unsigned int, sa_family_t, + void (*shutdown)(struct svc_serv *)); struct svc_rqst *svc_prepare_thread(struct svc_serv *serv, struct svc_pool *pool); void svc_exit_thread(struct svc_rqst *); struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, - void (*shutdown)(struct svc_serv*), svc_thread_fn, - struct module *); + sa_family_t, void (*shutdown)(struct svc_serv *), + svc_thread_fn, struct module *); int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); void svc_destroy(struct svc_serv *); int svc_process(struct svc_rqst *); -- cgit v1.2.3 From 04716e6621ff4abb422d64ba7b48718f52716a3e Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 7 Aug 2008 13:00:20 -0400 Subject: nfsd: permit unauthenticated stat of export root RFC 2623 section 2.3.2 permits the server to bypass gss authentication checks for certain operations that a client may perform when mounting. In the case of a client that doesn't have some form of credentials available to it on boot, this allows it to perform the mount unattended. (Presumably real file access won't be needed until a user with credentials logs in.) Being slightly more lenient allows lots of old clients to access krb5-only exports, with the only loss being a small amount of information leaked about the root directory of the export. This affects only v2 and v3; v4 still requires authentication for all access. Thanks to Peter Staubach testing against a Solaris client, which suggesting addition of v3 getattr, to the list, and to Trond for noting that doing so exposes no additional information. Signed-off-by: J. Bruce Fields Cc: Peter Staubach Cc: Trond Myklebust --- include/linux/nfsd/nfsd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 108f47e5fd9..21269405ffe 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h @@ -38,6 +38,7 @@ #define NFSD_MAY_LOCK 32 #define NFSD_MAY_OWNER_OVERRIDE 64 #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) @@ -125,7 +126,7 @@ int nfsd_truncate(struct svc_rqst *, struct svc_fh *, __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, loff_t *, struct readdir_cd *, filldir_t); __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, - struct kstatfs *); + struct kstatfs *, int access); int nfsd_notify_change(struct inode *, struct iattr *); __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, -- cgit v1.2.3 From bfcd17a6c5529bc37234cfa720a047cf9397bcfc Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 6 Aug 2008 15:12:22 +0200 Subject: Configure out file locking features This patch adds the CONFIG_FILE_LOCKING option which allows to remove support for advisory locks. With this patch enabled, the flock() system call, the F_GETLK, F_SETLK and F_SETLKW operations of fcntl() and NFS support are disabled. These features are not necessarly needed on embedded systems. It allows to save ~11 Kb of kernel code and data: text data bss dec hex filename 1125436 118764 212992 1457192 163c28 vmlinux.old 1114299 118564 212992 1445855 160fdf vmlinux -11137 -200 0 -11337 -2C49 +/- This patch has originally been written by Matt Mackall , and is part of the Linux Tiny project. Signed-off-by: Thomas Petazzoni Signed-off-by: Matt Mackall Cc: matthew@wil.cx Cc: linux-fsdevel@vger.kernel.org Cc: mpm@selenic.com Cc: akpm@linux-foundation.org Signed-off-by: J. Bruce Fields --- include/linux/fs.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 580b513668f..9f540165a07 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -983,6 +983,13 @@ struct file_lock { #include +extern void send_sigio(struct fown_struct *fown, int fd, int band); + +/* fs/sync.c */ +extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset, + loff_t endbyte, unsigned int flags); + +#ifdef CONFIG_FILE_LOCKING extern int fcntl_getlk(struct file *, struct flock __user *); extern int fcntl_setlk(unsigned int, struct file *, unsigned int, struct flock __user *); @@ -993,14 +1000,9 @@ extern int fcntl_setlk64(unsigned int, struct file *, unsigned int, struct flock64 __user *); #endif -extern void send_sigio(struct fown_struct *fown, int fd, int band); extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg); extern int fcntl_getlease(struct file *filp); -/* fs/sync.c */ -extern int do_sync_mapping_range(struct address_space *mapping, loff_t offset, - loff_t endbyte, unsigned int flags); - /* fs/locks.c */ extern void locks_init_lock(struct file_lock *); extern void locks_copy_lock(struct file_lock *, struct file_lock *); @@ -1023,6 +1025,37 @@ extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); extern struct seq_operations locks_seq_operations; +#else /* !CONFIG_FILE_LOCKING */ +#define fcntl_getlk(a, b) ({ -EINVAL; }) +#define fcntl_setlk(a, b, c, d) ({ -EACCES; }) +#if BITS_PER_LONG == 32 +#define fcntl_getlk64(a, b) ({ -EINVAL; }) +#define fcntl_setlk64(a, b, c, d) ({ -EACCES; }) +#endif +#define fcntl_setlease(a, b, c) ({ 0; }) +#define fcntl_getlease(a) ({ 0; }) +#define locks_init_lock(a) ({ }) +#define __locks_copy_lock(a, b) ({ }) +#define locks_copy_lock(a, b) ({ }) +#define locks_remove_posix(a, b) ({ }) +#define locks_remove_flock(a) ({ }) +#define posix_test_lock(a, b) ({ 0; }) +#define posix_lock_file(a, b, c) ({ -ENOLCK; }) +#define posix_lock_file_wait(a, b) ({ -ENOLCK; }) +#define posix_unblock_lock(a, b) (-ENOENT) +#define vfs_test_lock(a, b) ({ 0; }) +#define vfs_lock_file(a, b, c, d) (-ENOLCK) +#define vfs_cancel_lock(a, b) ({ 0; }) +#define flock_lock_file_wait(a, b) ({ -ENOLCK; }) +#define __break_lease(a, b) ({ 0; }) +#define lease_get_mtime(a, b) ({ }) +#define generic_setlease(a, b, c) ({ -EINVAL; }) +#define vfs_setlease(a, b, c) ({ -EINVAL; }) +#define lease_modify(a, b) ({ -EINVAL; }) +#define lock_may_read(a, b, c) ({ 1; }) +#define lock_may_write(a, b, c) ({ 1; }) +#endif /* !CONFIG_FILE_LOCKING */ + struct fasync_struct { int magic; @@ -1554,9 +1587,12 @@ extern int vfs_statfs(struct dentry *, struct kstatfs *); /* /sys/fs */ extern struct kobject *fs_kobj; +extern int rw_verify_area(int, struct file *, loff_t *, size_t); + #define FLOCK_VERIFY_READ 1 #define FLOCK_VERIFY_WRITE 2 +#ifdef CONFIG_FILE_LOCKING extern int locks_mandatory_locked(struct inode *); extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t); @@ -1587,8 +1623,6 @@ static inline int locks_verify_locked(struct inode *inode) return 0; } -extern int rw_verify_area(int, struct file *, loff_t *, size_t); - static inline int locks_verify_truncate(struct inode *inode, struct file *filp, loff_t size) @@ -1609,6 +1643,15 @@ static inline int break_lease(struct inode *inode, unsigned int mode) return __break_lease(inode, mode); return 0; } +#else /* !CONFIG_FILE_LOCKING */ +#define locks_mandatory_locked(a) ({ 0; }) +#define locks_mandatory_area(a, b, c, d, e) ({ 0; }) +#define __mandatory_lock(a) ({ 0; }) +#define mandatory_lock(a) ({ 0; }) +#define locks_verify_locked(a) ({ 0; }) +#define locks_verify_truncate(a, b, c) ({ 0; }) +#define break_lease(a, b) ({ 0; }) +#endif /* CONFIG_FILE_LOCKING */ /* fs/open.c */ -- cgit v1.2.3 From 14aeb2118d6e9fd9ee988324c740a00c80979093 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 18 Aug 2008 19:34:00 -0400 Subject: SUNRPC: Simplify rpcb_register() API Bruce suggested there's no need to expose the difference between an error sending the PMAP_SET request and an error reply from the portmapper to rpcb_register's callers. The user space equivalent of rpcb_register() is pmap_set(3), which returns a bool_t : either the PMAP set worked, or it didn't. Simple. So let's remove the "*okay" argument from rpcb_register() and rpcb_v4_register(), and simply return an error if any part of the call didn't work. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/clnt.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index e5bfe01ee30..8ac8e75243a 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -124,10 +124,10 @@ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); void rpc_shutdown_client(struct rpc_clnt *); void rpc_release_client(struct rpc_clnt *); -int rpcb_register(u32, u32, int, unsigned short, int *); +int rpcb_register(u32, u32, int, unsigned short); int rpcb_v4_register(const u32 program, const u32 version, const struct sockaddr *address, - const char *netid, int *result); + const char *netid); int rpcb_getport_sync(struct sockaddr_in *, u32, u32, int); void rpcb_getport_async(struct rpc_task *); -- cgit v1.2.3 From a26cfad6e0a308a2c68df1f1ef50aabd48b17e6d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Mon, 18 Aug 2008 19:34:16 -0400 Subject: SUNRPC: Support IPv6 when registering kernel RPC services In order to advertise NFS-related services on IPv6 interfaces via rpcbind, the kernel RPC server implementation must use rpcb_v4_register() instead of rpcb_register(). A new kernel build option allows distributions to use the legacy v2 call until they integrate an appropriate user-space rpcbind daemon that can support IPv6 RPC services. I tried adding some automatic logic to fall back if registering with a v4 protocol request failed, but there are too many corner cases. So I just made it a compile-time switch that distributions can throw when they've replaced portmapper with rpcbind. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 23143f38b12..54a79e1ad63 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -393,7 +393,9 @@ struct svc_serv * svc_create_pooled(struct svc_program *, unsigned int, int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int); void svc_destroy(struct svc_serv *); int svc_process(struct svc_rqst *); -int svc_register(struct svc_serv *, int, unsigned short); +int svc_register(const struct svc_serv *, const unsigned short, + const unsigned short); + void svc_wake_up(struct svc_serv *); void svc_reserve(struct svc_rqst *rqstp, int space); struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu); -- cgit v1.2.3 From 1b333c54a15a746ff6b04a684b0845a66daacef2 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 27 Aug 2008 16:57:23 -0400 Subject: lockd: address-family independent printable addresses Knowing which source address is used for communicating with remote NLM services can be helpful for debugging configuration problems on hosts with multiple addresses. Keep the dprintk debugging here, but adapt it so it displays AF_INET6 addresses properly. There are also a couple of dprintk clean-ups as well. At some point we will aggregate the helpers that display presentation format addresses into a single set of shared helpers. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index dbb87ab282e..0691efbd0b3 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -61,6 +61,9 @@ struct nlm_host { struct list_head h_granted; /* Locks in GRANTED state */ struct list_head h_reclaim; /* Locks in RECLAIM state */ struct nsm_handle * h_nsmhandle; /* NSM status handle */ + + char h_addrbuf[48], /* address eyecatchers */ + h_saddrbuf[48]; }; struct nsm_handle { @@ -70,6 +73,7 @@ struct nsm_handle { struct sockaddr_in sm_addr; unsigned int sm_monitored : 1, sm_sticky : 1; /* don't unmonitor */ + char sm_addrbuf[48]; /* address eyecatcher */ }; /* -- cgit v1.2.3 From 5344b12d4f97d4a9a62d806425977a6ff64b6baf Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 27 Aug 2008 16:57:46 -0400 Subject: SUNRPC: Make svc_addr's argument a constant Clean up: Add extra type safety and squelch a few compiler complaints in upcoming patches. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 54a79e1ad63..3afe7fb403b 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -266,17 +266,17 @@ struct svc_rqst { /* * Rigorous type checking on sockaddr type conversions */ -static inline struct sockaddr_in *svc_addr_in(struct svc_rqst *rqst) +static inline struct sockaddr_in *svc_addr_in(const struct svc_rqst *rqst) { return (struct sockaddr_in *) &rqst->rq_addr; } -static inline struct sockaddr_in6 *svc_addr_in6(struct svc_rqst *rqst) +static inline struct sockaddr_in6 *svc_addr_in6(const struct svc_rqst *rqst) { return (struct sockaddr_in6 *) &rqst->rq_addr; } -static inline struct sockaddr *svc_addr(struct svc_rqst *rqst) +static inline struct sockaddr *svc_addr(const struct svc_rqst *rqst) { return (struct sockaddr *) &rqst->rq_addr; } -- cgit v1.2.3 From b4ed58fd34d4def88bda59f9cc566ec9fca6a096 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 3 Sep 2008 14:35:39 -0400 Subject: lockd: Use sockaddr_storage + length for h_addr field To store larger addresses in the nlm_host structure, make h_addr a sockaddr_storage, and add an address length field. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 0691efbd0b3..41d7a8e61ce 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -38,7 +38,8 @@ */ struct nlm_host { struct hlist_node h_hash; /* doubly linked list */ - struct sockaddr_in h_addr; /* peer address */ + struct sockaddr_storage h_addr; /* peer address */ + size_t h_addrlen; struct sockaddr_in h_saddr; /* our address (optional) */ struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ char * h_name; /* remote hostname */ @@ -76,6 +77,19 @@ struct nsm_handle { char sm_addrbuf[48]; /* address eyecatcher */ }; +/* + * Rigorous type checking on sockaddr type conversions + */ +static inline struct sockaddr_in *nlm_addr_in(const struct nlm_host *host) +{ + return (struct sockaddr_in *)&host->h_addr; +} + +static inline struct sockaddr *nlm_addr(const struct nlm_host *host) +{ + return (struct sockaddr *)&host->h_addr; +} + /* * Map an fl_owner_t into a unique 32-bit "pid" */ -- cgit v1.2.3 From 90151e6e4d00a3150d03d52170c246734b274622 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 3 Sep 2008 14:35:46 -0400 Subject: lockd: Use sockaddr_storage for h_saddr field To store larger addresses in the nlm_host structure, make h_saddr a sockaddr_storage. And let's call it something more self-explanatory: "saddr" could easily be mistaken for "server address". Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 41d7a8e61ce..964e6c93830 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -40,7 +40,7 @@ struct nlm_host { struct hlist_node h_hash; /* doubly linked list */ struct sockaddr_storage h_addr; /* peer address */ size_t h_addrlen; - struct sockaddr_in h_saddr; /* our address (optional) */ + struct sockaddr_storage h_srcaddr; /* our address (optional) */ struct rpc_clnt * h_rpcclnt; /* RPC client to talk to peer */ char * h_name; /* remote hostname */ u32 h_version; /* interface version */ @@ -64,7 +64,7 @@ struct nlm_host { struct nsm_handle * h_nsmhandle; /* NSM status handle */ char h_addrbuf[48], /* address eyecatchers */ - h_saddrbuf[48]; + h_srcaddrbuf[48]; }; struct nsm_handle { @@ -90,6 +90,16 @@ static inline struct sockaddr *nlm_addr(const struct nlm_host *host) return (struct sockaddr *)&host->h_addr; } +static inline struct sockaddr_in *nlm_srcaddr_in(const struct nlm_host *host) +{ + return (struct sockaddr_in *)&host->h_srcaddr; +} + +static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host) +{ + return (struct sockaddr *)&host->h_srcaddr; +} + /* * Map an fl_owner_t into a unique 32-bit "pid" */ -- cgit v1.2.3 From 7e9d7746bfd40121438b155023793796499497d8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 3 Sep 2008 14:35:54 -0400 Subject: NSM: Use sockaddr_storage for sm_addr field To store larger addresses in the nsm_handle structure, make sm_addr a sockaddr_storage. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 964e6c93830..b1dfa0b1d1b 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -71,7 +71,8 @@ struct nsm_handle { struct list_head sm_link; atomic_t sm_count; char * sm_name; - struct sockaddr_in sm_addr; + struct sockaddr_storage sm_addr; + size_t sm_addrlen; unsigned int sm_monitored : 1, sm_sticky : 1; /* don't unmonitor */ char sm_addrbuf[48]; /* address eyecatcher */ @@ -100,6 +101,16 @@ static inline struct sockaddr *nlm_srcaddr(const struct nlm_host *host) return (struct sockaddr *)&host->h_srcaddr; } +static inline struct sockaddr_in *nsm_addr_in(const struct nsm_handle *handle) +{ + return (struct sockaddr_in *)&handle->sm_addr; +} + +static inline struct sockaddr *nsm_addr(const struct nsm_handle *handle) +{ + return (struct sockaddr *)&handle->sm_addr; +} + /* * Map an fl_owner_t into a unique 32-bit "pid" */ -- cgit v1.2.3 From 781b61a6f4ff94cb8c14cf598b547f5d5c490969 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Wed, 3 Sep 2008 14:36:01 -0400 Subject: lockd: Teach nlm_cmp_addr() to support AF_INET6 addresses Update the nlm_cmp_addr() helper to support AF_INET6 as well as AF_INET addresses. New version takes two "struct sockaddr *" arguments instead of "struct sockaddr_in *" arguments. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index b1dfa0b1d1b..ec8af115843 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -12,6 +12,8 @@ #ifdef __KERNEL__ #include +#include +#include #include #include #include @@ -272,13 +274,39 @@ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) return file->f_file->f_path.dentry->d_inode; } +static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, + const struct sockaddr *sap2) +{ + const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1; + const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2; + return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; +} + +static inline int __nlm_cmp_addr6(const struct sockaddr *sap1, + const struct sockaddr *sap2) +{ + const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1; + const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2; + return ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr); +} + /* - * Compare two host addresses (needs modifying for ipv6) + * Compare two host addresses + * + * Return TRUE if the addresses are the same; otherwise FALSE. */ -static inline int nlm_cmp_addr(const struct sockaddr_in *sin1, - const struct sockaddr_in *sin2) +static inline int nlm_cmp_addr(const struct sockaddr *sap1, + const struct sockaddr *sap2) { - return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr; + if (sap1->sa_family == sap2->sa_family) { + switch (sap1->sa_family) { + case AF_INET: + return __nlm_cmp_addr4(sap1, sap2); + case AF_INET6: + return __nlm_cmp_addr6(sap1, sap2); + } + } + return 0; } /* -- cgit v1.2.3 From d5b337b4877f7c4e1d761434ee04d045b0201e03 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Sun, 28 Sep 2008 09:21:26 +0300 Subject: nfsd: use nfs client rpc callback program since commit ff7d9756b501744540be65e172d27ee321d86103 "nfsd: use static memory for callback program and stats" do_probe_callback uses a static callback program (NFS4_CALLBACK) rather than the one set in clp->cl_callback.cb_prog as passed in by the client in setclientid (4.0) or create_session (4.1). This patches introduces rpc_create_args.prognumber that allows overriding program->number when creating rpc_clnt. Signed-off-by: Benny Halevy Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/clnt.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 8ac8e75243a..6f0ee1b84a4 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -104,6 +104,7 @@ struct rpc_create_args { const struct rpc_timeout *timeout; char *servername; struct rpc_program *program; + u32 prognumber; /* overrides program->number */ u32 version; rpc_authflavor_t authflavor; unsigned long flags; -- cgit v1.2.3 From cf04a4c764cd3e651a64b3e667bb6a673ead99e1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 30 Sep 2008 02:22:14 -0700 Subject: netdev: use const for some name functions dev_change_name and netdev_drivername should use const char on parameters that are read-only input values. The strcpy to newname is not needed since newname is not used later in function. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- include/linux/netdevice.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d675df08b94..9cfd20be8b7 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1225,7 +1225,7 @@ extern int dev_ioctl(struct net *net, unsigned int cmd, void __user *); extern int dev_ethtool(struct net *net, struct ifreq *); extern unsigned dev_get_flags(const struct net_device *); extern int dev_change_flags(struct net_device *, unsigned); -extern int dev_change_name(struct net_device *, char *); +extern int dev_change_name(struct net_device *, const char *); extern int dev_set_alias(struct net_device *, const char *, size_t); extern int dev_change_net_namespace(struct net_device *, struct net *, const char *); @@ -1670,7 +1670,7 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern int netdev_class_create_file(struct class_attribute *class_attr); extern void netdev_class_remove_file(struct class_attribute *class_attr); -extern char *netdev_drivername(struct net_device *dev, char *buffer, int len); +extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len); extern void linkwatch_run_queue(void); -- cgit v1.2.3 From a57334e95e4fb132acca05bdc0efa2f9dda194af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Tue, 30 Sep 2008 02:53:18 -0700 Subject: Phonet: declare headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/Kbuild | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index b68ec09399b..f431e40725d 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -126,6 +126,7 @@ header-y += pci_regs.h header-y += pfkeyv2.h header-y += pg.h header-y += phantom.h +header-y += phonet.h header-y += pkt_cls.h header-y += pkt_sched.h header-y += posix_types.h @@ -232,6 +233,7 @@ unifdef-y += if_fddi.h unifdef-y += if_frad.h unifdef-y += if_ltalk.h unifdef-y += if_link.h +unifdef-y += if_phonet.h unifdef-y += if_pppol2tp.h unifdef-y += if_pppox.h unifdef-y += if_tr.h -- cgit v1.2.3 From 1c50b728c3e734150b8a4a8310ce3e01bc5c70be Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 29 Sep 2008 11:06:46 -0400 Subject: rcu: add rcu_read_lock_sched() / rcu_read_unlock_sched() Add rcu_read_lock_sched() and rcu_read_unlock_sched() to rcupdate.h to match the recently added write-side call_rcu_sched() and rcu_barrier_sched(). They also match the no-so-recently-added synchronize_sched(). It will help following matching use of the update/read lock primitives. Those new read lock will replace preempt_disable()/enable() used in pair with RCU-classic synchronization. Signed-off-by: Mathieu Desnoyers Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/rcupdate.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index e8b4039cfb2..86f1f5e43e3 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -132,6 +132,26 @@ struct rcu_head { */ #define rcu_read_unlock_bh() __rcu_read_unlock_bh() +/** + * rcu_read_lock_sched - mark the beginning of a RCU-classic critical section + * + * Should be used with either + * - synchronize_sched() + * or + * - call_rcu_sched() and rcu_barrier_sched() + * on the write-side to insure proper synchronization. + */ +#define rcu_read_lock_sched() preempt_disable() + +/* + * rcu_read_unlock_sched - marks the end of a RCU-classic critical section + * + * See rcu_read_lock_sched for more information. + */ +#define rcu_read_unlock_sched() preempt_enable() + + + /** * rcu_dereference - fetch an RCU-protected pointer in an * RCU read-side critical section. This pointer may later -- cgit v1.2.3 From 24268245d8ba9270152b2281666099ddc8ca389d Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 1 Oct 2008 08:59:40 +0200 Subject: x86: add PCI IDs for AMD Barcelona PCI devices Signed-off-by: Robert Richter Cc: oprofile-list Cc: Barry Kasindorf Signed-off-by: Ingo Molnar --- include/linux/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2886b0eb53e..c114103af98 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -497,6 +497,11 @@ #define PCI_DEVICE_ID_AMD_K8_NB_ADDRMAP 0x1101 #define PCI_DEVICE_ID_AMD_K8_NB_MEMCTL 0x1102 #define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 +#define PCI_DEVICE_ID_AMD_10H_NB_HT 0x1200 +#define PCI_DEVICE_ID_AMD_10H_NB_MAP 0x1201 +#define PCI_DEVICE_ID_AMD_10H_NB_DRAM 0x1202 +#define PCI_DEVICE_ID_AMD_10H_NB_MISC 0x1203 +#define PCI_DEVICE_ID_AMD_10H_NB_LINK 0x1204 #define PCI_DEVICE_ID_AMD_11H_NB_HT 0x1300 #define PCI_DEVICE_ID_AMD_11H_NB_MAP 0x1301 #define PCI_DEVICE_ID_AMD_11H_NB_DRAM 0x1302 -- cgit v1.2.3 From bbfbd8b151fe35c9a1180a7f5254c5d6b8387cc0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 1 Oct 2008 16:13:54 +0900 Subject: sh: Move the shared INTC code out to drivers/sh/ The INTC code will be re-used across different architectures, so move this out to drivers/sh/ and include/linux/sh_intc.h respectively. Signed-off-by: Paul Mundt --- include/linux/sh_intc.h | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 include/linux/sh_intc.h (limited to 'include/linux') diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h new file mode 100644 index 00000000000..68e212ff9dd --- /dev/null +++ b/include/linux/sh_intc.h @@ -0,0 +1,91 @@ +#ifndef __SH_INTC_H +#define __SH_INTC_H + +typedef unsigned char intc_enum; + +struct intc_vect { + intc_enum enum_id; + unsigned short vect; +}; + +#define INTC_VECT(enum_id, vect) { enum_id, vect } +#define INTC_IRQ(enum_id, irq) INTC_VECT(enum_id, irq2evt(irq)) + +struct intc_group { + intc_enum enum_id; + intc_enum enum_ids[32]; +}; + +#define INTC_GROUP(enum_id, ids...) { enum_id, { ids } } + +struct intc_mask_reg { + unsigned long set_reg, clr_reg, reg_width; + intc_enum enum_ids[32]; +#ifdef CONFIG_SMP + unsigned long smp; +#endif +}; + +struct intc_prio_reg { + unsigned long set_reg, clr_reg, reg_width, field_width; + intc_enum enum_ids[16]; +#ifdef CONFIG_SMP + unsigned long smp; +#endif +}; + +struct intc_sense_reg { + unsigned long reg, reg_width, field_width; + intc_enum enum_ids[16]; +}; + +#ifdef CONFIG_SMP +#define INTC_SMP(stride, nr) .smp = (stride) | ((nr) << 8) +#else +#define INTC_SMP(stride, nr) +#endif + +struct intc_desc { + struct intc_vect *vectors; + unsigned int nr_vectors; + struct intc_group *groups; + unsigned int nr_groups; + struct intc_mask_reg *mask_regs; + unsigned int nr_mask_regs; + struct intc_prio_reg *prio_regs; + unsigned int nr_prio_regs; + struct intc_sense_reg *sense_regs; + unsigned int nr_sense_regs; + char *name; +#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) + struct intc_mask_reg *ack_regs; + unsigned int nr_ack_regs; +#endif +}; + +#define _INTC_ARRAY(a) a, sizeof(a)/sizeof(*a) +#define DECLARE_INTC_DESC(symbol, chipname, vectors, groups, \ + mask_regs, prio_regs, sense_regs) \ +struct intc_desc symbol __initdata = { \ + _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ + _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ + _INTC_ARRAY(sense_regs), \ + chipname, \ +} + +#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A) +#define DECLARE_INTC_DESC_ACK(symbol, chipname, vectors, groups, \ + mask_regs, prio_regs, sense_regs, ack_regs) \ +struct intc_desc symbol __initdata = { \ + _INTC_ARRAY(vectors), _INTC_ARRAY(groups), \ + _INTC_ARRAY(mask_regs), _INTC_ARRAY(prio_regs), \ + _INTC_ARRAY(sense_regs), \ + chipname, \ + _INTC_ARRAY(ack_regs), \ +} +#endif + +void __init register_intc_controller(struct intc_desc *desc); +int intc_set_priority(unsigned int irq, unsigned int prio); + +#endif /* __SH_INTC_H */ -- cgit v1.2.3 From 6e50e8a2136f1a90de251c653226ded447c5c915 Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Wed, 1 Oct 2008 01:30:19 -0700 Subject: phonet: Protect if_phonet.h against multiple inclusions. From: Remi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/if_phonet.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h index 7e989216ec1..d70034bcec0 100644 --- a/include/linux/if_phonet.h +++ b/include/linux/if_phonet.h @@ -5,14 +5,15 @@ * * Copyright (C) 2008 Nokia Corporation. All rights reserved. */ +#ifndef LINUX_IF_PHONET_H +#define LINUX_IF_PHONET_H -#define PHONET_HEADER_LEN 8 /* Phonet header length */ - -#define PHONET_MIN_MTU 6 -/* 6 bytes header + 65535 bytes payload */ -#define PHONET_MAX_MTU 65541 +#define PHONET_MIN_MTU 6 /* pn_length = 0 */ +#define PHONET_MAX_MTU 65541 /* pn_length = 0xffff */ #define PHONET_DEV_MTU PHONET_MAX_MTU #ifdef __KERNEL__ extern struct header_ops phonet_header_ops; #endif + +#endif -- cgit v1.2.3 From 04a4bb55bcf35b63d40fd2725e58599ff8310dd7 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 1 Oct 2008 02:33:12 -0700 Subject: net: add skb_recycle_check() to enable netdriver skb recycling This patch adds skb_recycle_check(), which can be used by a network driver after transmitting an skb to check whether this skb can be recycled as a receive buffer. skb_recycle_check() checks that the skb is not shared or cloned, and that it is linear and its head portion large enough (as determined by the driver) to be recycled as a receive buffer. If these conditions are met, it does any necessary reference count dropping and cleans up the skbuff as if it just came from __alloc_skb(). Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a19ea43fea0..720b688c22b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -383,6 +383,8 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size, return __alloc_skb(size, priority, 1, -1); } +extern int skb_recycle_check(struct sk_buff *skb, int skb_size); + extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src); extern struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t priority); -- cgit v1.2.3 From 12a169e7d8f4b1c95252d8b04ed0f1033ed7cfe2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 1 Oct 2008 07:03:24 -0700 Subject: ipsec: Put dumpers on the dump list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Herbert Xu came up with the idea and the original patch to make xfrm_state dump list contain also dumpers: As it is we go to extraordinary lengths to ensure that states don't go away while dumpers go to sleep. It's much easier if we just put the dumpers themselves on the list since they can't go away while they're going. I've also changed the order of addition on new states to prevent a never-ending dump. Timo Teräs improved the patch to apply cleanly to latest tree, modified iteration code to be more readable by using a common struct for entries in the list, implemented the same idea for xfrm_policy dumping and moved the af_key specific "last" entry caching to af_key. Signed-off-by: Herbert Xu Signed-off-by: Timo Teras Signed-off-by: David S. Miller --- include/linux/netlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index cbba7760545..9ff1b54908f 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -220,7 +220,7 @@ struct netlink_callback int (*dump)(struct sk_buff * skb, struct netlink_callback *cb); int (*done)(struct netlink_callback *cb); int family; - long args[7]; + long args[6]; }; struct netlink_notify -- cgit v1.2.3 From f5715aea4564f233767ea1d944b2637a5fd7cd2e Mon Sep 17 00:00:00 2001 From: KOVACS Krisztian Date: Wed, 1 Oct 2008 07:30:02 -0700 Subject: ipv4: Implement IP_TRANSPARENT socket option This patch introduces the IP_TRANSPARENT socket option: enabling that will make the IPv4 routing omit the non-local source address check on output. Setting IP_TRANSPARENT requires NET_ADMIN capability. Signed-off-by: KOVACS Krisztian Signed-off-by: David S. Miller --- include/linux/in.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/in.h b/include/linux/in.h index 4065313cd7e..db458beef19 100644 --- a/include/linux/in.h +++ b/include/linux/in.h @@ -75,6 +75,7 @@ struct in_addr { #define IP_IPSEC_POLICY 16 #define IP_XFRM_POLICY 17 #define IP_PASSSEC 18 +#define IP_TRANSPARENT 19 /* BSD compatibility */ #define IP_RECVRETOPTS IP_RETOPTS -- cgit v1.2.3 From 4e9687d9c843dc34d368358a36f5f1610e4fbab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Va=C5=A1ut?= Date: Thu, 11 Sep 2008 19:37:32 +0100 Subject: [ARM] 5248/1: wm97xx generic battery driver This patch adds generic battery driver for wm97xx chips. Signed-off-by: Marek Vasut Acked-by: Anton Vorontsov Acked-by: Mark Brown Signed-off-by: Russell King --- include/linux/wm97xx_batt.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 include/linux/wm97xx_batt.h (limited to 'include/linux') diff --git a/include/linux/wm97xx_batt.h b/include/linux/wm97xx_batt.h new file mode 100644 index 00000000000..9681d1ab0e4 --- /dev/null +++ b/include/linux/wm97xx_batt.h @@ -0,0 +1,26 @@ +#ifndef _LINUX_WM97XX_BAT_H +#define _LINUX_WM97XX_BAT_H + +#include + +struct wm97xx_batt_info { + int batt_aux; + int temp_aux; + int charge_gpio; + int min_voltage; + int max_voltage; + int batt_div; + int batt_mult; + int temp_div; + int temp_mult; + int batt_tech; + char *batt_name; +}; + +#ifdef CONFIG_BATTERY_WM97XX +void __init wm97xx_bat_set_pdata(struct wm97xx_batt_info *data); +#else +static inline void wm97xx_bat_set_pdata(struct wm97xx_batt_info *data) {} +#endif + +#endif -- cgit v1.2.3 From 4b19de6d1cb07c8bcb6778e771f9cfd5bcfdfd3e Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Thu, 2 Oct 2008 14:50:16 -0700 Subject: mm: tiny-shmem nommu fix The previous patch db203d53d474aa068984e409d807628f5841da1b ("mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex") to fix the lock ordering in tiny-shmem breaks shared anonymous and IPC memory on NOMMU architectures because it was using the expanding truncate to signal ramfs to allocate a physically contiguous RAM backing the inode (otherwise it is unusable for "memory mapping" it to userspace). However do_truncate is what caused the lock ordering error, due to it taking i_mutex. In this case, we can actually just call ramfs directly to allocate memory for the mapping, rather than go via truncate. Acked-by: David Howells Acked-by: Hugh Dickins Signed-off-by: Nick Piggin Cc: Matt Mackall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ramfs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index b160fb18e8d..37aaf2b3986 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -6,6 +6,7 @@ extern int ramfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt); #ifndef CONFIG_MMU +extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, -- cgit v1.2.3 From 2133b5d7ff531bc15a923db4a6a50bf96c561be9 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Thu, 2 Oct 2008 16:06:39 -0700 Subject: rcu: RCU-based detection of stalled CPUs for Classic RCU This patch adds stalled-CPU detection to Classic RCU. This capability is enabled by a new config variable CONFIG_RCU_CPU_STALL_DETECTOR, which defaults disabled. This is a debugging feature to detect infinite loops in kernel code, not something that non-kernel-hackers would be expected to care about. This feature can detect looping CPUs in !PREEMPT builds and looping CPUs with preemption disabled in PREEMPT builds. This is essentially a port of this functionality from the treercu patch, replacing the stall debug patch that is already in tip/core/rcu (commit 67182ae1c4). The changes from the patch in tip/core/rcu include making the config variable name match that in treercu, changing from seconds to jiffies to avoid spurious warnings, and printing a boot message when this feature is enabled. Signed-off-by: Paul E. McKenney Signed-off-by: Ingo Molnar --- include/linux/rcuclassic.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcuclassic.h b/include/linux/rcuclassic.h index 29bf528c7dc..5f89b62e698 100644 --- a/include/linux/rcuclassic.h +++ b/include/linux/rcuclassic.h @@ -40,15 +40,21 @@ #include #include +#ifdef CONFIG_RCU_CPU_STALL_DETECTOR +#define RCU_SECONDS_TILL_STALL_CHECK ( 3 * HZ) /* for rcp->jiffies_stall */ +#define RCU_SECONDS_TILL_STALL_RECHECK (30 * HZ) /* for rcp->jiffies_stall */ +#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ /* Global control variables for rcupdate callback mechanism. */ struct rcu_ctrlblk { long cur; /* Current batch number. */ long completed; /* Number of the last completed batch */ long pending; /* Number of the last pending batch */ -#ifdef CONFIG_DEBUG_RCU_STALL - unsigned long gp_check; /* Time grace period should end, in seconds. */ -#endif /* #ifdef CONFIG_DEBUG_RCU_STALL */ +#ifdef CONFIG_RCU_CPU_STALL_DETECTOR + unsigned long gp_start; /* Time at which GP started in jiffies. */ + unsigned long jiffies_stall; + /* Time at which to check for CPU stalls. */ +#endif /* #ifdef CONFIG_RCU_CPU_STALL_DETECTOR */ int signaled; -- cgit v1.2.3 From 3c9f3681d0b4af09c1cbf04f92fdfb72bd81ad7b Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 31 Aug 2008 10:13:54 -0500 Subject: [SCSI] lib: add generic helper to print sizes rounded to the correct SI range This patch adds the ability to print sizes in either units of 10^3 (SI) or 2^10 (Binary) units. It rounds up to three significant figures and can be used for either memory or storage capacities. Oh, and I'm fully aware that 64 bits is only 16EiB ... the Zetta and Yotta units are added for future proofing against the day we have 128 bit computers ... [fujita.tomonori@lab.ntt.co.jp: fix missed unsigned long long cast] Signed-off-by: James Bottomley --- include/linux/string_helpers.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 include/linux/string_helpers.h (limited to 'include/linux') diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h new file mode 100644 index 00000000000..a3eb2f65b65 --- /dev/null +++ b/include/linux/string_helpers.h @@ -0,0 +1,16 @@ +#ifndef _LINUX_STRING_HELPERS_H_ +#define _LINUX_STRING_HELPERS_H_ + +#include + +/* Descriptions of the types of units to + * print in */ +enum string_size_units { + STRING_UNITS_10, /* use powers of 10^3 (standard SI) */ + STRING_UNITS_2, /* use binary powers of 2^10 */ +}; + +int string_get_size(u64 size, enum string_size_units units, + char *buf, int len); + +#endif -- cgit v1.2.3 From af558e33bedab672f5cfd3260bce7445e353fe21 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 6 Sep 2007 12:34:25 -0400 Subject: nfsd: common grace period control Rewrite grace period code to unify management of grace period across lockd and nfsd. The current code has lockd and nfsd cooperate to compute a grace period which is satisfactory to them both, and then individually enforce it. This creates a slight race condition, since the enforcement is not coordinated. It's also more complicated than necessary. Here instead we have lockd and nfsd each inform common code when they enter the grace period, and when they're ready to leave the grace period, and allow normal locking only after both of them are ready to leave. We also expect the locks_start_grace()/locks_end_grace() interface here to be simpler to build on for future cluster/high-availability work, which may require (for example) putting individual filesystems into grace, or enforcing grace periods across multiple cluster nodes. Signed-off-by: J. Bruce Fields --- include/linux/fs.h | 8 ++++++++ include/linux/lockd/bind.h | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 9f540165a07..27cfa723b92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -942,6 +942,14 @@ struct lock_manager_operations { int (*fl_change)(struct file_lock **, int); }; +struct lock_manager { + struct list_head list; +}; + +void locks_start_grace(struct lock_manager *); +void locks_end_grace(struct lock_manager *); +int locks_in_grace(void); + /* that will die - we need it for nfs_lock_info */ #include diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index 3d25bcd139d..1f0465c374d 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -27,7 +27,6 @@ struct nlmsvc_binding { struct nfs_fh *, struct file **); void (*fclose)(struct file *); - unsigned long (*get_grace_period)(void); }; extern struct nlmsvc_binding * nlmsvc_ops; @@ -56,12 +55,4 @@ extern int nlmclnt_proc(struct nlm_host *host, int cmd, extern int lockd_up(int proto); extern void lockd_down(void); -unsigned long get_nfs_grace_period(void); - -#ifdef CONFIG_NFSD_V4 -unsigned long get_nfs4_grace_period(void); -#else -static inline unsigned long get_nfs4_grace_period(void) {return 0;} -#endif - #endif /* LINUX_LOCKD_BIND_H */ -- cgit v1.2.3 From b2b5028905226f85075a408b1118857c9aa48bb3 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 6 Feb 2008 13:59:23 -0500 Subject: lockd: move grace period checks to common code Do all the grace period checks in svclock.c. This simplifies the code a bit, and will ease some later changes. Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index ec8af115843..973ab1d6e86 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -242,7 +242,7 @@ typedef int (*nlm_host_match_fn_t)(void *cur, struct nlm_host *ref); */ __be32 nlmsvc_lock(struct svc_rqst *, struct nlm_file *, struct nlm_host *, struct nlm_lock *, int, - struct nlm_cookie *); + struct nlm_cookie *, int); __be32 nlmsvc_unlock(struct nlm_file *, struct nlm_lock *); __be32 nlmsvc_testlock(struct svc_rqst *, struct nlm_file *, struct nlm_host *, struct nlm_lock *, -- cgit v1.2.3 From 0d3ebb9ae9f9c887518fd4c81a68084111d154d7 Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Tue, 30 Sep 2008 13:06:13 -0500 Subject: svcrdma: Add Fast Reg MR Data Types Add data types to track Fast Reg Memory Regions. The core data type is svc_rdma_fastreg_mr that associates a device MR with a host kva and page list. A field is added to the WR context to keep track of the FRMR used to map the local memory for an RPC. An FRMR list and spin lock are added to the transport instance to keep track of all FRMR allocated for the transport. Also added are device capability flags to indicate what the memory registration capabilities are for the underlying device and whether or not fast memory registration is supported. Signed-off-by: Tom Tucker --- include/linux/sunrpc/svc_rdma.h | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index dc05b54bd3a..49e458d9894 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -72,6 +72,7 @@ extern atomic_t rdma_stat_sq_prod; */ struct svc_rdma_op_ctxt { struct svc_rdma_op_ctxt *read_hdr; + struct svc_rdma_fastreg_mr *frmr; int hdr_count; struct xdr_buf arg; struct list_head dto_q; @@ -103,16 +104,30 @@ struct svc_rdma_chunk_sge { int start; /* sge no for this chunk */ int count; /* sge count for this chunk */ }; +struct svc_rdma_fastreg_mr { + struct ib_mr *mr; + void *kva; + struct ib_fast_reg_page_list *page_list; + int page_list_len; + unsigned long access_flags; + unsigned long map_len; + enum dma_data_direction direction; + struct list_head frmr_list; +}; struct svc_rdma_req_map { + struct svc_rdma_fastreg_mr *frmr; unsigned long count; union { struct kvec sge[RPCSVC_MAXPAGES]; struct svc_rdma_chunk_sge ch[RPCSVC_MAXPAGES]; }; }; - +#define RDMACTXT_F_FAST_UNREG 1 #define RDMACTXT_F_LAST_CTXT 2 +#define SVCRDMA_DEVCAP_FAST_REG 1 /* fast mr registration */ +#define SVCRDMA_DEVCAP_READ_W_INV 2 /* read w/ invalidate */ + struct svcxprt_rdma { struct svc_xprt sc_xprt; /* SVC transport structure */ struct rdma_cm_id *sc_cm_id; /* RDMA connection id */ @@ -136,6 +151,11 @@ struct svcxprt_rdma { struct ib_cq *sc_rq_cq; struct ib_cq *sc_sq_cq; struct ib_mr *sc_phys_mr; /* MR for server memory */ + u32 sc_dev_caps; /* distilled device caps */ + u32 sc_dma_lkey; /* local dma key */ + unsigned int sc_frmr_pg_list_len; + struct list_head sc_frmr_q; + spinlock_t sc_frmr_q_lock; spinlock_t sc_lock; /* transport lock */ -- cgit v1.2.3 From d7d204403b31beb83b1aefef7bd76f5209369555 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 12:50:21 -0400 Subject: lockd: Adjust nlmclnt_lookup_host() signature to accomodate non-AF_INET Pass a struct sockaddr * and a length to nlmclnt_lookup_host() to accomodate non-AF_INET family addresses. As a side benefit, eliminate the hostname_len argument, as the hostname is always NUL-terminated. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 973ab1d6e86..90a996d2f00 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -215,10 +215,11 @@ void nlmclnt_next_cookie(struct nlm_cookie *); /* * Host cache */ -struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *sin, - int proto, u32 version, - const char *hostname, - unsigned int hostname_len); +struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, + const size_t salen, + const unsigned short protocol, + const u32 version, + const char *hostname); struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *, unsigned int); struct rpc_clnt * nlm_bind_host(struct nlm_host *); -- cgit v1.2.3 From 6bfbe8af4674458e6d88aef8f0136bd1b8855b11 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 12:50:29 -0400 Subject: lockd: Adjust nlmsvc_lookup_host() to accomodate AF_INET6 addresses Fix up nlmsvc_lookup_host() to pass AF_INET6 source addresses to nlm_lookup_host(). Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 90a996d2f00..16ff2e88f05 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -220,8 +220,9 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const unsigned short protocol, const u32 version, const char *hostname); -struct nlm_host *nlmsvc_lookup_host(struct svc_rqst *, const char *, - unsigned int); +struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, + const char *hostname, + const size_t hostname_len); struct rpc_clnt * nlm_bind_host(struct nlm_host *); void nlm_rebind_host(struct nlm_host *); struct nlm_host * nlm_get_host(struct nlm_host *); -- cgit v1.2.3 From dcff09f124f71d1d4fe61eb63c79e52f488ac22e Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 12:50:36 -0400 Subject: lockd: change nlmclnt_grant() to take a "struct sockaddr *" Adjust the signature and callers of nlmclnt_grant() to pass a "struct sockaddr *" instead of a "struct sockaddr_in *" in order to support IPv6 addresses. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 16ff2e88f05..e6b07097928 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -207,7 +207,8 @@ int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *); struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_wait *block); int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout); -__be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *); +__be32 nlmclnt_grant(const struct sockaddr *addr, + const struct nlm_lock *lock); void nlmclnt_recovery(struct nlm_host *); int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); void nlmclnt_next_cookie(struct nlm_cookie *); -- cgit v1.2.3 From b85e4676344fc4d7ec5e0f62c3d3712e48bbe223 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 12:50:44 -0400 Subject: lockd: Add helper to sanity check incoming NOTIFY requests lockd accepts SM_NOTIFY calls only from a privileged process on the local system. If lockd uses an AF_INET6 listener, the sender's address (ie the local rpc.statd) will be the IPv6 loopback address, not the IPv4 loopback address. Make sure the privilege test in nlmsvc_proc_sm_notify() and nlm4svc_proc_sm_notify() works for both AF_INET and AF_INET6 family addresses by refactoring the test into a helper and adding support for IPv6 addresses. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/lockd.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'include/linux') diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index e6b07097928..b56d5aa9b19 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -277,6 +277,47 @@ static inline struct inode *nlmsvc_file_inode(struct nlm_file *file) return file->f_file->f_path.dentry->d_inode; } +static inline int __nlm_privileged_request4(const struct sockaddr *sap) +{ + const struct sockaddr_in *sin = (struct sockaddr_in *)sap; + return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) && + (ntohs(sin->sin_port) < 1024); +} + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +static inline int __nlm_privileged_request6(const struct sockaddr *sap) +{ + const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; + return (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LOOPBACK) && + (ntohs(sin6->sin6_port) < 1024); +} +#else /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ +static inline int __nlm_privileged_request6(const struct sockaddr *sap) +{ + return 0; +} +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ + +/* + * Ensure incoming requests are from local privileged callers. + * + * Return TRUE if sender is local and is connecting via a privileged port; + * otherwise return FALSE. + */ +static inline int nlm_privileged_requester(const struct svc_rqst *rqstp) +{ + const struct sockaddr *sap = svc_addr(rqstp); + + switch (sap->sa_family) { + case AF_INET: + return __nlm_privileged_request4(sap); + case AF_INET6: + return __nlm_privileged_request6(sap); + default: + return 0; + } +} + static inline int __nlm_cmp_addr4(const struct sockaddr *sap1, const struct sockaddr *sap2) { -- cgit v1.2.3 From 9a38a83880c224c6a3fd973ac9ae30a043487f0f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 12:50:51 -0400 Subject: lockd: Remove unused fields in the nlm_reboot structure The nlm_reboot structure is used to store information provided by the NSM_NOTIFY procedure. This procedure is not specified by the NLM or NSM protocols, other than to say that the procedure can be used to transmit information private to a particular NLM/NSM implementation. For Linux, the callback arguments include the name of the monitored host, the new NSM state of the host, and a 16-byte private opaque. As a clean up, remove the unused fields and the server-side XDR logic that decodes them. Signed-off-by: Chuck Lever Signed-off-by: J. Bruce Fields --- include/linux/lockd/xdr.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h index df18fa053bc..d6b3a802c04 100644 --- a/include/linux/lockd/xdr.h +++ b/include/linux/lockd/xdr.h @@ -81,8 +81,6 @@ struct nlm_reboot { unsigned int len; u32 state; __be32 addr; - __be32 vers; - __be32 proto; }; /* -- cgit v1.2.3 From c4b929b85bdb64afacbbf6453b1f2bf7e14c9e89 Mon Sep 17 00:00:00 2001 From: Mark Fasheh Date: Wed, 8 Oct 2008 19:44:18 -0400 Subject: vfs: vfs-level fiemap interface Basic vfs-level fiemap infrastructure, which sets up a new ->fiemap inode operation. Userspace can get extent information on a file via fiemap ioctl. As input, the fiemap ioctl takes a struct fiemap which includes an array of struct fiemap_extent (fm_extents). Size of the extent array is passed as fm_extent_count and number of extents returned will be written into fm_mapped_extents. Offset and length fields on the fiemap structure (fm_start, fm_length) describe a logical range which will be searched for extents. All extents returned will at least partially contain this range. The actual extent offsets and ranges returned will be unmodified from their offset and range on-disk. The fiemap ioctl returns '0' on success. On error, -1 is returned and errno is set. If errno is equal to EBADR, then fm_flags will contain those flags which were passed in which the kernel did not understand. On all other errors, the contents of fm_extents is undefined. As fiemap evolved, there have been many authors of the vfs patch. As far as I can tell, the list includes: Kalpak Shah Andreas Dilger Eric Sandeen Mark Fasheh Signed-off-by: Mark Fasheh Signed-off-by: "Theodore Ts'o" Cc: Michael Kerrisk Cc: linux-api@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org --- include/linux/fiemap.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 18 ++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 include/linux/fiemap.h (limited to 'include/linux') diff --git a/include/linux/fiemap.h b/include/linux/fiemap.h new file mode 100644 index 00000000000..671decbd2ae --- /dev/null +++ b/include/linux/fiemap.h @@ -0,0 +1,64 @@ +/* + * FS_IOC_FIEMAP ioctl infrastructure. + * + * Some portions copyright (C) 2007 Cluster File Systems, Inc + * + * Authors: Mark Fasheh + * Kalpak Shah + * Andreas Dilger + */ + +#ifndef _LINUX_FIEMAP_H +#define _LINUX_FIEMAP_H + +struct fiemap_extent { + __u64 fe_logical; /* logical offset in bytes for the start of + * the extent from the beginning of the file */ + __u64 fe_physical; /* physical offset in bytes for the start + * of the extent from the beginning of the disk */ + __u64 fe_length; /* length in bytes for this extent */ + __u64 fe_reserved64[2]; + __u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */ + __u32 fe_reserved[3]; +}; + +struct fiemap { + __u64 fm_start; /* logical offset (inclusive) at + * which to start mapping (in) */ + __u64 fm_length; /* logical length of mapping which + * userspace wants (in) */ + __u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */ + __u32 fm_mapped_extents;/* number of extents that were mapped (out) */ + __u32 fm_extent_count; /* size of fm_extents array (in) */ + __u32 fm_reserved; + struct fiemap_extent fm_extents[0]; /* array of mapped extents (out) */ +}; + +#define FIEMAP_MAX_OFFSET (~0ULL) + +#define FIEMAP_FLAG_SYNC 0x00000001 /* sync file data before map */ +#define FIEMAP_FLAG_XATTR 0x00000002 /* map extended attribute tree */ + +#define FIEMAP_FLAGS_COMPAT (FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR) + +#define FIEMAP_EXTENT_LAST 0x00000001 /* Last extent in file. */ +#define FIEMAP_EXTENT_UNKNOWN 0x00000002 /* Data location unknown. */ +#define FIEMAP_EXTENT_DELALLOC 0x00000004 /* Location still pending. + * Sets EXTENT_UNKNOWN. */ +#define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read + * while fs is unmounted */ +#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs. + * Sets EXTENT_NO_BYPASS. */ +#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be + * block aligned. */ +#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata. + * Sets EXTENT_NOT_ALIGNED.*/ +#define FIEMAP_EXTENT_DATA_TAIL 0x00000400 /* Multiple files in block. + * Sets EXTENT_NOT_ALIGNED.*/ +#define FIEMAP_EXTENT_UNWRITTEN 0x00000800 /* Space allocated, but + * no data (i.e. zero). */ +#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively + * support extents. Result + * merged for efficiency. */ + +#endif /* _LINUX_FIEMAP_H */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 580b513668f..194fb237a30 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -231,6 +231,7 @@ extern int dir_notify_enable; #define FS_IOC_SETFLAGS _IOW('f', 2, long) #define FS_IOC_GETVERSION _IOR('v', 1, long) #define FS_IOC_SETVERSION _IOW('v', 2, long) +#define FS_IOC_FIEMAP _IOWR('f', 11, struct fiemap) #define FS_IOC32_GETFLAGS _IOR('f', 1, int) #define FS_IOC32_SETFLAGS _IOW('f', 2, int) #define FS_IOC32_GETVERSION _IOR('v', 1, int) @@ -291,6 +292,7 @@ extern int dir_notify_enable; #include #include #include +#include #include #include @@ -1178,6 +1180,20 @@ extern void dentry_unhash(struct dentry *dentry); */ extern int file_permission(struct file *, int); +/* + * VFS FS_IOC_FIEMAP helper definitions. + */ +struct fiemap_extent_info { + unsigned int fi_flags; /* Flags as passed from user */ + unsigned int fi_extents_mapped; /* Number of mapped extents */ + unsigned int fi_extents_max; /* Size of fiemap_extent array */ + struct fiemap_extent *fi_extents_start; /* Start of fiemap_extent + * array */ +}; +int fiemap_fill_next_extent(struct fiemap_extent_info *info, u64 logical, + u64 phys, u64 len, u32 flags); +int fiemap_check_flags(struct fiemap_extent_info *fieinfo, u32 fs_flags); + /* * File types * @@ -1287,6 +1303,8 @@ struct inode_operations { void (*truncate_range)(struct inode *, loff_t, loff_t); long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len); + int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, + u64 len); }; struct seq_file; -- cgit v1.2.3 From 68c9d702bb72f367f3b148963ec6cf5e07ff7f65 Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Fri, 3 Oct 2008 17:32:43 -0400 Subject: generic block based fiemap implementation Any block based fs (this patch includes ext3) just has to declare its own fiemap() function and then call this generic function with its own get_block_t. This works well for block based filesystems that will map multiple contiguous blocks at one time, but will work for filesystems that only map one block at a time, you will just end up with an "extent" for each block. One gotcha is this will not play nicely where there is hole+data after the EOF. This function will assume its hit the end of the data as soon as it hits a hole after the EOF, so if there is any data past that it will not pick that up. AFAIK no block based fs does this anyway, but its in the comments of the function anyway just in case. Signed-off-by: Josef Bacik Signed-off-by: Mark Fasheh Signed-off-by: "Theodore Ts'o" Cc: linux-fsdevel@vger.kernel.org --- include/linux/ext3_fs.h | 2 ++ include/linux/fs.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 80171ee89a2..8120fa1bc23 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -837,6 +837,8 @@ extern void ext3_truncate (struct inode *); extern void ext3_set_inode_flags(struct inode *); extern void ext3_get_inode_flags(struct ext3_inode_info *); extern void ext3_set_aops(struct inode *inode); +extern int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, + u64 start, u64 len); /* ioctl.c */ extern int ext3_ioctl (struct inode *, struct file *, unsigned int, diff --git a/include/linux/fs.h b/include/linux/fs.h index 194fb237a30..385c9a197df 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1998,6 +1998,9 @@ extern int vfs_fstat(unsigned int, struct kstat *); extern int do_vfs_ioctl(struct file *filp, unsigned int fd, unsigned int cmd, unsigned long arg); +extern int generic_block_fiemap(struct inode *inode, + struct fiemap_extent_info *fieinfo, u64 start, + u64 len, get_block_t *get_block); extern void get_filesystem(struct file_system_type *fs); extern void put_filesystem(struct file_system_type *fs); -- cgit v1.2.3 From 897312bd240357c88ce906633703c324c6f0a5cd Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 3 Oct 2008 15:23:41 -0700 Subject: include/linux/stacktrace.h: declare struct task_struct include/linux/stacktrace.h:13: warning: 'struct task_struct' declared inside parameter list (This might be a hard error on sparc64, which uses this header and has -Werror) Reported-by: "Randy.Dunlap" Acked-by: Ingo Molnar Cc: Peter Zijlstra Cc: Arjan van de Ven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/stacktrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/stacktrace.h b/include/linux/stacktrace.h index 5da9794b2d7..b106fd8e0d5 100644 --- a/include/linux/stacktrace.h +++ b/include/linux/stacktrace.h @@ -1,6 +1,8 @@ #ifndef __LINUX_STACKTRACE_H #define __LINUX_STACKTRACE_H +struct task_struct; + #ifdef CONFIG_STACKTRACE struct stack_trace { unsigned int nr_entries, max_entries; -- cgit v1.2.3 From 26a414092353590ceaa5955bcb53f863d6ea7549 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 17:15:30 -0400 Subject: NLM: Remove "proto" argument from lockd_up() Clean up: Now that lockd_up() starts listeners for both transports, the "proto" argument is no longer needed. Signed-off-by: Chuck Lever Cc: Neil Brown Signed-off-by: J. Bruce Fields --- include/linux/lockd/bind.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h index 1f0465c374d..e5872dc994c 100644 --- a/include/linux/lockd/bind.h +++ b/include/linux/lockd/bind.h @@ -52,7 +52,7 @@ extern void nlmclnt_done(struct nlm_host *host); extern int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl); -extern int lockd_up(int proto); +extern int lockd_up(void); extern void lockd_down(void); #endif /* LINUX_LOCKD_BIND_H */ -- cgit v1.2.3 From 2937391385807b3da9cd7a39345259caf550b032 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Fri, 3 Oct 2008 17:15:38 -0400 Subject: NLM: Remove unused argument from svc_addsock() function Clean up: The svc_addsock() function no longer uses its "proto" argument, so remove it. Signed-off-by: Chuck Lever Cc: Neil Brown Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svcsock.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h index 8cff696dedf..483e10380aa 100644 --- a/include/linux/sunrpc/svcsock.h +++ b/include/linux/sunrpc/svcsock.h @@ -39,10 +39,7 @@ int svc_send(struct svc_rqst *); void svc_drop(struct svc_rqst *); void svc_sock_update_bufs(struct svc_serv *serv); int svc_sock_names(char *buf, struct svc_serv *serv, char *toclose); -int svc_addsock(struct svc_serv *serv, - int fd, - char *name_return, - int *proto); +int svc_addsock(struct svc_serv *serv, int fd, char *name_return); void svc_init_xprt_sock(void); void svc_cleanup_xprt_sock(void); -- cgit v1.2.3 From f20f258603ebc5da91e76884cf0c0d7ac9804b1c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Sun, 5 Oct 2008 18:23:27 +0200 Subject: ide-cd: temporary tray close fix This one fixes http://bugzilla.kernel.org/show_bug.cgi?id=11602. A more generic fix for drives which cannot autoclose tray will follow. Signed-off-by: Borislav Petkov Cc: Jens Axboe [bart: add an extra parentheses for consistency with the rest of kernel code] Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 1524829f73f..6514db8fd2e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -366,7 +366,9 @@ enum { /* Currently on a filemark */ IDE_AFLAG_FILEMARK = (1 << 25), /* 0 = no tape is loaded, so we don't rewind after ejecting */ - IDE_AFLAG_MEDIUM_PRESENT = (1 << 26) + IDE_AFLAG_MEDIUM_PRESENT = (1 << 26), + + IDE_AFLAG_NO_AUTOCLOSE = (1 << 27), }; struct ide_drive_s { -- cgit v1.2.3 From 9641458d3ec42def729fde64669abf07f3220cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 5 Oct 2008 11:15:13 -0700 Subject: Phonet: Pipe End Point for Phonet Pipes protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This protocol provides some connection handling and negotiated congestion control. Nokia cellular modems use it for bulk transfers. It provides packet boundaries (hence SOCK_SEQPACKET). Congestion control is per packet rather per byte, so we do not re-use the generic socket memory accounting. Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/phonet.h b/include/linux/phonet.h index 3a027f588a4..f9218524207 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -27,7 +27,9 @@ #define PN_PROTO_TRANSPORT 0 /* Phonet datagram socket */ #define PN_PROTO_PHONET 1 -#define PHONET_NPROTO 2 +/* Phonet pipe */ +#define PN_PROTO_PIPE 2 +#define PHONET_NPROTO 3 #define PNADDR_ANY 0 #define PNPORT_RESOURCE_ROUTING 0 -- cgit v1.2.3 From 02a47617cdce440f60c71a51f3a93f9f5fcc5a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Denis-Courmont?= Date: Sun, 5 Oct 2008 11:16:16 -0700 Subject: Phonet: implement GPRS virtual interface over PEP socket MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rémi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 8 ++++++++ include/linux/socket.h | 1 + 2 files changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phonet.h b/include/linux/phonet.h index f9218524207..c9609f9aeda 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -31,9 +31,17 @@ #define PN_PROTO_PIPE 2 #define PHONET_NPROTO 3 +/* Socket options for SOL_PNPIPE level */ +#define PNPIPE_ENCAP 1 +#define PNPIPE_IFINDEX 2 + #define PNADDR_ANY 0 #define PNPORT_RESOURCE_ROUTING 0 +/* Values for PNPIPE_ENCAP option */ +#define PNPIPE_ENCAP_NONE 0 +#define PNPIPE_ENCAP_IP 1 + /* ioctls */ #define SIOCPNGETOBJECT (SIOCPROTOPRIVATE + 0) diff --git a/include/linux/socket.h b/include/linux/socket.h index 818ca33bf79..20fc4bbfca4 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -297,6 +297,7 @@ struct ucred { #define SOL_RXRPC 272 #define SOL_PPPOL2TP 273 #define SOL_BLUETOOTH 274 +#define SOL_PNPIPE 275 /* IPX options */ #define IPX_TYPE 1 -- cgit v1.2.3 From 13c1d18931ebb5cf407cb348ef2cd6284d68902d Mon Sep 17 00:00:00 2001 From: Arnaud Ebalard Date: Sun, 5 Oct 2008 13:33:42 -0700 Subject: xfrm: MIGRATE enhancements (draft-ebalard-mext-pfkey-enhanced-migrate) Provides implementation of the enhancements of XFRM/PF_KEY MIGRATE mechanism specified in draft-ebalard-mext-pfkey-enhanced-migrate-00. Defines associated PF_KEY SADB_X_EXT_KMADDRESS extension and XFRM/netlink XFRMA_KMADDRESS attribute. Signed-off-by: Arnaud Ebalard Signed-off-by: David S. Miller --- include/linux/pfkeyv2.h | 13 ++++++++++++- include/linux/xfrm.h | 10 ++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pfkeyv2.h b/include/linux/pfkeyv2.h index 700725ddcaa..01b262959f2 100644 --- a/include/linux/pfkeyv2.h +++ b/include/linux/pfkeyv2.h @@ -226,6 +226,15 @@ struct sadb_x_sec_ctx { } __attribute__((packed)); /* sizeof(struct sadb_sec_ctx) = 8 */ +/* Used by MIGRATE to pass addresses IKE will use to perform + * negotiation with the peer */ +struct sadb_x_kmaddress { + uint16_t sadb_x_kmaddress_len; + uint16_t sadb_x_kmaddress_exttype; + uint32_t sadb_x_kmaddress_reserved; +} __attribute__((packed)); +/* sizeof(struct sadb_x_kmaddress) == 8 */ + /* Message types */ #define SADB_RESERVED 0 #define SADB_GETSPI 1 @@ -346,7 +355,9 @@ struct sadb_x_sec_ctx { #define SADB_X_EXT_NAT_T_DPORT 22 #define SADB_X_EXT_NAT_T_OA 23 #define SADB_X_EXT_SEC_CTX 24 -#define SADB_EXT_MAX 24 +/* Used with MIGRATE to pass @ to IKE for negotiation */ +#define SADB_X_EXT_KMADDRESS 25 +#define SADB_EXT_MAX 25 /* Identity Extension values */ #define SADB_IDENTTYPE_RESERVED 0 diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index fb0c215a305..4bc1e6b86cb 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -279,6 +279,7 @@ enum xfrm_attr_type_t { XFRMA_POLICY_TYPE, /* struct xfrm_userpolicy_type */ XFRMA_MIGRATE, XFRMA_ALG_AEAD, /* struct xfrm_algo_aead */ + XFRMA_KMADDRESS, /* struct xfrm_user_kmaddress */ __XFRMA_MAX #define XFRMA_MAX (__XFRMA_MAX - 1) @@ -415,6 +416,15 @@ struct xfrm_user_report { struct xfrm_selector sel; }; +/* Used by MIGRATE to pass addresses IKE should use to perform + * SA negotiation with the peer */ +struct xfrm_user_kmaddress { + xfrm_address_t local; + xfrm_address_t remote; + __u32 reserved; + __u16 family; +}; + struct xfrm_user_migrate { xfrm_address_t old_daddr; xfrm_address_t old_saddr; -- cgit v1.2.3 From 1e19b16a30c34c042f1eaa23db4c99bfad1dac0e Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 6 Oct 2008 14:15:24 +0200 Subject: AMD IOMMU: use iommu_device_max_index, fix include/linux/iommu-helper.h has no header guards, which breaks sparc64 build. Add them. Signed-off-by: Thomas Gleixner Cc: Joerg Roedel Cc: FUJITA Tomonori Signed-off-by: Ingo Molnar --- include/linux/iommu-helper.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index 786539e432d..a6d0586e2bf 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h @@ -1,3 +1,6 @@ +#ifndef _LINUX_IOMMU_HELPER_H +#define _LINUX_IOMMU_HELPER_H + static inline unsigned long iommu_device_max_index(unsigned long size, unsigned long offset, u64 dma_mask) @@ -19,3 +22,5 @@ extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, unsigned long align_mask); extern void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr); + +#endif -- cgit v1.2.3 From 64be8608c163bd480cf5ec4b34366f11e0f3c87f Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Mon, 6 Oct 2008 14:45:18 -0500 Subject: svcrdma: Add FRMR get/put services Add services for the allocating, freeing, and unmapping Fast Reg MR. These services will be used by the transport connection setup, send and receive routines. Signed-off-by: Tom Tucker --- include/linux/sunrpc/svc_rdma.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 49e458d9894..34252683671 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -214,6 +214,9 @@ extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *); extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int); extern struct svc_rdma_req_map *svc_rdma_get_req_map(void); extern void svc_rdma_put_req_map(struct svc_rdma_req_map *); +extern struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *); +extern void svc_rdma_put_frmr(struct svcxprt_rdma *, + struct svc_rdma_fastreg_mr *); extern void svc_sq_reap(struct svcxprt_rdma *); extern void svc_rq_reap(struct svcxprt_rdma *); extern struct svc_xprt_class svc_rdma_class; -- cgit v1.2.3 From e1183210625cc8e02ce13eec78fb7a246567fc59 Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Fri, 3 Oct 2008 15:22:18 -0500 Subject: svcrdma: Add a service to register a Fast Reg MR with the device Fast Reg MR introduces a new WR type. Add a service to register the region with the adapter and update the completion handling to support completions with a NULL WR context. Signed-off-by: Tom Tucker --- include/linux/sunrpc/svc_rdma.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 34252683671..1402d193b39 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -214,6 +214,7 @@ extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *); extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int); extern struct svc_rdma_req_map *svc_rdma_get_req_map(void); extern void svc_rdma_put_req_map(struct svc_rdma_req_map *); +extern int svc_rdma_fastreg(struct svcxprt_rdma *, struct svc_rdma_fastreg_mr *); extern struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *); extern void svc_rdma_put_frmr(struct svcxprt_rdma *, struct svc_rdma_fastreg_mr *); -- cgit v1.2.3 From 146b6df6a537939570c5772ebd7db826fdbd5d82 Mon Sep 17 00:00:00 2001 From: Tom Tucker Date: Tue, 12 Aug 2008 15:12:10 -0500 Subject: svcrdma: Modify the RPC recv path to use FRMR when available RPCRDMA requests that specify a read-list are fetched with RDMA_READ. Using an FRMR to map the data sink improves NFSRDMA security on transports that place the RDMA_READ data sink LKEY on the wire because the valid lifetime of the MR is only the duration of the RDMA_READ. The LKEY is invalidated when the last RDMA_READ WR completes. Mapping the data sink also allows for very large amounts to data to be fetched with a single WR, so if the client is also using FRMR, the entire RPC read-list can be fetched with a single WR. Signed-off-by: Tom Tucker --- include/linux/sunrpc/svc_rdma.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index 1402d193b39..c14fe86dac5 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -212,6 +212,7 @@ extern int svc_rdma_post_recv(struct svcxprt_rdma *); extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *); extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *); extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int); +extern void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt); extern struct svc_rdma_req_map *svc_rdma_get_req_map(void); extern void svc_rdma_put_req_map(struct svc_rdma_req_map *); extern int svc_rdma_fastreg(struct svcxprt_rdma *, struct svc_rdma_fastreg_mr *); -- cgit v1.2.3 From 1daef0a868370c5a96d031b9202e3354bea060e6 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 27 Jul 2008 18:19:01 -0400 Subject: NFS: Clean up nfs_sb_active/nfs_sb_deactive Instead of causing umount requests to block on server->active_wq while the asynchronous sillyrename deletes are executing, we can use the sb->s_active counter to obtain a reference to the super_block, and then release that reference in nfs_async_unlink_release(). Signed-off-by: Trond Myklebust --- include/linux/nfs_fs_sb.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index c9beacd16c0..4e477ae5869 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -119,7 +119,6 @@ struct nfs_server { void (*destroy)(struct nfs_server *); atomic_t active; /* Keep trace of any activity to this server */ - wait_queue_head_t active_wq; /* Wait for any activity to stop */ /* mountd-related mount options */ struct sockaddr_storage mountd_address; -- cgit v1.2.3 From 1b483a6a7b2998e9c98ad985d7494b9b725bd228 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 15 Sep 2008 23:09:08 +0000 Subject: powerpc: Remove remains of /proc/ppc_htab commit 14cf11af6cf608eb8c23e989ddb17a715ddce109 ("powerpc: Merge enough to start building in arch/powerpc.") unwired /proc/ppc_htab, and commit 917f0af9e5a9ceecf9e72537fabb501254ba321d ("powerpc: Remove arch/ppc and include/asm-ppc") removed the rest of the /proc/ppc_htab support, but there are still a few references left. Kill them for good. Signed-off-by: Geert Uytterhoeven Signed-off-by: Benjamin Herrenschmidt --- include/linux/proc_fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index fb61850d1cf..27d534f4470 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -139,7 +139,6 @@ extern int proc_readdir(struct file *, void *, filldir_t); extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *); extern const struct file_operations proc_kcore_operations; -extern const struct file_operations ppc_htab_operations; extern int pid_ns_prepare_proc(struct pid_namespace *ns); extern void pid_ns_release_proc(struct pid_namespace *ns); -- cgit v1.2.3 From 2075eb8d95612cadde91ef5be82691d97a2ea6c5 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Tue, 7 Oct 2008 10:57:54 -0700 Subject: rangetimer: fix x86 build failure for the !HRTIMERS case the timer peek function was on the wrong side of an ifdef, breaking for the !HRTIMERs case. Just provide an empty inline for that case since it doesn't make sense in that scenario. Signed-off-by: Arjan van de Ven --- include/linux/hrtimer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index d93b1e1dc16..508ce20b8f9 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -283,6 +283,8 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) return timer->base->cpu_base->hres_active; } +extern void hrtimer_peek_ahead_timers(void); + /* * The resolution of the clocks. The resolution value is returned in * the clock_getres() system call to give application programmers an @@ -305,6 +307,7 @@ static inline int hrtimer_is_hres_active(struct hrtimer *timer) * is expired in the next softirq when the clock was advanced. */ static inline void clock_was_set(void) { } +static inline void hrtimer_peek_ahead_timers(void) { } static inline void hres_timers_resume(void) { } @@ -328,7 +331,6 @@ extern ktime_t ktime_get_real(void); DECLARE_PER_CPU(struct tick_device, tick_cpu_device); -extern void hrtimer_peek_ahead_timers(void); /* Exported timer functions: */ -- cgit v1.2.3 From 4eec952e42314b53e48fef1f54dd89cbf9789734 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 15 Jul 2008 17:58:13 -0400 Subject: NFS: Add options for finer control of the lookup cache Add the flag NFS_MOUNT_LOOKUP_CACHE_NONEG to turn off the caching of negative dentries. In reality what we do is to force nfs_lookup_revalidate() to always discard negative dentries. Add the flag NFS_MOUNT_LOOKUP_CACHE_NONE for enforcing stricter revalidation of dentries. It forces the revalidate code to always do a lookup instead of just checking the cached mtime of the parent directory. Signed-off-by: Trond Myklebust --- include/linux/nfs_mount.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/nfs_mount.h b/include/linux/nfs_mount.h index df7c6b7a7eb..6549a06ac16 100644 --- a/include/linux/nfs_mount.h +++ b/include/linux/nfs_mount.h @@ -65,4 +65,8 @@ struct nfs_mount_data { #define NFS_MOUNT_UNSHARED 0x8000 /* 5 */ #define NFS_MOUNT_FLAGMASK 0xFFFF +/* The following are for internal use only */ +#define NFS_MOUNT_LOOKUP_CACHE_NONEG 0x10000 +#define NFS_MOUNT_LOOKUP_CACHE_NONE 0x20000 + #endif -- cgit v1.2.3 From 654bed16cf86a9ef94495d9e6131b7ff7840a3dd Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Tue, 7 Oct 2008 14:22:33 -0700 Subject: net: packet split receive api Add some packet-split receive hooks. For one this allows to do NUMA node affine page allocs. Later on these hooks will be extended to do emergency reserve allocations for fragments. Signed-off-by: Peter Zijlstra Signed-off-by: David S. Miller --- include/linux/skbuff.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 720b688c22b..2725f4e5a9b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -968,6 +968,9 @@ static inline void skb_fill_page_desc(struct sk_buff *skb, int i, skb_shinfo(skb)->nr_frags = i + 1; } +extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, + int off, int size); + #define SKB_PAGE_ASSERT(skb) BUG_ON(skb_shinfo(skb)->nr_frags) #define SKB_FRAG_ASSERT(skb) BUG_ON(skb_shinfo(skb)->frag_list) #define SKB_LINEAR_ASSERT(skb) BUG_ON(skb_is_nonlinear(skb)) @@ -1382,6 +1385,26 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev, return __netdev_alloc_skb(dev, length, GFP_ATOMIC); } +extern struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask); + +/** + * netdev_alloc_page - allocate a page for ps-rx on a specific device + * @dev: network device to receive on + * + * Allocate a new page node local to the specified device. + * + * %NULL is returned if there is no free memory. + */ +static inline struct page *netdev_alloc_page(struct net_device *dev) +{ + return __netdev_alloc_page(dev, GFP_ATOMIC); +} + +static inline void netdev_free_page(struct net_device *dev, struct page *page) +{ + __free_page(page); +} + /** * skb_clone_writable - is the header of a clone writable * @skb: buffer to check -- cgit v1.2.3 From 33f5f57eeb0c6386fdd85f9c690dc8d700ba7928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ilpo=20J=C3=A4rvinen?= Date: Tue, 7 Oct 2008 14:43:06 -0700 Subject: tcp: kill pointless urg_mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It all started from me noticing that this urgent check in tcp_clean_rtx_queue is unnecessarily inside the loop. Then I took a longer look to it and found out that the users of urg_mode can trivially do without, well almost, there was one gotcha. Bonus: those funny people who use urg with >= 2^31 write_seq - snd_una could now rejoice too (that's the only purpose for the between being there, otherwise a simple compare would have done the thing). Not that I assume that the rest of the tcp code happily lives with such mind-boggling numbers :-). Alas, it turned out to be impossible to set wmem to such numbers anyway, yes I really tried a big sendfile after setting some wmem but nothing happened :-). ...Tcp_wmem is int and so is sk_sndbuf... So I hacked a bit variable to long and found out that it seems to work... :-) Signed-off-by: Ilpo Järvinen Signed-off-by: David S. Miller --- include/linux/tcp.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 76729062829..fe77e1499ab 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -312,8 +312,11 @@ struct tcp_sock { u32 retrans_out; /* Retransmitted packets out */ u16 urg_data; /* Saved octet of OOB data and control flags */ - u8 urg_mode; /* In urgent mode */ u8 ecn_flags; /* ECN status bits. */ + u8 reordering; /* Packet reordering metric. */ + u32 snd_up; /* Urgent pointer */ + + u8 keepalive_probes; /* num of allowed keep alive probes */ /* * Options received (usually on last packet, some only on SYN packets). */ @@ -361,8 +364,6 @@ struct tcp_sock { u32 lost_retrans_low; /* Sent seq after any rxmit (lowest) */ - u8 reordering; /* Packet reordering metric. */ - u8 keepalive_probes; /* num of allowed keep alive probes */ u32 prior_ssthresh; /* ssthresh saved at recovery start */ u32 high_seq; /* snd_nxt at onset of congestion */ @@ -374,8 +375,6 @@ struct tcp_sock { u32 total_retrans; /* Total retransmits for entire connection */ u32 urg_seq; /* Seq of received urgent pointer */ - u32 snd_up; /* Urgent pointer */ - unsigned int keepalive_time; /* time before keep alive takes place */ unsigned int keepalive_intvl; /* time interval between keep alive probes */ -- cgit v1.2.3 From 691beb13cdc88358334ef0ba867c080a247a760f Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 5 Oct 2008 14:48:22 -0400 Subject: NFS: Allow concurrent inode revalidation Currently, if two processes are both trying to revalidate metadata for the same inode, they will find themselves being serialised. There is no good justification for this now that we have improved our ability to detect stale attribute data, so we should remove that serialisation. Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 78a5922a2f1..ca563ee13e3 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -200,11 +200,10 @@ struct nfs_inode { /* * Bit offsets in flags field */ -#define NFS_INO_REVALIDATING (0) /* revalidating attrs */ -#define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */ -#define NFS_INO_STALE (2) /* possible stale inode */ -#define NFS_INO_ACL_LRU_SET (3) /* Inode is on the LRU list */ -#define NFS_INO_MOUNTPOINT (4) /* inode is remote mountpoint */ +#define NFS_INO_ADVISE_RDPLUS (0) /* advise readdirplus */ +#define NFS_INO_STALE (1) /* possible stale inode */ +#define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */ +#define NFS_INO_MOUNTPOINT (3) /* inode is remote mountpoint */ static inline struct nfs_inode *NFS_I(const struct inode *inode) { -- cgit v1.2.3 From 9fa8d66f1e55bf197568c8c689043c2aad1ffc97 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Tue, 26 Aug 2008 16:23:20 +0100 Subject: NFS: remove 8 bytes of padding from struct nfs_fattr on 64 bit builds remove 8 bytes of padding from struct nfs_fattr on 64 bit builds This also removes padding from several nfs structures, including 16 bytes from nfs4_opendata, nfs4_createdata,nfs3_createdata & 8 bytes from nfs_read_data,nfs_write_data,nfs_removeres,nfs4_closedata This also reduces the reported stack usage of many nfs functions (30+). Signed-off-by: Richard Kennedy ---- This patch is against the latest git 2.6.27-rc4. I've built & run this on my AMD64 desktop, & successfully run _simple_ tests with a 64 bit client => 32 bit server & 32 bit client to 64 bit server. On fedora with gcc (GCC) 4.3.0 20080428 (Red Hat 4.3.0-8) checkpatch reports 33 functions with reduced stack usage. e.g. __nfs_revalidate_inode [nfs] 216 => 200 _nfs4_proc_access [nfs] 304 => 288 _nfs4_proc_link [nfs] 536 => 504 _nfs4_proc_remove [nfs] 304 => 288 _nfs4_proc_rename [nfs] 584 => 552 nfs3_proc_access [nfs] 272 => 256 nfs3_proc_getacl [nfs] 384 => 368 nfs3_proc_link [nfs] 496 => 464 etc I can supply the complete list if anyone is interested. regards Richard Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 8c77c11224d..9cabbb3a9e6 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -36,6 +36,7 @@ struct nfs_fattr { __u32 nlink; __u32 uid; __u32 gid; + dev_t rdev; __u64 size; union { struct { @@ -46,7 +47,6 @@ struct nfs_fattr { __u64 used; } nfs3; } du; - dev_t rdev; struct nfs_fsid fsid; __u64 fileid; struct timespec atime; -- cgit v1.2.3 From d1ce02e1689dff9d413138f60a79b4e3affb4708 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Thu, 25 Sep 2008 11:57:12 -0400 Subject: NFS: SETCLIENTID truncates client ID and netid The sc_name field is currently 56 bytes long. This is not large enough to hold a pair of IPv6 addresses, the authentication type, the protocol name, and a uniquifier number. The maximum possible size of the name string using IPv6 addresses is just under 110 bytes, so I increased the size of the sc_name field to accomodate this maximum. In addition, the strings in the nfs4_setclientid structure are constructed with scnprintf(), which wants to terminate its output with '\0'. The sc_netid field was large enough only for a three byte netid string and a '\0' so inet6 netids were being truncated. Perhaps we don't need the overhead of scnprintf() to do a simple string copy, but I fixed this by increasing the size of the buffer by one byte. Since all three of the string buffers in nfs4_setclientid are constructed with scnprintf(), I increased the size of all three by one byte to document the requirement, although I don't think either the universal address field or the name field will be so small that these strings get truncated in this way. The size of the Linux client's client ID on the wire will be larger than before. RFC 3530 suggests the size limit for client IDs is 1024, and we are still well below that. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 9cabbb3a9e6..f6e95bfad5d 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -672,16 +672,16 @@ struct nfs4_rename_res { struct nfs_fattr * new_fattr; }; -#define NFS4_SETCLIENTID_NAMELEN (56) +#define NFS4_SETCLIENTID_NAMELEN (128) struct nfs4_setclientid { const nfs4_verifier * sc_verifier; unsigned int sc_name_len; - char sc_name[NFS4_SETCLIENTID_NAMELEN]; + char sc_name[NFS4_SETCLIENTID_NAMELEN + 1]; u32 sc_prog; unsigned int sc_netid_len; - char sc_netid[RPCBIND_MAXNETIDLEN]; + char sc_netid[RPCBIND_MAXNETIDLEN + 1]; unsigned int sc_uaddr_len; - char sc_uaddr[RPCBIND_MAXUADDRLEN]; + char sc_uaddr[RPCBIND_MAXUADDRLEN + 1]; u32 sc_cb_ident; }; -- cgit v1.2.3 From b8bae41ed6a53cce56c50811a91cd963e3187d1c Mon Sep 17 00:00:00 2001 From: Rami Rosen Date: Tue, 7 Oct 2008 15:34:37 -0700 Subject: ipv4: add mc_count to in_device. This patch add mc_count to struct in_device and updates increment/decrement/initilaize of this field in IPv4 and in IPv6. - Also printing the vfs /proc entry (/proc/net/igmp) is adjusted to use the new mc_count. Signed-off-by: Rami Rosen Signed-off-by: David S. Miller --- include/linux/inetdevice.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/inetdevice.h b/include/linux/inetdevice.h index c6f51ad52d5..06fcdb45106 100644 --- a/include/linux/inetdevice.h +++ b/include/linux/inetdevice.h @@ -25,6 +25,7 @@ struct in_device struct in_ifaddr *ifa_list; /* IP ifaddr chain */ rwlock_t mc_list_lock; struct ip_mc_list *mc_list; /* IP multicast filter chain */ + int mc_count; /* Number of installed mcasts */ spinlock_t mc_tomb_lock; struct ip_mc_list *mc_tomb; unsigned long mr_v1_seen; -- cgit v1.2.3 From 76108cea065cda58366d16a7eb6ca90d717a1396 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:00 +0200 Subject: netfilter: Use unsigned types for hooknum and pf vars and (try to) consistently use u_int8_t for the L3 family. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 30 ++++++++++++++++-------------- include/linux/netfilter/x_tables.h | 28 ++++++++++++++-------------- 2 files changed, 30 insertions(+), 28 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 0c5eb7ed8b3..8c83d2e23bd 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -92,8 +92,8 @@ struct nf_hook_ops /* User fills in from here down. */ nf_hookfn *hook; struct module *owner; - int pf; - int hooknum; + u_int8_t pf; + unsigned int hooknum; /* Hooks are ordered in ascending priority. */ int priority; }; @@ -102,7 +102,7 @@ struct nf_sockopt_ops { struct list_head list; - int pf; + u_int8_t pf; /* Non-inclusive ranges: use 0/0/NULL to never get called. */ int set_optmin; @@ -140,7 +140,7 @@ extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[]; extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; -int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, +int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), int thresh); @@ -151,7 +151,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, * okfn must be invoked by the caller in this case. Any other return * value indicates the packet has been consumed by the hook. */ -static inline int nf_hook_thresh(int pf, unsigned int hook, +static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, @@ -167,7 +167,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook, return nf_hook_slow(pf, hook, skb, indev, outdev, okfn, thresh); } -static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb, +static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { @@ -212,14 +212,14 @@ __ret;}) NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, INT_MIN) /* Call setsockopt() */ -int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt, +int nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, int len); -int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt, +int nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, int *len); -int compat_nf_setsockopt(struct sock *sk, int pf, int optval, +int compat_nf_setsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, int len); -int compat_nf_getsockopt(struct sock *sk, int pf, int optval, +int compat_nf_getsockopt(struct sock *sk, u_int8_t pf, int optval, char __user *opt, int *len); /* Call this before modifying an existing packet: ensures it is @@ -292,7 +292,7 @@ extern void nf_unregister_afinfo(const struct nf_afinfo *afinfo); extern void (*ip_nat_decode_session)(struct sk_buff *, struct flowi *); static inline void -nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) +nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) { #ifdef CONFIG_NF_NAT_NEEDED void (*decodefn)(struct sk_buff *, struct flowi *); @@ -315,7 +315,7 @@ extern struct proc_dir_entry *proc_net_netfilter; #else /* !CONFIG_NETFILTER */ #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb) #define NF_HOOK_COND(pf, hook, skb, indev, outdev, okfn, cond) (okfn)(skb) -static inline int nf_hook_thresh(int pf, unsigned int hook, +static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, @@ -324,7 +324,7 @@ static inline int nf_hook_thresh(int pf, unsigned int hook, { return okfn(skb); } -static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb, +static inline int nf_hook(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *)) { @@ -332,7 +332,9 @@ static inline int nf_hook(int pf, unsigned int hook, struct sk_buff *skb, } struct flowi; static inline void -nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, int family) {} +nf_nat_decode_session(struct sk_buff *skb, struct flowi *fl, u_int8_t family) +{ +} #endif /*CONFIG_NETFILTER*/ #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 2326296b6f2..6989b22716e 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -292,7 +292,7 @@ struct xt_table /* Set this to THIS_MODULE if you are a module, otherwise NULL */ struct module *me; - int af; /* address/protocol family */ + u_int8_t af; /* address/protocol family */ }; #include @@ -346,19 +346,19 @@ extern struct xt_table_info *xt_replace_table(struct xt_table *table, struct xt_table_info *newinfo, int *error); -extern struct xt_match *xt_find_match(int af, const char *name, u8 revision); -extern struct xt_target *xt_find_target(int af, const char *name, u8 revision); -extern struct xt_target *xt_request_find_target(int af, const char *name, +extern struct xt_match *xt_find_match(u8 af, const char *name, u8 revision); +extern struct xt_target *xt_find_target(u8 af, const char *name, u8 revision); +extern struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision); -extern int xt_find_revision(int af, const char *name, u8 revision, int target, - int *err); +extern int xt_find_revision(u8 af, const char *name, u8 revision, + int target, int *err); -extern struct xt_table *xt_find_table_lock(struct net *net, int af, +extern struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af, const char *name); extern void xt_table_unlock(struct xt_table *t); -extern int xt_proto_init(struct net *net, int af); -extern void xt_proto_fini(struct net *net, int af); +extern int xt_proto_init(struct net *net, u_int8_t af); +extern void xt_proto_fini(struct net *net, u_int8_t af); extern struct xt_table_info *xt_alloc_table_info(unsigned int size); extern void xt_free_table_info(struct xt_table_info *info); @@ -423,12 +423,12 @@ struct compat_xt_counters_info #define COMPAT_XT_ALIGN(s) (((s) + (__alignof__(struct compat_xt_counters)-1)) \ & ~(__alignof__(struct compat_xt_counters)-1)) -extern void xt_compat_lock(int af); -extern void xt_compat_unlock(int af); +extern void xt_compat_lock(u_int8_t af); +extern void xt_compat_unlock(u_int8_t af); -extern int xt_compat_add_offset(int af, unsigned int offset, short delta); -extern void xt_compat_flush_offsets(int af); -extern short xt_compat_calc_jump(int af, unsigned int offset); +extern int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta); +extern void xt_compat_flush_offsets(u_int8_t af); +extern short xt_compat_calc_jump(u_int8_t af, unsigned int offset); extern int xt_compat_match_offset(const struct xt_match *match); extern int xt_compat_match_from_user(struct xt_entry_match *m, -- cgit v1.2.3 From e948b20a71a06a740c925d6ea22b59b4e17cfa0c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:00 +0200 Subject: netfilter: rename ipt_recent to xt_recent Like with other modules (such as ipt_state), ipt_recent.h is changed to forward definitions to (IOW include) xt_recent.h, and xt_recent.c is changed to use the new constant names. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/Kbuild | 1 + include/linux/netfilter/xt_recent.h | 26 ++++++++++++++++++++++++++ include/linux/netfilter_ipv4/ipt_recent.h | 28 +++++++++++----------------- 3 files changed, 38 insertions(+), 17 deletions(-) create mode 100644 include/linux/netfilter/xt_recent.h (limited to 'include/linux') diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild index 3aff513d12c..5a8af875bce 100644 --- a/include/linux/netfilter/Kbuild +++ b/include/linux/netfilter/Kbuild @@ -32,6 +32,7 @@ header-y += xt_owner.h header-y += xt_pkttype.h header-y += xt_rateest.h header-y += xt_realm.h +header-y += xt_recent.h header-y += xt_sctp.h header-y += xt_state.h header-y += xt_statistic.h diff --git a/include/linux/netfilter/xt_recent.h b/include/linux/netfilter/xt_recent.h new file mode 100644 index 00000000000..5cfeb81c679 --- /dev/null +++ b/include/linux/netfilter/xt_recent.h @@ -0,0 +1,26 @@ +#ifndef _LINUX_NETFILTER_XT_RECENT_H +#define _LINUX_NETFILTER_XT_RECENT_H 1 + +enum { + XT_RECENT_CHECK = 1 << 0, + XT_RECENT_SET = 1 << 1, + XT_RECENT_UPDATE = 1 << 2, + XT_RECENT_REMOVE = 1 << 3, + XT_RECENT_TTL = 1 << 4, + + XT_RECENT_SOURCE = 0, + XT_RECENT_DEST = 1, + + XT_RECENT_NAME_LEN = 200, +}; + +struct xt_recent_mtinfo { + u_int32_t seconds; + u_int32_t hit_count; + u_int8_t check_set; + u_int8_t invert; + char name[XT_RECENT_NAME_LEN]; + u_int8_t side; +}; + +#endif /* _LINUX_NETFILTER_XT_RECENT_H */ diff --git a/include/linux/netfilter_ipv4/ipt_recent.h b/include/linux/netfilter_ipv4/ipt_recent.h index 6508a459265..d636cca133c 100644 --- a/include/linux/netfilter_ipv4/ipt_recent.h +++ b/include/linux/netfilter_ipv4/ipt_recent.h @@ -1,27 +1,21 @@ #ifndef _IPT_RECENT_H #define _IPT_RECENT_H -#define RECENT_NAME "ipt_recent" -#define RECENT_VER "v0.3.1" +#include -#define IPT_RECENT_CHECK 1 -#define IPT_RECENT_SET 2 -#define IPT_RECENT_UPDATE 4 -#define IPT_RECENT_REMOVE 8 -#define IPT_RECENT_TTL 16 +#define ipt_recent_info xt_recent_mtinfo -#define IPT_RECENT_SOURCE 0 -#define IPT_RECENT_DEST 1 +enum { + IPT_RECENT_CHECK = XT_RECENT_CHECK, + IPT_RECENT_SET = XT_RECENT_SET, + IPT_RECENT_UPDATE = XT_RECENT_UPDATE, + IPT_RECENT_REMOVE = XT_RECENT_REMOVE, + IPT_RECENT_TTL = XT_RECENT_TTL, -#define IPT_RECENT_NAME_LEN 200 + IPT_RECENT_SOURCE = XT_RECENT_SOURCE, + IPT_RECENT_DEST = XT_RECENT_DEST, -struct ipt_recent_info { - u_int32_t seconds; - u_int32_t hit_count; - u_int8_t check_set; - u_int8_t invert; - char name[IPT_RECENT_NAME_LEN]; - u_int8_t side; + IPT_RECENT_NAME_LEN = XT_RECENT_NAME_LEN, }; #endif /*_IPT_RECENT_H*/ -- cgit v1.2.3 From 7e9c6eeb136a46dfd941852803b3a9dd78939b69 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:00 +0200 Subject: netfilter: Introduce NFPROTO_* constants The netfilter subsystem only supports a handful of protocols (much less than PF_*) and even non-PF protocols like ARP and pseudo-protocols like PF_BRIDGE. By creating NFPROTO_*, we can earn a few memory savings on arrays that previously were always PF_MAX-sized and keep the pseudo-protocols to ourselves. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index 8c83d2e23bd..bf3afb0844f 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -52,6 +52,16 @@ enum nf_inet_hooks { NF_INET_NUMHOOKS }; +enum { + NFPROTO_UNSPEC = 0, + NFPROTO_IPV4 = 2, + NFPROTO_ARP = 3, + NFPROTO_BRIDGE = 7, + NFPROTO_IPV6 = 10, + NFPROTO_DECNET = 12, + NFPROTO_NUMPROTO, +}; + union nf_inet_addr { __u32 all[4]; __be32 ip; @@ -138,7 +148,7 @@ extern struct ctl_path nf_net_netfilter_sysctl_path[]; extern struct ctl_path nf_net_ipv4_netfilter_sysctl_path[]; #endif /* CONFIG_SYSCTL */ -extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; +extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, @@ -247,7 +257,7 @@ struct nf_afinfo { int route_key_size; }; -extern const struct nf_afinfo *nf_afinfo[NPROTO]; +extern const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO]; static inline const struct nf_afinfo *nf_get_afinfo(unsigned short family) { return rcu_dereference(nf_afinfo[family]); -- cgit v1.2.3 From 48dc7865aa3db9404aedc8677d9daf8f8f469ab0 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 8 Oct 2008 11:35:01 +0200 Subject: netfilter: netns: remove nf_*_net() wrappers Now that dev_net() exists, the usefullness of them is even less. Also they're a big problem in resolving circular header dependencies necessary for NOTRACK-in-netns patch. See below. Signed-off-by: Alexey Dobriyan Signed-off-by: Patrick McHardy --- include/linux/netfilter.h | 53 ----------------------------------------------- 1 file changed, 53 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h index bf3afb0844f..48cfe51bfdd 100644 --- a/include/linux/netfilter.h +++ b/include/linux/netfilter.h @@ -5,13 +5,11 @@ #include #include #include -#include #include #include #include #include #include -#include #endif #include #include @@ -355,56 +353,5 @@ extern void (*nf_ct_destroy)(struct nf_conntrack *); static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {} #endif -static inline struct net *nf_pre_routing_net(const struct net_device *in, - const struct net_device *out) -{ -#ifdef CONFIG_NET_NS - return in->nd_net; -#else - return &init_net; -#endif -} - -static inline struct net *nf_local_in_net(const struct net_device *in, - const struct net_device *out) -{ -#ifdef CONFIG_NET_NS - return in->nd_net; -#else - return &init_net; -#endif -} - -static inline struct net *nf_forward_net(const struct net_device *in, - const struct net_device *out) -{ -#ifdef CONFIG_NET_NS - BUG_ON(in->nd_net != out->nd_net); - return in->nd_net; -#else - return &init_net; -#endif -} - -static inline struct net *nf_local_out_net(const struct net_device *in, - const struct net_device *out) -{ -#ifdef CONFIG_NET_NS - return out->nd_net; -#else - return &init_net; -#endif -} - -static inline struct net *nf_post_routing_net(const struct net_device *in, - const struct net_device *out) -{ -#ifdef CONFIG_NET_NS - return out->nd_net; -#else - return &init_net; -#endif -} - #endif /*__KERNEL__*/ #endif /*__LINUX_NETFILTER_H*/ -- cgit v1.2.3 From 3bb0d1c00f86b13bb184193a8f0189ddd6f0459f Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 8 Oct 2008 11:35:10 +0200 Subject: netfilter: netns nf_conntrack: GRE conntracking in netns * make keymap list per-netns * per-netns keymal lock (not strictly necessary) * flush keymap at netns stop and module unload. Signed-off-by: Alexey Dobriyan Signed-off-by: Patrick McHardy --- include/linux/netfilter/nf_conntrack_proto_gre.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/nf_conntrack_proto_gre.h b/include/linux/netfilter/nf_conntrack_proto_gre.h index 535e4219d2b..2a10efda17f 100644 --- a/include/linux/netfilter/nf_conntrack_proto_gre.h +++ b/include/linux/netfilter/nf_conntrack_proto_gre.h @@ -87,7 +87,7 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, /* delete keymap entries */ void nf_ct_gre_keymap_destroy(struct nf_conn *ct); -extern void nf_ct_gre_keymap_flush(void); +extern void nf_ct_gre_keymap_flush(struct net *net); extern void nf_nat_need_gre(void); #endif /* __KERNEL__ */ -- cgit v1.2.3 From e84392707e10301b93121e1b74e2823db50cdf9e Mon Sep 17 00:00:00 2001 From: KOVACS Krisztian Date: Wed, 8 Oct 2008 11:35:12 +0200 Subject: netfilter: iptables TPROXY target The TPROXY target implements redirection of non-local TCP/UDP traffic to local sockets. Additionally, it's possible to manipulate the packet mark if and only if a socket has been found. (We need this because we cannot use multiple targets in the same iptables rule.) Signed-off-by: KOVACS Krisztian Signed-off-by: Patrick McHardy --- include/linux/netfilter/xt_TPROXY.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 include/linux/netfilter/xt_TPROXY.h (limited to 'include/linux') diff --git a/include/linux/netfilter/xt_TPROXY.h b/include/linux/netfilter/xt_TPROXY.h new file mode 100644 index 00000000000..152e8f97132 --- /dev/null +++ b/include/linux/netfilter/xt_TPROXY.h @@ -0,0 +1,14 @@ +#ifndef _XT_TPROXY_H_target +#define _XT_TPROXY_H_target + +/* TPROXY target is capable of marking the packet to perform + * redirection. We can get rid of that whenever we get support for + * mutliple targets in the same rule. */ +struct xt_tproxy_target_info { + u_int32_t mark_mask; + u_int32_t mark_value; + __be32 laddr; + __be16 lport; +}; + +#endif /* _XT_TPROXY_H_target */ -- cgit v1.2.3 From 18219d3f7d6a5bc43825a41e0763158efbdb80d3 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:13 +0200 Subject: netfilter: ebtables: do centralized size checking Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 892f5b7771c..fd085af8962 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -215,6 +215,7 @@ struct ebt_match int (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *matchdata, unsigned int datalen); void (*destroy)(void *matchdata, unsigned int datalen); + unsigned int matchsize; struct module *me; }; @@ -229,6 +230,7 @@ struct ebt_watcher int (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *watcherdata, unsigned int datalen); void (*destroy)(void *watcherdata, unsigned int datalen); + unsigned int targetsize; struct module *me; }; @@ -244,6 +246,7 @@ struct ebt_target int (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *targetdata, unsigned int datalen); void (*destroy)(void *targetdata, unsigned int datalen); + unsigned int targetsize; struct module *me; }; -- cgit v1.2.3 From 19eda879a136889110c692dec4c2ab59e0e43cef Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:13 +0200 Subject: netfilter: change return types of check functions for Ebtables extensions Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index fd085af8962..5f71719b7a2 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -211,8 +211,7 @@ struct ebt_match int (*match)(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchdata, unsigned int datalen); - /* 0 == let it in */ - int (*check)(const char *tablename, unsigned int hookmask, + bool (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *matchdata, unsigned int datalen); void (*destroy)(void *matchdata, unsigned int datalen); unsigned int matchsize; @@ -226,8 +225,7 @@ struct ebt_watcher void (*watcher)(const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, const struct net_device *out, const void *watcherdata, unsigned int datalen); - /* 0 == let it in */ - int (*check)(const char *tablename, unsigned int hookmask, + bool (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *watcherdata, unsigned int datalen); void (*destroy)(void *watcherdata, unsigned int datalen); unsigned int targetsize; @@ -242,8 +240,7 @@ struct ebt_target int (*target)(struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, const struct net_device *out, const void *targetdata, unsigned int datalen); - /* 0 == let it in */ - int (*check)(const char *tablename, unsigned int hookmask, + bool (*check)(const char *tablename, unsigned int hookmask, const struct ebt_entry *e, void *targetdata, unsigned int datalen); void (*destroy)(void *targetdata, unsigned int datalen); unsigned int targetsize; -- cgit v1.2.3 From 8cc784eec6676b58e7f60419c88179aaa97bf71c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:13 +0200 Subject: netfilter: change return types of match functions for ebtables extensions Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 5f71719b7a2..f9fda2c442a 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -207,8 +207,7 @@ struct ebt_match { struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; - /* 0 == it matches */ - int (*match)(const struct sk_buff *skb, const struct net_device *in, + bool (*match)(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchdata, unsigned int datalen); bool (*check)(const char *tablename, unsigned int hookmask, -- cgit v1.2.3 From 0ac6ab1f7915fc820ca0cf8f597290dbb249edcc Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:13 +0200 Subject: netfilter: Change return types of targets/watchers for Ebtables extensions Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index f9fda2c442a..097432b94c5 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -221,7 +221,7 @@ struct ebt_watcher { struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; - void (*watcher)(const struct sk_buff *skb, unsigned int hooknr, + unsigned int (*watcher)(const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, const struct net_device *out, const void *watcherdata, unsigned int datalen); bool (*check)(const char *tablename, unsigned int hookmask, @@ -235,8 +235,8 @@ struct ebt_target { struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; - /* returns one of the standard verdicts */ - int (*target)(struct sk_buff *skb, unsigned int hooknr, + /* returns one of the standard EBT_* verdicts */ + unsigned int (*target)(struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, const struct net_device *out, const void *targetdata, unsigned int datalen); bool (*check)(const char *tablename, unsigned int hookmask, -- cgit v1.2.3 From 001a18d369f4813ed792629ff4a9a6ade2a4a031 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:14 +0200 Subject: netfilter: add dummy members to Ebtables code to ease transition to Xtables Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 097432b94c5..82f854bf37e 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -214,6 +214,8 @@ struct ebt_match const struct ebt_entry *e, void *matchdata, unsigned int datalen); void (*destroy)(void *matchdata, unsigned int datalen); unsigned int matchsize; + u_int8_t revision; + u_int8_t family; struct module *me; }; @@ -228,6 +230,8 @@ struct ebt_watcher const struct ebt_entry *e, void *watcherdata, unsigned int datalen); void (*destroy)(void *watcherdata, unsigned int datalen); unsigned int targetsize; + u_int8_t revision; + u_int8_t family; struct module *me; }; @@ -243,6 +247,8 @@ struct ebt_target const struct ebt_entry *e, void *targetdata, unsigned int datalen); void (*destroy)(void *targetdata, unsigned int datalen); unsigned int targetsize; + u_int8_t revision; + u_int8_t family; struct module *me; }; -- cgit v1.2.3 From 2d06d4a5cc107046508d860a0b47dbc43b829b79 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:15 +0200 Subject: netfilter: change Ebtables function signatures to match Xtables's Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 43 +++++++++++++++++++------------ 1 file changed, 26 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 82f854bf37e..f20a57da7a2 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -31,6 +31,9 @@ * The 4 lsb are more than enough to store the verdict. */ #define EBT_VERDICT_BITS 0x0000000F +struct xt_match; +struct xt_target; + struct ebt_counter { uint64_t pcnt; @@ -208,11 +211,13 @@ struct ebt_match struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; bool (*match)(const struct sk_buff *skb, const struct net_device *in, - const struct net_device *out, const void *matchdata, - unsigned int datalen); - bool (*check)(const char *tablename, unsigned int hookmask, - const struct ebt_entry *e, void *matchdata, unsigned int datalen); - void (*destroy)(void *matchdata, unsigned int datalen); + const struct net_device *out, const struct xt_match *match, + const void *matchinfo, int offset, unsigned int protoff, + bool *hotdrop); + bool (*checkentry)(const char *table, const void *entry, + const struct xt_match *match, void *matchinfo, + unsigned int hook_mask); + void (*destroy)(const struct xt_match *match, void *matchinfo); unsigned int matchsize; u_int8_t revision; u_int8_t family; @@ -223,12 +228,14 @@ struct ebt_watcher { struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; - unsigned int (*watcher)(const struct sk_buff *skb, unsigned int hooknr, - const struct net_device *in, const struct net_device *out, - const void *watcherdata, unsigned int datalen); - bool (*check)(const char *tablename, unsigned int hookmask, - const struct ebt_entry *e, void *watcherdata, unsigned int datalen); - void (*destroy)(void *watcherdata, unsigned int datalen); + unsigned int (*target)(struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + unsigned int hook_num, const struct xt_target *target, + const void *targinfo); + bool (*checkentry)(const char *table, const void *entry, + const struct xt_target *target, void *targinfo, + unsigned int hook_mask); + void (*destroy)(const struct xt_target *target, void *targinfo); unsigned int targetsize; u_int8_t revision; u_int8_t family; @@ -240,12 +247,14 @@ struct ebt_target struct list_head list; const char name[EBT_FUNCTION_MAXNAMELEN]; /* returns one of the standard EBT_* verdicts */ - unsigned int (*target)(struct sk_buff *skb, unsigned int hooknr, - const struct net_device *in, const struct net_device *out, - const void *targetdata, unsigned int datalen); - bool (*check)(const char *tablename, unsigned int hookmask, - const struct ebt_entry *e, void *targetdata, unsigned int datalen); - void (*destroy)(void *targetdata, unsigned int datalen); + unsigned int (*target)(struct sk_buff *skb, + const struct net_device *in, const struct net_device *out, + unsigned int hook_num, const struct xt_target *target, + const void *targinfo); + bool (*checkentry)(const char *table, const void *entry, + const struct xt_target *target, void *targinfo, + unsigned int hook_mask); + void (*destroy)(const struct xt_target *target, void *targinfo); unsigned int targetsize; u_int8_t revision; u_int8_t family; -- cgit v1.2.3 From 043ef46c7690bfdbd5b012e15812a14a19ca5604 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:15 +0200 Subject: netfilter: move Ebtables to use Xtables Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index f20a57da7a2..d3f9243b9d9 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -124,7 +124,7 @@ struct ebt_entry_match { union { char name[EBT_FUNCTION_MAXNAMELEN]; - struct ebt_match *match; + struct xt_match *match; } u; /* size of data */ unsigned int match_size; @@ -135,7 +135,7 @@ struct ebt_entry_watcher { union { char name[EBT_FUNCTION_MAXNAMELEN]; - struct ebt_watcher *watcher; + struct xt_target *watcher; } u; /* size of data */ unsigned int watcher_size; @@ -146,7 +146,7 @@ struct ebt_entry_target { union { char name[EBT_FUNCTION_MAXNAMELEN]; - struct ebt_target *target; + struct xt_target *target; } u; /* size of data */ unsigned int target_size; -- cgit v1.2.3 From 66bff35b722956cc2423f55fcf1b69cefa24ef8b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:16 +0200 Subject: netfilter: remove unused Ebtables functions Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter_bridge/ebtables.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index d3f9243b9d9..568a690f6a6 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -302,12 +302,6 @@ struct ebt_table ~(__alignof__(struct ebt_replace)-1)) extern int ebt_register_table(struct ebt_table *table); extern void ebt_unregister_table(struct ebt_table *table); -extern int ebt_register_match(struct ebt_match *match); -extern void ebt_unregister_match(struct ebt_match *match); -extern int ebt_register_watcher(struct ebt_watcher *watcher); -extern void ebt_unregister_watcher(struct ebt_watcher *watcher); -extern int ebt_register_target(struct ebt_target *target); -extern void ebt_unregister_target(struct ebt_target *target); extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, struct ebt_table *table); -- cgit v1.2.3 From 367c679007fa4f990eb7ee381326ec59d8148b0e Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:17 +0200 Subject: netfilter: xtables: do centralized checkentry call (1/2) It used to be that {ip,ip6,etc}_tables called extension->checkentry themselves, but this can be moved into the xtables core. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 6989b22716e..85aa42785a5 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -330,10 +330,12 @@ extern void xt_unregister_matches(struct xt_match *match, unsigned int n); extern int xt_check_match(const struct xt_match *match, unsigned short family, unsigned int size, const char *table, unsigned int hook, - unsigned short proto, int inv_proto); + unsigned short proto, int inv_proto, + const void *entry, void *matchinfo); extern int xt_check_target(const struct xt_target *target, unsigned short family, unsigned int size, const char *table, unsigned int hook, - unsigned short proto, int inv_proto); + unsigned short proto, int inv_proto, + const void *entry, void *targinfo); extern struct xt_table *xt_register_table(struct net *net, struct xt_table *table, -- cgit v1.2.3 From f7108a20dee44e5bb037f9e48f6a207b42e6ae1c Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:18 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (1/6) The function signatures for Xtables extensions have grown over time. It involves a lot of typing/replication, and also a bit of stack space even if they are not used. Realize an NFWS2008 idea and pack them into structs. The skb remains outside of the struct so gcc can continue to apply its optimizations. This patch does this for match extensions' match functions. A few ambiguities have also been addressed. The "offset" parameter for example has been renamed to "fragoff" (there are so many different offsets already) and "protoff" to "thoff" (there is more than just one protocol here, so clarify). Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 85aa42785a5..bcd40ec8325 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -173,6 +173,26 @@ struct xt_counters_info #include +/** + * struct xt_match_param - parameters for match extensions' match functions + * + * @in: input netdevice + * @out: output netdevice + * @match: struct xt_match through which this function was invoked + * @matchinfo: per-match data + * @fragoff: packet is a fragment, this is the data offset + * @thoff: position of transport header relative to skb->data + * @hotdrop: drop packet if we had inspection problems + */ +struct xt_match_param { + const struct net_device *in, *out; + const struct xt_match *match; + const void *matchinfo; + int fragoff; + unsigned int thoff; + bool *hotdrop; +}; + struct xt_match { struct list_head list; @@ -185,13 +205,7 @@ struct xt_match non-linear skb, using skb_header_pointer and skb_ip_make_writable. */ bool (*match)(const struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - const struct xt_match *match, - const void *matchinfo, - int offset, - unsigned int protoff, - bool *hotdrop); + const struct xt_match_param *); /* Called when user tries to insert an entry of this type. */ /* Should return true or false. */ -- cgit v1.2.3 From 9b4fce7a3508a9776534188b6065b206a9608ccf Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:18 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (2/6) This patch does this for match extensions' checkentry functions. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index bcd40ec8325..763a704ce83 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -193,6 +193,25 @@ struct xt_match_param { bool *hotdrop; }; +/** + * struct xt_mtchk_param - parameters for match extensions' + * checkentry functions + * + * @table: table the rule is tried to be inserted into + * @entryinfo: the family-specific rule data + * (struct ipt_ip, ip6t_ip, ebt_entry) + * @match: struct xt_match through which this function was invoked + * @matchinfo: per-match data + * @hook_mask: via which hooks the new rule is reachable + */ +struct xt_mtchk_param { + const char *table; + const void *entryinfo; + const struct xt_match *match; + void *matchinfo; + unsigned int hook_mask; +}; + struct xt_match { struct list_head list; @@ -208,12 +227,7 @@ struct xt_match const struct xt_match_param *); /* Called when user tries to insert an entry of this type. */ - /* Should return true or false. */ - bool (*checkentry)(const char *tablename, - const void *ip, - const struct xt_match *match, - void *matchinfo, - unsigned int hook_mask); + bool (*checkentry)(const struct xt_mtchk_param *); /* Called when entry of this type deleted. */ void (*destroy)(const struct xt_match *match, void *matchinfo); @@ -342,10 +356,8 @@ extern void xt_unregister_match(struct xt_match *target); extern int xt_register_matches(struct xt_match *match, unsigned int n); extern void xt_unregister_matches(struct xt_match *match, unsigned int n); -extern int xt_check_match(const struct xt_match *match, unsigned short family, - unsigned int size, const char *table, unsigned int hook, - unsigned short proto, int inv_proto, - const void *entry, void *matchinfo); +extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, + unsigned int size, u_int8_t proto, bool inv_proto); extern int xt_check_target(const struct xt_target *target, unsigned short family, unsigned int size, const char *table, unsigned int hook, unsigned short proto, int inv_proto, -- cgit v1.2.3 From 6be3d8598e883fb632edf059ba2f8d1b9f4da138 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:19 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (3/6) This patch does this for match extensions' destroy functions. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 763a704ce83..c79c8838014 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -212,6 +212,12 @@ struct xt_mtchk_param { unsigned int hook_mask; }; +/* Match destructor parameters */ +struct xt_mtdtor_param { + const struct xt_match *match; + void *matchinfo; +}; + struct xt_match { struct list_head list; @@ -230,7 +236,7 @@ struct xt_match bool (*checkentry)(const struct xt_mtchk_param *); /* Called when entry of this type deleted. */ - void (*destroy)(const struct xt_match *match, void *matchinfo); + void (*destroy)(const struct xt_mtdtor_param *); /* Called when userspace align differs from kernel space one */ void (*compat_from_user)(void *dst, void *src); -- cgit v1.2.3 From 7eb3558655aaa87a3e71a0c065dfaddda521fa6d Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:19 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (4/6) This patch does this for target extensions' target functions. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index c79c8838014..46d0cb1ad34 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -218,6 +218,22 @@ struct xt_mtdtor_param { void *matchinfo; }; +/** + * struct xt_target_param - parameters for target extensions' target functions + * + * @hooknum: hook through which this target was invoked + * @target: struct xt_target through which this function was invoked + * @targinfo: per-target data + * + * Other fields see above. + */ +struct xt_target_param { + const struct net_device *in, *out; + unsigned int hooknum; + const struct xt_target *target; + const void *targinfo; +}; + struct xt_match { struct list_head list; @@ -269,11 +285,7 @@ struct xt_target must now handle non-linear skbs, using skb_copy_bits and skb_ip_make_writable. */ unsigned int (*target)(struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - unsigned int hooknum, - const struct xt_target *target, - const void *targinfo); + const struct xt_target_param *); /* Called when user tries to insert an entry of this type: hook_mask is a bitmask of hooks from which it can be -- cgit v1.2.3 From af5d6dc200eb0fcc6fbd3df1ab4d8969004cb37f Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:19 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (5/6) This patch does this for target extensions' checkentry functions. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 29 ++++++++++++++++++++--------- include/linux/netfilter_bridge/ebtables.h | 4 ++-- 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 46d0cb1ad34..8daeb496ba7 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -234,6 +234,23 @@ struct xt_target_param { const void *targinfo; }; +/** + * struct xt_tgchk_param - parameters for target extensions' + * checkentry functions + * + * @entryinfo: the family-specific rule data + * (struct ipt_entry, ip6t_entry, arpt_entry, ebt_entry) + * + * Other fields see above. + */ +struct xt_tgchk_param { + const char *table; + void *entryinfo; + const struct xt_target *target; + void *targinfo; + unsigned int hook_mask; +}; + struct xt_match { struct list_head list; @@ -291,11 +308,7 @@ struct xt_target hook_mask is a bitmask of hooks from which it can be called. */ /* Should return true or false. */ - bool (*checkentry)(const char *tablename, - const void *entry, - const struct xt_target *target, - void *targinfo, - unsigned int hook_mask); + bool (*checkentry)(const struct xt_tgchk_param *); /* Called when entry of this type deleted. */ void (*destroy)(const struct xt_target *target, void *targinfo); @@ -376,10 +389,8 @@ extern void xt_unregister_matches(struct xt_match *match, unsigned int n); extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, unsigned int size, u_int8_t proto, bool inv_proto); -extern int xt_check_target(const struct xt_target *target, unsigned short family, - unsigned int size, const char *table, unsigned int hook, - unsigned short proto, int inv_proto, - const void *entry, void *targinfo); +extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family, + unsigned int size, u_int8_t proto, bool inv_proto); extern struct xt_table *xt_register_table(struct net *net, struct xt_table *table, diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h index 568a690f6a6..d45e29cd1cf 100644 --- a/include/linux/netfilter_bridge/ebtables.h +++ b/include/linux/netfilter_bridge/ebtables.h @@ -310,9 +310,9 @@ extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff *skb, #define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) /* True if the hook mask denotes that the rule is in a base chain, * used in the check() functions */ -#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) +#define BASE_CHAIN (par->hook_mask & (1 << NF_BR_NUMHOOKS)) /* Clear the bit in the hook mask that tells if the rule is on a base chain */ -#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) +#define CLEAR_BASE_CHAIN_BIT (par->hook_mask &= ~(1 << NF_BR_NUMHOOKS)) /* True if the target is not a standard target */ #define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) -- cgit v1.2.3 From a2df1648ba615dd5908e9a1fa7b2f133fa302487 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:19 +0200 Subject: netfilter: xtables: move extension arguments into compound structure (6/6) This patch does this for target extensions' destroy functions. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 8daeb496ba7..e3b3b669a14 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -251,6 +251,12 @@ struct xt_tgchk_param { unsigned int hook_mask; }; +/* Target destructor parameters */ +struct xt_tgdtor_param { + const struct xt_target *target; + void *targinfo; +}; + struct xt_match { struct list_head list; @@ -311,7 +317,7 @@ struct xt_target bool (*checkentry)(const struct xt_tgchk_param *); /* Called when entry of this type deleted. */ - void (*destroy)(const struct xt_target *target, void *targinfo); + void (*destroy)(const struct xt_tgdtor_param *); /* Called when userspace align differs from kernel space one */ void (*compat_from_user)(void *dst, void *src); -- cgit v1.2.3 From 916a917dfec18535ff9e2afdafba82e6279eb4f4 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Wed, 8 Oct 2008 11:35:20 +0200 Subject: netfilter: xtables: provide invoked family value to extensions By passing in the family through which extensions were invoked, a bit of data space can be reclaimed. The "family" member will be added to the parameter structures and the check functions be adjusted. Signed-off-by: Jan Engelhardt Signed-off-by: Patrick McHardy --- include/linux/netfilter/x_tables.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index e3b3b669a14..be41b609c88 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -183,6 +183,8 @@ struct xt_counters_info * @fragoff: packet is a fragment, this is the data offset * @thoff: position of transport header relative to skb->data * @hotdrop: drop packet if we had inspection problems + * @family: Actual NFPROTO_* through which the function is invoked + * (helpful when match->family == NFPROTO_UNSPEC) */ struct xt_match_param { const struct net_device *in, *out; @@ -191,6 +193,7 @@ struct xt_match_param { int fragoff; unsigned int thoff; bool *hotdrop; + u_int8_t family; }; /** @@ -210,12 +213,14 @@ struct xt_mtchk_param { const struct xt_match *match; void *matchinfo; unsigned int hook_mask; + u_int8_t family; }; /* Match destructor parameters */ struct xt_mtdtor_param { const struct xt_match *match; void *matchinfo; + u_int8_t family; }; /** @@ -232,6 +237,7 @@ struct xt_target_param { unsigned int hooknum; const struct xt_target *target; const void *targinfo; + u_int8_t family; }; /** @@ -249,12 +255,14 @@ struct xt_tgchk_param { const struct xt_target *target; void *targinfo; unsigned int hook_mask; + u_int8_t family; }; /* Target destructor parameters */ struct xt_tgdtor_param { const struct xt_target *target; void *targinfo; + u_int8_t family; }; struct xt_match @@ -393,9 +401,9 @@ extern void xt_unregister_match(struct xt_match *target); extern int xt_register_matches(struct xt_match *match, unsigned int n); extern void xt_unregister_matches(struct xt_match *match, unsigned int n); -extern int xt_check_match(struct xt_mtchk_param *, u_int8_t family, +extern int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, bool inv_proto); -extern int xt_check_target(struct xt_tgchk_param *, u_int8_t family, +extern int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, bool inv_proto); extern struct xt_table *xt_register_table(struct net *net, -- cgit v1.2.3 From 19d771f3caccaf66ce2fb539319222139e5b4e88 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Wed, 8 Oct 2008 13:54:52 -0400 Subject: NFS: Save padding bytes in struct nfs4_setclientid Peter Staubach suggested reducing NFS4_SETCLIENTID_NAMELEN by one byte so as to avoid 7 bytes of unnecessary padding. Signed-off-by: Trond Myklebust --- include/linux/nfs_xdr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index f6e95bfad5d..6ee6ae3f095 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -672,7 +672,7 @@ struct nfs4_rename_res { struct nfs_fattr * new_fattr; }; -#define NFS4_SETCLIENTID_NAMELEN (128) +#define NFS4_SETCLIENTID_NAMELEN (127) struct nfs4_setclientid { const nfs4_verifier * sc_verifier; unsigned int sc_name_len; -- cgit v1.2.3 From 18ee49ddb0d242ed1d0e273038d5e4f6de7379d3 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 1 Oct 2008 15:41:33 +0000 Subject: phylib: rename mii_bus::dev to mii_bus::parent In preparation of giving mii_bus objects a device tree presence of their own, rename struct mii_bus's ->dev argument to ->parent, since having a 'struct device *dev' that points to our parent device conflicts with introducing a 'struct device dev' representing our own device. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller Acked-by: Andy Fleming --- include/linux/phy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/phy.h b/include/linux/phy.h index 5f170f5b1a3..87499bdedc6 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -99,7 +99,7 @@ struct mii_bus { */ struct mutex mdio_lock; - struct device *dev; + struct device *parent; /* list of all PHYs on bus */ struct phy_device *phy_map[PHY_MAX_ADDR]; -- cgit v1.2.3 From 298cf9beb9679522de995e249eccbd82f7c51999 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 8 Oct 2008 16:29:57 -0700 Subject: phylib: move to dynamic allocation of struct mii_bus This patch introduces mdiobus_alloc() and mdiobus_free(), and makes all mdio bus drivers use these functions to allocate their struct mii_bus'es dynamically. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller Acked-by: Andy Fleming --- include/linux/phy.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phy.h b/include/linux/phy.h index 87499bdedc6..ca4a83c4c53 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -408,8 +408,10 @@ void phy_start(struct phy_device *phydev); void phy_stop(struct phy_device *phydev); int phy_start_aneg(struct phy_device *phydev); +struct mii_bus *mdiobus_alloc(void); int mdiobus_register(struct mii_bus *bus); void mdiobus_unregister(struct mii_bus *bus); +void mdiobus_free(struct mii_bus *bus); struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); void phy_sanitize_settings(struct phy_device *phydev); -- cgit v1.2.3 From 46abc02175b3c246dd5141d878f565a8725060c9 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 8 Oct 2008 16:33:40 -0700 Subject: phylib: give mdio buses a device tree presence Introduce the mdio_bus class, and give each 'struct mii_bus' its own 'struct device', so that mii_bus objects are represented in the device tree and can be found by querying the device tree. Signed-off-by: Lennert Buytenhek Acked-by: Andy Fleming Signed-off-by: David S. Miller --- include/linux/phy.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/phy.h b/include/linux/phy.h index ca4a83c4c53..891f27f9137 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -100,6 +100,13 @@ struct mii_bus { struct mutex mdio_lock; struct device *parent; + enum { + MDIOBUS_ALLOCATED = 1, + MDIOBUS_REGISTERED, + MDIOBUS_UNREGISTERED, + MDIOBUS_RELEASED, + } state; + struct device dev; /* list of all PHYs on bus */ struct phy_device *phy_map[PHY_MAX_ADDR]; @@ -113,6 +120,7 @@ struct mii_bus { */ int *irq; }; +#define to_mii_bus(d) container_of(d, struct mii_bus, dev) #define PHY_INTERRUPT_DISABLED 0x0 #define PHY_INTERRUPT_ENABLED 0x80000000 -- cgit v1.2.3 From 2e888103295f47b8fcbf7e9bb8c5da97dd2ecd76 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Mon, 29 Sep 2008 17:12:35 +0000 Subject: phylib: add mdiobus_{read,write} Add mdiobus_{read,write} routines to allow direct reading/writing of registers on an mii bus without having to go through the PHY abstraction, and make phy_{read,write} use these primitives. Signed-off-by: Lennert Buytenhek Signed-off-by: David S. Miller --- include/linux/phy.h | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/phy.h b/include/linux/phy.h index 891f27f9137..77c4ed60b98 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -122,6 +122,15 @@ struct mii_bus { }; #define to_mii_bus(d) container_of(d, struct mii_bus, dev) +struct mii_bus *mdiobus_alloc(void); +int mdiobus_register(struct mii_bus *bus); +void mdiobus_unregister(struct mii_bus *bus); +void mdiobus_free(struct mii_bus *bus); +struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); +int mdiobus_read(struct mii_bus *bus, int addr, u16 regnum); +int mdiobus_write(struct mii_bus *bus, int addr, u16 regnum, u16 val); + + #define PHY_INTERRUPT_DISABLED 0x0 #define PHY_INTERRUPT_ENABLED 0x80000000 @@ -399,8 +408,35 @@ struct phy_fixup { int (*run)(struct phy_device *phydev); }; -int phy_read(struct phy_device *phydev, u16 regnum); -int phy_write(struct phy_device *phydev, u16 regnum, u16 val); +/** + * phy_read - Convenience function for reading a given PHY register + * @phydev: the phy_device struct + * @regnum: register number to read + * + * NOTE: MUST NOT be called from interrupt context, + * because the bus read/write functions may wait for an interrupt + * to conclude the operation. + */ +static inline int phy_read(struct phy_device *phydev, u16 regnum) +{ + return mdiobus_read(phydev->bus, phydev->addr, regnum); +} + +/** + * phy_write - Convenience function for writing a given PHY register + * @phydev: the phy_device struct + * @regnum: register number to write + * @val: value to write to @regnum + * + * NOTE: MUST NOT be called from interrupt context, + * because the bus read/write functions may wait for an interrupt + * to conclude the operation. + */ +static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val) +{ + return mdiobus_write(phydev->bus, phydev->addr, regnum, val); +} + int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id); struct phy_device* get_phy_device(struct mii_bus *bus, int addr); int phy_clear_interrupt(struct phy_device *phydev); @@ -416,12 +452,6 @@ void phy_start(struct phy_device *phydev); void phy_stop(struct phy_device *phydev); int phy_start_aneg(struct phy_device *phydev); -struct mii_bus *mdiobus_alloc(void); -int mdiobus_register(struct mii_bus *bus); -void mdiobus_unregister(struct mii_bus *bus); -void mdiobus_free(struct mii_bus *bus); -struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr); - void phy_sanitize_settings(struct phy_device *phydev); int phy_stop_interrupts(struct phy_device *phydev); int phy_enable_interrupts(struct phy_device *phydev); -- cgit v1.2.3 From 91da11f870f00a3322b81c73042291d7f0be5a17 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 7 Oct 2008 13:44:02 +0000 Subject: net: Distributed Switch Architecture protocol support Distributed Switch Architecture is a protocol for managing hardware switch chips. It consists of a set of MII management registers and commands to configure the switch, and an ethernet header format to signal which of the ports of the switch a packet was received from or is intended to be sent to. The switches that this driver supports are typically embedded in access points and routers, and a typical setup with a DSA switch looks something like this: +-----------+ +-----------+ | | RGMII | | | +-------+ +------ 1000baseT MDI ("WAN") | | | 6-port +------ 1000baseT MDI ("LAN1") | CPU | | ethernet +------ 1000baseT MDI ("LAN2") | |MIImgmt| switch +------ 1000baseT MDI ("LAN3") | +-------+ w/5 PHYs +------ 1000baseT MDI ("LAN4") | | | | +-----------+ +-----------+ The switch driver presents each port on the switch as a separate network interface to Linux, polls the switch to maintain software link state of those ports, forwards MII management interface accesses to those network interfaces (e.g. as done by ethtool) to the switch, and exposes the switch's hardware statistics counters via the appropriate Linux kernel interfaces. This initial patch supports the MII management interface register layout of the Marvell 88E6123, 88E6161 and 88E6165 switch chips, and supports the "Ethertype DSA" packet tagging format. (There is no officially registered ethertype for the Ethertype DSA packet format, so we just grab a random one. The ethertype to use is programmed into the switch, and the switch driver uses the value of ETH_P_EDSA for this, so this define can be changed at any time in the future if the one we chose is allocated to another protocol or if Ethertype DSA gets its own officially registered ethertype, and everything will continue to work.) Signed-off-by: Lennert Buytenhek Tested-by: Nicolas Pitre Tested-by: Byron Bradley Tested-by: Tim Ellis Tested-by: Peter van Valderen Tested-by: Dirk Teurlings Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + include/linux/netdevice.h | 3 +++ 2 files changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 723a1c5fbc6..2140aacb633 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -77,6 +77,7 @@ #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ #define ETH_P_AOE 0x88A2 /* ATA over Ethernet */ #define ETH_P_TIPC 0x88CA /* TIPC */ +#define ETH_P_EDSA 0xDADA /* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */ /* * Non DIX types. Won't clash for 1500 types. diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9cfd20be8b7..794eeb4b346 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -607,6 +607,9 @@ struct net_device /* Protocol specific pointers */ +#ifdef CONFIG_NET_DSA + void *dsa_ptr; /* dsa specific data */ +#endif void *atalk_ptr; /* AppleTalk link */ void *ip_ptr; /* IPv4 specific data */ void *dn_ptr; /* DECnet specific data */ -- cgit v1.2.3 From cf85d08fdf4548ee46657ccfb7f9949a85145db5 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 7 Oct 2008 13:45:02 +0000 Subject: dsa: add support for original DSA tagging format Most of the DSA switches currently in the field do not support the Ethertype DSA tagging format that one of the previous patches added support for, but only the original DSA tagging format. The original DSA tagging format carries the same information as the Ethertype DSA tagging format, but with the difference that it does not have an ethertype field. In other words, when receiving a packet that is tagged with an original DSA tag, there is no way of telling in eth_type_trans() that this packet is in fact a DSA-tagged packet. This patch adds a hook into eth_type_trans() which is only compiled in if support for a switch chip that doesn't support Ethertype DSA is selected, and which checks whether there is a DSA switch driver instance attached to this network device which uses the old tag format. If so, it sets the protocol field to ETH_P_DSA without looking at the packet, so that the packet ends up in the right place. Signed-off-by: Lennert Buytenhek Tested-by: Nicolas Pitre Tested-by: Peter van Valderen Tested-by: Dirk Teurlings Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + include/linux/netdevice.h | 11 +++++++++++ 2 files changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 2140aacb633..32b9dcda68c 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -101,6 +101,7 @@ #define ETH_P_ECONET 0x0018 /* Acorn Econet */ #define ETH_P_HDLC 0x0019 /* HDLC frames */ #define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ +#define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ /* diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 794eeb4b346..97f0c64c152 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -42,6 +42,7 @@ #include #include +#include struct vlan_group; struct ethtool_ops; @@ -801,6 +802,16 @@ void dev_net_set(struct net_device *dev, struct net *net) #endif } +static inline bool netdev_uses_dsa_tags(struct net_device *dev) +{ +#ifdef CONFIG_NET_DSA_TAG_DSA + if (dev->dsa_ptr != NULL) + return dsa_uses_dsa_tags(dev->dsa_ptr); +#endif + + return 0; +} + /** * netdev_priv - access network device private data * @dev: network device -- cgit v1.2.3 From 396138f03f4521c55ecc3a5dd75d4c56e6323244 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 7 Oct 2008 13:46:07 +0000 Subject: dsa: add support for Trailer tagging format This adds support for the Trailer switch tagging format. This is another tagging that doesn't explicitly mark tagged packets with a distinct ethertype, so that we need to add a similar hack in the receive path as for the Original DSA tagging format. Signed-off-by: Lennert Buytenhek Tested-by: Byron Bradley Tested-by: Tim Ellis Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + include/linux/netdevice.h | 10 ++++++++++ 2 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index 32b9dcda68c..a0099e98b5c 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -102,6 +102,7 @@ #define ETH_P_HDLC 0x0019 /* HDLC frames */ #define ETH_P_ARCNET 0x001A /* 1A for ArcNet :-) */ #define ETH_P_DSA 0x001B /* Distributed Switch Arch. */ +#define ETH_P_TRAILER 0x001C /* Trailer switch tagging */ #define ETH_P_PHONET 0x00F5 /* Nokia Phonet frames */ /* diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 97f0c64c152..d3ea3de70a8 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -812,6 +812,16 @@ static inline bool netdev_uses_dsa_tags(struct net_device *dev) return 0; } +static inline bool netdev_uses_trailer_tags(struct net_device *dev) +{ +#ifdef CONFIG_NET_DSA_TAG_TRAILER + if (dev->dsa_ptr != NULL) + return dsa_uses_trailer_tags(dev->dsa_ptr); +#endif + + return 0; +} + /** * netdev_priv - access network device private data * @dev: network device -- cgit v1.2.3 From 7a67f63b3233ff28e753854fe27891c44f8588ae Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 8 Aug 2008 11:17:12 +0200 Subject: block: add bio_has_data() to detect whether a bio carries data or not Signed-off-by: Jens Axboe --- include/linux/bio.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 0933a14e641..9e93c929947 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -445,6 +445,14 @@ static inline char *__bio_kmap_irq(struct bio *bio, unsigned short idx, __bio_kmap_irq((bio), (bio)->bi_idx, (flags)) #define bio_kunmap_irq(buf,flags) __bio_kunmap_irq(buf, flags) +/* + * Check whether this bio carries any data or not. A NULL bio is allowed. + */ +static inline int bio_has_data(struct bio *bio) +{ + return bio && bio->bi_io_vec != NULL; +} + #if defined(CONFIG_BLK_DEV_INTEGRITY) #define bip_vec_idx(bip, idx) (&(bip->bip_vec[(idx)])) -- cgit v1.2.3 From a9c701e594669dd49fed448c27c64f20cfacc8a7 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 8 Aug 2008 11:04:44 +0200 Subject: block: use bio_has_data() to check for data carrying bio Signed-off-by: Jens Axboe --- include/linux/bio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 9e93c929947..dbeb66f813a 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -185,7 +185,7 @@ struct bio { #define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) -#define bio_empty_barrier(bio) (bio_barrier(bio) && !(bio)->bi_size) +#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio)) static inline unsigned int bio_cur_sectors(struct bio *bio) { -- cgit v1.2.3 From d628eaef310533767ce68664873869c2d7f78f09 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 9 Aug 2008 16:22:17 +0100 Subject: Fix up comments about matching flags between bio and rq Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/bio.h | 4 ++-- include/linux/blkdev.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index dbeb66f813a..17f1fbdb31b 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -150,8 +150,8 @@ struct bio { * bit 3 -- fail fast, don't want low level driver retries * bit 4 -- synchronous I/O hint: the block layer will unplug immediately */ -#define BIO_RW 0 -#define BIO_RW_AHEAD 1 +#define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ +#define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ #define BIO_RW_BARRIER 2 #define BIO_RW_FAILFAST 3 #define BIO_RW_SYNC 4 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 53ea933cf60..e0ba018f5e8 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -84,7 +84,7 @@ enum { }; /* - * request type modified bits. first three bits match BIO_RW* bits, important + * request type modified bits. first two bits match BIO_RW* bits, important */ enum rq_flag_bits { __REQ_RW, /* not set, read. set, write */ -- cgit v1.2.3 From fb2dce862d9f9a68e6b9374579056ec9eca02a63 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 5 Aug 2008 18:01:53 +0100 Subject: Add 'discard' request handling Some block devices benefit from a hint that they can forget the contents of certain sectors. Add basic support for this to the block core, along with a 'blkdev_issue_discard()' helper function which issues such requests. The caller doesn't get to provide an end_io functio, since blkdev_issue_discard() will automatically split the request up into multiple bios if appropriate. Neither does the function wait for completion -- it's expected that callers won't care about when, or even _if_, the request completes. It's only a hint to the device anyway. By definition, the file system doesn't _care_ about these sectors any more. [With feedback from OGAWA Hirofumi and Jens Axboe Signed-off-by: Jens Axboe --- include/linux/bio.h | 8 ++++++-- include/linux/blkdev.h | 16 ++++++++++++++++ include/linux/fs.h | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 17f1fbdb31b..1fdfc5621c8 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -149,6 +149,8 @@ struct bio { * bit 2 -- barrier * bit 3 -- fail fast, don't want low level driver retries * bit 4 -- synchronous I/O hint: the block layer will unplug immediately + * bit 5 -- metadata request + * bit 6 -- discard sectors */ #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ @@ -156,6 +158,7 @@ struct bio { #define BIO_RW_FAILFAST 3 #define BIO_RW_SYNC 4 #define BIO_RW_META 5 +#define BIO_RW_DISCARD 6 /* * upper 16 bits of bi_rw define the io priority of this bio @@ -186,13 +189,14 @@ struct bio { #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) #define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio)) +#define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD)) static inline unsigned int bio_cur_sectors(struct bio *bio) { if (bio->bi_vcnt) return bio_iovec(bio)->bv_len >> 9; - - return 0; + else /* dataless requests such as discard */ + return bio->bi_size >> 9; } static inline void *bio_data(struct bio *bio) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e0ba018f5e8..26ececbbebe 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -89,6 +89,7 @@ enum { enum rq_flag_bits { __REQ_RW, /* not set, read. set, write */ __REQ_FAILFAST, /* no low level driver retries */ + __REQ_DISCARD, /* request to discard sectors */ __REQ_SORTED, /* elevator knows about this request */ __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ __REQ_HARDBARRIER, /* may not be passed by drive either */ @@ -111,6 +112,7 @@ enum rq_flag_bits { }; #define REQ_RW (1 << __REQ_RW) +#define REQ_DISCARD (1 << __REQ_DISCARD) #define REQ_FAILFAST (1 << __REQ_FAILFAST) #define REQ_SORTED (1 << __REQ_SORTED) #define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER) @@ -252,6 +254,7 @@ typedef void (request_fn_proc) (struct request_queue *q); typedef int (make_request_fn) (struct request_queue *q, struct bio *bio); typedef int (prep_rq_fn) (struct request_queue *, struct request *); typedef void (unplug_fn) (struct request_queue *); +typedef int (prepare_discard_fn) (struct request_queue *, struct request *); struct bio_vec; struct bvec_merge_data { @@ -307,6 +310,7 @@ struct request_queue make_request_fn *make_request_fn; prep_rq_fn *prep_rq_fn; unplug_fn *unplug_fn; + prepare_discard_fn *prepare_discard_fn; merge_bvec_fn *merge_bvec_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; @@ -546,6 +550,7 @@ enum { #define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED) #define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER) #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() */ @@ -796,6 +801,7 @@ extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); extern void blk_queue_dma_alignment(struct request_queue *, int); extern void blk_queue_update_dma_alignment(struct request_queue *, int); extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); +extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *); 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 **); @@ -837,6 +843,16 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, } extern int blkdev_issue_flush(struct block_device *, sector_t *); +extern int blkdev_issue_discard(struct block_device *, sector_t sector, + unsigned nr_sects); + +static inline int sb_issue_discard(struct super_block *sb, + sector_t block, unsigned nr_blocks) +{ + block <<= (sb->s_blocksize_bits - 9); + nr_blocks <<= (sb->s_blocksize_bits - 9); + return blkdev_issue_discard(sb->s_bdev, block, nr_blocks); +} /* * command filter functions diff --git a/include/linux/fs.h b/include/linux/fs.h index 580b513668f..eb013131913 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,7 +86,8 @@ extern int dir_notify_enable; #define READ_META (READ | (1 << BIO_RW_META)) #define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) #define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) -#define WRITE_BARRIER ((1 << BIO_RW) | (1 << BIO_RW_BARRIER)) +#define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) +#define WRITE_DISCARD (WRITE | (1 << BIO_RW_DISCARD)) #define SEL_IN 1 #define SEL_OUT 2 -- cgit v1.2.3 From eae9acd13a8d14b50c00a961fa959606f34bbd92 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 5 Aug 2008 18:08:25 +0100 Subject: Support 'discard sectors' operation in translation layer support core Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 + include/linux/mtd/blktrans.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 26ececbbebe..727886d25c4 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -81,6 +81,7 @@ enum { */ REQ_LB_OP_EJECT = 0x40, /* eject request */ REQ_LB_OP_FLUSH = 0x41, /* flush device */ + REQ_LB_OP_DISCARD = 0x42, /* discard sectors */ }; /* diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h index 310e6160641..8b4aa0523db 100644 --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h @@ -41,6 +41,8 @@ struct mtd_blktrans_ops { unsigned long block, char *buffer); int (*writesect)(struct mtd_blktrans_dev *dev, unsigned long block, char *buffer); + int (*discard)(struct mtd_blktrans_dev *dev, + unsigned long block, unsigned nr_blocks); /* Block layer ioctls */ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); -- cgit v1.2.3 From 27b29e86bf3d4b3cf6641a0efd78ed11a9b633b2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sun, 10 Aug 2008 11:21:57 +0100 Subject: blktrace: support discard requests Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/blktrace_api.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index d084b8d227a..27da2cc682e 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -21,6 +21,7 @@ enum blktrace_cat { BLK_TC_NOTIFY = 1 << 10, /* special message */ BLK_TC_AHEAD = 1 << 11, /* readahead */ BLK_TC_META = 1 << 12, /* metadata */ + BLK_TC_DISCARD = 1 << 13, /* discard requests */ BLK_TC_END = 1 << 15, /* only 16-bits, reminder */ }; @@ -195,6 +196,9 @@ static inline void blk_add_trace_rq(struct request_queue *q, struct request *rq, if (likely(!bt)) return; + if (blk_discard_rq(rq)) + rw |= (1 << BIO_RW_DISCARD); + if (blk_pc_request(rq)) { what |= BLK_TC_ACT(BLK_TC_PC); __blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors, sizeof(rq->cmd), rq->cmd); -- cgit v1.2.3 From d30a2605be9d5132d95944916e8f578fcfe4f976 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 11 Aug 2008 15:58:42 +0100 Subject: Add BLKDISCARD ioctl to allow userspace to discard sectors We may well want mkfs tools to use this to mark the whole device as unwanted before they format it, for example. The ioctl takes a pair of uint64_ts, which are start offset and length in _bytes_. Although at the moment it might make sense for them both to be in 512-byte sectors, I don't want to limit the ABI to that. Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index eb013131913..88358ca6af2 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -223,6 +223,7 @@ extern int dir_notify_enable; #define BLKTRACESTART _IO(0x12,116) #define BLKTRACESTOP _IO(0x12,117) #define BLKTRACETEARDOWN _IO(0x12,118) +#define BLKDISCARD _IO(0x12,119) #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ #define FIBMAP _IO(0x00,1) /* bmap access */ -- cgit v1.2.3 From e17fc0a1ccf88f6d4dcb363729f3141b0958c325 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Sat, 9 Aug 2008 16:42:20 +0100 Subject: Allow elevators to sort/merge discard requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit But blkdev_issue_discard() still emits requests which are interpreted as soft barriers, because naïve callers might otherwise issue subsequent writes to those same sectors, which might cross on the queue (if they're reallocated quickly enough). Callers still _can_ issue non-barrier discard requests, but they have to take care of queue ordering for themselves. Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/bio.h | 2 +- include/linux/blkdev.h | 5 +++-- include/linux/fs.h | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 1fdfc5621c8..33c3947d61e 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -188,8 +188,8 @@ struct bio { #define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) -#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio)) #define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD)) +#define bio_empty_barrier(bio) (bio_barrier(bio) && !bio_has_data(bio) && !bio_discard(bio)) static inline unsigned int bio_cur_sectors(struct bio *bio) { diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 727886d25c4..e9eb35c9bf2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -541,7 +541,7 @@ enum { #define blk_noretry_request(rq) ((rq)->cmd_flags & REQ_FAILFAST) #define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) -#define blk_account_rq(rq) (blk_rq_started(rq) && blk_fs_request(rq)) +#define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) #define blk_pm_suspend_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_SUSPEND) #define blk_pm_resume_request(rq) ((rq)->cmd_type == REQ_TYPE_PM_RESUME) @@ -598,7 +598,8 @@ static inline void blk_clear_queue_full(struct request_queue *q, int rw) #define RQ_NOMERGE_FLAGS \ (REQ_NOMERGE | REQ_STARTED | REQ_HARDBARRIER | REQ_SOFTBARRIER) #define rq_mergeable(rq) \ - (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && blk_fs_request((rq))) + (!((rq)->cmd_flags & RQ_NOMERGE_FLAGS) && \ + (blk_discard_rq(rq) || blk_fs_request((rq)))) /* * q->prep_rq_fn return values diff --git a/include/linux/fs.h b/include/linux/fs.h index 88358ca6af2..860689f541b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -87,7 +87,8 @@ extern int dir_notify_enable; #define WRITE_SYNC (WRITE | (1 << BIO_RW_SYNC)) #define SWRITE_SYNC (SWRITE | (1 << BIO_RW_SYNC)) #define WRITE_BARRIER (WRITE | (1 << BIO_RW_BARRIER)) -#define WRITE_DISCARD (WRITE | (1 << BIO_RW_DISCARD)) +#define DISCARD_NOBARRIER (1 << BIO_RW_DISCARD) +#define DISCARD_BARRIER ((1 << BIO_RW_DISCARD) | (1 << BIO_RW_BARRIER)) #define SEL_IN 1 #define SEL_OUT 2 -- cgit v1.2.3 From 1a8e2bddd5c29008f311613e75925fecbf522c5b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 13 Aug 2008 12:35:09 +0100 Subject: Kill REQ_TYPE_FLUSH It was only used by ps3disk, and it should probably have been REQ_TYPE_LINUX_BLOCK + REQ_LB_OP_FLUSH. Signed-off-by: David Woodhouse Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e9eb35c9bf2..f131776f029 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -54,7 +54,6 @@ enum rq_cmd_type_bits { REQ_TYPE_PM_SUSPEND, /* suspend request */ REQ_TYPE_PM_RESUME, /* resume request */ REQ_TYPE_PM_SHUTDOWN, /* shutdown request */ - REQ_TYPE_FLUSH, /* flush request */ REQ_TYPE_SPECIAL, /* driver defined type */ REQ_TYPE_LINUX_BLOCK, /* generic block layer message */ /* @@ -76,11 +75,8 @@ enum rq_cmd_type_bits { * */ enum { - /* - * just examples for now - */ REQ_LB_OP_EJECT = 0x40, /* eject request */ - REQ_LB_OP_FLUSH = 0x41, /* flush device */ + REQ_LB_OP_FLUSH = 0x41, /* flush request */ REQ_LB_OP_DISCARD = 0x42, /* discard sectors */ }; -- cgit v1.2.3 From 766ca4428d1239a970926856c447310c9c191af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Luis=20V=C3=A1zquez=20Cao?= Date: Thu, 14 Aug 2008 09:59:13 +0200 Subject: virtio_blk: use a wrapper function to access io context information of IO requests struct request has an ioprio member but it is never updated because currently bios do not hold io context information. The implication of this is that virtio_blk ends up passing useless information to the backend driver. That said, some IO schedulers such as CFQ do store io context information in struct request, but use private members for that, which means that that information cannot be directly accessed in a IO scheduler-independent way. This patch adds a function to obtain the ioprio of a request. We should avoid accessing ioprio directly and use this function instead, so that its users do not have to care about future changes in block layer structures or what the currently active IO controller is. This patch does not introduce any functional changes but paves the way for future clean-ups and enhancements. Signed-off-by: Fernando Luis Vazquez Cao Acked-by: Rusty Russell Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index f131776f029..490ce458b03 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -232,6 +232,11 @@ struct request { struct request *next_rq; }; +static inline unsigned short req_get_ioprio(struct request *req) +{ + return req->ioprio; +} + /* * State information carried for REQ_TYPE_PM_SUSPEND and REQ_TYPE_PM_RESUME * requests. Some step values could eventually be made generic. -- cgit v1.2.3 From b8b3e16cfe6435d961f6aaebcfd52a1ff2a988c5 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 15 Aug 2008 10:15:19 +0200 Subject: block: drop virtual merging accounting Remove virtual merge accounting. Signed-off-by: Mikulas Patocka Signed-off-by: Jens Axboe --- include/linux/bio.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 33c3947d61e..894d16ce002 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -26,21 +26,8 @@ #ifdef CONFIG_BLOCK -/* Platforms may set this to teach the BIO layer about IOMMU hardware. */ #include -#if defined(BIO_VMERGE_MAX_SIZE) && defined(BIO_VMERGE_BOUNDARY) -#define BIOVEC_VIRT_START_SIZE(x) (bvec_to_phys(x) & (BIO_VMERGE_BOUNDARY - 1)) -#define BIOVEC_VIRT_OVERSIZE(x) ((x) > BIO_VMERGE_MAX_SIZE) -#else -#define BIOVEC_VIRT_START_SIZE(x) 0 -#define BIOVEC_VIRT_OVERSIZE(x) 0 -#endif - -#ifndef BIO_VMERGE_BOUNDARY -#define BIO_VMERGE_BOUNDARY 0 -#endif - #define BIO_DEBUG #ifdef BIO_DEBUG @@ -240,8 +227,6 @@ static inline void *bio_data(struct bio *bio) ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) #endif -#define BIOVEC_VIRT_MERGEABLE(vec1, vec2) \ - ((((bvec_to_phys((vec1)) + (vec1)->bv_len) | bvec_to_phys((vec2))) & (BIO_VMERGE_BOUNDARY - 1)) == 0) #define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \ (((addr1) | (mask)) == (((addr2) - 1) | (mask))) #define BIOVEC_SEG_BOUNDARY(q, b1, b2) \ -- cgit v1.2.3 From 5df97b91b5d7ed426034fcc84cb6e7cf682b8838 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 15 Aug 2008 10:20:02 +0200 Subject: drop vmerge accounting Remove hw_segments field from struct bio and struct request. Without virtual merge accounting they have no purpose. Signed-off-by: Mikulas Patocka Signed-off-by: Jens Axboe --- include/linux/bio.h | 16 +--------------- include/linux/blkdev.h | 7 ------- 2 files changed, 1 insertion(+), 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 894d16ce002..dfc3556d311 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -77,21 +77,8 @@ struct bio { */ unsigned short bi_phys_segments; - /* Number of segments after physical and DMA remapping - * hardware coalescing is performed. - */ - unsigned short bi_hw_segments; - unsigned int bi_size; /* residual I/O count */ - /* - * To keep track of the max hw size, we account for the - * sizes of the first and last virtually mergeable segments - * in this bio - */ - unsigned int bi_hw_front_size; - unsigned int bi_hw_back_size; - unsigned int bi_max_vecs; /* max bvl_vecs we can hold */ struct bio_vec *bi_io_vec; /* the actual vec list */ @@ -113,7 +100,7 @@ struct bio { #define BIO_UPTODATE 0 /* ok after I/O completion */ #define BIO_RW_BLOCK 1 /* RW_AHEAD set, and read/write would block */ #define BIO_EOF 2 /* out-out-bounds error */ -#define BIO_SEG_VALID 3 /* nr_hw_seg valid */ +#define BIO_SEG_VALID 3 /* bi_phys_segments valid */ #define BIO_CLONED 4 /* doesn't own data */ #define BIO_BOUNCED 5 /* bio is a bounce bio */ #define BIO_USER_MAPPED 6 /* contains user pages */ @@ -324,7 +311,6 @@ extern void bio_free(struct bio *, struct bio_set *); extern void bio_endio(struct bio *, int); struct request_queue; extern int bio_phys_segments(struct request_queue *, struct bio *); -extern int bio_hw_segments(struct request_queue *, struct bio *); extern void __bio_clone(struct bio *, struct bio *); extern struct bio *bio_clone(struct bio *, gfp_t); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 490ce458b03..1adb03827bd 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -189,13 +189,6 @@ struct request { */ unsigned short nr_phys_segments; - /* Number of scatter-gather addr+len pairs after - * physical and DMA remapping hardware coalescing is performed. - * This is the number of scatter-gather entries the driver - * will actually have to deal with after DMA mapping is done. - */ - unsigned short nr_hw_segments; - unsigned short ioprio; void *special; -- cgit v1.2.3 From 5b99c2ffa980528a197f26c7d876cceeccce8dd5 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 15 Aug 2008 10:56:11 +0200 Subject: block: make bi_phys_segments an unsigned int instead of short raid5 can overflow with more than 255 stripes, and we can increase it to an int for free on both 32 and 64-bit archs due to the padding. Signed-off-by: Jens Axboe --- include/linux/bio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index dfc3556d311..2c0c09034fd 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -75,7 +75,7 @@ struct bio { /* Number of segments in this BIO after * physical address coalescing is performed. */ - unsigned short bi_phys_segments; + unsigned int bi_phys_segments; unsigned int bi_size; /* residual I/O count */ -- cgit v1.2.3 From a1ed5b0cffe4b16a93a6a3390e8cee0fbef94f86 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:50:16 +0200 Subject: klist: don't iterate over deleted entries A klist entry is kept on the list till all its current iterations are finished; however, a new iteration after deletion also iterates over deleted entries as long as their reference count stays above zero. This causes problems for cases where there are users which iterate over the list while synchronized against list manipulations and natuarally expect already deleted entries to not show up during iteration. This patch implements dead flag which gets set on deletion so that iteration can skip already deleted entries. The dead flag piggy backs on the lowest bit of knode->n_klist and only visible to klist implementation proper. While at it, drop klist_iter->i_head as it's redundant and doesn't offer anything in semantics or performance wise as klist_iter->i_klist is dereferenced on every iteration anyway. Signed-off-by: Tejun Heo Cc: Greg Kroah-Hartman Cc: Alan Stern Cc: Jens Axboe Signed-off-by: Jens Axboe --- include/linux/klist.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/klist.h b/include/linux/klist.h index 06c338ef7f1..8ea98db223e 100644 --- a/include/linux/klist.h +++ b/include/linux/klist.h @@ -38,7 +38,7 @@ extern void klist_init(struct klist *k, void (*get)(struct klist_node *), void (*put)(struct klist_node *)); struct klist_node { - struct klist *n_klist; + void *n_klist; /* never access directly */ struct list_head n_node; struct kref n_ref; struct completion n_removed; @@ -57,7 +57,6 @@ extern int klist_node_attached(struct klist_node *n); struct klist_iter { struct klist *i_klist; - struct list_head *i_head; struct klist_node *i_cur; }; -- cgit v1.2.3 From 5a3ceb861663040f9ef0176df4aaa494bba5e352 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:50:19 +0200 Subject: driver-core: use klist for class device list and implement iterator Iterating over entries using callback usually isn't too fun especially when the entry being iterated over can't be manipulated freely. This patch converts class->p->class_devices to klist and implements class device iterator so that the users can freely build their own control structure. The users are also free to call back into class code without worrying about locking. class_for_each_device() and class_find_device() are converted to use the new iterators, so their users don't have to worry about locking anymore either. Note: This depends on klist-dont-iterate-over-deleted-entries patch because class_intf->add/remove_dev() depends on proper synchronization with device removal. Signed-off-by: Tejun Heo Cc: Greg Kroah-Hartman Cc: Jens Axboe Signed-off-by: Jens Axboe --- include/linux/device.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index 4d8372d135d..246937c9cbc 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -199,6 +199,11 @@ struct class { struct class_private *p; }; +struct class_dev_iter { + struct klist_iter ki; + const struct device_type *type; +}; + extern struct kobject *sysfs_dev_block_kobj; extern struct kobject *sysfs_dev_char_kobj; extern int __must_check __class_register(struct class *class, @@ -213,6 +218,13 @@ extern void class_unregister(struct class *class); __class_register(class, &__key); \ }) +extern void class_dev_iter_init(struct class_dev_iter *iter, + struct class *class, + struct device *start, + const struct device_type *type); +extern struct device *class_dev_iter_next(struct class_dev_iter *iter); +extern void class_dev_iter_exit(struct class_dev_iter *iter); + extern int class_for_each_device(struct class *class, struct device *start, void *data, int (*fn)(struct device *dev, void *data)); @@ -396,7 +408,7 @@ struct device { spinlock_t devres_lock; struct list_head devres_head; - struct list_head node; + struct klist_node knode_class; struct class *class; dev_t devt; /* dev_t, creates the sysfs "dev" */ struct attribute_group **groups; /* optional groups */ -- cgit v1.2.3 From 310a2c1012934f590192377f65940cad4aa72b15 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:17 +0900 Subject: block: misc updates This patch makes the following misc updates in preparation for disk->part dereference fix and extended block devt support. * implment part_to_disk() * fix comment about gendisk->part indexing * rename get_part() to disk_map_sector() * don't use n which is always zero while printing disk information in diskstats_show() Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index be4f5e5bfe0..c64e659c984 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -116,7 +116,7 @@ struct gendisk { int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ char disk_name[32]; /* name of major driver */ - struct hd_struct **part; /* [indexed by minor] */ + struct hd_struct **part; /* [indexed by minor - 1] */ struct block_device_operations *fops; struct request_queue *queue; void *private_data; @@ -145,14 +145,21 @@ struct gendisk { #endif }; +static inline struct gendisk *part_to_disk(struct hd_struct *part) +{ + if (likely(part)) + return dev_to_disk((part)->dev.parent); + return NULL; +} + /* * Macros to operate on percpu disk statistics: * * The __ variants should only be called in critical sections. The full * variants disable/enable preemption. */ -static inline struct hd_struct *get_part(struct gendisk *gendiskp, - sector_t sector) +static inline struct hd_struct *disk_map_sector(struct gendisk *gendiskp, + sector_t sector) { struct hd_struct *part; int i; -- cgit v1.2.3 From cf771cb5a7b716f3f9e532fd42a1e3a0a75adec5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 3 Sep 2008 09:01:09 +0200 Subject: block: make variable and argument names more consistent In hd_struct, @partno is used to denote partition number and a number of other places use @part to denote hd_struct. Functions use @part and @index instead. This causes confusion and makes it difficult to use consistent variable names for hd_struct. Always use @partno if a variable represents partition number. Also, print out functions use @f or @part for seq_file argument. Use @seqf uniformly instead. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index c64e659c984..d1723c0a860 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -365,7 +365,7 @@ extern int get_blkdev_list(char *, int); extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern void unlink_gendisk(struct gendisk *gp); -extern struct gendisk *get_gendisk(dev_t dev, int *part); +extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); @@ -534,8 +534,8 @@ struct unixware_disklabel { #define ADDPART_FLAG_RAID 1 #define ADDPART_FLAG_WHOLEDISK 2 -extern dev_t blk_lookup_devt(const char *name, int part); -extern char *disk_name (struct gendisk *hd, int part, char *buf); +extern dev_t blk_lookup_devt(const char *name, int partno); +extern char *disk_name (struct gendisk *hd, int partno, char *buf); extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); extern int __must_check add_partition(struct gendisk *, int, sector_t, sector_t, int); @@ -553,16 +553,16 @@ extern void blk_register_region(dev_t devt, unsigned long range, void *data); extern void blk_unregister_region(dev_t devt, unsigned long range); -static inline struct block_device *bdget_disk(struct gendisk *disk, int index) +static inline struct block_device *bdget_disk(struct gendisk *disk, int partno) { - return bdget(MKDEV(disk->major, disk->first_minor) + index); + return bdget(MKDEV(disk->major, disk->first_minor) + partno); } #else /* CONFIG_BLOCK */ static inline void printk_all_partitions(void) { } -static inline dev_t blk_lookup_devt(const char *name, int part) +static inline dev_t blk_lookup_devt(const char *name, int partno) { dev_t devt = MKDEV(0, 0); return devt; -- cgit v1.2.3 From f331c0296f2a9fee0d396a70598b954062603015 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 3 Sep 2008 09:01:48 +0200 Subject: block: don't depend on consecutive minor space * Implement disk_devt() and part_devt() and use them to directly access devt instead of computing it from ->major and ->first_minor. Note that all references to ->major and ->first_minor outside of block layer is used to determine devt of the disk (the part0) and as ->major and ->first_minor will continue to represent devt for the disk, converting these users aren't strictly necessary. However, convert them for consistency. * Implement disk_max_parts() to avoid directly deferencing genhd->minors. * Update bdget_disk() such that it doesn't assume consecutive minor space. * Move devt computation from register_disk() to add_disk() and make it the only one (all other usages use the initially determined value). These changes clean up the code and will help disk->part dereference fix and extended block device numbers. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index d1723c0a860..0ff75329199 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -111,10 +111,14 @@ struct hd_struct { #define GENHD_FL_FAIL 64 struct gendisk { + /* major, first_minor and minors are input parameters only, + * don't use directly. Use disk_devt() and disk_max_parts(). + */ int major; /* major number of driver */ int first_minor; int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ + char disk_name[32]; /* name of major driver */ struct hd_struct **part; /* [indexed by minor - 1] */ struct block_device_operations *fops; @@ -152,6 +156,21 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part) return NULL; } +static inline int disk_max_parts(struct gendisk *disk) +{ + return disk->minors - 1; +} + +static inline dev_t disk_devt(struct gendisk *disk) +{ + return disk->dev.devt; +} + +static inline dev_t part_devt(struct hd_struct *part) +{ + return part->dev.devt; +} + /* * Macros to operate on percpu disk statistics: * @@ -163,7 +182,7 @@ static inline struct hd_struct *disk_map_sector(struct gendisk *gendiskp, { struct hd_struct *part; int i; - for (i = 0; i < gendiskp->minors - 1; i++) { + for (i = 0; i < disk_max_parts(gendiskp); i++) { part = gendiskp->part[i]; if (part && part->start_sect <= sector && sector < part->start_sect + part->nr_sects) @@ -366,6 +385,7 @@ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); extern void unlink_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); +extern struct block_device *bdget_disk(struct gendisk *disk, int partno); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); @@ -553,11 +573,6 @@ extern void blk_register_region(dev_t devt, unsigned long range, void *data); extern void blk_unregister_region(dev_t devt, unsigned long range); -static inline struct block_device *bdget_disk(struct gendisk *disk, int partno) -{ - return bdget(MKDEV(disk->major, disk->first_minor) + partno); -} - #else /* CONFIG_BLOCK */ static inline void printk_all_partitions(void) { } -- cgit v1.2.3 From e71bf0d0ee89e51b92776391c5634938236977d5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 3 Sep 2008 09:03:02 +0200 Subject: block: fix disk->part[] dereferencing race disk->part[] is protected by its matching bdev's lock. However, non-critical accesses like collecting stats and printing out sysfs and proc information used to be performed without any locking. As partitions can come and go dynamically, partitions can go away underneath those non-critical accesses. As some of those accesses are writes, this theoretically can lead to silent corruption. This patch fixes the race by using RCU for the partition array and dev reference counter to hold partitions. * Rename disk->part[] to disk->__part[] to make sure no one outside genhd layer proper accesses it directly. * Use RCU for disk->__part[] dereferencing. * Implement disk_{get|put}_part() which can be used to get and put partitions from gendisk respectively. * Iterators are implemented to help iterate through all partitions safely. * Functions which require RCU readlock are marked with _rcu suffix. * Use disk_put_part() in __blkdev_put() instead of directly putting the contained kobject. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 53 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 0ff75329199..7fbba19e076 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -11,6 +11,7 @@ #include #include +#include #ifdef CONFIG_BLOCK @@ -100,6 +101,7 @@ struct hd_struct { #else struct disk_stats dkstats; #endif + struct rcu_head rcu_head; }; #define GENHD_FL_REMOVABLE 1 @@ -120,7 +122,14 @@ struct gendisk { * disks that can't be partitioned. */ char disk_name[32]; /* name of major driver */ - struct hd_struct **part; /* [indexed by minor - 1] */ + + /* Array of pointers to partitions indexed by partno - 1. + * Protected with matching bdev lock but stat and other + * non-critical accesses use RCU. Always access through + * helpers. + */ + struct hd_struct **__part; + struct block_device_operations *fops; struct request_queue *queue; void *private_data; @@ -171,25 +180,41 @@ static inline dev_t part_devt(struct hd_struct *part) return part->dev.devt; } +extern struct hd_struct *disk_get_part(struct gendisk *disk, int partno); + +static inline void disk_put_part(struct hd_struct *part) +{ + if (likely(part)) + put_device(&part->dev); +} + +/* + * Smarter partition iterator without context limits. + */ +#define DISK_PITER_REVERSE (1 << 0) /* iterate in the reverse direction */ +#define DISK_PITER_INCL_EMPTY (1 << 1) /* include 0-sized parts */ + +struct disk_part_iter { + struct gendisk *disk; + struct hd_struct *part; + int idx; + unsigned int flags; +}; + +extern void disk_part_iter_init(struct disk_part_iter *piter, + struct gendisk *disk, unsigned int flags); +extern struct hd_struct *disk_part_iter_next(struct disk_part_iter *piter); +extern void disk_part_iter_exit(struct disk_part_iter *piter); + +extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, + sector_t sector); + /* * Macros to operate on percpu disk statistics: * * The __ variants should only be called in critical sections. The full * variants disable/enable preemption. */ -static inline struct hd_struct *disk_map_sector(struct gendisk *gendiskp, - sector_t sector) -{ - struct hd_struct *part; - int i; - for (i = 0; i < disk_max_parts(gendiskp); i++) { - part = gendiskp->part[i]; - if (part && part->start_sect <= sector - && sector < part->start_sect + part->nr_sects) - return part; - } - return NULL; -} #ifdef CONFIG_SMP #define __disk_stat_add(gendiskp, field, addnd) \ -- cgit v1.2.3 From c9959059161ddd7bf4670cf47367033d6b2f79c4 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:21 +0900 Subject: block: fix diskstats access There are two variants of stat functions - ones prefixed with double underbars which don't care about preemption and ones without which disable preemption before manipulating per-cpu counters. It's unclear whether the underbarred ones assume that preemtion is disabled on entry as some callers don't do that. This patch unifies diskstats access by implementing disk_stat_lock() and disk_stat_unlock() which take care of both RCU (for partition access) and preemption (for per-cpu counter access). diskstats access should always be enclosed between the two functions. As such, there's no need for the versions which disables preemption. They're removed and double underbars ones are renamed to drop the underbars. As an extra argument is added, there's no danger of using the old version unconverted. disk_stat_lock() uses get_cpu() and returns the cpu index and all diskstat functions which access per-cpu counters now has @cpu argument to help RT. This change adds RCU or preemption operations at some places but also collapses several preemption ops into one at others. Overall, the performance difference should be negligible as all involved ops are very lightweight per-cpu ones. Signed-off-by: Tejun Heo Cc: Peter Zijlstra Signed-off-by: Jens Axboe --- include/linux/genhd.h | 139 +++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 82 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 7fbba19e076..ac8a901f200 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -209,16 +209,24 @@ extern void disk_part_iter_exit(struct disk_part_iter *piter); extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, sector_t sector); -/* +/* * Macros to operate on percpu disk statistics: * - * The __ variants should only be called in critical sections. The full - * variants disable/enable preemption. + * {disk|part|all}_stat_{add|sub|inc|dec}() modify the stat counters + * and should be called between disk_stat_lock() and + * disk_stat_unlock(). + * + * part_stat_read() can be called at any time. + * + * part_stat_{add|set_all}() and {init|free}_part_stats are for + * internal use only. */ - #ifdef CONFIG_SMP -#define __disk_stat_add(gendiskp, field, addnd) \ - (per_cpu_ptr(gendiskp->dkstats, smp_processor_id())->field += addnd) +#define disk_stat_lock() ({ rcu_read_lock(); get_cpu(); }) +#define disk_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) + +#define disk_stat_add(cpu, gendiskp, field, addnd) \ + (per_cpu_ptr(gendiskp->dkstats, cpu)->field += addnd) #define disk_stat_read(gendiskp, field) \ ({ \ @@ -229,7 +237,8 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, res; \ }) -static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { +static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) +{ int i; for_each_possible_cpu(i) @@ -237,14 +246,14 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) { sizeof(struct disk_stats)); } -#define __part_stat_add(part, field, addnd) \ - (per_cpu_ptr(part->dkstats, smp_processor_id())->field += addnd) +#define part_stat_add(cpu, part, field, addnd) \ + (per_cpu_ptr(part->dkstats, cpu)->field += addnd) -#define __all_stat_add(gendiskp, part, field, addnd, sector) \ -({ \ - if (part) \ - __part_stat_add(part, field, addnd); \ - __disk_stat_add(gendiskp, field, addnd); \ +#define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ +({ \ + if (part) \ + part_stat_add(cpu, part, field, addnd); \ + disk_stat_add(cpu, gendiskp, field, addnd); \ }) #define part_stat_read(part, field) \ @@ -264,10 +273,13 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) memset(per_cpu_ptr(part->dkstats, i), value, sizeof(struct disk_stats)); } - + #else /* !CONFIG_SMP */ -#define __disk_stat_add(gendiskp, field, addnd) \ - (gendiskp->dkstats.field += addnd) +#define disk_stat_lock() ({ rcu_read_lock(); 0; }) +#define disk_stat_unlock() rcu_read_unlock() + +#define disk_stat_add(cpu, gendiskp, field, addnd) \ + (gendiskp->dkstats.field += addnd) #define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) @@ -275,14 +287,14 @@ static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); } -#define __part_stat_add(part, field, addnd) \ +#define part_stat_add(cpu, part, field, addnd) \ (part->dkstats.field += addnd) -#define __all_stat_add(gendiskp, part, field, addnd, sector) \ -({ \ - if (part) \ - part->dkstats.field += addnd; \ - __disk_stat_add(gendiskp, field, addnd); \ +#define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ +({ \ + if (part) \ + part_stat_add(cpu, part, field, addnd); \ + disk_stat_add(cpu, gendiskp, field, addnd); \ }) #define part_stat_read(part, field) (part->dkstats.field) @@ -294,63 +306,26 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) #endif /* CONFIG_SMP */ -#define disk_stat_add(gendiskp, field, addnd) \ - do { \ - preempt_disable(); \ - __disk_stat_add(gendiskp, field, addnd); \ - preempt_enable(); \ - } while (0) - -#define __disk_stat_dec(gendiskp, field) __disk_stat_add(gendiskp, field, -1) -#define disk_stat_dec(gendiskp, field) disk_stat_add(gendiskp, field, -1) - -#define __disk_stat_inc(gendiskp, field) __disk_stat_add(gendiskp, field, 1) -#define disk_stat_inc(gendiskp, field) disk_stat_add(gendiskp, field, 1) - -#define __disk_stat_sub(gendiskp, field, subnd) \ - __disk_stat_add(gendiskp, field, -subnd) -#define disk_stat_sub(gendiskp, field, subnd) \ - disk_stat_add(gendiskp, field, -subnd) - -#define part_stat_add(gendiskp, field, addnd) \ - do { \ - preempt_disable(); \ - __part_stat_add(gendiskp, field, addnd);\ - preempt_enable(); \ - } while (0) - -#define __part_stat_dec(gendiskp, field) __part_stat_add(gendiskp, field, -1) -#define part_stat_dec(gendiskp, field) part_stat_add(gendiskp, field, -1) - -#define __part_stat_inc(gendiskp, field) __part_stat_add(gendiskp, field, 1) -#define part_stat_inc(gendiskp, field) part_stat_add(gendiskp, field, 1) - -#define __part_stat_sub(gendiskp, field, subnd) \ - __part_stat_add(gendiskp, field, -subnd) -#define part_stat_sub(gendiskp, field, subnd) \ - part_stat_add(gendiskp, field, -subnd) - -#define all_stat_add(gendiskp, part, field, addnd, sector) \ - do { \ - preempt_disable(); \ - __all_stat_add(gendiskp, part, field, addnd, sector); \ - preempt_enable(); \ - } while (0) - -#define __all_stat_dec(gendiskp, field, sector) \ - __all_stat_add(gendiskp, field, -1, sector) -#define all_stat_dec(gendiskp, field, sector) \ - all_stat_add(gendiskp, field, -1, sector) - -#define __all_stat_inc(gendiskp, part, field, sector) \ - __all_stat_add(gendiskp, part, field, 1, sector) -#define all_stat_inc(gendiskp, part, field, sector) \ - all_stat_add(gendiskp, part, field, 1, sector) - -#define __all_stat_sub(gendiskp, part, field, subnd, sector) \ - __all_stat_add(gendiskp, part, field, -subnd, sector) -#define all_stat_sub(gendiskp, part, field, subnd, sector) \ - all_stat_add(gendiskp, part, field, -subnd, sector) +#define disk_stat_dec(cpu, gendiskp, field) \ + disk_stat_add(cpu, gendiskp, field, -1) +#define disk_stat_inc(cpu, gendiskp, field) \ + disk_stat_add(cpu, gendiskp, field, 1) +#define disk_stat_sub(cpu, gendiskp, field, subnd) \ + disk_stat_add(cpu, gendiskp, field, -subnd) + +#define part_stat_dec(cpu, gendiskp, field) \ + part_stat_add(cpu, gendiskp, field, -1) +#define part_stat_inc(cpu, gendiskp, field) \ + part_stat_add(cpu, gendiskp, field, 1) +#define part_stat_sub(cpu, gendiskp, field, subnd) \ + part_stat_add(cpu, gendiskp, field, -subnd) + +#define all_stat_dec(cpu, gendiskp, field, sector) \ + all_stat_add(cpu, gendiskp, field, -1, sector) +#define all_stat_inc(cpu, gendiskp, part, field, sector) \ + all_stat_add(cpu, gendiskp, part, field, 1, sector) +#define all_stat_sub(cpu, gendiskp, part, field, subnd, sector) \ + all_stat_add(cpu, gendiskp, part, field, -subnd, sector) /* Inlines to alloc and free disk stats in struct gendisk */ #ifdef CONFIG_SMP @@ -401,8 +376,8 @@ static inline void free_part_stats(struct hd_struct *part) #endif /* CONFIG_SMP */ /* drivers/block/ll_rw_blk.c */ -extern void disk_round_stats(struct gendisk *disk); -extern void part_round_stats(struct hd_struct *part); +extern void disk_round_stats(int cpu, struct gendisk *disk); +extern void part_round_stats(int cpu, struct hd_struct *part); /* drivers/block/genhd.c */ extern int get_blkdev_list(char *, int); -- cgit v1.2.3 From bcce3de1be61e424deef35d1e86e86a35c4b6e65 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:22 +0900 Subject: block: implement extended dev numbers Implement extended device numbers. A block driver can tell block layer that it wants to use extended device numbers. After the usual minor space is used up, block layer automatically allocates devt's from EXT_BLOCK_MAJOR. Currently only one major number is allocated for this but as the allocation is strictly on-demand, ~1mil minor space under it should suffice unless the system actually has more than ~1mil partitions and if that ever happens adding more majors to the extended devt area is easy. Due to internal implementation issues, the first partition can't be allocated on the extended area. In other words, genhd->minors should at least be 1. This limitation will be lifted by later changes. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 13 ++++++++++--- include/linux/major.h | 2 ++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ac8a901f200..6fc53242406 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -113,13 +113,15 @@ struct hd_struct { #define GENHD_FL_FAIL 64 struct gendisk { - /* major, first_minor and minors are input parameters only, - * don't use directly. Use disk_devt() and disk_max_parts(). + /* major, first_minor, minors and ext_minors are input + * parameters only, don't use directly. Use disk_devt() and + * disk_max_parts(). */ int major; /* major number of driver */ int first_minor; int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ + int ext_minors; /* number of extended dynamic minors */ char disk_name[32]; /* name of major driver */ @@ -167,7 +169,7 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part) static inline int disk_max_parts(struct gendisk *disk) { - return disk->minors - 1; + return disk->minors + disk->ext_minors - 1; } static inline dev_t disk_devt(struct gendisk *disk) @@ -554,6 +556,8 @@ struct unixware_disklabel { #define ADDPART_FLAG_RAID 1 #define ADDPART_FLAG_WHOLEDISK 2 +extern int blk_alloc_devt(struct hd_struct *part, dev_t *devt); +extern void blk_free_devt(dev_t devt); extern dev_t blk_lookup_devt(const char *name, int partno); extern char *disk_name (struct gendisk *hd, int partno, char *buf); @@ -564,6 +568,9 @@ extern void printk_all_partitions(void); extern struct gendisk *alloc_disk_node(int minors, int node_id); extern struct gendisk *alloc_disk(int minors); +extern struct gendisk *alloc_disk_ext_node(int minors, int ext_minrs, + int node_id); +extern struct gendisk *alloc_disk_ext(int minors, int ext_minors); extern struct kobject *get_disk(struct gendisk *disk); extern void put_disk(struct gendisk *disk); extern void blk_register_region(dev_t devt, unsigned long range, diff --git a/include/linux/major.h b/include/linux/major.h index 53d5fafd85c..88249452b93 100644 --- a/include/linux/major.h +++ b/include/linux/major.h @@ -170,4 +170,6 @@ #define VIOTAPE_MAJOR 230 +#define BLOCK_EXT_MAJOR 259 + #endif -- cgit v1.2.3 From 1f0142905d4812966831613847db38a66da29eb8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:47:23 +0900 Subject: block: adjust formatting for large minors and add ext_range sysfs attr With extended minors and the soon-to-follow debug feature, large minor numbers for block devices will be common. This patch does the followings to make printouts pretty. * Adapt print formats such that large minors don't break the formatting. * For extended MAJ:MIN, %02x%02x for MAJ:MIN used in printk_all_partitions() doesn't cut it anymore. Update it such that %03x:%05x is used if either MAJ or MIN doesn't fit in %02x. * Implement ext_range sysfs attribute which shows total minors the device can use including both conventional minor space and the extended one. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 860689f541b..02a9fb5a830 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1685,6 +1685,7 @@ extern void chrdev_show(struct seq_file *,off_t); /* fs/block_dev.c */ #define BDEVNAME_SIZE 32 /* Largest string for a blockdev identifier */ +#define BDEVT_SIZE 10 /* Largest string for MAJ:MIN for blkdev */ #ifdef CONFIG_BLOCK #define BLKDEV_MAJOR_HASH_SIZE 255 -- cgit v1.2.3 From ed9e1982347b36573cd622ee5f4e2a7ccd79b3fd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:05 +0900 Subject: block: implement and use {disk|part}_to_dev() Implement {disk|part}_to_dev() and use them to access generic device instead of directly dereferencing {disk|part}->dev. To make sure no user is left behind, rename generic devices fields to __dev. This is in preparation of unifying partition 0 handling with other partitions. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 6fc53242406..e4e18c509ac 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -15,9 +15,11 @@ #ifdef CONFIG_BLOCK -#define kobj_to_dev(k) container_of(k, struct device, kobj) -#define dev_to_disk(device) container_of(device, struct gendisk, dev) -#define dev_to_part(device) container_of(device, struct hd_struct, dev) +#define kobj_to_dev(k) container_of((k), struct device, kobj) +#define dev_to_disk(device) container_of((device), struct gendisk, __dev) +#define dev_to_part(device) container_of((device), struct hd_struct, __dev) +#define disk_to_dev(disk) (&((disk)->__dev)) +#define part_to_dev(part) (&((part)->__dev)) extern struct device_type part_type; extern struct kobject *block_depr; @@ -88,7 +90,7 @@ struct disk_stats { struct hd_struct { sector_t start_sect; sector_t nr_sects; - struct device dev; + struct device __dev; struct kobject *holder_dir; int policy, partno; #ifdef CONFIG_FAIL_MAKE_REQUEST @@ -139,7 +141,7 @@ struct gendisk { int flags; struct device *driverfs_dev; // FIXME: remove - struct device dev; + struct device __dev; struct kobject *holder_dir; struct kobject *slave_dir; @@ -163,7 +165,7 @@ struct gendisk { static inline struct gendisk *part_to_disk(struct hd_struct *part) { if (likely(part)) - return dev_to_disk((part)->dev.parent); + return dev_to_disk(part_to_dev(part)->parent); return NULL; } @@ -174,12 +176,12 @@ static inline int disk_max_parts(struct gendisk *disk) static inline dev_t disk_devt(struct gendisk *disk) { - return disk->dev.devt; + return disk_to_dev(disk)->devt; } static inline dev_t part_devt(struct hd_struct *part) { - return part->dev.devt; + return part_to_dev(part)->devt; } extern struct hd_struct *disk_get_part(struct gendisk *disk, int partno); @@ -187,7 +189,7 @@ extern struct hd_struct *disk_get_part(struct gendisk *disk, int partno); static inline void disk_put_part(struct hd_struct *part) { if (likely(part)) - put_device(&part->dev); + put_device(part_to_dev(part)); } /* -- cgit v1.2.3 From b5d0b9df0ba5d9a044f3a21e7544f53d90bd1465 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 3 Sep 2008 09:06:42 +0200 Subject: block: introduce partition 0 genhd and partition code handled disk and partitions separately. All information about the whole disk was in struct genhd and partitions in struct hd_struct. However, the whole disk (part0) and other partitions have a lot in common and the data structures end up having good number of common fields and thus separate code paths doing the same thing. Also, the partition array was indexed by partno - 1 which gets pretty confusing at times. This patch introduces partition 0 and makes the partition array indexed by partno. Following patches will unify the handling of disk and parts piece-by-piece. This patch also implements disk_partitionable() which tests whether a disk is partitionable. With coming dynamic partition array change, the most common usage of disk_max_parts() will be testing whether a disk is partitionable and the number of max partitions will become much less important. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e4e18c509ac..9e866a2aee5 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -127,12 +127,13 @@ struct gendisk { char disk_name[32]; /* name of major driver */ - /* Array of pointers to partitions indexed by partno - 1. + /* Array of pointers to partitions indexed by partno. * Protected with matching bdev lock but stat and other * non-critical accesses use RCU. Always access through * helpers. */ struct hd_struct **__part; + struct hd_struct part0; struct block_device_operations *fops; struct request_queue *queue; @@ -171,7 +172,12 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part) static inline int disk_max_parts(struct gendisk *disk) { - return disk->minors + disk->ext_minors - 1; + return disk->minors + disk->ext_minors; +} + +static inline bool disk_partitionable(struct gendisk *disk) +{ + return disk_max_parts(disk) > 1; } static inline dev_t disk_devt(struct gendisk *disk) @@ -197,6 +203,7 @@ static inline void disk_put_part(struct hd_struct *part) */ #define DISK_PITER_REVERSE (1 << 0) /* iterate in the reverse direction */ #define DISK_PITER_INCL_EMPTY (1 << 1) /* include 0-sized parts */ +#define DISK_PITER_INCL_PART0 (1 << 2) /* include partition 0 */ struct disk_part_iter { struct gendisk *disk; -- cgit v1.2.3 From 80795aefb76d10c5d698e60c7e7750b5330787da Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:07 +0900 Subject: block: move capacity from disk to part0 Move disk->capacity to part0->nr_sects and convert all users who directly accessed the field to use {get|set}_capacity(). This is done early to allow the __dev field to be moved. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 9e866a2aee5..1cf828148ec 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -138,7 +138,6 @@ struct gendisk { struct block_device_operations *fops; struct request_queue *queue; void *private_data; - sector_t capacity; int flags; struct device *driverfs_dev; // FIXME: remove @@ -411,11 +410,11 @@ static inline sector_t get_start_sect(struct block_device *bdev) } static inline sector_t get_capacity(struct gendisk *disk) { - return disk->capacity; + return disk->part0.nr_sects; } static inline void set_capacity(struct gendisk *disk, sector_t size) { - disk->capacity = size; + disk->part0.nr_sects = size; } #ifdef CONFIG_SOLARIS_X86_PARTITION -- cgit v1.2.3 From 548b10eb2959c96cef6fc29fc96e0931eeb53bc5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 29 Aug 2008 09:01:47 +0200 Subject: block: move __dev from disk to part0 Move disk->__dev to part0->__dev. This simplifies bdget_disk() and lookup_devt() and allows common sysfs attributes to be unified. part_to_disk() is updated to handle part0 -> disk. Updated to include a fix from Bartlomiej Zolnierkiewicz , he writes: "part0 is a "special" partition and doesn't need to have capacity set - this fixes regression caused by "block: move __dev from disk to part0" commit." Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 1cf828148ec..ff293ec8b3f 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -16,9 +16,9 @@ #ifdef CONFIG_BLOCK #define kobj_to_dev(k) container_of((k), struct device, kobj) -#define dev_to_disk(device) container_of((device), struct gendisk, __dev) +#define dev_to_disk(device) container_of((device), struct gendisk, part0.__dev) #define dev_to_part(device) container_of((device), struct hd_struct, __dev) -#define disk_to_dev(disk) (&((disk)->__dev)) +#define disk_to_dev(disk) (&(disk)->part0.__dev) #define part_to_dev(part) (&((part)->__dev)) extern struct device_type part_type; @@ -141,7 +141,6 @@ struct gendisk { int flags; struct device *driverfs_dev; // FIXME: remove - struct device __dev; struct kobject *holder_dir; struct kobject *slave_dir; @@ -164,8 +163,12 @@ struct gendisk { static inline struct gendisk *part_to_disk(struct hd_struct *part) { - if (likely(part)) - return dev_to_disk(part_to_dev(part)->parent); + if (likely(part)) { + if (part->partno) + return dev_to_disk(part_to_dev(part)->parent); + else + return dev_to_disk(part_to_dev(part)); + } return NULL; } -- cgit v1.2.3 From e56105214943ce5f0901d20e972a7cfd0d1d0656 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:09 +0900 Subject: block: unify sysfs size node handling Now that capacity and __dev are moved to part0, part0 and others can share the same method. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ff293ec8b3f..9cb8380cf0e 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -591,6 +591,9 @@ extern void blk_register_region(dev_t devt, unsigned long range, void *data); extern void blk_unregister_region(dev_t devt, unsigned long range); +extern ssize_t part_size_show(struct device *dev, + struct device_attribute *attr, char *buf); + #else /* CONFIG_BLOCK */ static inline void printk_all_partitions(void) { } -- cgit v1.2.3 From b7db9956e57c8151b930d5e5fe5c766e6aad3ff7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:10 +0900 Subject: block: move policy from disk to part0 Move disk->policy to part0->policy. Implement and use get_disk_ro(). Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 9cb8380cf0e..4411bdd671d 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -145,7 +145,6 @@ struct gendisk { struct kobject *slave_dir; struct timer_rand_state *random; - int policy; atomic_t sync_io; /* RAID */ unsigned long stamp; @@ -403,6 +402,11 @@ extern struct block_device *bdget_disk(struct gendisk *disk, int partno); extern void set_device_ro(struct block_device *bdev, int flag); extern void set_disk_ro(struct gendisk *disk, int flag); +static inline int get_disk_ro(struct gendisk *disk) +{ + return disk->part0.policy; +} + /* drivers/char/random.c */ extern void add_disk_randomness(struct gendisk *disk); extern void rand_initialize_disk(struct gendisk *disk); -- cgit v1.2.3 From 4c46501d1659475dc6c89554af6ce7fe6ecf615c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:11 +0900 Subject: block: move holder_dir from disk to part0 Move disk->holder_dir to part0->holder_dir. Kill now mostly superflous bdev_get_holder(). While at it, kill superflous kobject_get/put() around holder_dir, slave_dir and cmd_filter creation and collapse disk_sysfs_add_subdirs() into register_disk(). These serve no purpose but obfuscating the code. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 4411bdd671d..2c0e1b597ab 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -141,7 +141,6 @@ struct gendisk { int flags; struct device *driverfs_dev; // FIXME: remove - struct kobject *holder_dir; struct kobject *slave_dir; struct timer_rand_state *random; -- cgit v1.2.3 From 0762b8bde9729f10f8e6249809660ff2ec3ad735 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:12 +0900 Subject: block: always set bdev->bd_part Till now, bdev->bd_part is set only if the bdev was for parts other than part0. This patch makes bdev->bd_part always set so that code paths don't have to differenciate common handling. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 2c0e1b597ab..45a3682b5d8 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -412,7 +412,7 @@ extern void rand_initialize_disk(struct gendisk *disk); static inline sector_t get_start_sect(struct block_device *bdev) { - return bdev->bd_contains == bdev ? 0 : bdev->bd_part->start_sect; + return bdev->bd_part->start_sect; } static inline sector_t get_capacity(struct gendisk *disk) { -- cgit v1.2.3 From eddb2e26b5ee3c5da68ba4bf1921ba20e2097bff Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:13 +0900 Subject: block: kill GENHD_FL_FAIL and use part0->make_it_fail GENHD_FL_FAIL for disk is what make_it_fail is for parts. Kill it and use part0->make_it_fail. Sysfs node handling is unified too. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 45a3682b5d8..3d15b42dc35 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -112,7 +112,6 @@ struct hd_struct { #define GENHD_FL_CD 8 #define GENHD_FL_UP 16 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 -#define GENHD_FL_FAIL 64 struct gendisk { /* major, first_minor, minors and ext_minors are input @@ -596,6 +595,13 @@ extern void blk_unregister_region(dev_t devt, unsigned long range); extern ssize_t part_size_show(struct device *dev, struct device_attribute *attr, char *buf); +#ifdef CONFIG_FAIL_MAKE_REQUEST +extern ssize_t part_fail_show(struct device *dev, + struct device_attribute *attr, char *buf); +extern ssize_t part_fail_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +#endif /* CONFIG_FAIL_MAKE_REQUEST */ #else /* CONFIG_BLOCK */ -- cgit v1.2.3 From 074a7aca7afa6f230104e8e65eba3420263714a5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:14 +0900 Subject: block: move stats from disk to part0 Move stats related fields - stamp, in_flight, dkstats - from disk to part0 and unify stat handling such that... * part_stat_*() now updates part0 together if the specified partition is not part0. ie. part_stat_*() are now essentially all_stat_*(). * {disk|all}_stat_*() are gone. * part_round_stats() is updated similary. It handles part0 stats automatically and disk_round_stats() is killed. * part_{inc|dec}_in_fligh() is implemented which automatically updates part0 stats for parts other than part0. * disk_map_sector_rcu() is updated to return part0 if no part matches. Combined with the above changes, this makes NULL special case handling in callers unnecessary. * Separate stats show code paths for disk are collapsed into part stats show code paths. * Rename disk_stat_lock/unlock() to part_stat_lock/unlock() While at it, reposition stat handling macros a bit and add missing parentheses around macro parameters. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 159 ++++++++++++++------------------------------------ 1 file changed, 45 insertions(+), 114 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 3d15b42dc35..c90e1b4fbe5 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -145,13 +145,6 @@ struct gendisk { struct timer_rand_state *random; atomic_t sync_io; /* RAID */ - unsigned long stamp; - int in_flight; -#ifdef CONFIG_SMP - struct disk_stats *dkstats; -#else - struct disk_stats dkstats; -#endif struct work_struct async_notify; #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity; @@ -232,46 +225,18 @@ extern struct hd_struct *disk_map_sector_rcu(struct gendisk *disk, * internal use only. */ #ifdef CONFIG_SMP -#define disk_stat_lock() ({ rcu_read_lock(); get_cpu(); }) -#define disk_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) - -#define disk_stat_add(cpu, gendiskp, field, addnd) \ - (per_cpu_ptr(gendiskp->dkstats, cpu)->field += addnd) - -#define disk_stat_read(gendiskp, field) \ -({ \ - typeof(gendiskp->dkstats->field) res = 0; \ - int i; \ - for_each_possible_cpu(i) \ - res += per_cpu_ptr(gendiskp->dkstats, i)->field; \ - res; \ -}) - -static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) -{ - int i; - - for_each_possible_cpu(i) - memset(per_cpu_ptr(gendiskp->dkstats, i), value, - sizeof(struct disk_stats)); -} +#define part_stat_lock() ({ rcu_read_lock(); get_cpu(); }) +#define part_stat_unlock() do { put_cpu(); rcu_read_unlock(); } while (0) -#define part_stat_add(cpu, part, field, addnd) \ - (per_cpu_ptr(part->dkstats, cpu)->field += addnd) - -#define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ -({ \ - if (part) \ - part_stat_add(cpu, part, field, addnd); \ - disk_stat_add(cpu, gendiskp, field, addnd); \ -}) +#define __part_stat_add(cpu, part, field, addnd) \ + (per_cpu_ptr((part)->dkstats, (cpu))->field += (addnd)) #define part_stat_read(part, field) \ ({ \ - typeof(part->dkstats->field) res = 0; \ + typeof((part)->dkstats->field) res = 0; \ int i; \ for_each_possible_cpu(i) \ - res += per_cpu_ptr(part->dkstats, i)->field; \ + res += per_cpu_ptr((part)->dkstats, i)->field; \ res; \ }) @@ -284,109 +249,73 @@ static inline void part_stat_set_all(struct hd_struct *part, int value) sizeof(struct disk_stats)); } -#else /* !CONFIG_SMP */ -#define disk_stat_lock() ({ rcu_read_lock(); 0; }) -#define disk_stat_unlock() rcu_read_unlock() - -#define disk_stat_add(cpu, gendiskp, field, addnd) \ - (gendiskp->dkstats.field += addnd) -#define disk_stat_read(gendiskp, field) (gendiskp->dkstats.field) - -static inline void disk_stat_set_all(struct gendisk *gendiskp, int value) +static inline int init_part_stats(struct hd_struct *part) { - memset(&gendiskp->dkstats, value, sizeof (struct disk_stats)); + part->dkstats = alloc_percpu(struct disk_stats); + if (!part->dkstats) + return 0; + return 1; } -#define part_stat_add(cpu, part, field, addnd) \ - (part->dkstats.field += addnd) - -#define all_stat_add(cpu, gendiskp, part, field, addnd, sector) \ -({ \ - if (part) \ - part_stat_add(cpu, part, field, addnd); \ - disk_stat_add(cpu, gendiskp, field, addnd); \ -}) - -#define part_stat_read(part, field) (part->dkstats.field) - -static inline void part_stat_set_all(struct hd_struct *part, int value) +static inline void free_part_stats(struct hd_struct *part) { - memset(&part->dkstats, value, sizeof(struct disk_stats)); + free_percpu(part->dkstats); } -#endif /* CONFIG_SMP */ - -#define disk_stat_dec(cpu, gendiskp, field) \ - disk_stat_add(cpu, gendiskp, field, -1) -#define disk_stat_inc(cpu, gendiskp, field) \ - disk_stat_add(cpu, gendiskp, field, 1) -#define disk_stat_sub(cpu, gendiskp, field, subnd) \ - disk_stat_add(cpu, gendiskp, field, -subnd) - -#define part_stat_dec(cpu, gendiskp, field) \ - part_stat_add(cpu, gendiskp, field, -1) -#define part_stat_inc(cpu, gendiskp, field) \ - part_stat_add(cpu, gendiskp, field, 1) -#define part_stat_sub(cpu, gendiskp, field, subnd) \ - part_stat_add(cpu, gendiskp, field, -subnd) +#else /* !CONFIG_SMP */ +#define part_stat_lock() ({ rcu_read_lock(); 0; }) +#define part_stat_unlock() rcu_read_unlock() -#define all_stat_dec(cpu, gendiskp, field, sector) \ - all_stat_add(cpu, gendiskp, field, -1, sector) -#define all_stat_inc(cpu, gendiskp, part, field, sector) \ - all_stat_add(cpu, gendiskp, part, field, 1, sector) -#define all_stat_sub(cpu, gendiskp, part, field, subnd, sector) \ - all_stat_add(cpu, gendiskp, part, field, -subnd, sector) +#define __part_stat_add(cpu, part, field, addnd) \ + ((part)->dkstats.field += addnd) -/* Inlines to alloc and free disk stats in struct gendisk */ -#ifdef CONFIG_SMP -static inline int init_disk_stats(struct gendisk *disk) -{ - disk->dkstats = alloc_percpu(struct disk_stats); - if (!disk->dkstats) - return 0; - return 1; -} +#define part_stat_read(part, field) ((part)->dkstats.field) -static inline void free_disk_stats(struct gendisk *disk) +static inline void part_stat_set_all(struct hd_struct *part, int value) { - free_percpu(disk->dkstats); + memset(&part->dkstats, value, sizeof(struct disk_stats)); } static inline int init_part_stats(struct hd_struct *part) { - part->dkstats = alloc_percpu(struct disk_stats); - if (!part->dkstats) - return 0; return 1; } static inline void free_part_stats(struct hd_struct *part) { - free_percpu(part->dkstats); } -#else /* CONFIG_SMP */ -static inline int init_disk_stats(struct gendisk *disk) -{ - return 1; -} +#endif /* CONFIG_SMP */ -static inline void free_disk_stats(struct gendisk *disk) -{ -} +#define part_stat_add(cpu, part, field, addnd) do { \ + __part_stat_add((cpu), (part), field, addnd); \ + if ((part)->partno) \ + __part_stat_add((cpu), &part_to_disk((part))->part0, \ + field, addnd); \ +} while (0) -static inline int init_part_stats(struct hd_struct *part) +#define part_stat_dec(cpu, gendiskp, field) \ + part_stat_add(cpu, gendiskp, field, -1) +#define part_stat_inc(cpu, gendiskp, field) \ + part_stat_add(cpu, gendiskp, field, 1) +#define part_stat_sub(cpu, gendiskp, field, subnd) \ + part_stat_add(cpu, gendiskp, field, -subnd) + +static inline void part_inc_in_flight(struct hd_struct *part) { - return 1; + part->in_flight++; + if (part->partno) + part_to_disk(part)->part0.in_flight++; } -static inline void free_part_stats(struct hd_struct *part) +static inline void part_dec_in_flight(struct hd_struct *part) { + part->in_flight--; + if (part->partno) + part_to_disk(part)->part0.in_flight--; } -#endif /* CONFIG_SMP */ /* drivers/block/ll_rw_blk.c */ -extern void disk_round_stats(int cpu, struct gendisk *disk); extern void part_round_stats(int cpu, struct hd_struct *part); /* drivers/block/genhd.c */ @@ -595,6 +524,8 @@ extern void blk_unregister_region(dev_t devt, unsigned long range); extern ssize_t part_size_show(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t part_stat_show(struct device *dev, + struct device_attribute *attr, char *buf); #ifdef CONFIG_FAIL_MAKE_REQUEST extern ssize_t part_fail_show(struct device *dev, struct device_attribute *attr, char *buf); -- cgit v1.2.3 From 540eed5637b766bb1e881ef744c42617760b4815 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:15 +0900 Subject: block: make partition array dynamic disk->__part used to be statically allocated to the maximum possible number of partitions. This patch makes partition array allocation dynamic. The added overhead is minimal as only real change is one memory dereference changed to RCU one. This saves both a bit of memory and cpu cycles iterating through unoccupied slots and makes increasing partition limit easier. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index c90e1b4fbe5..ecf649c3dee 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -113,6 +113,21 @@ struct hd_struct { #define GENHD_FL_UP 16 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define BLK_SCSI_MAX_CMDS (256) +#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) + +struct blk_scsi_cmd_filter { + unsigned long read_ok[BLK_SCSI_CMD_PER_LONG]; + unsigned long write_ok[BLK_SCSI_CMD_PER_LONG]; + struct kobject kobj; +}; + +struct disk_part_tbl { + struct rcu_head rcu_head; + int len; + struct hd_struct *part[]; +}; + struct gendisk { /* major, first_minor, minors and ext_minors are input * parameters only, don't use directly. Use disk_devt() and @@ -131,7 +146,7 @@ struct gendisk { * non-critical accesses use RCU. Always access through * helpers. */ - struct hd_struct **__part; + struct disk_part_tbl *part_tbl; struct hd_struct part0; struct block_device_operations *fops; @@ -149,6 +164,7 @@ struct gendisk { #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity; #endif + int node_id; }; static inline struct gendisk *part_to_disk(struct hd_struct *part) @@ -503,6 +519,7 @@ extern void blk_free_devt(dev_t devt); extern dev_t blk_lookup_devt(const char *name, int partno); extern char *disk_name (struct gendisk *hd, int partno, char *buf); +extern int disk_expand_part_tbl(struct gendisk *disk, int target); extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); extern int __must_check add_partition(struct gendisk *, int, sector_t, sector_t, int); extern void delete_partition(struct gendisk *, int); -- cgit v1.2.3 From 689d6fac40b41c7bf154f362deaf442548e4dc81 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:16 +0900 Subject: block: replace @ext_minors with GENHD_FL_EXT_DEVT With previous changes, it's meaningless to limit the number of partitions. Replace @ext_minors with GENHD_FL_EXT_DEVT such that setting the flag allows the disk to have maximum number of allowed partitions (only limited by the number of entries in parsed_partitions as determined by MAX_PART constant). This kills not-too-pretty alloc_disk_ext[_node]() functions and makes @minors parameter to alloc_disk[_node]() unnecessary. The parameter is left alone to avoid disturbing the users. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index ecf649c3dee..04524c213de 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -58,6 +58,8 @@ enum { UNIXWARE_PARTITION = 0x63, /* Same as GNU_HURD and SCO Unix */ }; +#define DISK_MAX_PARTS 256 + #include #include #include @@ -112,6 +114,7 @@ struct hd_struct { #define GENHD_FL_CD 8 #define GENHD_FL_UP 16 #define GENHD_FL_SUPPRESS_PARTITION_INFO 32 +#define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define BLK_SCSI_MAX_CMDS (256) #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) @@ -129,15 +132,13 @@ struct disk_part_tbl { }; struct gendisk { - /* major, first_minor, minors and ext_minors are input - * parameters only, don't use directly. Use disk_devt() and - * disk_max_parts(). + /* major, first_minor and minors are input parameters only, + * don't use directly. Use disk_devt() and disk_max_parts(). */ int major; /* major number of driver */ int first_minor; int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ - int ext_minors; /* number of extended dynamic minors */ char disk_name[32]; /* name of major driver */ @@ -180,7 +181,9 @@ static inline struct gendisk *part_to_disk(struct hd_struct *part) static inline int disk_max_parts(struct gendisk *disk) { - return disk->minors + disk->ext_minors; + if (disk->flags & GENHD_FL_EXT_DEVT) + return DISK_MAX_PARTS; + return disk->minors; } static inline bool disk_partitionable(struct gendisk *disk) @@ -527,9 +530,6 @@ extern void printk_all_partitions(void); extern struct gendisk *alloc_disk_node(int minors, int node_id); extern struct gendisk *alloc_disk(int minors); -extern struct gendisk *alloc_disk_ext_node(int minors, int ext_minrs, - int node_id); -extern struct gendisk *alloc_disk_ext(int minors, int ext_minors); extern struct kobject *get_disk(struct gendisk *disk); extern void put_disk(struct gendisk *disk); extern void blk_register_region(dev_t devt, unsigned long range, -- cgit v1.2.3 From 3e1a7ff8a0a7b948f2684930166954f9e8e776fe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 25 Aug 2008 19:56:17 +0900 Subject: block: allow disk to have extended device number Now that disk and partition handlings are mostly unified, it's easy to allow disk to have extended device number. This patch makes add_disk() use extended device number if disk->minors is zero. Both sd and ide-disk are updated to use this. * sd_format_disk_name() is implemented which can generically determine the drive name. This removes disk number restriction stemming from limited device names. * If sd index goes over SD_MAX_DISKS (which can be increased now BTW), sd simply doesn't initialize minors letting block layer choose extended device number. * If CONFIG_DEBUG_EXT_DEVT is set, both sd and ide-disk always set minors to 0 and use extended device numbers. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- include/linux/genhd.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 04524c213de..206cdf96c3a 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -59,6 +59,7 @@ enum { }; #define DISK_MAX_PARTS 256 +#define DISK_NAME_LEN 32 #include #include @@ -140,7 +141,7 @@ struct gendisk { int minors; /* maximum number of minors, =1 for * disks that can't be partitioned. */ - char disk_name[32]; /* name of major driver */ + char disk_name[DISK_NAME_LEN]; /* name of major driver */ /* Array of pointers to partitions indexed by partno. * Protected with matching bdev lock but stat and other -- cgit v1.2.3 From 18887ad910e56066233a07fd3cfb2fa11338b782 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 28 Jul 2008 13:08:45 +0200 Subject: block: make kblockd_schedule_work() take the queue as parameter Preparatory patch for checking queuing affinity. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 1adb03827bd..10aa46c8f17 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -912,7 +912,7 @@ static inline void put_dev_sector(Sector p) } struct work_struct; -int kblockd_schedule_work(struct work_struct *work); +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) \ -- cgit v1.2.3 From c7c22e4d5c1fdebfac4dba76de7d0338c2b0d832 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 13 Sep 2008 20:26:01 +0200 Subject: block: add support for IO CPU affinity This patch adds support for controlling the IO completion CPU of either all requests on a queue, or on a per-request basis. We export a sysfs variable (rq_affinity) which, if set, migrates completions of requests to the CPU that originally submitted it. A bio helper (bio_set_completion_cpu()) is also added, so that queuers can ask for completion on that specific CPU. In testing, this has been show to cut the system time by as much as 20-40% on synthetic workloads where CPU affinity is desired. This requires a little help from the architecture, so it'll only work as designed for archs that are using the new generic smp helper infrastructure. Signed-off-by: Jens Axboe --- include/linux/bio.h | 11 +++++++++++ include/linux/blkdev.h | 5 ++++- include/linux/elevator.h | 8 ++++---- 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 2c0c09034fd..13aba20edb2 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -81,6 +81,8 @@ struct bio { unsigned int bi_max_vecs; /* max bvl_vecs we can hold */ + unsigned int bi_comp_cpu; /* completion CPU */ + struct bio_vec *bi_io_vec; /* the actual vec list */ bio_end_io_t *bi_end_io; @@ -105,6 +107,7 @@ struct bio { #define BIO_BOUNCED 5 /* bio is a bounce bio */ #define BIO_USER_MAPPED 6 /* contains user pages */ #define BIO_EOPNOTSUPP 7 /* not supported */ +#define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /* @@ -342,6 +345,14 @@ void zero_fill_bio(struct bio *bio); extern struct bio_vec *bvec_alloc_bs(gfp_t, int, unsigned long *, struct bio_set *); extern unsigned int bvec_nr_vecs(unsigned short idx); +/* + * Allow queuer to specify a completion CPU for this bio + */ +static inline void bio_set_completion_cpu(struct bio *bio, unsigned int cpu) +{ + bio->bi_comp_cpu = cpu; +} + /* * bio_set is used to allow other portions of the IO system to * allocate their own private memory pools for bio and iovec structures. diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 10aa46c8f17..93204bf7b29 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -139,7 +140,8 @@ enum rq_flag_bits { */ struct request { struct list_head queuelist; - struct list_head donelist; + struct call_single_data csd; + int cpu; struct request_queue *q; @@ -420,6 +422,7 @@ struct request_queue #define QUEUE_FLAG_ELVSWITCH 8 /* don't use elevator, just do FIFO */ #define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */ #define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */ +#define QUEUE_FLAG_SAME_COMP 11 /* force complete on same CPU */ static inline int queue_is_locked(struct request_queue *q) { diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 639624b55fb..bb791c311a5 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -173,15 +173,15 @@ enum { #define rb_entry_rq(node) rb_entry((node), struct request, rb_node) /* - * Hack to reuse the donelist list_head as the fifo time holder while + * Hack to reuse the csd.list list_head as the fifo time holder while * the request is in the io scheduler. Saves an unsigned long in rq. */ -#define rq_fifo_time(rq) ((unsigned long) (rq)->donelist.next) -#define rq_set_fifo_time(rq,exp) ((rq)->donelist.next = (void *) (exp)) +#define rq_fifo_time(rq) ((unsigned long) (rq)->csd.list.next) +#define rq_set_fifo_time(rq,exp) ((rq)->csd.list.next = (void *) (exp)) #define rq_entry_fifo(ptr) list_entry((ptr), struct request, queuelist) #define rq_fifo_clear(rq) do { \ list_del_init(&(rq)->queuelist); \ - INIT_LIST_HEAD(&(rq)->donelist); \ + INIT_LIST_HEAD(&(rq)->csd.list); \ } while (0) /* -- cgit v1.2.3 From ab780f1ece0dc8d5e8e8e85435acc5e4747ccda3 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 26 Aug 2008 10:25:02 +0200 Subject: block: inherit CPU completion on bio->rq and rq->rq merges Somewhat incomplete, as we do allow merges of requests and bios that have different completion CPUs given. This is done on the assumption that a larger IO is still more beneficial than CPU locality. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 93204bf7b29..12df8efeef1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -545,6 +545,7 @@ enum { #define blk_pm_request(rq) \ (blk_pm_suspend_request(rq) || blk_pm_resume_request(rq)) +#define blk_rq_cpu_valid(rq) ((rq)->cpu != -1) #define blk_sorted_rq(rq) ((rq)->cmd_flags & REQ_SORTED) #define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER) #define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) -- cgit v1.2.3 From a3bce90edd8f6cafe3f63b1a943800792e830178 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 28 Aug 2008 16:17:05 +0900 Subject: block: add gfp_mask argument to blk_rq_map_user and blk_rq_map_user_iov Currently, blk_rq_map_user and blk_rq_map_user_iov always do GFP_KERNEL allocation. This adds gfp_mask argument to blk_rq_map_user and blk_rq_map_user_iov so sg can use it (sg always does GFP_ATOMIC allocation). Signed-off-by: FUJITA Tomonori Signed-off-by: Douglas Gilbert Cc: Mike Christie Cc: James Bottomley Signed-off-by: Jens Axboe --- include/linux/bio.h | 9 +++++---- include/linux/blkdev.h | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 13aba20edb2..200b185c3e8 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -325,11 +325,11 @@ extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, unsigned int, unsigned int); extern int bio_get_nr_vecs(struct block_device *); extern struct bio *bio_map_user(struct request_queue *, struct block_device *, - unsigned long, unsigned int, int); + unsigned long, unsigned int, int, gfp_t); struct sg_iovec; extern struct bio *bio_map_user_iov(struct request_queue *, struct block_device *, - struct sg_iovec *, int, int); + struct sg_iovec *, int, int, gfp_t); extern void bio_unmap_user(struct bio *); extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int, gfp_t); @@ -337,9 +337,10 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int, gfp_t, int); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); -extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int); +extern struct bio *bio_copy_user(struct request_queue *, unsigned long, + unsigned int, int, gfp_t); extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *, - int, int); + int, int, gfp_t); 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 *); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 12df8efeef1..00e388d0e22 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -710,11 +710,12 @@ extern void __blk_stop_queue(struct request_queue *q); extern void __blk_run_queue(struct request_queue *); extern void blk_run_queue(struct request_queue *); extern void blk_start_queueing(struct request_queue *); -extern int blk_rq_map_user(struct request_queue *, struct request *, void __user *, unsigned long); +extern int blk_rq_map_user(struct request_queue *, struct request *, + void __user *, unsigned long, gfp_t); extern int blk_rq_unmap_user(struct bio *); extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t); extern int blk_rq_map_user_iov(struct request_queue *, struct request *, - struct sg_iovec *, int, unsigned int); + struct sg_iovec *, int, unsigned int, gfp_t); extern int blk_execute_rq(struct request_queue *, struct gendisk *, struct request *, int); extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, -- cgit v1.2.3 From 152e283fdfea0cd11e297d982378b55937842dde Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 28 Aug 2008 16:17:06 +0900 Subject: block: introduce struct rq_map_data to use reserved pages This patch introduces struct rq_map_data to enable bio_copy_use_iov() use reserved pages. Currently, bio_copy_user_iov allocates bounce pages but drivers/scsi/sg.c wants to allocate pages by itself and use them. struct rq_map_data can be used to pass allocated pages to bio_copy_user_iov. The current users of bio_copy_user_iov simply passes NULL (they don't want to use pre-allocated pages). Signed-off-by: FUJITA Tomonori Cc: Jens Axboe Cc: Douglas Gilbert Cc: Mike Christie Cc: James Bottomley Signed-off-by: Jens Axboe --- include/linux/bio.h | 8 +++++--- include/linux/blkdev.h | 12 ++++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 200b185c3e8..bc386cd5e99 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -327,6 +327,7 @@ extern int bio_get_nr_vecs(struct block_device *); extern struct bio *bio_map_user(struct request_queue *, struct block_device *, unsigned long, unsigned int, int, gfp_t); struct sg_iovec; +struct rq_map_data; extern struct bio *bio_map_user_iov(struct request_queue *, struct block_device *, struct sg_iovec *, int, int, gfp_t); @@ -337,9 +338,10 @@ extern struct bio *bio_copy_kern(struct request_queue *, void *, unsigned int, gfp_t, int); extern void bio_set_pages_dirty(struct bio *bio); extern void bio_check_pages_dirty(struct bio *bio); -extern struct bio *bio_copy_user(struct request_queue *, unsigned long, - unsigned int, int, gfp_t); -extern struct bio *bio_copy_user_iov(struct request_queue *, struct sg_iovec *, +extern struct bio *bio_copy_user(struct request_queue *, struct rq_map_data *, + unsigned long, unsigned int, int, gfp_t); +extern struct bio *bio_copy_user_iov(struct request_queue *, + struct rq_map_data *, struct sg_iovec *, int, int, gfp_t); extern int bio_uncopy_user(struct bio *); void zero_fill_bio(struct bio *bio); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 00e388d0e22..358ac423ed2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -642,6 +642,12 @@ static inline void blk_queue_bounce(struct request_queue *q, struct bio **bio) } #endif /* CONFIG_MMU */ +struct rq_map_data { + struct page **pages; + int page_order; + int nr_entries; +}; + struct req_iterator { int i; struct bio *bio; @@ -711,11 +717,13 @@ extern void __blk_run_queue(struct request_queue *); extern void blk_run_queue(struct request_queue *); extern void blk_start_queueing(struct request_queue *); extern int blk_rq_map_user(struct request_queue *, struct request *, - void __user *, unsigned long, gfp_t); + struct rq_map_data *, void __user *, unsigned long, + gfp_t); extern int blk_rq_unmap_user(struct bio *); extern int blk_rq_map_kern(struct request_queue *, struct request *, void *, unsigned int, gfp_t); extern int blk_rq_map_user_iov(struct request_queue *, struct request *, - struct sg_iovec *, int, unsigned int, gfp_t); + struct rq_map_data *, struct sg_iovec *, int, + unsigned int, gfp_t); extern int blk_execute_rq(struct request_queue *, struct gendisk *, struct request *, int); extern void blk_execute_rq_nowait(struct request_queue *, struct gendisk *, -- cgit v1.2.3 From 879040742cf09f2360a9ac41846288707e4e567c Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Thu, 28 Aug 2008 15:05:58 +0900 Subject: block: add blk_rq_aligned helper function This adds blk_rq_aligned helper function to see if alignment and padding requirement is satisfied for DMA transfer. This also converts blk_rq_map_kern and __blk_rq_map_user to use the helper function. Signed-off-by: FUJITA Tomonori Cc: Jens Axboe Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 358ac423ed2..9c254926042 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -899,6 +899,13 @@ static inline int queue_dma_alignment(struct request_queue *q) return q ? q->dma_alignment : 511; } +static inline int blk_rq_aligned(struct request_queue *q, void *addr, + unsigned int len) +{ + unsigned int alignment = queue_dma_alignment(q) | q->dma_pad_mask; + return !((unsigned long)addr & alignment) && !(len & alignment); +} + /* assumes size > 256 */ static inline unsigned int blksize_bits(unsigned int size) { -- cgit v1.2.3 From 818827669d85b84241696ffef2de485db46b0b5e Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Tue, 2 Sep 2008 16:20:19 +0900 Subject: block: make blk_rq_map_user take a NULL user-space buffer This patch changes blk_rq_map_user to accept a NULL user-space buffer with a READ command if rq_map_data is not NULL. Thus a caller can pass page frames to lk_rq_map_user to just set up a request and bios with page frames propely. bio_uncopy_user (called via blk_rq_unmap_user) doesn't copy data to user space with such request. Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index bc386cd5e99..7af373f253d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -108,6 +108,7 @@ struct bio { #define BIO_USER_MAPPED 6 /* contains user pages */ #define BIO_EOPNOTSUPP 7 /* not supported */ #define BIO_CPU_AFFINE 8 /* complete bio on same CPU as submitted */ +#define BIO_NULL_MAPPED 9 /* contains invalid user pages */ #define bio_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /* -- cgit v1.2.3 From 0c002c2f74e10baa9021d3ecc50585c6eafea568 Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Thu, 4 Sep 2008 14:27:20 -0600 Subject: Wrapper for lower-level revalidate_disk routines. This is a wrapper for the lower-level revalidate_disk call-backs such as sd_revalidate_disk(). It allows us to perform pre and post operations when calling them. We will use this wrapper in a later patch to adjust block device sizes after an online resize (a _post_ operation). Signed-off-by: Andrew Patterson Signed-off-by: Jens Axboe --- include/linux/fs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 02a9fb5a830..d63461f9798 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1722,6 +1722,7 @@ extern int fs_may_remount_ro(struct super_block *); */ #define bio_data_dir(bio) ((bio)->bi_rw & 1) +extern int revalidate_disk(struct gendisk *); extern int check_disk_change(struct block_device *); extern int __invalidate_device(struct block_device *); extern int invalidate_partition(struct gendisk *, int); -- cgit v1.2.3 From c3279d1454cdfed02a557d789d8a6d08ab4cbe70 Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Thu, 4 Sep 2008 14:27:25 -0600 Subject: Adjust block device size after an online resize of a disk. The revalidate_disk routine now checks if a disk has been resized by comparing the gendisk capacity to the bdev inode size. If they are different (usually because the disk has been resized underneath the kernel) the bdev inode size is adjusted to match the capacity. Signed-off-by: Andrew Patterson Signed-off-by: Jens Axboe --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index d63461f9798..32477e8872d 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1722,6 +1722,8 @@ extern int fs_may_remount_ro(struct super_block *); */ #define bio_data_dir(bio) ((bio)->bi_rw & 1) +extern void check_disk_size_change(struct gendisk *disk, + struct block_device *bdev); extern int revalidate_disk(struct gendisk *); extern int check_disk_change(struct block_device *); extern int __invalidate_device(struct block_device *); -- cgit v1.2.3 From 242f9dcb8ba6f68fcd217a119a7648a4f69290e9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 14 Sep 2008 05:55:09 -0700 Subject: block: unify request timeout handling Right now SCSI and others do their own command timeout handling. Move those bits to the block layer. Instead of having a timer per command, we try to be a bit more clever and simply have one per-queue. This avoids the overhead of having to tear down and setup a timer for each command, so it will result in a lot less timer fiddling. Signed-off-by: Mike Anderson Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9c254926042..067f28b8007 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -147,6 +147,7 @@ struct request { unsigned int cmd_flags; enum rq_cmd_type_bits cmd_type; + unsigned long atomic_flags; /* Maintain bio traversal state for part by part I/O submission. * hard_* are block layer internals, no driver should touch them! @@ -214,6 +215,8 @@ struct request { void *data; void *sense; + unsigned long deadline; + struct list_head timeout_list; unsigned int timeout; int retries; @@ -266,6 +269,14 @@ typedef void (prepare_flush_fn) (struct request_queue *, struct request *); typedef void (softirq_done_fn)(struct request *); typedef int (dma_drain_needed_fn)(struct request *); +enum blk_eh_timer_return { + BLK_EH_NOT_HANDLED, + BLK_EH_HANDLED, + BLK_EH_RESET_TIMER, +}; + +typedef enum blk_eh_timer_return (rq_timed_out_fn)(struct request *); + enum blk_queue_state { Queue_down, Queue_up, @@ -311,6 +322,7 @@ struct request_queue merge_bvec_fn *merge_bvec_fn; prepare_flush_fn *prepare_flush_fn; softirq_done_fn *softirq_done_fn; + rq_timed_out_fn *rq_timed_out_fn; dma_drain_needed_fn *dma_drain_needed; /* @@ -386,6 +398,10 @@ struct request_queue unsigned int nr_sorted; unsigned int in_flight; + unsigned int rq_timeout; + struct timer_list timeout; + struct list_head timeout_list; + /* * sg stuff */ @@ -770,6 +786,8 @@ extern int blk_end_request_callback(struct request *rq, int error, unsigned int nr_bytes, int (drv_callback)(struct request *)); extern void blk_complete_request(struct request *); +extern void __blk_complete_request(struct request *); +extern void blk_abort_request(struct request *); /* * blk_end_request() takes bytes instead of sectors as a complete size. @@ -811,6 +829,8 @@ extern void blk_queue_dma_alignment(struct request_queue *, int); extern void blk_queue_update_dma_alignment(struct request_queue *, int); extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); extern void blk_queue_set_discard(struct request_queue *, prepare_discard_fn *); +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 **); -- cgit v1.2.3 From 11914a53d2ec2974a565311af327b8983d8c820d Mon Sep 17 00:00:00 2001 From: Mike Anderson Date: Sat, 13 Sep 2008 20:31:27 +0200 Subject: block: Add interface to abort queued requests Signed-off-by: Mike Anderson Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 + include/linux/blktrace_api.h | 2 ++ include/linux/elevator.h | 1 + 3 files changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 067f28b8007..37781d6fe04 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -788,6 +788,7 @@ extern int blk_end_request_callback(struct request *rq, int error, extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); +extern void blk_abort_queue(struct request_queue *); /* * blk_end_request() takes bytes instead of sectors as a complete size. diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 27da2cc682e..dcaf2452ed1 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -48,6 +48,7 @@ enum blktrace_act { __BLK_TA_SPLIT, /* bio was split */ __BLK_TA_BOUNCE, /* bio was bounced */ __BLK_TA_REMAP, /* bio was remapped */ + __BLK_TA_ABORT, /* request aborted */ }; /* @@ -78,6 +79,7 @@ enum blktrace_notify { #define BLK_TA_SPLIT (__BLK_TA_SPLIT) #define BLK_TA_BOUNCE (__BLK_TA_BOUNCE) #define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE)) #define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY)) #define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY)) diff --git a/include/linux/elevator.h b/include/linux/elevator.h index bb791c311a5..92f6f634e3e 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -112,6 +112,7 @@ extern struct request *elv_latter_request(struct request_queue *, struct request extern int elv_register_queue(struct request_queue *q); extern void elv_unregister_queue(struct request_queue *q); extern int elv_may_queue(struct request_queue *, int); +extern void elv_abort_queue(struct request_queue *); extern void elv_completed_request(struct request_queue *, struct request *); extern int elv_set_request(struct request_queue *, struct request *, gfp_t); extern void elv_put_request(struct request_queue *, struct request *); -- cgit v1.2.3 From 3e6053d76dcbd92b2f9f4ad5ece9bce83149523e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 11 Sep 2008 10:57:55 +0200 Subject: block: adjust blkdev_issue_discard for swap Two mods to blkdev_issue_discard(), thinking ahead to its use on swap: 1. Add gfp_mask argument, so swap allocation can use it where GFP_KERNEL might deadlock but GFP_NOIO is safe. 2. Enlarge nr_sects argument from unsigned to sector_t: unsigned long is enough to cover a whole swap area, but sector_t suits any partition. Change sb_issue_discard()'s nr_blocks to sector_t too; but no need seen for a gfp_mask there, just pass GFP_KERNEL down to blkdev_issue_discard(). Signed-off-by: Hugh Dickins Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 37781d6fe04..b47767c72ce 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -873,15 +874,15 @@ static inline struct request *blk_map_queue_find_tag(struct blk_queue_tag *bqt, } extern int blkdev_issue_flush(struct block_device *, sector_t *); -extern int blkdev_issue_discard(struct block_device *, sector_t sector, - unsigned nr_sects); +extern int blkdev_issue_discard(struct block_device *, + sector_t sector, sector_t nr_sects, gfp_t); static inline int sb_issue_discard(struct super_block *sb, - sector_t block, unsigned nr_blocks) + sector_t block, sector_t nr_blocks) { block <<= (sb->s_blocksize_bits - 9); nr_blocks <<= (sb->s_blocksize_bits - 9); - return blkdev_issue_discard(sb->s_bdev, block, nr_blocks); + return blkdev_issue_discard(sb->s_bdev, block, nr_blocks, GFP_KERNEL); } /* -- cgit v1.2.3 From 0a0d96b03a1f3bfd6bc3ea08008699e8e59fccd9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 11 Sep 2008 13:17:37 +0200 Subject: block: add bio_kmalloc() Not all callers need (or want!) the mempool backing guarentee, it essentially means that you can only use bio_alloc() for short allocations and not for preallocating some bio's at setup or init time. So add bio_kmalloc() which does the same thing as bio_alloc(), except it just uses kmalloc() as the backing instead of the bio mempools. Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 7af373f253d..6520ee1a3f6 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -308,6 +308,7 @@ extern struct bio_set *bioset_create(int, int); extern void bioset_free(struct bio_set *); extern struct bio *bio_alloc(gfp_t, int); +extern struct bio *bio_kmalloc(gfp_t, int); extern struct bio *bio_alloc_bioset(gfp_t, int, struct bio_set *); extern void bio_put(struct bio *); extern void bio_free(struct bio *, struct bio_set *); -- cgit v1.2.3 From 581d4e28d9195aa8b2231383dbabc288988d615e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sun, 14 Sep 2008 05:56:33 -0700 Subject: block: add fault injection mechanism for faking request timeouts Only works for the generic request timer handling. Allows one to sporadically ignore request completions, thus exercising the timeout handling. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b47767c72ce..e34999d14c1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -440,6 +440,7 @@ struct request_queue #define QUEUE_FLAG_BIDI 9 /* queue supports bidi requests */ #define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */ #define QUEUE_FLAG_SAME_COMP 11 /* force complete on same CPU */ +#define QUEUE_FLAG_FAIL_IO 12 /* fake timeout */ static inline int queue_is_locked(struct request_queue *q) { -- cgit v1.2.3 From 9c02f2b02e29a2244e36c6e1f246080d8afc6cff Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 18 Sep 2008 09:31:53 -0700 Subject: block: cleanup some of the integrity stuff in blkdev.h Don't put functions that are only used in fs/bio-integrity.c in blkdev.h, it's much cleaner to just keep it in there. Also kill completely unused bdev_get_tag_size() Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 43 ------------------------------------------- 1 file changed, 43 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e34999d14c1..e23b838825b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1004,47 +1004,6 @@ extern int blk_integrity_compare(struct block_device *, struct block_device *); extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); extern int blk_rq_count_integrity_sg(struct request *); -static inline unsigned short blk_integrity_tuple_size(struct blk_integrity *bi) -{ - if (bi) - return bi->tuple_size; - - return 0; -} - -static inline struct blk_integrity *bdev_get_integrity(struct block_device *bdev) -{ - return bdev->bd_disk->integrity; -} - -static inline unsigned int bdev_get_tag_size(struct block_device *bdev) -{ - struct blk_integrity *bi = bdev_get_integrity(bdev); - - if (bi) - return bi->tag_size; - - return 0; -} - -static inline int bdev_integrity_enabled(struct block_device *bdev, int rw) -{ - struct blk_integrity *bi = bdev_get_integrity(bdev); - - if (bi == NULL) - return 0; - - if (rw == READ && bi->verify_fn != NULL && - (bi->flags & INTEGRITY_FLAG_READ)) - return 1; - - if (rw == WRITE && bi->generate_fn != NULL && - (bi->flags & INTEGRITY_FLAG_WRITE)) - return 1; - - return 0; -} - static inline int blk_integrity_rq(struct request *rq) { if (rq->bio == NULL) @@ -1058,8 +1017,6 @@ static inline int blk_integrity_rq(struct request *rq) #define blk_integrity_rq(rq) (0) #define blk_rq_count_integrity_sg(a) (0) #define blk_rq_map_integrity_sg(a, b) (0) -#define bdev_get_integrity(a) (0) -#define bdev_get_tag_size(a) (0) #define blk_integrity_compare(a, b) (0) #define blk_integrity_register(a, b) (0) #define blk_integrity_unregister(a) do { } while (0); -- cgit v1.2.3 From 32fab448e5e86694beade415e750363538ea5f49 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 18 Sep 2008 10:45:09 -0400 Subject: block: add request update interface This patch adds blk_update_request(), which updates struct request with completing its data part, but doesn't complete the struct request itself. Though it looks like end_that_request_first() of older kernels, blk_update_request() should be used only by request stacking drivers. Request-based dm will use it in bio->bi_end_io callback to update the original request when a data part of a cloned request completes. Followings are additional background information of why request-based dm needs this interface. - Request stacking drivers can't use blk_end_request() directly from the lower driver's completion context (bio->bi_end_io or rq->end_io), because some device drivers (e.g. ide) may try to complete their request with queue lock held, and it may cause deadlock. See below for detailed description of possible deadlock: - To solve that, request-based dm offloads the completion of cloned struct request to softirq context (i.e. using blk_complete_request() from rq->end_io). - Though it is possible to use the same solution from bio->bi_end_io, it will delay the notification of bio completion to the original submitter. Also, it will cause inefficient partial completion, because the lower driver can't perform the cloned request anymore and request-based dm needs to requeue and redispatch it to the lower driver again later. That's not good. - So request-based dm needs blk_update_request() to perform the bio completion in the lower driver's completion context, which is more efficient. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e23b838825b..e82a84c9f37 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -791,6 +791,8 @@ extern void blk_complete_request(struct request *); extern void __blk_complete_request(struct request *); extern void blk_abort_request(struct request *); extern void blk_abort_queue(struct request_queue *); +extern void blk_update_request(struct request *rq, int error, + unsigned int nr_bytes); /* * blk_end_request() takes bytes instead of sectors as a complete size. -- cgit v1.2.3 From 82124d60354846623a4b94af335717a5e142a074 Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 18 Sep 2008 10:45:38 -0400 Subject: block: add request submission interface This patch adds blk_insert_cloned_request(), a generic request submission interface for request stacking drivers. Request-based dm will use it to submit their clones to underlying devices. blk_rq_check_limits() is also added because it is possible that the lower queue has stronger limitations than the upper queue if multiple drivers are stacking at request-level. Not only for blk_insert_cloned_request()'s internal use, the function will be used by request-based dm when the queue limitation is modified (e.g. by replacing dm's table). Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index e82a84c9f37..964c246bc27 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -693,6 +693,9 @@ extern void __blk_put_request(struct request_queue *, struct request *); extern struct request *blk_get_request(struct request_queue *, int, gfp_t); extern void blk_insert_request(struct request_queue *, struct request *, int, void *); extern void blk_requeue_request(struct request_queue *, struct request *); +extern int blk_rq_check_limits(struct request_queue *q, struct request *rq); +extern int blk_insert_cloned_request(struct request_queue *q, + struct request *rq); extern void blk_plug_device(struct request_queue *); extern void blk_plug_device_unlocked(struct request_queue *); extern int blk_remove_plug(struct request_queue *); -- cgit v1.2.3 From 4ee5eaf4516a60f8ef64d3c246c64c6be0cf8c3a Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Thu, 18 Sep 2008 10:46:13 -0400 Subject: block: add a queue flag for request stacking support This patch adds a queue flag to indicate the block device can be used for request stacking. Request stacking drivers need to stack their devices on top of only devices of which q->request_fn is functional. Since bio stacking drivers (e.g. md, loop) basically initialize their queue using blk_alloc_queue() and don't set q->request_fn, the check of (q->request_fn == NULL) looks enough for that purpose. However, dm will become both types of stacking driver (bio-based and request-based). And dm will always set q->request_fn even if the dm device is bio-based of which q->request_fn is not functional actually. So we need something else to distinguish the type of the device. Adding a queue flag is a solution for that. The reason why dm always sets q->request_fn is to keep the compatibility of dm user-space tools. Currently, all dm user-space tools are using bio-based dm without specifying the type of the dm device they use. To use request-based dm without changing such tools, the kernel must decide the type of the dm device automatically. The automatic type decision can't be done at the device creation time and needs to be deferred until such tools load a mapping table, since the actual type is decided by dm target type included in the mapping table. So a dm device has to be initialized using blk_init_queue() so that we can load either type of table. Then, all queue stuffs are set (e.g. q->request_fn) and we have no element to distinguish that it is bio-based or request-based, even after a table is loaded and the type of the device is decided. By the way, some stuffs of the queue (e.g. request_list, elevator) are needless when the dm device is used as bio-based. But the memory size is not so large (about 20[KB] per queue on ia64), so I hope the memory loss can be acceptable for bio-based dm users. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 964c246bc27..86f77ef127f 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -441,6 +441,7 @@ struct request_queue #define QUEUE_FLAG_NOMERGES 10 /* disable merge attempts */ #define QUEUE_FLAG_SAME_COMP 11 /* force complete on same CPU */ #define QUEUE_FLAG_FAIL_IO 12 /* fake timeout */ +#define QUEUE_FLAG_STACKABLE 13 /* supports request stacking */ static inline int queue_is_locked(struct request_queue *q) { @@ -547,6 +548,8 @@ enum { #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) #define blk_queue_flushing(q) ((q)->ordseq) +#define blk_queue_stackable(q) \ + test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) #define blk_fs_request(rq) ((rq)->cmd_type == REQ_TYPE_FS) #define blk_pc_request(rq) ((rq)->cmd_type == REQ_TYPE_BLOCK_PC) -- cgit v1.2.3 From 9e49184c82e9ec3ab4d45f9ea5a17ccaf43869f0 Mon Sep 17 00:00:00 2001 From: Keith Wansbrough Date: Mon, 22 Sep 2008 14:57:17 -0700 Subject: floppy: support arbitrary first-sector numbers The current floppy_struct allows floppies to number sectors starting from 0 or 1. This patch allows arbitrary first-sector numbers - for example, 0xC1 for Amstrad CPC disks. This extends the existing 1-bit field (FD_ZEROBASED, bit 2 of stretch) to 8 bits (FD_SECTMASK, bits 2 to 9). Currently 0x00 denotes a first sector number of 1, and 0x01 denotes a first sector number of 0. We extend this by interpreting FD_SECTMASK as the first sector number with the LSB flipped. Signed-off-by: Keith Wansbrough Cc: Alain Knaff Cc: Michael Kerrisk Cc: Karel Zak Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- include/linux/fd.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fd.h b/include/linux/fd.h index b6bd41d2b46..f5d194af07a 100644 --- a/include/linux/fd.h +++ b/include/linux/fd.h @@ -15,10 +15,16 @@ struct floppy_struct { sect, /* sectors per track */ head, /* nr of heads */ track, /* nr of tracks */ - stretch; /* !=0 means double track steps */ + stretch; /* bit 0 !=0 means double track steps */ + /* bit 1 != 0 means swap sides */ + /* bits 2..9 give the first sector */ + /* number (the LSB is flipped) */ #define FD_STRETCH 1 #define FD_SWAPSIDES 2 #define FD_ZEROBASED 4 +#define FD_SECTBASEMASK 0x3FC +#define FD_MKSECTBASE(s) (((s) ^ 1) << 2) +#define FD_SECTBASE(floppy) ((((floppy)->stretch & FD_SECTBASEMASK) >> 2) ^ 1) unsigned char gap, /* gap1 size */ -- cgit v1.2.3 From a68bbddba486020c9c74825ce90c4c1ec463e0e8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 24 Sep 2008 13:03:33 +0200 Subject: block: add queue flag for SSD/non-rotational devices We don't want to idle in AS/CFQ if the device doesn't have a seek penalty. So add a QUEUE_FLAG_NONROT to indicate a non-rotational device, low level drivers should set this flag upon discovery of an SSD or similar device type. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 86f77ef127f..0cf3e619fb2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -442,6 +442,7 @@ struct request_queue #define QUEUE_FLAG_SAME_COMP 11 /* force complete on same CPU */ #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) */ static inline int queue_is_locked(struct request_queue *q) { @@ -547,6 +548,7 @@ enum { #define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) #define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) #define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) +#define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) #define blk_queue_flushing(q) ((q)->ordseq) #define blk_queue_stackable(q) \ test_bit(QUEUE_FLAG_STACKABLE, &(q)->queue_flags) -- cgit v1.2.3 From 8bff7c6b0f63c7ee9c5e3a076338d74125b8debb Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 24 Sep 2008 13:05:10 +0200 Subject: libata: set queue SSD flag for SSD devices SSD devices should give an RPM setting of 1 in word 217 of the ID page. If we see such a device, tell the block layer about it. Signed-off-by: Jens Axboe --- include/linux/ata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 8a12d718c16..c1c8b4a4ba2 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -88,6 +88,7 @@ enum { ATA_ID_DLF = 128, ATA_ID_CSFO = 129, ATA_ID_CFA_POWER = 160, + ATA_ID_ROT_SPEED = 217, ATA_ID_PIO4 = (1 << 1), ATA_ID_SERNO_LEN = 20, @@ -691,6 +692,11 @@ static inline int ata_id_is_cfa(const u16 *id) return 0; } +static inline int ata_id_is_ssd(const u16 *id) +{ + return id[ATA_ID_ROT_SPEED] == 0x01; +} + static inline int ata_drive_40wire(const u16 *dev_id) { if (ata_id_is_sata(dev_id)) -- cgit v1.2.3 From c0ddffa84a7d12da9943a94d04dadbfb1883b904 Mon Sep 17 00:00:00 2001 From: Sven Schuetz Date: Fri, 26 Sep 2008 10:58:02 +0200 Subject: include blktrace_api.h in headers_install This header file is of interest for user space programming, i.e. for tools that process blktrace data. We would like to use it for a tool on-top of blktrace which processes data provided by blktrace. For this purpose, it would be helpful if the blktrace API would make it to /usr/include/linux. The git tree for the blktrace tools comes with its own copy of this header file. I didn't manage to replace that copy with the file generated by the patch below yet. A few more cleanups would be needed. For example, the blktrace ioctl numbers, which are currently defined in usr/include/fs.h, might need to be moved. Should be feasible, though. Signed-off-by: Sven Schuetz Signed-off-by: Martin Peschke Signed-off-by: Jens Axboe --- include/linux/Kbuild | 1 + include/linux/blktrace_api.h | 58 ++++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 26 deletions(-) (limited to 'include/linux') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index b68ec09399b..31474e89c59 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -180,6 +180,7 @@ unifdef-y += audit.h unifdef-y += auto_fs.h unifdef-y += auxvec.h unifdef-y += binfmts.h +unifdef-y += blktrace_api.h unifdef-y += capability.h unifdef-y += capi.h unifdef-y += cciss_ioctl.h diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index dcaf2452ed1..a2a7d0ca275 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -1,8 +1,10 @@ #ifndef BLKTRACE_H #define BLKTRACE_H +#ifdef __KERNEL__ #include #include +#endif /* * Trace categories @@ -92,17 +94,17 @@ enum blktrace_notify { * The trace itself */ struct blk_io_trace { - u32 magic; /* MAGIC << 8 | version */ - u32 sequence; /* event number */ - u64 time; /* in microseconds */ - u64 sector; /* disk offset */ - u32 bytes; /* transfer length */ - u32 action; /* what happened */ - u32 pid; /* who did it */ - u32 device; /* device number */ - u32 cpu; /* on what cpu did it happen */ - u16 error; /* completion error */ - u16 pdu_len; /* length of data after this trace */ + __u32 magic; /* MAGIC << 8 | version */ + __u32 sequence; /* event number */ + __u64 time; /* in microseconds */ + __u64 sector; /* disk offset */ + __u32 bytes; /* transfer length */ + __u32 action; /* what happened */ + __u32 pid; /* who did it */ + __u32 device; /* device number */ + __u32 cpu; /* on what cpu did it happen */ + __u16 error; /* completion error */ + __u16 pdu_len; /* length of data after this trace */ }; /* @@ -120,6 +122,25 @@ enum { Blktrace_stopped, }; +/* + * User setup structure passed with BLKTRACESTART + */ +struct blk_user_trace_setup { +#ifdef __KERNEL__ + char name[BDEVNAME_SIZE]; /* output */ +#else + char name[32]; /* output */ +#endif + __u16 act_mask; /* input */ + __u32 buf_size; /* input */ + __u32 buf_nr; /* input */ + __u64 start_lba; + __u64 end_lba; + __u32 pid; +}; + +#ifdef __KERNEL__ +#if defined(CONFIG_BLK_DEV_IO_TRACE) struct blk_trace { int trace_state; struct rchan *rchan; @@ -136,21 +157,6 @@ struct blk_trace { atomic_t dropped; }; -/* - * User setup structure passed with BLKTRACESTART - */ -struct blk_user_trace_setup { - char name[BDEVNAME_SIZE]; /* output */ - u16 act_mask; /* input */ - u32 buf_size; /* input */ - u32 buf_nr; /* input */ - u64 start_lba; - u64 end_lba; - u32 pid; -}; - -#ifdef __KERNEL__ -#if defined(CONFIG_BLK_DEV_IO_TRACE) extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); extern void blk_trace_shutdown(struct request_queue *); extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *); -- cgit v1.2.3 From ef9e3facdf1fe1228721a7c295a76d1b7a0e57ec Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Wed, 1 Oct 2008 16:12:15 +0200 Subject: block: add lld busy state exporting interface This patch adds an new interface, blk_lld_busy(), to check lld's busy state from the block layer. blk_lld_busy() calls down into low-level drivers for the checking if the drivers set q->lld_busy_fn() using blk_queue_lld_busy(). This resolves a performance problem on request stacking devices below. Some drivers like scsi mid layer stop dispatching request when they detect busy state on its low-level device like host/target/device. It allows other requests to stay in the I/O scheduler's queue for a chance of merging. Request stacking drivers like request-based dm should follow the same logic. However, there is no generic interface for the stacked device to check if the underlying device(s) are busy. If the request stacking driver dispatches and submits requests to the busy underlying device, the requests will stay in the underlying device's queue without a chance of merging. This causes performance problem on burst I/O load. With this patch, busy state of the underlying device is exported via q->lld_busy_fn(). So the request stacking driver can check it and stop dispatching requests if busy. The underlying device driver must return the busy state appropriately: 1: when the device driver can't process requests immediately. 0: when the device driver can process requests immediately, including abnormal situations where the device driver needs to kill all requests. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Cc: Andrew Morton Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 0cf3e619fb2..9e0ee1a8254 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -269,6 +269,7 @@ typedef int (merge_bvec_fn) (struct request_queue *, struct bvec_merge_data *, typedef void (prepare_flush_fn) (struct request_queue *, struct request *); typedef void (softirq_done_fn)(struct request *); typedef int (dma_drain_needed_fn)(struct request *); +typedef int (lld_busy_fn) (struct request_queue *q); enum blk_eh_timer_return { BLK_EH_NOT_HANDLED, @@ -325,6 +326,7 @@ struct request_queue softirq_done_fn *softirq_done_fn; rq_timed_out_fn *rq_timed_out_fn; dma_drain_needed_fn *dma_drain_needed; + lld_busy_fn *lld_busy_fn; /* * Dispatch queue sorting @@ -699,6 +701,7 @@ extern struct request *blk_get_request(struct request_queue *, int, gfp_t); extern void blk_insert_request(struct request_queue *, struct request *, int, void *); extern void blk_requeue_request(struct request_queue *, struct request *); extern int blk_rq_check_limits(struct request_queue *q, struct request *rq); +extern int blk_lld_busy(struct request_queue *q); extern int blk_insert_cloned_request(struct request_queue *q, struct request *rq); extern void blk_plug_device(struct request_queue *); @@ -835,6 +838,7 @@ extern void blk_queue_update_dma_pad(struct request_queue *, unsigned int); extern int blk_queue_dma_drain(struct request_queue *q, dma_drain_needed_fn *dma_drain_needed, void *buf, unsigned int size); +extern void blk_queue_lld_busy(struct request_queue *q, lld_busy_fn *fn); extern void blk_queue_segment_boundary(struct request_queue *, unsigned long); extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn); extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); -- cgit v1.2.3 From 0497b345e7d067109e0dd9bf9f4978a6847ee13b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 1 Oct 2008 16:16:25 +0200 Subject: blktrace: use BLKTRACE_BDEV_SIZE as the name size for setup structure Define as 32, which is is what BDEVNAME_SIZE is/was as well. This keeps the user interface the same and gets rid of the difference between kernel and user api here. Signed-off-by: Jens Axboe --- include/linux/blktrace_api.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index a2a7d0ca275..3a31eb50616 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -122,15 +122,13 @@ enum { Blktrace_stopped, }; +#define BLKTRACE_BDEV_SIZE 32 + /* * User setup structure passed with BLKTRACESTART */ struct blk_user_trace_setup { -#ifdef __KERNEL__ - char name[BDEVNAME_SIZE]; /* output */ -#else - char name[32]; /* output */ -#endif + char name[BLKTRACE_BDEV_SIZE]; /* output */ __u16 act_mask; /* input */ __u32 buf_size; /* input */ __u32 buf_nr; /* input */ -- cgit v1.2.3 From d00e29fd99dd63d1c51917604e35dee824ed567f Mon Sep 17 00:00:00 2001 From: Kiyoshi Ueda Date: Wed, 1 Oct 2008 10:14:46 -0400 Subject: block: remove end_{queued|dequeued}_request() This patch removes end_queued_request() and end_dequeued_request(), which are no longer used. As a results, users of __end_request() became only end_request(). So the actual code in __end_request() is moved to end_request() and __end_request() is removed. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 9e0ee1a8254..bfc18e497c7 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -793,8 +793,6 @@ extern int __blk_end_request(struct request *rq, int error, extern int blk_end_bidi_request(struct request *rq, int error, unsigned int nr_bytes, unsigned int bidi_bytes); extern void end_request(struct request *, int); -extern void end_queued_request(struct request *, int); -extern void end_dequeued_request(struct request *, int); extern int blk_end_request_callback(struct request *rq, int error, unsigned int nr_bytes, int (drv_callback)(struct request *)); -- cgit v1.2.3 From 8deaf7210728c453295dc1cb2a5b66c68183ac85 Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Thu, 2 Oct 2008 12:46:53 +0200 Subject: bio.h: Remove unused conditional code The whole bio_integrity() definition is inside an #ifdef CONFIG_BLK_DEV_INTEGRITY, there's no need for the conditional code. Signed-off-by: Alberto Bertogli Signed-off-by: Jens Axboe --- include/linux/bio.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 6520ee1a3f6..98c2d057065 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -457,14 +457,7 @@ static inline int bio_has_data(struct bio *bio) #define bip_for_each_vec(bvl, bip, i) \ __bip_for_each_vec(bvl, bip, i, (bip)->bip_idx) -static inline int bio_integrity(struct bio *bio) -{ -#if defined(CONFIG_BLK_DEV_INTEGRITY) - return bio->bi_integrity != NULL; -#else - return 0; -#endif -} +#define bio_integrity(bio) (bio->bi_integrity != NULL) extern struct bio_integrity_payload *bio_integrity_alloc_bioset(struct bio *, gfp_t, unsigned int, struct bio_set *); extern struct bio_integrity_payload *bio_integrity_alloc(struct bio *, gfp_t, unsigned int); -- cgit v1.2.3 From b04accc425d52ca59699290661e0dfd09b0feeeb Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 2 Oct 2008 12:53:22 +0200 Subject: block: revert part of d7533ad0e132f92e75c1b2eb7c26387b25a583c1 We need bdev_get_integrity() to support the pending md/dm patches. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index bfc18e497c7..bc693f5c388 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1016,6 +1016,12 @@ extern int blk_integrity_compare(struct block_device *, struct block_device *); extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); extern int blk_rq_count_integrity_sg(struct request *); +static inline +struct blk_integrity *bdev_get_integrity(struct block_device *bdev) +{ + return bdev->bd_disk->integrity; +} + static inline int blk_integrity_rq(struct request *rq) { if (rq->bio == NULL) @@ -1029,6 +1035,7 @@ static inline int blk_integrity_rq(struct request *rq) #define blk_integrity_rq(rq) (0) #define blk_rq_count_integrity_sg(a) (0) #define blk_rq_map_integrity_sg(a, b) (0) +#define bdev_get_integrity(a) (0) #define blk_integrity_compare(a, b) (0) #define blk_integrity_register(a, b) (0) #define blk_integrity_unregister(a) do { } while (0); -- cgit v1.2.3 From 74aa8c2cc010035a7eef2b4ca4d6430e0dae206a Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 1 Oct 2008 03:38:37 -0400 Subject: block: Introduce integrity data ownership flag A filesystem might supply its own integrity metadata. Introduce a flag that indicates whether the filesystem or the block layer owns the integrity buffer. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 98c2d057065..d86d39d490e 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -109,6 +109,7 @@ struct bio { #define BIO_EOPNOTSUPP 7 /* not supported */ #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_flagged(bio, flag) ((bio)->bi_flags & (1 << (flag))) /* -- cgit v1.2.3 From ad7fce93147d32ae53d25d9ea1a8ba31a239deee Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 1 Oct 2008 03:38:39 -0400 Subject: block: Switch blk_integrity_compare from bdev to gendisk The DM and MD integrity support now depends on being able to use gendisks instead of block_devices when comparing integrity profiles. Change function parameters accordingly. Also update comparison logic so that two NULL profiles are a valid configuration. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index bc693f5c388..00d340b0f75 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1012,7 +1012,7 @@ struct blk_integrity { extern int blk_integrity_register(struct gendisk *, struct blk_integrity *); extern void blk_integrity_unregister(struct gendisk *); -extern int blk_integrity_compare(struct block_device *, struct block_device *); +extern int blk_integrity_compare(struct gendisk *, struct gendisk *); extern int blk_rq_map_integrity_sg(struct request *, struct scatterlist *); extern int blk_rq_count_integrity_sg(struct request *); -- cgit v1.2.3 From b02739b01c5309d74a59859f2ce92c931d1f1955 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Thu, 2 Oct 2008 18:47:49 +0200 Subject: block: gendisk integrity wrapper This is a wrapper for accessing a gendisk's integrity bits. It allows the integrity support in MD to be compiled with BLK_DEV_INTEGRITY off. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 00d340b0f75..a92d9e4ea96 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1022,6 +1022,11 @@ struct blk_integrity *bdev_get_integrity(struct block_device *bdev) return bdev->bd_disk->integrity; } +static inline struct blk_integrity *blk_get_integrity(struct gendisk *disk) +{ + return disk->integrity; +} + static inline int blk_integrity_rq(struct request *rq) { if (rq->bio == NULL) @@ -1036,6 +1041,7 @@ static inline int blk_integrity_rq(struct request *rq) #define blk_rq_count_integrity_sg(a) (0) #define blk_rq_map_integrity_sg(a, b) (0) #define bdev_get_integrity(a) (0) +#define blk_get_integrity(a) (0) #define blk_integrity_compare(a, b) (0) #define blk_integrity_register(a, b) (0) #define blk_integrity_unregister(a) do { } while (0); -- cgit v1.2.3 From ad3316bf4eeb53c89164f759767f911072b56203 Mon Sep 17 00:00:00 2001 From: "Martin K. Petersen" Date: Wed, 1 Oct 2008 22:42:53 -0400 Subject: block: Find bio sector offset given idx and offset Helper function to find the sector offset in a bio given bvec index and page offset. Signed-off-by: Martin K. Petersen Signed-off-by: Jens Axboe --- include/linux/bio.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index d86d39d490e..fe12d0f9eba 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -327,6 +327,7 @@ extern int bio_add_page(struct bio *, struct page *, unsigned int,unsigned int); extern int bio_add_pc_page(struct request_queue *, struct bio *, struct page *, unsigned int, unsigned int); extern int bio_get_nr_vecs(struct block_device *); +extern sector_t bio_sector_offset(struct bio *, unsigned short, unsigned int); extern struct bio *bio_map_user(struct request_queue *, struct block_device *, unsigned long, unsigned int, int, gfp_t); struct sg_iovec; -- cgit v1.2.3 From 6feef531f55cf4a20fd9eb39f5352e5745203603 Mon Sep 17 00:00:00 2001 From: Denis ChengRq Date: Thu, 9 Oct 2008 08:57:05 +0200 Subject: block: mark bio_split_pool static Since all bio_split calls refer the same single bio_split_pool, the bio_split function can use bio_split_pool directly instead of the mempool_t parameter; then the mempool_t parameter can be removed from bio_split param list, and bio_split_pool is only referred in fs/bio.c file, can be marked static. Signed-off-by: Denis ChengRq Signed-off-by: Jens Axboe --- include/linux/bio.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index fe12d0f9eba..fb97221d7c3 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -300,9 +300,7 @@ struct bio_pair { atomic_t cnt; int error; }; -extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, - int first_sectors); -extern mempool_t *bio_split_pool; +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); -- cgit v1.2.3 From af5639424008ffe96f89b059bea1aec15e0115a9 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 9 Oct 2008 09:01:10 +0200 Subject: block: add some comments around the bio read-write flags Signed-off-by: Jens Axboe --- include/linux/bio.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index fb97221d7c3..ff5b4cf9e2d 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -123,13 +123,23 @@ struct bio { /* * bio bi_rw flags * - * bit 0 -- read (not set) or write (set) + * bit 0 -- data direction + * If not set, bio is a read from device. If set, it's a write to device. * bit 1 -- rw-ahead when set * bit 2 -- barrier + * Insert a serialization point in the IO queue, forcing previously + * submitted IO to be completed before this oen is issued. * bit 3 -- fail fast, don't want low level driver retries * bit 4 -- synchronous I/O hint: the block layer will unplug immediately + * Note that this does NOT indicate that the IO itself is sync, just + * that the block layer will not postpone issue of this IO by plugging. * bit 5 -- metadata request + * Used for tracing to differentiate metadata and data IO. May also + * get some preferential treatment in the IO scheduler * bit 6 -- discard sectors + * Informs the lower level device that this range of sectors is no longer + * used by the file system and may thus be freed by the device. Used + * for flash based storage. */ #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ -- cgit v1.2.3 From a5d8c3483a6e19aca95ef6a2c5890e33bfa5b293 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 9 Oct 2008 11:35:51 +0200 Subject: sched debug: add name to sched_domain sysctl entries add /proc/sys/kernel/sched_domain/cpu0/domain0/name, to make it easier to see which specific scheduler domain remained at that entry. Since we process the scheduler domain tree and simplify it, it's not always immediately clear during debugging which domain came from where. depends on CONFIG_SCHED_DEBUG=y. Signed-off-by: Ingo Molnar --- include/linux/sched.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index d8e699b5585..5d0819ee442 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -824,6 +824,9 @@ struct sched_domain { unsigned int ttwu_move_affine; unsigned int ttwu_move_balance; #endif +#ifdef CONFIG_SCHED_DEBUG + char *name; +#endif }; extern void partition_sched_domains(int ndoms_new, cpumask_t *doms_new, -- cgit v1.2.3 From bf0b90e357c883e8efd72954432efe652de74c76 Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Mon, 4 Aug 2008 11:59:07 -0700 Subject: [CPUFREQ][1/6] cpufreq: Add cpu number parameter to __cpufreq_driver_getavg() Add a cpu parameter to __cpufreq_driver_getavg(). This is needed for software cpufreq coordination where policy->cpu may not be same as the CPU on which we want to getavg frequency. A follow-on patch will use this parameter to getavg freq from all cpus in policy->cpus. Change since last patch. Fix the offline/online and suspend/resume oops reported by Youquan Song Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- include/linux/cpufreq.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 6fd5668aa57..1ee608fd7b7 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -187,7 +187,8 @@ extern int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int relation); -extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy); +extern int __cpufreq_driver_getavg(struct cpufreq_policy *policy, + unsigned int cpu); int cpufreq_register_governor(struct cpufreq_governor *governor); void cpufreq_unregister_governor(struct cpufreq_governor *governor); @@ -226,7 +227,9 @@ struct cpufreq_driver { unsigned int (*get) (unsigned int cpu); /* optional */ - unsigned int (*getavg) (unsigned int cpu); + unsigned int (*getavg) (struct cpufreq_policy *policy, + unsigned int cpu); + int (*exit) (struct cpufreq_policy *policy); int (*suspend) (struct cpufreq_policy *policy, pm_message_t pmsg); int (*resume) (struct cpufreq_policy *policy); -- cgit v1.2.3 From 8083e4ad970e4eb567e31037060cdd4ba346f0c0 Mon Sep 17 00:00:00 2001 From: "venkatesh.pallipadi@intel.com" Date: Mon, 4 Aug 2008 11:59:11 -0700 Subject: [CPUFREQ][5/6] cpufreq: Changes to get_cpu_idle_time_us(), used by ondemand governor export get_cpu_idle_time_us() for it to be used in ondemand governor. Last update time can be current time when the CPU is currently non-idle, accounting for the busy time since last idle. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Dave Jones --- include/linux/tick.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tick.h b/include/linux/tick.h index 8cf8cfe2cc9..98921a3e1aa 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -126,7 +126,7 @@ static inline ktime_t tick_nohz_get_sleep_length(void) return len; } static inline void tick_nohz_stop_idle(int cpu) { } -static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return 0; } +static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } # endif /* !NO_HZ */ #endif -- cgit v1.2.3 From c19e654ddbe3831252f61e76a74d661e1a755530 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 9 Oct 2008 11:59:55 -0700 Subject: gre: Add netlink interface This patch adds a netlink interface that will eventually displace the existing ioctl interface. It utilises the elegant rtnl_link_ops mechanism. This also means that user-space no longer needs to rely on the tunnel interface being of type GRE to identify GRE tunnels. The identification can now occur using rtnl_link_ops. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/if_tunnel.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_tunnel.h b/include/linux/if_tunnel.h index d4efe401470..aeab2cb32a9 100644 --- a/include/linux/if_tunnel.h +++ b/include/linux/if_tunnel.h @@ -2,6 +2,7 @@ #define _IF_TUNNEL_H_ #include +#include #define SIOCGETTUNNEL (SIOCDEVPRIVATE + 0) #define SIOCADDTUNNEL (SIOCDEVPRIVATE + 1) @@ -47,4 +48,22 @@ struct ip_tunnel_prl { /* PRL flags */ #define PRL_DEFAULT 0x0001 +enum +{ + IFLA_GRE_UNSPEC, + IFLA_GRE_LINK, + IFLA_GRE_IFLAGS, + IFLA_GRE_OFLAGS, + IFLA_GRE_IKEY, + IFLA_GRE_OKEY, + IFLA_GRE_LOCAL, + IFLA_GRE_REMOTE, + IFLA_GRE_TTL, + IFLA_GRE_TOS, + IFLA_GRE_PMTUDISC, + __IFLA_GRE_MAX, +}; + +#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1) + #endif /* _IF_TUNNEL_H_ */ -- cgit v1.2.3 From e1a8000228e16212c93b23cfbed4d622e2ec7a6b Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 9 Oct 2008 12:00:17 -0700 Subject: gre: Add Transparent Ethernet Bridging This patch adds support for Ethernet over GRE encapsulation. This is exposed to user-space with a new link type of "gretap" instead of "gre". It will create an ARPHRD_ETHER device in lieu of the usual ARPHRD_IPGRE. Note that to preserver backwards compatibility all Transparent Ethernet Bridging packets are passed to an ARPHRD_IPGRE tunnel if its key matches and there is no ARPHRD_ETHER device whose key matches more closely. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/if_ether.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index a0099e98b5c..bf1a53b2682 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -56,6 +56,7 @@ #define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ #define ETH_P_CUST 0x6006 /* DEC Customer use */ #define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ +#define ETH_P_TEB 0x6558 /* Trans Ether Bridging */ #define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ #define ETH_P_ATALK 0x809B /* Appletalk DDP */ #define ETH_P_AARP 0x80F3 /* Appletalk AARP */ -- cgit v1.2.3 From 82b1519b345d61dcfae526e3fcb08128f39f9bcc Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 10 Oct 2008 13:37:09 +0100 Subject: dm: export struct dm_dev Split struct dm_dev in two and publish the part that other targets need in include/linux/device-mapper.h. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index a90222e3297..178390de195 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -13,7 +13,6 @@ struct dm_target; struct dm_table; -struct dm_dev; struct mapped_device; struct bio_vec; @@ -84,6 +83,12 @@ void dm_error(const char *message); */ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev); +struct dm_dev { + struct block_device *bdev; + int mode; + char name[16]; +}; + /* * Constructors should call these functions to ensure destination devices * are opened/closed correctly. -- cgit v1.2.3 From 89343da077ad564ed130c46e5ea6a79388410fa5 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 10 Oct 2008 13:37:10 +0100 Subject: dm: publish dm_get_mapinfo Publish dm_get_mapinfo in include/linux/device-mapper.h because this function is used by targets. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 178390de195..6b80961650f 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -207,6 +207,7 @@ int dm_copy_name_and_uuid(struct mapped_device *md, char *name, char *uuid); struct gendisk *dm_disk(struct mapped_device *md); int dm_suspended(struct mapped_device *md); int dm_noflush_suspending(struct dm_target *ti); +union map_info *dm_get_mapinfo(struct bio *bio); /* * Geometry functions. -- cgit v1.2.3 From ea0ec640940c2ae3a8d71af3249fccf06a9997a3 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 10 Oct 2008 13:37:11 +0100 Subject: dm: publish dm_table_unplug_all Publish dm_table_unplug_all in include/linux/device-mapper.h because this function is used by targets. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 6b80961650f..e462c7f3b39 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -237,6 +237,11 @@ int dm_table_add_target(struct dm_table *t, const char *type, */ int dm_table_complete(struct dm_table *t); +/* + * Unplug all devices in a table. + */ +void dm_table_unplug_all(struct dm_table *t); + /* * Table reference counting. */ -- cgit v1.2.3 From 54160904260fa764ba6e2dc738770be30fdf9553 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Fri, 10 Oct 2008 13:37:12 +0100 Subject: dm: publish dm_vcalloc Publish dm_vcalloc in include/linux/device-mapper.h because this function is used by targets. Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index e462c7f3b39..08d783592b7 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -267,6 +267,11 @@ void dm_table_event(struct dm_table *t); */ int dm_swap_table(struct mapped_device *md, struct dm_table *t); +/* + * A wrapper around vmalloc. + */ +void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); + /*----------------------------------------------------------------- * Macros. *---------------------------------------------------------------*/ -- cgit v1.2.3 From a3cdcbfa8fb1fccfe48d359da86e99546610c562 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Fri, 10 Oct 2008 12:01:37 -0700 Subject: mlx4_core: Add QP range reservation support To allow allocating an aligned range of consecutive QP numbers, add an interface to reserve an aligned range of QP numbers and have the QP allocation function always take a QP number. This will be used for RSS support in the mlx4_en Ethernet driver and also potentially by IPoIB RSS support. Signed-off-by: Yevgeny Petrilin Signed-off-by: Roland Dreier --- include/linux/mlx4/device.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index b2f94446831..d21e879f3c9 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -400,7 +400,10 @@ int mlx4_cq_alloc(struct mlx4_dev *dev, int nent, struct mlx4_mtt *mtt, int collapsed); void mlx4_cq_free(struct mlx4_dev *dev, struct mlx4_cq *cq); -int mlx4_qp_alloc(struct mlx4_dev *dev, int sqpn, struct mlx4_qp *qp); +int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base); +void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt); + +int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp); void mlx4_qp_free(struct mlx4_dev *dev, struct mlx4_qp *qp); int mlx4_srq_alloc(struct mlx4_dev *dev, u32 pdn, struct mlx4_mtt *mtt, -- cgit v1.2.3 From fe9053b30bb48b99f7b45541249f5cfe96bdf7f7 Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Thu, 9 Oct 2008 14:59:59 -0400 Subject: RPC/RDMA: add data types and new FRMR memory registration enum. Internal RPC/RDMA structure updates in preparation for FRMR support. Signed-off-by: Tom Talpey Acked-by: Tom Tucker Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprtrdma.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h index 4de56b1d372..55a5d92ca1e 100644 --- a/include/linux/sunrpc/xprtrdma.h +++ b/include/linux/sunrpc/xprtrdma.h @@ -78,6 +78,7 @@ enum rpcrdma_memreg { RPCRDMA_MEMWINDOWS, RPCRDMA_MEMWINDOWS_ASYNC, RPCRDMA_MTHCAFMR, + RPCRDMA_FRMR, RPCRDMA_ALLPHYSICAL, RPCRDMA_LAST }; -- cgit v1.2.3 From 5675add36e76b9487e7f9e689f854cb8d6afd9b4 Mon Sep 17 00:00:00 2001 From: Tom Talpey Date: Thu, 9 Oct 2008 15:01:41 -0400 Subject: RPC/RDMA: harden connection logic against missing/late rdma_cm upcalls. Add defensive timeouts to wait_for_completion() calls in RDMA address resolution, and make them interruptible. Fix the timeout units to milliseconds (formerly jiffies) and move to private header. Signed-off-by: Tom Talpey Signed-off-by: Trond Myklebust --- include/linux/sunrpc/xprtrdma.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sunrpc/xprtrdma.h b/include/linux/sunrpc/xprtrdma.h index 55a5d92ca1e..54a379c9e8e 100644 --- a/include/linux/sunrpc/xprtrdma.h +++ b/include/linux/sunrpc/xprtrdma.h @@ -66,9 +66,6 @@ #define RPCRDMA_INLINE_PAD_THRESH (512)/* payload threshold to pad (bytes) */ -#define RDMA_RESOLVE_TIMEOUT (5*HZ) /* TBD 5 seconds */ -#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */ - /* memory registration strategies */ #define RPCRDMA_PERSISTENT_REGISTRATION (1) -- cgit v1.2.3 From 4dde4492d850a4c9bcaa92e5bd7f4eebe3e2f5ab Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:19 +0200 Subject: ide: make drive->id an union (take 2) Make drive->id an unnamed union so id can be accessed either by using 'u16 *id' or 'struct hd_driveid *driveid'. Then convert all existing drive->id users accordingly (using 'u16 *id' when possible). This is an intermediate step to make ide 'struct hd_driveid'-free. While at it: - Add missing KERN_CONTs in it821x.c. - Use ATA_ID_WORDS and ATA_ID_*_LEN defines. - Remove unnecessary checks for drive->id. - s/drive_table/table/ in ide_in_drive_list(). - Cleanup ide_config_drive_speed() a bit. - s/drive1/dev1/ & s/drive0/dev0/ in ide_undecoded_slave(). v2: Fix typo in drivers/ide/ppc/pmac.c. (From Stephen Rothwell) There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 6514db8fd2e..0c85aff3edf 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -380,7 +380,11 @@ struct ide_drive_s { struct request *rq; /* current request */ struct ide_drive_s *next; /* circular list of hwgroup drives */ void *driver_data; /* extra driver data */ - struct hd_driveid *id; /* drive model identification info */ + union { + /* identification info */ + struct hd_driveid *driveid; + u16 *id; + }; #ifdef CONFIG_IDE_PROC_FS struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ struct ide_settings_s *settings;/* /proc/ide/ drive settings */ @@ -920,7 +924,7 @@ ide_startstop_t __ide_error(ide_drive_t *, struct request *, u8, u8); ide_startstop_t ide_error (ide_drive_t *drive, const char *msg, byte stat); -extern void ide_fix_driveid(struct hd_driveid *); +void ide_fix_driveid(u16 *); extern void ide_fixstring(u8 *, const int, const int); @@ -1240,7 +1244,7 @@ struct drive_list_entry { const char *id_firmware; }; -int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); +int ide_in_drive_list(u16 *, const struct drive_list_entry *); #ifdef CONFIG_BLK_DEV_IDEDMA int __ide_dma_bad_drive(ide_drive_t *); @@ -1347,12 +1351,13 @@ const char *ide_xfer_verbose(u8 mode); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); -static inline int ide_dev_has_iordy(struct hd_driveid *id) +static inline int ide_dev_has_iordy(u16 *id) { - return ((id->field_valid & 2) && (id->capability & 8)) ? 1 : 0; + return ((id[ATA_ID_FIELD_VALID] & 2) && + (((struct hd_driveid *)id)->capability & 8)) ? 1 : 0; } -static inline int ide_dev_is_sata(struct hd_driveid *id) +static inline int ide_dev_is_sata(u16 *id) { /* * See if word 93 is 0 AND drive is at least ATA-5 compatible @@ -1360,7 +1365,7 @@ static inline int ide_dev_is_sata(struct hd_driveid *id) * this trick allows us to filter out the reserved values of * 0x0000 and 0xffff along with the earlier ATA revisions... */ - if (id->hw_config == 0 && (short)id->major_rev_num >= 0x0020) + if (id[ATA_ID_HW_CONFIG] == 0 && (short)id[ATA_ID_MAJOR_VER] >= 0x0020) return 1; return 0; } @@ -1437,11 +1442,11 @@ extern struct bus_type ide_bus_type; extern struct class *ide_port_class; /* check if CACHE FLUSH (EXT) command is supported (bits defined in ATA-6) */ -#define ide_id_has_flush_cache(id) ((id)->cfs_enable_2 & 0x3000) +#define ide_id_has_flush_cache(id) ((id)[ATA_ID_CFS_ENABLE_2] & 0x3000) /* some Maxtor disks have bit 13 defined incorrectly so check bit 10 too */ #define ide_id_has_flush_cache_ext(id) \ - (((id)->cfs_enable_2 & 0x2400) == 0x2400) + (((id)[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400) static inline void ide_dump_identify(u8 *id) { -- cgit v1.2.3 From 48fb2688aa67baba373531cc4ed2d9e695983c3f Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:19 +0200 Subject: ide: remove drive->driveid * Factor out HDIO_[OBSOLETE,GET]_IDENTITY ioctls handling to ide_get_identity_ioctl(). * Use temporary buffer in ide_get_identity_ioctl() instead of accessing drive->id directly. * Add ide_id_to_hd_driveid() inline to convert raw id into struct hd_driveid format (needed on big-endian). * Use ide_id_to_hd_driveid() in ide_get_identity_ioctl(), cleanup ide_fix_driveid() and switch ide to use use raw id. * Remove no longer needed drive->driveid. This leaves us with 3 users of struct hd_driveid in tree: - arch/um/drivers/ubd_kern.c - drivers/block/xsysace.c - drivers/usb/storage/isd200.c While at it: * Use ata_id_u{32,64}() and ata_id_has_{dma,lba,iordy}() macros. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 0c85aff3edf..e887927e00e 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -380,11 +380,7 @@ struct ide_drive_s { struct request *rq; /* current request */ struct ide_drive_s *next; /* circular list of hwgroup drives */ void *driver_data; /* extra driver data */ - union { - /* identification info */ - struct hd_driveid *driveid; - u16 *id; - }; + u16 *id; /* identification info */ #ifdef CONFIG_IDE_PROC_FS struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ struct ide_settings_s *settings;/* /proc/ide/ drive settings */ @@ -1353,8 +1349,7 @@ extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); static inline int ide_dev_has_iordy(u16 *id) { - return ((id[ATA_ID_FIELD_VALID] & 2) && - (((struct hd_driveid *)id)->capability & 8)) ? 1 : 0; + return ((id[ATA_ID_FIELD_VALID] & 2) && ata_id_has_iordy(id)) ? 1 : 0; } static inline int ide_dev_is_sata(u16 *id) -- cgit v1.2.3 From 3a7d24841ad794ae64c90d7d00d62a83741912aa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:21 +0200 Subject: ide: use ATA_* defines instead of *_STAT and *_ERR ones * ERR_STAT -> ATA_ERR * INDEX_STAT -> ATA_IDX * ECC_STAT -> ATA_CORR * DRQ_STAT -> ATA_DRQ * SEEK_STAT -> ATA_DSC * WRERR_STAT -> ATA_DF * READY_STAT -> ATA_DRDY * BUSY_STAT -> ATA_BUSY * MARK_ERR -> ATA_AMNF * TRK0_ERR -> ATA_TRK0NF * ABRT_ERR -> ATA_ABORTED * MCR_ERR -> ATA_MCR * ID_ERR -> ATA_IDNF * MC_ERR -> ATA_MC * ECC_ERR -> ATA_UNC * ICRC_ERR -> ATA_ICRC * BBD_ERR -> ATA_BBK Also: * ILI_ERR -> ATAPI_ILI * EOM_ERR -> ATAPI_EOM * LFS_ERR -> ATAPI_LFS * CD -> ATAPI_COD * IO -> ATAPI_IO Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index e887927e00e..d963c1929c8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -87,12 +87,13 @@ struct ide_io_ports { }; #define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) -#define BAD_R_STAT (BUSY_STAT | ERR_STAT) -#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) -#define BAD_STAT (BAD_R_STAT | DRQ_STAT) -#define DRIVE_READY (READY_STAT | SEEK_STAT) -#define BAD_CRC (ABRT_ERR | ICRC_ERR) +#define BAD_R_STAT (ATA_BUSY | ATA_ERR) +#define BAD_W_STAT (BAD_R_STAT | ATA_DF) +#define BAD_STAT (BAD_R_STAT | ATA_DRQ) +#define DRIVE_READY (ATA_DRDY | ATA_DSC) + +#define BAD_CRC (ATA_ABORTED | ATA_ICRC) #define SATA_NR_PORTS (3) /* 16 possible ?? */ @@ -438,8 +439,8 @@ struct ide_drive_s { u8 mult_req; /* requested multiple sector setting */ u8 tune_req; /* requested drive tuning setting */ u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ - u8 bad_wstat; /* used for ignoring WRERR_STAT */ - u8 nowerr; /* used for ignoring WRERR_STAT */ + u8 bad_wstat; /* used for ignoring ATA_DF */ + u8 nowerr; /* used for ignoring ATA_DF */ u8 sect0; /* offset of first sector for DM6:DDO */ u8 head; /* "real" number of heads */ u8 sect; /* "real" sectors per track */ -- cgit v1.2.3 From 3c619ffd48d7fdb3b17f0df67c4eb4b0bd80e253 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:22 +0200 Subject: ide: remove no longer needed ide_drive_t fields Remove ->remap_0_to_1 and ->sect0 (they are always zero now). Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index d963c1929c8..ca0b132de1a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -418,7 +418,6 @@ struct ide_drive_s { unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */ unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ unsigned nodma : 1; /* disallow DMA */ - unsigned remap_0_to_1 : 1; /* 0=noremap, 1=remap 0->1 (for EZDrive) */ unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */ unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ @@ -441,7 +440,6 @@ struct ide_drive_s { u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ u8 bad_wstat; /* used for ignoring ATA_DF */ u8 nowerr; /* used for ignoring ATA_DF */ - u8 sect0; /* offset of first sector for DM6:DDO */ u8 head; /* "real" number of heads */ u8 sect; /* "real" sectors per track */ u8 bios_head; /* BIOS/fdisk/LILO number of heads */ -- cgit v1.2.3 From b163f46d5ecf48d883ce156e5e5a21a1a9a125c7 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:23 +0200 Subject: ide: enhance ide_busy_sleep() * Make ide_busy_sleep() take timeout value as a parameter and also allow use of AltStatus Register if requested with altstatus parameter. Update existing users accordingly. * Convert ide_driveid_update() and actual_try_to_identify() to use ide_busy_sleep(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ca0b132de1a..2ad8548135d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -923,6 +923,8 @@ void ide_fix_driveid(u16 *); extern void ide_fixstring(u8 *, const int, const int); +int ide_busy_sleep(ide_hwif_t *, unsigned long, int); + int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); extern ide_startstop_t ide_do_reset (ide_drive_t *); -- cgit v1.2.3 From a2cdee5a9a93360165d0576bbc7e9ccb3127afee Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:24 +0200 Subject: ide: remove IDE_CHIPSET_* macros They just obfuscate the code. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 2ad8548135d..a9206c463d7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -473,10 +473,6 @@ typedef struct ide_drive_s ide_drive_t; #define to_ide_device(dev)container_of(dev, ide_drive_t, gendev) -#define IDE_CHIPSET_PCI_MASK \ - ((1<> (c)) & 1) - struct ide_task_s; struct ide_port_info; -- cgit v1.2.3 From 7e59ea21aab1a91ca31bc64c7d3035ebdbd336d1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:26 +0200 Subject: ide: check drive->present in ide_get_paired_drive() * Change ide_get_paired_drive() to return NULL if peer device is not present and update all users accordingly. While at it: * ide_get_paired_drive() -> ide_get_pair_dev() * Use ide_get_pair_dev() in cs5530.c, sc1200.c and via82cxxx.c. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a9206c463d7..1d9716a95dc 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1450,10 +1450,10 @@ static inline int hwif_to_node(ide_hwif_t *hwif) return hwif->dev ? dev_to_node(hwif->dev) : -1; } -static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive) +static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive) { - ide_hwif_t *hwif = HWIF(drive); + ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1]; - return &hwif->drives[(drive->dn ^ 1) & 1]; + return peer->present ? peer : NULL; } #endif /* _IDE_H */ -- cgit v1.2.3 From 3ceca727fe3a38dd8d7a3adf938fefda83eee8af Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:27 +0200 Subject: ide: include only when needed * Include directly in instead of through . * Include only when needed. Cc: Christoph Hellwig Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 1d9716a95dc..a7f980d2fe5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include -- cgit v1.2.3 From 263138a0ad6e38de7f6526b7de037ed4511308ef Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:27 +0200 Subject: ide: preparations for /proc/ide/hd*/settings rework After rework settings will be no longer created dynamically for each device so we need to make some fixups first. * Use set_[ksettings,unmaskirq]() as a set function for ["keepsettings","unmaskirq"] setting. * Allow writes to ["io_32bit","unmaskirq"] settings also when drive->no_[io_32bit,unmask] is set (this is checked later inside set_[io_32bit,unmaskirq]() anywyay and keeps consistency with the corresponding HDIO_SET_[32BIT,UNMASKINTR] ioctls). * Use max possible multi sectors value (16) as an allowed max for "multcount" setting. set_multcount() set function checks against device's max possbile value anyway and it makes the proc setting consistent with the corresponding HDIO_SET_MULTCOUNT ioctl. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a7f980d2fe5..ad09e7c81ae 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -688,7 +688,9 @@ typedef struct ide_driver_s ide_driver_t; extern struct mutex ide_setting_mtx; int set_io_32bit(ide_drive_t *, int); +int set_ksettings(ide_drive_t *, int); int set_pio_mode(ide_drive_t *, int); +int set_unmaskirq(ide_drive_t *, int); int set_using_dma(ide_drive_t *, int); /* ATAPI packet command flags */ -- cgit v1.2.3 From 8185d5aa93e0a5c111adc4952a5b87193a68ae5b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:28 +0200 Subject: ide: /proc/ide/hd*/settings rework * Add struct ide_devset, S_* flags, *DEVSET() & ide*_devset_*() macros. * Add 'const struct ide_devset **settings' to ide_driver_t. * Use 'const struct ide_devset **settings' in ide_drive_t instead of 'struct ide_settings_s *settings'. Then convert core code and device drivers to use struct ide_devset and co.: - device settings are no longer allocated dynamically for each device but instead there is an unique struct ide_devset instance per setting - device driver keeps the pointer to the table of pointers to its settings in ide_driver_t.settings - generic settings are kept in ide_generic_setting[] - ide_proc_[un]register_driver(), ide_find_setting_by_name(), ide_{read,write}_setting() and proc_ide_{read,write}_settings() are updated accordingly - ide*_add_settings() are removed * Remove no longer used __ide_add_setting(), ide_add_setting(), __ide_remove_setting() and auto_remove_settings(). * Remove no longer used TYPE_*, SETTING_*, ide_procset_t and ide_settings_t. * ->keep_settings, ->using_dma, ->unmask, ->noflush, ->dsc_overlap, ->nice1, ->addressing, ->wcache and ->nowerr ide_drive_t fields can now be bitfield flags. While at it: * Rename ide_find_setting_by_name() to ide_find_setting(). * Rename write_wcache() to set_wcache(). There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 110 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 74 insertions(+), 36 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ad09e7c81ae..4667ec8aeeb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -304,8 +304,8 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; +struct ide_devset; struct ide_driver_s; -struct ide_settings_s; #ifdef CONFIG_BLK_DEV_IDEACPI struct ide_acpi_drive_link; @@ -384,7 +384,7 @@ struct ide_drive_s { u16 *id; /* identification info */ #ifdef CONFIG_IDE_PROC_FS struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - struct ide_settings_s *settings;/* /proc/ide/ drive settings */ + const struct ide_devset **settings; /* /proc/ide/ drive settings */ #endif struct hwif_s *hwif; /* actually (ide_hwif_t *) */ @@ -396,16 +396,16 @@ struct ide_drive_s { special_t special; /* special action flags */ select_t select; /* basic drive/head select reg value */ - u8 keep_settings; /* restore settings after drive reset */ - u8 using_dma; /* disk is using dma for read/write */ u8 retry_pio; /* retrying dma capable host in pio */ u8 state; /* retry state */ u8 waiting_for_dma; /* dma currently in progress */ - u8 unmask; /* okay to unmask other irqs */ - u8 noflush; /* don't attempt flushes */ - u8 dsc_overlap; /* DSC overlap */ - u8 nice1; /* give potential excess bandwidth */ + unsigned keep_settings : 1; /* restore settings after drive reset */ + unsigned using_dma : 1; /* disk is using dma for read/write */ + unsigned unmask : 1; /* okay to unmask other irqs */ + unsigned noflush : 1; /* don't attempt flushes */ + unsigned dsc_overlap : 1; /* DSC overlap */ + unsigned nice1 : 1; /* give potential excess bandwidth */ unsigned present : 1; /* drive is physically present */ unsigned dead : 1; /* device ejected hint */ unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */ @@ -423,14 +423,15 @@ struct ide_drive_s { unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ unsigned post_reset : 1; unsigned udma33_warned : 1; + unsigned addressing : 2; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */ + unsigned wcache : 1; /* status of write cache */ + unsigned nowerr : 1; /* used for ignoring ATA_DF */ - u8 addressing; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */ u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ u8 current_speed; /* current transfer rate set */ u8 desired_speed; /* desired transfer rate set */ u8 dn; /* now wide spread use */ - u8 wcache; /* status of write cache */ u8 acoustic; /* acoustic management */ u8 media; /* disk, cdrom, tape, floppy, ... */ u8 ready_stat; /* min status value for drive ready */ @@ -439,7 +440,6 @@ struct ide_drive_s { u8 tune_req; /* requested drive tuning setting */ u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ u8 bad_wstat; /* used for ignoring ATA_DF */ - u8 nowerr; /* used for ignoring ATA_DF */ u8 head; /* "real" number of heads */ u8 sect; /* "real" sectors per track */ u8 bios_head; /* BIOS/fdisk/LILO number of heads */ @@ -687,12 +687,29 @@ typedef struct ide_driver_s ide_driver_t; extern struct mutex ide_setting_mtx; +int get_io_32bit(ide_drive_t *); int set_io_32bit(ide_drive_t *, int); +int get_ksettings(ide_drive_t *); int set_ksettings(ide_drive_t *, int); int set_pio_mode(ide_drive_t *, int); +int get_unmaskirq(ide_drive_t *); int set_unmaskirq(ide_drive_t *, int); +int get_using_dma(ide_drive_t *); int set_using_dma(ide_drive_t *, int); +#define ide_devset_get(name, field) \ +int get_##name(ide_drive_t *drive) \ +{ \ + return drive->field; \ +} + +#define ide_devset_set(name, field) \ +int set_##name(ide_drive_t *drive, int arg) \ +{ \ + drive->field = arg; \ + return 0; \ +} + /* ATAPI packet command flags */ enum { /* set when an error is considered normal - no retry (ide-tape) */ @@ -757,30 +774,53 @@ struct ide_atapi_pc { * configurable drive settings */ -#define TYPE_INT 0 -#define TYPE_BYTE 1 -#define TYPE_SHORT 2 +#define S_READ (1 << 0) +#define S_WRITE (1 << 1) +#define S_RW (S_READ | S_WRITE) +#define S_NOLOCK (1 << 2) -#define SETTING_READ (1 << 0) -#define SETTING_WRITE (1 << 1) -#define SETTING_RW (SETTING_READ | SETTING_WRITE) +struct ide_devset { + const char *name; + unsigned int flags; + int min, max; + int (*get)(ide_drive_t *); + int (*set)(ide_drive_t *, int); + int (*mulf)(ide_drive_t *); + int (*divf)(ide_drive_t *); +}; -typedef int (ide_procset_t)(ide_drive_t *, int); -typedef struct ide_settings_s { - char *name; - int rw; - int data_type; - int min; - int max; - int mul_factor; - int div_factor; - void *data; - ide_procset_t *set; - int auto_remove; - struct ide_settings_s *next; -} ide_settings_t; - -int ide_add_setting(ide_drive_t *, const char *, int, int, int, int, int, int, void *, ide_procset_t *set); +#define __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) { \ + .name = __stringify(_name), \ + .flags = _flags, \ + .min = _min, \ + .max = _max, \ + .get = _get, \ + .set = _set, \ + .mulf = _mulf, \ + .divf = _divf, \ +} + +#define __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) \ +static const struct ide_devset ide_devset_##_name = \ + __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) + +#define IDE_DEVSET(_name, _flags, _min, _max, _get, _set) \ +__IDE_DEVSET(_name, _flags, _min, _max, _get, _set, NULL, NULL) + +#define ide_devset_rw_nolock(_name, _min, _max, _func) \ +IDE_DEVSET(_name, S_RW | S_NOLOCK, _min, _max, get_##_func, set_##_func) + +#define ide_devset_w_nolock(_name, _min, _max, _func) \ +IDE_DEVSET(_name, S_WRITE | S_NOLOCK, _min, _max, NULL, set_##_func) + +#define ide_devset_rw(_name, _min, _max, _field) \ +static ide_devset_get(_name, _field); \ +static ide_devset_set(_name, _field); \ +IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name) + +#define ide_devset_r(_name, _min, _max, _field) \ +ide_devset_get(_name, _field) \ +IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL) /* * /proc/ide interface @@ -801,8 +841,6 @@ void ide_proc_unregister_port(ide_hwif_t *); void ide_proc_register_driver(ide_drive_t *, ide_driver_t *); void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *); -void ide_add_generic_settings(ide_drive_t *); - read_proc_t proc_ide_read_capacity; read_proc_t proc_ide_read_geometry; @@ -830,7 +868,6 @@ static inline void ide_proc_unregister_device(ide_drive_t *drive) { ; } static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; } static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } -static inline void ide_add_generic_settings(ide_drive_t *drive) { ; } #define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; #endif @@ -887,6 +924,7 @@ struct ide_driver_s { void (*shutdown)(ide_drive_t *); #ifdef CONFIG_IDE_PROC_FS ide_proc_entry_t *proc; + const struct ide_devset **settings; #endif }; -- cgit v1.2.3 From 151a670186a0f8441798f90c8701647adb7a1589 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:28 +0200 Subject: ide: remove SECTOR_WORDS define Just use SECTOR_SIZE instead. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 4667ec8aeeb..4444b0884e5 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -126,7 +126,7 @@ struct ide_io_ports { #define PARTN_BITS 6 /* number of minor dev bits for partitions */ #define MAX_DRIVES 2 /* per interface; 2 assumed by lots of code */ #define SECTOR_SIZE 512 -#define SECTOR_WORDS (SECTOR_SIZE / 4) /* number of 32bit words per sector */ + #define IDE_LARGE_SEEK(b1,b2,t) (((b1) > (b2) + (t)) || ((b2) > (b1) + (t))) /* -- cgit v1.2.3 From ebc6be520673f65aef188abde43972f9cd2162e9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:29 +0200 Subject: ide: remove read-only ->atapi_overlap field from ide_drive_t Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 4444b0884e5..9cb935f2e7c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -415,7 +415,6 @@ struct ide_drive_s { unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ unsigned no_unmask : 1; /* disallow setting unmask bit */ unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ - unsigned atapi_overlap : 1; /* ATAPI overlap (not supported) */ unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ unsigned nodma : 1; /* disallow DMA */ unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ -- cgit v1.2.3 From 02d599a365d04658bc9ea71762ed17c895079927 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:29 +0200 Subject: ide: remove ->supports_dsc_overlap field from ide_driver_t * Use drive->media and drive->scsi to check if ->dsc_overlap can be set by HDIO_SET_NICE ioctl in generic_ide_ioctl(). * Remove unused ->supports_dsc_overlap field from ide_driver_t. There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 9cb935f2e7c..e5622bb5a4a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -912,7 +912,6 @@ enum { struct ide_driver_s { const char *version; u8 media; - unsigned supports_dsc_overlap : 1; ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t); int (*end_request)(ide_drive_t *, int, int); ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); -- cgit v1.2.3 From 5d5870f0a26e2304c4a82592870c5bc88017f7c9 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:29 +0200 Subject: ide: ide_dev_has_iordy() -> ata_id_has_iordy() * Remove (id[ATA_ID_FIELD_VALID] & 2) check from ide_dev_has_iordy() (it is for validity of words 64-70, IORDY is in word 49). * ide_dev_has_iordy() -> ata_id_has_iordy() Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index e5622bb5a4a..27829c13bef 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1382,11 +1382,6 @@ const char *ide_xfer_verbose(u8 mode); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); -static inline int ide_dev_has_iordy(u16 *id) -{ - return ((id[ATA_ID_FIELD_VALID] & 2) && ata_id_has_iordy(id)) ? 1 : 0; -} - static inline int ide_dev_is_sata(u16 *id) { /* -- cgit v1.2.3 From 367d7e78dd48cf6ad35182a99d97abb5486e040e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:30 +0200 Subject: ide: ide_dev_is_sata() -> ata_id_is_sata() * Use optimized ATA version check from Sergei in ata_id_is_sata(). * ide_dev_is_sata() -> ata_id_is_sata() Cc: Jeff Garzik Cc: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 10 +++++++++- include/linux/ide.h | 13 ------------- 2 files changed, 9 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index be00973d1a8..d28aad991c7 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -645,7 +645,15 @@ static inline unsigned int ata_id_major_version(const u16 *id) static inline int ata_id_is_sata(const u16 *id) { - return ata_id_major_version(id) >= 5 && id[ATA_ID_HW_CONFIG] == 0; + /* + * See if word 93 is 0 AND drive is at least ATA-5 compatible + * verifying that word 80 by casting it to a signed type -- + * this trick allows us to filter out the reserved values of + * 0x0000 and 0xffff along with the earlier ATA revisions... + */ + if (id[ATA_ID_HW_CONFIG] == 0 && (short)id[ATA_ID_MAJOR_VER] >= 0x0020) + return 1; + return 0; } static inline int ata_id_has_tpm(const u16 *id) diff --git a/include/linux/ide.h b/include/linux/ide.h index 27829c13bef..87b5b5d3953 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1382,19 +1382,6 @@ const char *ide_xfer_verbose(u8 mode); extern void ide_toggle_bounce(ide_drive_t *drive, int on); extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); -static inline int ide_dev_is_sata(u16 *id) -{ - /* - * See if word 93 is 0 AND drive is at least ATA-5 compatible - * verifying that word 80 by casting it to a signed type -- - * this trick allows us to filter out the reserved values of - * 0x0000 and 0xffff along with the earlier ATA revisions... - */ - if (id[ATA_ID_HW_CONFIG] == 0 && (short)id[ATA_ID_MAJOR_VER] >= 0x0020) - return 1; - return 0; -} - u64 ide_get_lba_addr(struct ide_taskfile *, int); u8 ide_dump_status(ide_drive_t *, const char *, u8); -- cgit v1.2.3 From 942dcd85bf8edf38cdc3745306ca250684d99a61 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:30 +0200 Subject: ide: idedisk_supports_lba48() -> ata_id_lba48_enabled() * Add ata_id_lba48_enabled() inline helper to . * idedisk_supports_lba48() -> ata_id_lba48_enabled() The latter one also checks validity of words 83 & 86. Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index d28aad991c7..8162257b474 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -574,6 +574,15 @@ static inline int ata_id_has_lba48(const u16 *id) return id[ATA_ID_COMMAND_SET_2] & (1 << 10); } +static inline int ata_id_lba48_enabled(const u16 *id) +{ + if (ata_id_has_lba48(id) == 0) + return 0; + if ((id[ATA_ID_CSF_DEFAULT] & 0xC000) != 0x4000) + return 0; + return id[ATA_ID_CFS_ENABLE_2] & (1 << 10); +} + static inline int ata_id_hpa_enabled(const u16 *id) { /* Yes children, word 83 valid bits cover word 82 data */ -- cgit v1.2.3 From 1a4e4d4d2cceb72be70526a485914abd638c7de1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:30 +0200 Subject: ide: check only for CACHE FLUSH command support in ide_id_has_flush_cache() All devices supporting CACHE FLUSH EXT command should also support CACHE FLUSH command so it is sufficient to check only for CACHE FLUSH in ide_id_has_flush_cache(). Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 87b5b5d3953..6e22cd20dd8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1453,8 +1453,8 @@ extern struct mutex ide_cfg_mtx; extern struct bus_type ide_bus_type; extern struct class *ide_port_class; -/* check if CACHE FLUSH (EXT) command is supported (bits defined in ATA-6) */ -#define ide_id_has_flush_cache(id) ((id)[ATA_ID_CFS_ENABLE_2] & 0x3000) +/* check if CACHE FLUSH command is supported (as defined in ATA-6) */ +#define ide_id_has_flush_cache(id) ((id)[ATA_ID_CFS_ENABLE_2] & 0x1000) /* some Maxtor disks have bit 13 defined incorrectly so check bit 10 too */ #define ide_id_has_flush_cache_ext(id) \ -- cgit v1.2.3 From 4b58f17d7c45a8e5f4acda641bec388398b9c0fa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:30 +0200 Subject: ide: ide_id_has_flush_cache() -> ata_id_flush_enabled() * Add ata_id_flush_enabled() inline helper to . * ide_id_has_flush_cache() -> ata_id_flush_enabled() The latter one also checks if the command is marked as supported in word 83 and validity of words 83 & 86. Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 9 +++++++++ include/linux/ide.h | 3 --- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 8162257b474..921cf0fc337 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -558,6 +558,15 @@ static inline int ata_id_has_flush(const u16 *id) return id[ATA_ID_COMMAND_SET_2] & (1 << 12); } +static inline int ata_id_flush_enabled(const u16 *id) +{ + if (ata_id_has_flush(id) == 0) + return 0; + if ((id[ATA_ID_CSF_DEFAULT] & 0xC000) != 0x4000) + return 0; + return id[ATA_ID_CFS_ENABLE_2] & (1 << 12); +} + static inline int ata_id_has_flush_ext(const u16 *id) { if ((id[ATA_ID_COMMAND_SET_2] & 0xC000) != 0x4000) diff --git a/include/linux/ide.h b/include/linux/ide.h index 6e22cd20dd8..d2213d7cc4c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1453,9 +1453,6 @@ extern struct mutex ide_cfg_mtx; extern struct bus_type ide_bus_type; extern struct class *ide_port_class; -/* check if CACHE FLUSH command is supported (as defined in ATA-6) */ -#define ide_id_has_flush_cache(id) ((id)[ATA_ID_CFS_ENABLE_2] & 0x1000) - /* some Maxtor disks have bit 13 defined incorrectly so check bit 10 too */ #define ide_id_has_flush_cache_ext(id) \ (((id)[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400) -- cgit v1.2.3 From ff2779b568e70822e0ef2cc7afeeefbe7c607652 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:31 +0200 Subject: ide: ide_id_has_flush_cache_ext() -> ata_id_flush_ext_enabled() * Add ata_id_flush_ext_enabled() inline helper to . * ide_id_has_flush_cache_ext() -> ata_id_flush_ext_enabled() The latter one also checks if the command is marked as supported in word 83 and validity of words 83 & 86. Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 13 +++++++++++++ include/linux/ide.h | 4 ---- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 921cf0fc337..81d9adeb819 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -574,6 +574,19 @@ static inline int ata_id_has_flush_ext(const u16 *id) return id[ATA_ID_COMMAND_SET_2] & (1 << 13); } +static inline int ata_id_flush_ext_enabled(const u16 *id) +{ + if (ata_id_has_flush_ext(id) == 0) + return 0; + if ((id[ATA_ID_CSF_DEFAULT] & 0xC000) != 0x4000) + return 0; + /* + * some Maxtor disks have bit 13 defined incorrectly + * so check bit 10 too + */ + return (id[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400; +} + static inline int ata_id_has_lba48(const u16 *id) { if ((id[ATA_ID_COMMAND_SET_2] & 0xC000) != 0x4000) diff --git a/include/linux/ide.h b/include/linux/ide.h index d2213d7cc4c..432eb98f7fe 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1453,10 +1453,6 @@ extern struct mutex ide_cfg_mtx; extern struct bus_type ide_bus_type; extern struct class *ide_port_class; -/* some Maxtor disks have bit 13 defined incorrectly so check bit 10 too */ -#define ide_id_has_flush_cache_ext(id) \ - (((id)[ATA_ID_CFS_ENABLE_2] & 0x2400) == 0x2400) - static inline void ide_dump_identify(u8 *id) { print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 2, id, 512, 0); -- cgit v1.2.3 From 93734a234447a3c091f76d76f7351af9d4dde518 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:31 +0200 Subject: ide: ide_id_to_hd_driveid() -> ata_id_to_hd_driveid() Rename ide_id_to_hd_driveid() to ata_id_to_hd_driveid() and move it to . Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 81d9adeb819..4c3f5007003 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -30,6 +30,7 @@ #define __LINUX_ATA_H__ #include +#include /* defines only for the constants which don't work well as enums */ #define ATA_DMA_BOUNDARY 0xffffUL @@ -781,6 +782,26 @@ static inline int atapi_id_dmadir(const u16 *dev_id) return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000); } +static inline void ata_id_to_hd_driveid(u16 *id) +{ +#ifdef __BIG_ENDIAN + /* accessed in struct hd_driveid as 8-bit values */ + id[ATA_ID_MAX_MULTSECT] = __cpu_to_le16(id[ATA_ID_MAX_MULTSECT]); + id[ATA_ID_CAPABILITY] = __cpu_to_le16(id[ATA_ID_CAPABILITY]); + id[ATA_ID_OLD_PIO_MODES] = __cpu_to_le16(id[ATA_ID_OLD_PIO_MODES]); + id[ATA_ID_OLD_DMA_MODES] = __cpu_to_le16(id[ATA_ID_OLD_DMA_MODES]); + id[ATA_ID_MULTSECT] = __cpu_to_le16(id[ATA_ID_MULTSECT]); + + /* as 32-bit values */ + *(u32 *)&id[ATA_ID_LBA_CAPACITY] = ata_id_u32(id, ATA_ID_LBA_CAPACITY); + *(u32 *)&id[ATA_ID_SPG] = ata_id_u32(id, ATA_ID_SPG); + + /* as 64-bit value */ + *(u64 *)&id[ATA_ID_LBA_CAPACITY_2] = + ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); +#endif +} + static inline int is_multi_taskfile(struct ata_taskfile *tf) { return (tf->command == ATA_CMD_READ_MULTI) || -- cgit v1.2.3 From a02227c9774b3bff08c7f557d06247e0a03ac435 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:31 +0200 Subject: ide: lba_capacity_is_ok() -> ata_id_is_lba_capacity_ok() Rename lba_capacity_is_ok() to ata_id_is_lba_capacity_ok() and move it to (remove needless parens while at it). Cc: Jeff Garzik Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ata.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 4c3f5007003..a53318b8cbd 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -782,6 +782,56 @@ static inline int atapi_id_dmadir(const u16 *dev_id) return ata_id_major_version(dev_id) >= 7 && (dev_id[62] & 0x8000); } +/* + * ata_id_is_lba_capacity_ok() performs a sanity check on + * the claimed LBA capacity value for the device. + * + * Returns 1 if LBA capacity looks sensible, 0 otherwise. + * + * It is called only once for each device. + */ +static inline int ata_id_is_lba_capacity_ok(u16 *id) +{ + unsigned long lba_sects, chs_sects, head, tail; + + /* No non-LBA info .. so valid! */ + if (id[ATA_ID_CYLS] == 0) + return 1; + + lba_sects = ata_id_u32(id, ATA_ID_LBA_CAPACITY); + + /* + * The ATA spec tells large drives to return + * C/H/S = 16383/16/63 independent of their size. + * Some drives can be jumpered to use 15 heads instead of 16. + * Some drives can be jumpered to use 4092 cyls instead of 16383. + */ + if ((id[ATA_ID_CYLS] == 16383 || + (id[ATA_ID_CYLS] == 4092 && id[ATA_ID_CUR_CYLS] == 16383)) && + id[ATA_ID_SECTORS] == 63 && + (id[ATA_ID_HEADS] == 15 || id[ATA_ID_HEADS] == 16) && + (lba_sects >= 16383 * 63 * id[ATA_ID_HEADS])) + return 1; + + chs_sects = id[ATA_ID_CYLS] * id[ATA_ID_HEADS] * id[ATA_ID_SECTORS]; + + /* perform a rough sanity check on lba_sects: within 10% is OK */ + if (lba_sects - chs_sects < chs_sects/10) + return 1; + + /* some drives have the word order reversed */ + head = (lba_sects >> 16) & 0xffff; + tail = lba_sects & 0xffff; + lba_sects = head | (tail << 16); + + if (lba_sects - chs_sects < chs_sects/10) { + *(__le32 *)&id[ATA_ID_LBA_CAPACITY] = __cpu_to_le32(lba_sects); + return 1; /* LBA capacity is (now) good */ + } + + return 0; /* LBA capacity value may be bad */ +} + static inline void ata_id_to_hd_driveid(u16 *id) { #ifdef __BIG_ENDIAN -- cgit v1.2.3 From feb22b7f8e62b1b987a3a1dbad95af767a1df832 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:32 +0200 Subject: ide: add proper PCI PM support (v2) * Keep pointer to ->init_chipset method also in struct ide_host and set it in ide_host_alloc_all(). * Add ide_pci_suspend() and ide_pci_resume() helpers (default ->suspend and ->resume implementations). * ->init_chipset can no longer be marked __devinit. * Add proper PCI PM support to IDE PCI host drivers (rz1000.c and tc86c001.c are skipped for now since they need to be converted from using ->init_hwif to use ->init_chipset instead). v2: * Cleanup CONFIG_PM #ifdef-s per akpm's suggestion. Cc: Andrew Morton Cc: "Rafael J. Wysocki" Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 432eb98f7fe..2c5d83ddaef 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -17,6 +17,7 @@ #include #include #include +#include #ifdef CONFIG_BLK_DEV_IDEACPI #include #endif @@ -639,6 +640,7 @@ struct ide_host { ide_hwif_t *ports[MAX_HWIFS]; unsigned int n_ports; struct device *dev[2]; + unsigned int (*init_chipset)(struct pci_dev *); unsigned long host_flags; void *host_priv; }; @@ -1264,6 +1266,14 @@ int ide_pci_init_two(struct pci_dev *, struct pci_dev *, const struct ide_port_info *, void *); void ide_pci_remove(struct pci_dev *); +#ifdef CONFIG_PM +int ide_pci_suspend(struct pci_dev *, pm_message_t); +int ide_pci_resume(struct pci_dev *); +#else +#define ide_pci_suspend NULL +#define ide_pci_resume NULL +#endif + void ide_map_sg(ide_drive_t *, struct request *); void ide_init_sg_cmd(ide_drive_t *, struct request *); -- cgit v1.2.3 From 9232c14bff36d65de254f34386c00b732c5b6099 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:33 +0200 Subject: ide: remove ->bus_state field from ide_hwif_t It is always set to BUSSTATE_ON. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 2c5d83ddaef..42f39781af8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -562,7 +562,6 @@ typedef struct hwif_s { u8 major; /* our major number */ u8 index; /* 0 for ide0; 1 for ide1; ... */ u8 channel; /* for dual-port chips: 0=primary, 1=secondary */ - u8 bus_state; /* power state of the IDE bus */ u32 host_flags; -- cgit v1.2.3 From aa7687738af3332470e02ac1060f6c046d83c9a3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:33 +0200 Subject: ide: add ide_setting_ioctl() helper * Add struct ide_ioctl_devset representing ioctl device setting. * Add ide_setting_ioctl() helper for matching given ioctl and its parameters against table of ioctl device settings. * Convert ide_setting_ioctl() and idedisk_ioctl() to use ide_setting_ioctl(). * Un-export ide_setting_mtx. While at it: * {get,set}_lba_addressing() -> {get,set}_addressing() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 42f39781af8..64624b9b645 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -932,7 +932,19 @@ struct ide_driver_s { int ide_device_get(ide_drive_t *); void ide_device_put(ide_drive_t *); -int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, unsigned, unsigned long); +struct ide_ioctl_devset { + unsigned int get_ioctl; + unsigned int set_ioctl; + + int (*get)(ide_drive_t *); + int (*set)(ide_drive_t *, int); +}; + +int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, + unsigned long, const struct ide_ioctl_devset *); + +int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, + unsigned, unsigned long); extern int ide_vlb_clk; extern int ide_pci_clk; -- cgit v1.2.3 From 05236ea6df7419f0f37cf9603cfee265cfce5832 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:33 +0200 Subject: ide: move ioctls handling to ide-ioctls.c * Move ioctls handling to ide-ioctls.c (except HDIO_DRIVE_TASKFILE for now). * Make ide_{cmd,task}() static. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 64624b9b645..40102bd50a7 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1128,8 +1128,6 @@ int ide_raw_taskfile(ide_drive_t *, ide_task_t *, u8 *, u16); int ide_no_data_taskfile(ide_drive_t *, ide_task_t *); int ide_taskfile_ioctl(ide_drive_t *, unsigned int, unsigned long); -int ide_cmd_ioctl(ide_drive_t *, unsigned int, unsigned long); -int ide_task_ioctl(ide_drive_t *, unsigned int, unsigned long); extern int ide_driveid_update(ide_drive_t *); extern int ide_config_drive_speed(ide_drive_t *, u8); -- cgit v1.2.3 From 51509eec34debffec3c6f481f7371c9aeb6c63c1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:34 +0200 Subject: ide: add ide_check_atapi_device() helper * Add ide_check_atapi_device() to ide-atapi.c and convert ide-{floppy,tape}.c to use it instead of ide*_identify_device(). While at it: * Add DRV_NAME defines to ide-{floppy,tape}.c. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 40102bd50a7..e63ff63d1f0 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1109,6 +1109,8 @@ extern int drive_is_ready(ide_drive_t *); void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); +int ide_check_atapi_device(ide_drive_t *, const char *); + ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), -- cgit v1.2.3 From acaa0f5f675ccf6b8a3a11a933419068b1ea1f46 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:36 +0200 Subject: ide: add ide_io_buffers() helper * Make ->io_buffers method return number of bytes transferred. * Use ide_end_request() instead of idefloppy_end_request() in ide_floppy_io_buffers() and then move the call out to ide_pc_intr(). * Add ide_io_buffers() helper and convert ide-{floppy,scsi}.c to use it instead of ide*_io_buffers(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index e63ff63d1f0..03dc2157a2b 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1099,6 +1099,8 @@ void ide_tf_read(ide_drive_t *, ide_task_t *); void ide_input_data(ide_drive_t *, struct request *, void *, unsigned int); void ide_output_data(ide_drive_t *, struct request *, void *, unsigned int); +int ide_io_buffers(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int); + extern void SELECT_DRIVE(ide_drive_t *); void SELECT_MASK(ide_drive_t *, int); @@ -1115,7 +1117,7 @@ ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), - void (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, + int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, ide_handler_t *, unsigned int, ide_expiry_t *); -- cgit v1.2.3 From 7bf7420a318978cd6042e5a5da34b7cfa18ae559 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:37 +0200 Subject: ide: add ide_init_pc() helper * Add IDE_PC_BUFFER_SIZE define. * Add ide_init_pc() and convert ide-{floppy,tape}.c to use it instead of ide*_init_pc(). * Remove no longer used IDE*_PC_BUFFER_SIZE and ide*_init_pc(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 03dc2157a2b..bba2f73b99a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -724,6 +724,12 @@ enum { PC_FLAG_TIMEDOUT = (1 << 7), }; +/* + * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. + * This is used for several packet commands (not for READ/WRITE commands). + */ +#define IDE_PC_BUFFER_SIZE 256 + struct ide_atapi_pc { /* actual packet bytes */ u8 c[12]; @@ -753,7 +759,7 @@ struct ide_atapi_pc { * those are more or less driver-specific and some of them are subject * to change/removal later. */ - u8 pc_buf[256]; + u8 pc_buf[IDE_PC_BUFFER_SIZE]; /* idetape only */ struct idetape_bh *bh; @@ -1113,6 +1119,8 @@ void ide_pktcmd_tf_load(ide_drive_t *, u32, u16, u8); int ide_check_atapi_device(ide_drive_t *, const char *); +void ide_init_pc(struct ide_atapi_pc *); + ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), -- cgit v1.2.3 From 7645c1514c7d34ebdf3ea0e8ee3a935c08abceb2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:37 +0200 Subject: ide: add ide_queue_pc_head() helper * Move REQ_IDETAPE_* enums to . * Add ide_queue_pc_head() and convert ide-{floppy,tape}.c to use it instead of ide*_queue_pc_head(). * Remove no longer used ide*_queue_pc_head(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index bba2f73b99a..1bd49784e4d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1121,6 +1121,22 @@ int ide_check_atapi_device(ide_drive_t *, const char *); void ide_init_pc(struct ide_atapi_pc *); +/* + * Special requests for ide-tape block device strategy routine. + * + * In order to service a character device command, we add special requests to + * the tail of our block device request queue and wait for their completion. + */ +enum { + REQ_IDETAPE_PC1 = (1 << 0), /* packet command (first stage) */ + REQ_IDETAPE_PC2 = (1 << 1), /* packet command (second stage) */ + REQ_IDETAPE_READ = (1 << 2), + REQ_IDETAPE_WRITE = (1 << 3), +}; + +void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, + struct request *); + ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), -- cgit v1.2.3 From 2ac07d920604eeee8966d52e70161f9b31fe90a3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:38 +0200 Subject: ide: add ide_queue_pc_tail() helper * Add ide_queue_pc_tail() and convert ide-{floppy,tape}.c to use it instead of ide*_queue_pc_tail(). * Remove no longer used ide*_queue_pc_tail(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 1bd49784e4d..b5be2368c96 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1136,6 +1136,7 @@ enum { void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, struct request *); +int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, -- cgit v1.2.3 From 49cac39e71bd6bbcf934c6ba837e21503902c088 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:38 +0200 Subject: ide-floppy: ->{srfp,wp} -> IDE_AFLAG_{SRFP,WP} Add IDE_AFLAG_{SRFP,WP} drive->atapi_flags and use them instead of ->{srfp,wp} struct ide_floppy_obj fields. There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index b5be2368c96..cc41a885688 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -356,21 +356,25 @@ enum { IDE_AFLAG_CLIK_DRIVE = (1 << 19), /* Requires BH algorithm for packets */ IDE_AFLAG_ZIP_DRIVE = (1 << 20), + /* Write protect */ + IDE_AFLAG_WP = (1 << 21), + /* Supports format progress report */ + IDE_AFLAG_SRFP = (1 << 22), /* ide-tape */ - IDE_AFLAG_IGNORE_DSC = (1 << 21), + IDE_AFLAG_IGNORE_DSC = (1 << 23), /* 0 When the tape position is unknown */ - IDE_AFLAG_ADDRESS_VALID = (1 << 22), + IDE_AFLAG_ADDRESS_VALID = (1 << 24), /* Device already opened */ - IDE_AFLAG_BUSY = (1 << 23), + IDE_AFLAG_BUSY = (1 << 25), /* Attempt to auto-detect the current user block size */ - IDE_AFLAG_DETECT_BS = (1 << 24), + IDE_AFLAG_DETECT_BS = (1 << 26), /* Currently on a filemark */ - IDE_AFLAG_FILEMARK = (1 << 25), + IDE_AFLAG_FILEMARK = (1 << 27), /* 0 = no tape is loaded, so we don't rewind after ejecting */ - IDE_AFLAG_MEDIUM_PRESENT = (1 << 26), + IDE_AFLAG_MEDIUM_PRESENT = (1 << 28), - IDE_AFLAG_NO_AUTOCLOSE = (1 << 27), + IDE_AFLAG_NO_AUTOCLOSE = (1 << 29), }; struct ide_drive_s { -- cgit v1.2.3 From 0578042db3191e1ac76b53d213f2a691c3e1eaed Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:38 +0200 Subject: ide: add ide_set_media_lock() helper * Set IDE_AFLAG_NO_DOORLOCK in idetape_get_mode_sense_result(), check it in ide_tape_set_media_lock() and cleanup idetape_create_prevent_cmd(). * Set IDE_AFLAG_NO_DOORLOCK in ide_floppy_create_read_capacity_cmd() and check it instead of IDE_AFLAG_CLIK_DRIVE in ide_floppy_set_media_lock(). * Add ide_set_media_lock() helper and convert ide-{floppy,tape}.c to use it. * Remove no longer used ide*_create_prevent_cmd()/ide*_set_media_lock(). * Update comment in accordingly. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index cc41a885688..ac067a3c1be 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -317,10 +317,10 @@ struct ide_acpi_hwif_link; enum { IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), IDE_AFLAG_MEDIA_CHANGED = (1 << 1), - - /* ide-cd */ /* Drive cannot lock the door. */ IDE_AFLAG_NO_DOORLOCK = (1 << 2), + + /* ide-cd */ /* Drive cannot eject the disc. */ IDE_AFLAG_NO_EJECT = (1 << 3), /* Drive is a pre ATAPI 1.2 drive. */ @@ -1142,6 +1142,8 @@ void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, struct request *); int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); +int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); + ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), -- cgit v1.2.3 From 0c8a6c7aead1d3be85ce53e3aaacd52e38ede03e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:39 +0200 Subject: ide: add ide_do_start_stop() helper * Add ide_do_start_stop() helper and convert ide-{floppy,tape}.c to use it. * Remove no longer used idefloppy_create_start_stop_cmd() and idetape_create_load_unload_cmd(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ac067a3c1be..be79122b943 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1142,6 +1142,7 @@ void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, struct request *); int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); +int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, -- cgit v1.2.3 From de699ad595fb45022d1b049ed91ffd06fdd16c13 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:39 +0200 Subject: ide: add ide_do_test_unit_ready() helper * Add ide_do_test_unit_ready() helper and convert ide-{floppy,tape}.c to use it. * Remove no longer used idetape_create_test_unit_ready_cmd(). There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index be79122b943..55098eed3b2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1142,6 +1142,7 @@ void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, struct request *); int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); +int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); -- cgit v1.2.3 From d6e2955a6b82d2312b5ff885ce13c8ab54d59d96 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 10 Oct 2008 22:39:39 +0200 Subject: ide: move IDE{FLOPPY,TAPE}_WAIT_CMD defines to While at it: * IDE{FLOPPY,TAPE}_WAIT_CMD -> WAIT_{FLOPPY,TAPE}_CMD * Use enum for WAIT_* defines. There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 55098eed3b2..a9eced25acc 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -133,12 +133,28 @@ struct ide_io_ports { /* * Timeouts for various operations: */ -#define WAIT_DRQ (HZ/10) /* 100msec - spec allows up to 20ms */ -#define WAIT_READY (5*HZ) /* 5sec - some laptops are very slow */ -#define WAIT_PIDENTIFY (10*HZ) /* 10sec - should be less than 3ms (?), if all ATAPI CD is closed at boot */ -#define WAIT_WORSTCASE (30*HZ) /* 30sec - worst case when spinning up */ -#define WAIT_CMD (10*HZ) /* 10sec - maximum wait for an IRQ to happen */ -#define WAIT_MIN_SLEEP (2*HZ/100) /* 20msec - minimum sleep time */ +enum { + /* spec allows up to 20ms */ + WAIT_DRQ = HZ / 10, /* 100ms */ + /* some laptops are very slow */ + WAIT_READY = 5 * HZ, /* 5s */ + /* should be less than 3ms (?), if all ATAPI CD is closed at boot */ + WAIT_PIDENTIFY = 10 * HZ, /* 10s */ + /* worst case when spinning up */ + WAIT_WORSTCASE = 30 * HZ, /* 30s */ + /* maximum wait for an IRQ to happen */ + WAIT_CMD = 10 * HZ, /* 10s */ + /* Some drives require a longer IRQ timeout. */ + WAIT_FLOPPY_CMD = 50 * HZ, /* 50s */ + /* + * Some drives (for example, Seagate STT3401A Travan) require a very + * long timeout, because they don't return an interrupt or clear their + * BSY bit until after the command completes (even retension commands). + */ + WAIT_TAPE_CMD = 900 * HZ, /* 900s */ + /* minimum sleep time */ + WAIT_MIN_SLEEP = HZ / 50, /* 20ms */ +}; /* * Op codes for special requests to be handled by ide_special_rq(). -- cgit v1.2.3 From 92f1f8fd8040e7b50a67a850a935509bb01201bb Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Fri, 10 Oct 2008 22:39:40 +0200 Subject: ide: Remove ide_spin_wait_hwgroup() and use special requests instead Use a special request for serialisation purposes and get rid of the awkward ide_spin_wait_hwgroup(). This also involves converting the ide_devset structure so it can be shared by the /proc and the ioctl code. Signed-off-by: Elias Oltmanns [bart: use rq->cmd[] directly] Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 138 +++++++++++++++++++++++++++------------------------- 1 file changed, 73 insertions(+), 65 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a9eced25acc..a9d82d6e6bd 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -161,6 +161,7 @@ enum { * Values should be in the range of 0x20 to 0x3f. */ #define REQ_DRIVE_RESET 0x20 +#define REQ_DEVSET_EXEC 0x21 /* * Check for an interrupt and acknowledge the interrupt status @@ -405,7 +406,7 @@ struct ide_drive_s { u16 *id; /* identification info */ #ifdef CONFIG_IDE_PROC_FS struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ - const struct ide_devset **settings; /* /proc/ide/ drive settings */ + const struct ide_proc_devset *settings; /* /proc/ide/ drive settings */ #endif struct hwif_s *hwif; /* actually (ide_hwif_t *) */ @@ -707,29 +708,62 @@ typedef struct ide_driver_s ide_driver_t; extern struct mutex ide_setting_mtx; -int get_io_32bit(ide_drive_t *); -int set_io_32bit(ide_drive_t *, int); -int get_ksettings(ide_drive_t *); -int set_ksettings(ide_drive_t *, int); -int set_pio_mode(ide_drive_t *, int); -int get_unmaskirq(ide_drive_t *); -int set_unmaskirq(ide_drive_t *, int); -int get_using_dma(ide_drive_t *); -int set_using_dma(ide_drive_t *, int); +/* + * configurable drive settings + */ + +#define DS_SYNC (1 << 0) + +struct ide_devset { + int (*get)(ide_drive_t *); + int (*set)(ide_drive_t *, int); + unsigned int flags; +}; + +#define __DEVSET(_flags, _get, _set) { \ + .flags = _flags, \ + .get = _get, \ + .set = _set, \ +} #define ide_devset_get(name, field) \ -int get_##name(ide_drive_t *drive) \ +static int get_##name(ide_drive_t *drive) \ { \ return drive->field; \ } #define ide_devset_set(name, field) \ -int set_##name(ide_drive_t *drive, int arg) \ +static int set_##name(ide_drive_t *drive, int arg) \ { \ drive->field = arg; \ return 0; \ } +#define __IDE_DEVSET(_name, _flags, _get, _set) \ +const struct ide_devset ide_devset_##_name = \ + __DEVSET(_flags, _get, _set) + +#define IDE_DEVSET(_name, _flags, _get, _set) \ +static __IDE_DEVSET(_name, _flags, _get, _set) + +#define ide_devset_rw(_name, _func) \ +IDE_DEVSET(_name, 0, get_##_func, set_##_func) + +#define ide_devset_w(_name, _func) \ +IDE_DEVSET(_name, 0, NULL, set_##_func) + +#define ide_devset_rw_sync(_name, _func) \ +IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) + +#define ide_decl_devset(_name) \ +extern const struct ide_devset ide_devset_##_name + +ide_decl_devset(io_32bit); +ide_decl_devset(keepsettings); +ide_decl_devset(pio_mode); +ide_decl_devset(unmaskirq); +ide_decl_devset(using_dma); + /* ATAPI packet command flags */ enum { /* set when an error is considered normal - no retry (ide-tape) */ @@ -797,60 +831,34 @@ struct ide_atapi_pc { #ifdef CONFIG_IDE_PROC_FS /* - * configurable drive settings + * /proc/ide interface */ -#define S_READ (1 << 0) -#define S_WRITE (1 << 1) -#define S_RW (S_READ | S_WRITE) -#define S_NOLOCK (1 << 2) - -struct ide_devset { - const char *name; - unsigned int flags; - int min, max; - int (*get)(ide_drive_t *); - int (*set)(ide_drive_t *, int); - int (*mulf)(ide_drive_t *); - int (*divf)(ide_drive_t *); +#define ide_devset_rw_field(_name, _field) \ +ide_devset_get(_name, _field); \ +ide_devset_set(_name, _field); \ +IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) + +struct ide_proc_devset { + const char *name; + const struct ide_devset *setting; + int min, max; + int (*mulf)(ide_drive_t *); + int (*divf)(ide_drive_t *); }; -#define __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) { \ - .name = __stringify(_name), \ - .flags = _flags, \ - .min = _min, \ - .max = _max, \ - .get = _get, \ - .set = _set, \ - .mulf = _mulf, \ - .divf = _divf, \ +#define __IDE_PROC_DEVSET(_name, _min, _max, _mulf, _divf) { \ + .name = __stringify(_name), \ + .setting = &ide_devset_##_name, \ + .min = _min, \ + .max = _max, \ + .mulf = _mulf, \ + .divf = _divf, \ } -#define __IDE_DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) \ -static const struct ide_devset ide_devset_##_name = \ - __DEVSET(_name, _flags, _min, _max, _get, _set, _mulf, _divf) - -#define IDE_DEVSET(_name, _flags, _min, _max, _get, _set) \ -__IDE_DEVSET(_name, _flags, _min, _max, _get, _set, NULL, NULL) - -#define ide_devset_rw_nolock(_name, _min, _max, _func) \ -IDE_DEVSET(_name, S_RW | S_NOLOCK, _min, _max, get_##_func, set_##_func) +#define IDE_PROC_DEVSET(_name, _min, _max) \ +__IDE_PROC_DEVSET(_name, _min, _max, NULL, NULL) -#define ide_devset_w_nolock(_name, _min, _max, _func) \ -IDE_DEVSET(_name, S_WRITE | S_NOLOCK, _min, _max, NULL, set_##_func) - -#define ide_devset_rw(_name, _min, _max, _field) \ -static ide_devset_get(_name, _field); \ -static ide_devset_set(_name, _field); \ -IDE_DEVSET(_name, S_RW, _min, _max, get_##_name, set_##_name) - -#define ide_devset_r(_name, _min, _max, _field) \ -ide_devset_get(_name, _field) \ -IDE_DEVSET(_name, S_READ, _min, _max, get_##_name, NULL) - -/* - * /proc/ide interface - */ typedef struct { const char *name; mode_t mode; @@ -948,8 +956,8 @@ struct ide_driver_s { void (*resume)(ide_drive_t *); void (*shutdown)(ide_drive_t *); #ifdef CONFIG_IDE_PROC_FS - ide_proc_entry_t *proc; - const struct ide_devset **settings; + ide_proc_entry_t *proc; + const struct ide_proc_devset *settings; #endif }; @@ -961,9 +969,7 @@ void ide_device_put(ide_drive_t *); struct ide_ioctl_devset { unsigned int get_ioctl; unsigned int set_ioctl; - - int (*get)(ide_drive_t *); - int (*set)(ide_drive_t *, int); + const struct ide_devset *setting; }; int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, @@ -1002,6 +1008,9 @@ int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long); extern ide_startstop_t ide_do_reset (ide_drive_t *); +extern int ide_devset_execute(ide_drive_t *drive, + const struct ide_devset *setting, int arg); + extern void ide_do_drive_cmd(ide_drive_t *, struct request *); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); @@ -1191,7 +1200,6 @@ extern int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout); extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout); -extern int ide_spin_wait_hwgroup(ide_drive_t *); extern void ide_timer_expiry(unsigned long); extern irqreturn_t ide_intr(int irq, void *dev_id); extern void do_ide_request(struct request_queue *); -- cgit v1.2.3 From 061b1bd394ca8628b7c24eb4658ba3535da4249a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 24 Sep 2008 14:46:44 -0700 Subject: Staging: add TAINT_CRAP for all drivers/staging code We need to add a flag for all code that is in the drivers/staging/ directory to prevent all other kernel developers from worrying about issues here, and to notify users that the drivers might not be as good as they are normally used to. Based on code from Andreas Gruenbacher and Jeff Mahoney to provide a TAINT flag for the support level of a kernel module in the Novell enterprise kernel release. This is the kernel portion of this feature, the ability for the flag to be set needs to be done in the build process and will happen in a follow-up patch. Cc: Andreas Gruenbacher Cc: Jeff Mahoney Signed-off-by: Greg Kroah-Hartman --- include/linux/kernel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2651f805ba6..b36805cb95f 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -260,6 +260,7 @@ extern enum system_states { #define TAINT_DIE (1<<7) #define TAINT_OVERRIDDEN_ACPI_TABLE (1<<8) #define TAINT_WARN (1<<9) +#define TAINT_CRAP (1<<10) extern void dump_stack(void) __cold; -- cgit v1.2.3 From 44519faf22ad6ce924ad0352d3dc200d9e0b66e8 Mon Sep 17 00:00:00 2001 From: Hidehiro Kawai Date: Fri, 10 Oct 2008 20:29:13 -0400 Subject: jbd2: fix error handling for checkpoint io When a checkpointing IO fails, current JBD2 code doesn't check the error and continue journaling. This means latest metadata can be lost from both the journal and filesystem. This patch leaves the failed metadata blocks in the journal space and aborts journaling in the case of jbd2_log_do_checkpoint(). To achieve this, we need to do: 1. don't remove the failed buffer from the checkpoint list where in the case of __try_to_free_cp_buf() because it may be released or overwritten by a later transaction 2. jbd2_log_do_checkpoint() is the last chance, remove the failed buffer from the checkpoint list and abort the journal 3. when checkpointing fails, don't update the journal super block to prevent the journaled contents from being cleaned. For safety, don't update j_tail and j_tail_sequence either 4. when checkpointing fails, notify this error to the ext4 layer so that ext4 don't clear the needs_recovery flag, otherwise the journaled contents are ignored and cleaned in the recovery phase 5. if the recovery fails, keep the needs_recovery flag 6. prevent jbd2_cleanup_journal_tail() from being called between __jbd2_journal_drop_transaction() and jbd2_journal_abort() (a possible race issue between jbd2_log_do_checkpoint()s called by jbd2_journal_flush() and __jbd2_log_wait_for_space()) Signed-off-by: Hidehiro Kawai Signed-off-by: Theodore Ts'o --- include/linux/jbd2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 66c3499478b..c9e7d781db3 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -1060,7 +1060,7 @@ extern void jbd2_journal_clear_features (journal_t *, unsigned long, unsigned long, unsigned long); extern int jbd2_journal_create (journal_t *); extern int jbd2_journal_load (journal_t *journal); -extern void jbd2_journal_destroy (journal_t *); +extern int jbd2_journal_destroy (journal_t *); extern int jbd2_journal_recover (journal_t *journal); extern int jbd2_journal_wipe (journal_t *, int); extern int jbd2_journal_skip_recovery (journal_t *); -- cgit v1.2.3 From 5bf5683a33f3584da6eced480967c4f7e11515a8 Mon Sep 17 00:00:00 2001 From: Hidehiro Kawai Date: Fri, 10 Oct 2008 22:12:43 -0400 Subject: ext4: add an option to control error handling on file data If the journal doesn't abort when it gets an IO error in file data blocks, the file data corruption will spread silently. Because most of applications and commands do buffered writes without fsync(), they don't notice the IO error. It's scary for mission critical systems. On the other hand, if the journal aborts whenever it gets an IO error in file data blocks, the system will easily become inoperable. So this patch introduces a filesystem option to determine whether it aborts the journal or just call printk() when it gets an IO error in file data. If you mount an ext4 fs with data_err=abort option, it aborts on file data write error. If you mount it with data_err=ignore, it doesn't abort, just call printk(). data_err=ignore is the default. Here is the corresponding patch of the ext3 version: http://kerneltrap.org/mailarchive/linux-kernel/2008/9/9/3239374 Signed-off-by: Hidehiro Kawai Signed-off-by: Theodore Ts'o --- include/linux/jbd2.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index c9e7d781db3..d2e91ea998f 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -967,6 +967,9 @@ struct journal_s #define JBD2_FLUSHED 0x008 /* The journal superblock has been flushed */ #define JBD2_LOADED 0x010 /* The journal superblock has been loaded */ #define JBD2_BARRIER 0x020 /* Use IDE barriers */ +#define JBD2_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file + * data write error in ordered + * mode */ /* * Function declarations for the journaling transaction and buffer -- cgit v1.2.3 From f9da8d157b60d8c5bfc5a21fc50538fdb754a65b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Fri, 10 Oct 2008 23:14:14 -0400 Subject: Input: move map_to_7segment.h to include/linux The map_to_7segment.h provides generic 7segment LED mappings and is designed to be used by other drivers. Moving it to common area will make it more usable. Also exporting it to userspace will help users of sysfs interface. Signed-off-by: Atsushi Nemoto Acked-by: Henk Vergonet Signed-off-by: Dmitry Torokhov --- include/linux/Kbuild | 1 + include/linux/map_to_7segment.h | 187 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 include/linux/map_to_7segment.h (limited to 'include/linux') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 4c4142c5aa6..0b136c5990c 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -106,6 +106,7 @@ header-y += keyctl.h header-y += limits.h header-y += magic.h header-y += major.h +header-y += map_to_7segment.h header-y += matroxfb.h header-y += meye.h header-y += minix_fs.h diff --git a/include/linux/map_to_7segment.h b/include/linux/map_to_7segment.h new file mode 100644 index 00000000000..7df8432c440 --- /dev/null +++ b/include/linux/map_to_7segment.h @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2005 Henk Vergonet + * + * 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 MAP_TO_7SEGMENT_H +#define MAP_TO_7SEGMENT_H + +/* This file provides translation primitives and tables for the conversion + * of (ASCII) characters to a 7-segments notation. + * + * The 7 segment's wikipedia notation below is used as standard. + * See: http://en.wikipedia.org/wiki/Seven_segment_display + * + * Notation: +-a-+ + * f b + * +-g-+ + * e c + * +-d-+ + * + * Usage: + * + * Register a map variable, and fill it with a character set: + * static SEG7_DEFAULT_MAP(map_seg7); + * + * + * Then use for conversion: + * seg7 = map_to_seg7(&map_seg7, some_char); + * ... + * + * In device drivers it is recommended, if required, to make the char map + * accessible via the sysfs interface using the following scheme: + * + * static ssize_t show_map(struct device *dev, char *buf) { + * memcpy(buf, &map_seg7, sizeof(map_seg7)); + * return sizeof(map_seg7); + * } + * static ssize_t store_map(struct device *dev, const char *buf, size_t cnt) { + * if(cnt != sizeof(map_seg7)) + * return -EINVAL; + * memcpy(&map_seg7, buf, cnt); + * return cnt; + * } + * static DEVICE_ATTR(map_seg7, PERMS_RW, show_map, store_map); + * + * History: + * 2005-05-31 RFC linux-kernel@vger.kernel.org + */ +#include + + +#define BIT_SEG7_A 0 +#define BIT_SEG7_B 1 +#define BIT_SEG7_C 2 +#define BIT_SEG7_D 3 +#define BIT_SEG7_E 4 +#define BIT_SEG7_F 5 +#define BIT_SEG7_G 6 +#define BIT_SEG7_RESERVED 7 + +struct seg7_conversion_map { + unsigned char table[128]; +}; + +static inline int map_to_seg7(struct seg7_conversion_map *map, int c) +{ + return c >= 0 && c < sizeof(map->table) ? map->table[c] : -EINVAL; +} + +#define SEG7_CONVERSION_MAP(_name, _map) \ + struct seg7_conversion_map _name = { .table = { _map } } + +/* + * It is recommended to use a facility that allows user space to redefine + * custom character sets for LCD devices. Please use a sysfs interface + * as described above. + */ +#define MAP_TO_SEG7_SYSFS_FILE "map_seg7" + +/******************************************************************************* + * ASCII conversion table + ******************************************************************************/ + +#define _SEG7(l,a,b,c,d,e,f,g) \ + ( a<',1,1,0,0,0,0,1), _SEG7('?',1,1,1,0,0,1,0),\ + _SEG7('@',1,1,0,1,1,1,1), + +#define _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \ + _SEG7('A',1,1,1,0,1,1,1), _SEG7('B',1,1,1,1,1,1,1), _SEG7('C',1,0,0,1,1,1,0),\ + _SEG7('D',1,1,1,1,1,1,0), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\ + _SEG7('G',1,1,1,1,0,1,1), _SEG7('H',0,1,1,0,1,1,1), _SEG7('I',0,1,1,0,0,0,0),\ + _SEG7('J',0,1,1,1,0,0,0), _SEG7('K',0,1,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\ + _SEG7('M',1,1,1,0,1,1,0), _SEG7('N',1,1,1,0,1,1,0), _SEG7('O',1,1,1,1,1,1,0),\ + _SEG7('P',1,1,0,0,1,1,1), _SEG7('Q',1,1,1,1,1,1,0), _SEG7('R',1,1,1,0,1,1,1),\ + _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('U',0,1,1,1,1,1,0),\ + _SEG7('V',0,1,1,1,1,1,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\ + _SEG7('Y',0,1,1,0,0,1,1), _SEG7('Z',1,1,0,1,1,0,1), + +#define _MAP_91_96_ASCII_SEG7_SYMBOL \ + _SEG7('[',1,0,0,1,1,1,0), _SEG7('\\',0,0,1,0,0,1,1),_SEG7(']',1,1,1,1,0,0,0),\ + _SEG7('^',1,1,0,0,0,1,0), _SEG7('_',0,0,0,1,0,0,0), _SEG7('`',0,1,0,0,0,0,0), + +#define _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \ + _SEG7('A',1,1,1,0,1,1,1), _SEG7('b',0,0,1,1,1,1,1), _SEG7('c',0,0,0,1,1,0,1),\ + _SEG7('d',0,1,1,1,1,0,1), _SEG7('E',1,0,0,1,1,1,1), _SEG7('F',1,0,0,0,1,1,1),\ + _SEG7('G',1,1,1,1,0,1,1), _SEG7('h',0,0,1,0,1,1,1), _SEG7('i',0,0,1,0,0,0,0),\ + _SEG7('j',0,0,1,1,0,0,0), _SEG7('k',0,0,1,0,1,1,1), _SEG7('L',0,0,0,1,1,1,0),\ + _SEG7('M',1,1,1,0,1,1,0), _SEG7('n',0,0,1,0,1,0,1), _SEG7('o',0,0,1,1,1,0,1),\ + _SEG7('P',1,1,0,0,1,1,1), _SEG7('q',1,1,1,0,0,1,1), _SEG7('r',0,0,0,0,1,0,1),\ + _SEG7('S',1,0,1,1,0,1,1), _SEG7('T',0,0,0,1,1,1,1), _SEG7('u',0,0,1,1,1,0,0),\ + _SEG7('v',0,0,1,1,1,0,0), _SEG7('W',0,1,1,1,1,1,1), _SEG7('X',0,1,1,0,1,1,1),\ + _SEG7('y',0,1,1,1,0,1,1), _SEG7('Z',1,1,0,1,1,0,1), + +#define _MAP_123_126_ASCII_SEG7_SYMBOL \ + _SEG7('{',1,0,0,1,1,1,0), _SEG7('|',0,0,0,0,1,1,0), _SEG7('}',1,1,1,1,0,0,0),\ + _SEG7('~',1,0,0,0,0,0,0), + +/* Maps */ + +/* This set tries to map as close as possible to the visible characteristics + * of the ASCII symbol, lowercase and uppercase letters may differ in + * presentation on the display. + */ +#define MAP_ASCII7SEG_ALPHANUM \ + _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \ + _MAP_33_47_ASCII_SEG7_SYMBOL \ + _MAP_48_57_ASCII_SEG7_NUMERIC \ + _MAP_58_64_ASCII_SEG7_SYMBOL \ + _MAP_65_90_ASCII_SEG7_ALPHA_UPPR \ + _MAP_91_96_ASCII_SEG7_SYMBOL \ + _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \ + _MAP_123_126_ASCII_SEG7_SYMBOL + +/* This set tries to map as close as possible to the symbolic characteristics + * of the ASCII character for maximum discrimination. + * For now this means all alpha chars are in lower case representations. + * (This for example facilitates the use of hex numbers with uppercase input.) + */ +#define MAP_ASCII7SEG_ALPHANUM_LC \ + _MAP_0_32_ASCII_SEG7_NON_PRINTABLE \ + _MAP_33_47_ASCII_SEG7_SYMBOL \ + _MAP_48_57_ASCII_SEG7_NUMERIC \ + _MAP_58_64_ASCII_SEG7_SYMBOL \ + _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \ + _MAP_91_96_ASCII_SEG7_SYMBOL \ + _MAP_97_122_ASCII_SEG7_ALPHA_LOWER \ + _MAP_123_126_ASCII_SEG7_SYMBOL + +#define SEG7_DEFAULT_MAP(_name) \ + SEG7_CONVERSION_MAP(_name,MAP_ASCII7SEG_ALPHANUM) + +#endif /* MAP_TO_7SEGMENT_H */ + -- cgit v1.2.3 From c865d2f6eb160c15b74245b4891c8e945d67d96c Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 19 Aug 2008 16:53:26 -0600 Subject: PNP: convert the last few pnp_info() uses to printk() There are only a few remaining uses of pnp_info(), so I just converted them to printk and removed the pnp_err(), pnp_info(), pnp_warn(), and pnp_dbg() wrappers. I also removed a couple debug messages that don't seem useful any more ("driver registered", "driver unregistered", "driver attached"). Signed-off-by: Bjorn Helgaas Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- include/linux/pnp.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pnp.h b/include/linux/pnp.h index be764e514e3..05daecec16c 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -483,14 +483,4 @@ static inline void pnp_unregister_driver(struct pnp_driver *drv) { } #endif /* CONFIG_PNP */ -#define pnp_err(format, arg...) printk(KERN_ERR "pnp: " format "\n" , ## arg) -#define pnp_info(format, arg...) printk(KERN_INFO "pnp: " format "\n" , ## arg) -#define pnp_warn(format, arg...) printk(KERN_WARNING "pnp: " format "\n" , ## arg) - -#ifdef CONFIG_PNP_DEBUG -#define pnp_dbg(format, arg...) printk(KERN_DEBUG "pnp: " format "\n" , ## arg) -#else -#define pnp_dbg(format, arg...) do {} while (0) -#endif - #endif /* _LINUX_PNP_H */ -- cgit v1.2.3 From fa89b6089b5f4c7a5244b642caaca3e72b06ebe4 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 24 Sep 2008 19:04:32 -0700 Subject: ACPI: remove unused have_arch_parse_srat This was a workaround for 32bit numa SRAT processing, and we removed those workarounds, making 32 bit more like 64 bit. HAVE_ARCH_PARSE_SRAT is no longer defined anywhere. Signed-off-by: Yinghai Lu Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- include/linux/acpi.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 702f79dad16..fd6a452b0ce 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -94,18 +94,10 @@ int acpi_parse_mcfg (struct acpi_table_header *header); void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); /* the following four functions are architecture-dependent */ -#ifdef CONFIG_HAVE_ARCH_PARSE_SRAT -#define NR_NODE_MEMBLKS MAX_NUMNODES -#define acpi_numa_slit_init(slit) do {} while (0) -#define acpi_numa_processor_affinity_init(pa) do {} while (0) -#define acpi_numa_memory_affinity_init(ma) do {} while (0) -#define acpi_numa_arch_fixup() do {} while (0) -#else void acpi_numa_slit_init (struct acpi_table_slit *slit); void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); void acpi_numa_arch_fixup(void); -#endif #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -- cgit v1.2.3 From ee63a7d2287c677ed022bf3f584f5a187b6c402f Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Tue, 2 Sep 2008 10:14:13 +0200 Subject: Fix comment in include/linux/mmc/host.h In include/linux/mmc/host.h, it is mentionned that the callback to know if a card is present or not is get_ro(). But it's get_cd(). Signed-off-by: Thomas Petazzoni Signed-off-by: Pierre Ossman --- include/linux/mmc/host.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 9c288c90987..bde891f6459 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -65,7 +65,7 @@ struct mmc_host_ops { * -ENOSYS when not supported (equal to NULL callback) * or a negative errno value when something bad happened * - * Return values for the get_ro callback should be: + * Return values for the get_cd callback should be: * 0 for a absent card * 1 for a present card * -ENOSYS when not supported (equal to NULL callback) -- cgit v1.2.3 From 325af5fb1418c79953db0954556de048e061d8b6 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Fri, 8 Aug 2008 15:58:39 -0700 Subject: x86: ioperm user_regset This adds a user_regset type for the x86 io permissions bitmap. This makes it appear in core dumps (when ioperm has been used). It will also make it visible to debuggers in the future. Signed-off-by: Roland McGrath Signed-off-by: H. Peter Anvin [conflict resolutions: Signed-off-by: Ingo Molnar ] --- include/linux/elf.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/elf.h b/include/linux/elf.h index edc3dac3f02..0b61ca41a04 100644 --- a/include/linux/elf.h +++ b/include/linux/elf.h @@ -360,6 +360,7 @@ typedef struct elf64_shdr { #define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ #define NT_PPC_VSX 0x102 /* PowerPC VSX registers */ #define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ +#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */ /* Note header in a PT_NOTE section */ -- cgit v1.2.3 From 188919ac57810e39138749338d5a33ba1e970e23 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 8 Aug 2008 07:21:00 -0300 Subject: V4L/DVB (8634): v4l2: extend MPEG Encoding API with AVC and AAC Adds Advanced Audio Coding (AAC) and MPEG-4 Advanced Video Coding (AVC/H.264) as audio/video codecs to the extended controls API. Updates cx2341x driver to the new values. Signed-off-by: Janne Grunau Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 303d93ffd6b..350aba2714f 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -910,6 +910,7 @@ enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0, V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, + V4L2_MPEG_AUDIO_ENCODING_AAC = 3, }; #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { @@ -992,8 +993,9 @@ enum v4l2_mpeg_audio_crc { /* MPEG video */ #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) enum v4l2_mpeg_video_encoding { - V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, - V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0, + V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1, + V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2, }; #define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201) enum v4l2_mpeg_video_aspect { -- cgit v1.2.3 From e6b5da88fb24c5c1e52707faea7c46df09da42f0 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 8 Aug 2008 07:38:07 -0300 Subject: V4L/DVB (8635): v4l: add AC-3 audio support to the MPEG Encoding API Some models of the saa6752hs support AC-3. Extend the API with the necessary controls for AC-3. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 350aba2714f..9054764f4cd 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -911,6 +911,7 @@ enum v4l2_mpeg_audio_encoding { V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1, V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2, V4L2_MPEG_AUDIO_ENCODING_AAC = 3, + V4L2_MPEG_AUDIO_ENCODING_AC3 = 4, }; #define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102) enum v4l2_mpeg_audio_l1_bitrate { @@ -989,6 +990,28 @@ enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+110) +enum v4l2_mpeg_audio_ac3_bitrate { + V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, + V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, + V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2, + V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3, + V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4, + V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5, + V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6, + V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7, + V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8, + V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9, + V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10, + V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11, + V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12, + V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13, + V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14, + V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15, + V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16, + V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17, + V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18, +}; /* MPEG video */ #define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200) -- cgit v1.2.3 From f723af16da8359cda47320001960609b0086082b Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 9 Aug 2008 10:35:29 -0300 Subject: V4L/DVB (8649): v4l2: add AAC bitrate control If you can select AAC as audio encoder, then you should also be able to set the bitrate. Add this missing control. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 9054764f4cd..d4b03034ee7 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -990,7 +990,8 @@ enum v4l2_mpeg_audio_crc { V4L2_MPEG_AUDIO_CRC_CRC16 = 1, }; #define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109) -#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110) +#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111) enum v4l2_mpeg_audio_ac3_bitrate { V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0, V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1, -- cgit v1.2.3 From 66c6bda79fdc273608e2700a0c6dd4cb82d0bac3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 08:33:14 -0300 Subject: V4L/DVB (8691): i2c-id: remove obsolete SAB3036 driver ID Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/i2c-id.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index bf34c5f4c05..493435bcdbe 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -41,7 +41,6 @@ #define I2C_DRIVERID_SAA7110 22 /* video decoder */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ #define I2C_DRIVERID_PCF8583 25 /* real time clock */ -#define I2C_DRIVERID_SAB3036 26 /* SAB3036 tuner */ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ -- cgit v1.2.3 From 4c522e74902a1fa15a7ec5e5a3325b250afa54ab Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Wed, 10 Sep 2008 08:22:06 -0300 Subject: V4L/DVB (8959): include into linux/ivtv.h linux/videodev2.h defines enum v4l2_buf_type and struct v4l2_rect Signed-off-by: Kirill A. Shutemov Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/ivtv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ivtv.h b/include/linux/ivtv.h index 17ca64b5a66..f2720280b9e 100644 --- a/include/linux/ivtv.h +++ b/include/linux/ivtv.h @@ -23,6 +23,7 @@ #include #include +#include /* ivtv knows several distinct output modes: MPEG streaming, YUV streaming, YUV updates through user DMA and the passthrough -- cgit v1.2.3 From 6b73eeafbc856c0cef7166242f0e55403407f355 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 4 Sep 2008 01:12:25 -0300 Subject: V4L/DVB (8985): S2API: Added dvb frontend changes to support a newer tuning API This is an experimental patch to add a new tuning mechanism for dvb frontends. Rather than passing fixed structures across the user/kernel boundary, which need to be revised for each new modulation type (or feature the kernel developers want to add), this implements a simpler message based approach, allowing fe commands to be broken down into a series of small fixed size transactions, presented in an array. The goal is to avoid changing the user/kernel ABI in the future, by simply creating new frontend commands (and sequencies of commands) that help us add support for brand new demodulator, delivery system or statistics related commmands. known issues: checkpatch voilations feedback from various developers yet to be implemented, relating to namespace conventions, variable length array passing conventions, and generally some optimization. This patch should support all existing tuning mechanisms through the new API, as well as adding 8PSK, DVB-S2 NBC-QPSK and ISDB-T API support. For testing and exercise purposes, see the latest tune.c tool available from http://www.steventoth.net/linux/s2 Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 130 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index c8cbd90ba37..4d377002173 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -62,6 +62,7 @@ typedef enum fe_caps { FE_CAN_HIERARCHY_AUTO = 0x100000, FE_CAN_8VSB = 0x200000, FE_CAN_16VSB = 0x400000, + FE_HAS_EXTENDED_CAPS = 0x800000, // We need more bitspace for newer APIs, indicate this. FE_NEEDS_BENDING = 0x20000000, // not supported anymore, don't use (frontend requires frequency bending) FE_CAN_RECOVER = 0x40000000, // frontend can recover from a cable unplug automatically FE_CAN_MUTE_TS = 0x80000000 // frontend can stop spurious TS data output @@ -147,7 +148,9 @@ typedef enum fe_code_rate { FEC_6_7, FEC_7_8, FEC_8_9, - FEC_AUTO + FEC_AUTO, + FEC_3_5, + FEC_9_10, } fe_code_rate_t; @@ -160,7 +163,11 @@ typedef enum fe_modulation { QAM_256, QAM_AUTO, VSB_8, - VSB_16 + VSB_16, + _8PSK, + _16APSK, + NBC_QPSK, + DQPSK, } fe_modulation_t; typedef enum fe_transmit_mode { @@ -239,6 +246,125 @@ struct dvb_frontend_event { struct dvb_frontend_parameters parameters; }; +/* TODO: Turn this into a series of defines, so future maintainers + * don't insert random new commands and break backwards + * binary compatability. + */ +typedef enum tv_cmd_types { + TV_SEQ_UNDEFINED, + TV_SEQ_START, + TV_SEQ_CONTINUE, + TV_SEQ_COMPLETE, + TV_SEQ_TERMINATE, + + TV_SET_FREQUENCY, + TV_SET_MODULATION, + TV_SET_BANDWIDTH, + TV_SET_INVERSION, + TV_SET_DISEQC_MASTER, + TV_SET_SYMBOLRATE, + TV_SET_INNERFEC, + TV_SET_VOLTAGE, + TV_SET_TONE, + TV_SET_PILOT, + TV_SET_ROLLOFF, + + TV_GET_FREQUENCY, + TV_GET_MODULATION, + TV_GET_BANDWIDTH, + TV_GET_INVERSION, + TV_GET_DISEQC_SLAVE_REPLY, + TV_GET_SYMBOLRATE, + TV_GET_INNERFEC, + TV_GET_VOLTAGE, + TV_GET_TONE, + TV_GET_PILOT, + TV_GET_ROLLOFF, + + /* Basic enumeration set for querying unlimited capabilities */ + TV_GET_FE_CAPABILITY_COUNT, + TV_GET_FE_CAPABILITY, + + /* New commands are always appended */ + TV_SET_DELIVERY_SYSTEM, + TV_GET_DELIVERY_SYSTEM, + + /* ISDB-T */ + TV_SET_ISDB_SEGMENT_NUM, + TV_GET_ISDB_SEGMENT_NUM, + TV_SET_ISDB_SEGMENT_WIDTH, + TV_GET_ISDB_SEGMENT_WIDTH, + TV_GET_ISDB_LAYERA_FEC, + TV_GET_ISDB_LAYERA_MODULATION, + TV_GET_ISDB_LAYERA_SEGMENT_WIDTH, + TV_GET_ISDB_LAYERB_FEC, + TV_GET_ISDB_LAYERB_MODULATION, + TV_GET_ISDB_LAYERB_SEGMENT_WIDTH, + TV_GET_ISDB_LAYERC_FEC, + TV_GET_ISDB_LAYERC_MODULATION, + TV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + +} tv_cmd_types_t; + +typedef enum fe_pilot { + PILOT_ON, + PILOT_OFF, + PILOT_AUTO, +} fe_pilot_t; + +typedef enum fe_rolloff { + ROLLOFF_20, + ROLLOFF_25, + ROLLOFF_35, + ROLLOFF_AUTO, +} fe_rolloff_t; + +typedef enum fe_delivery_system { + SYS_UNDEFINED, + SYS_DVBC_ANNEX_AC, + SYS_DVBC_ANNEX_B, + SYS_DVBT, + SYS_DVBS, + SYS_DVBS2, + SYS_DVBH, + SYS_ISDBT, + SYS_ISDBS, + SYS_ISDBC, + SYS_ATSC, + SYS_ATSCMH, + SYS_DMBTH, + SYS_CMMB, + SYS_DAB, +} fe_delivery_system_t; + +struct tv_cmds_h { + char *name; /* A display name for debugging purposes */ + + __u32 cmd; /* A unique ID */ + + /* Flags */ + __u32 set:1; /* Either a set or get property */ + __u32 buffer:1; /* Does this property use the buffer? */ + __u32 reserved:30; /* Align */ +}; + +typedef struct { + __u32 cmd; + union { + __u32 data; + struct { + __u8 data[32]; + __u32 len; + } buffer; + } u; +} tv_property_t; + +/* No more than 16 properties during any given ioctl */ +typedef tv_property_t tv_properties_t[16]; + +#define FE_SET_PROPERTY _IOW('o', 82, tv_properties_t) +#define FE_GET_PROPERTY _IOR('o', 83, tv_properties_t) + /** * When set, this flag will disable any zigzagging or other "normal" tuning -- cgit v1.2.3 From 56f0680a28397f4b412fc14f60ac380b910ee328 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 10:19:27 -0300 Subject: V4L/DVB (8995): S2API: tv_ / TV_ to dtv_ / DTV_ namespace changes The group preferred dtv_ over tv_, this implements it. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 108 +++++++++++++++++++++---------------------- 1 file changed, 54 insertions(+), 54 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 4d377002173..aeace74b536 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -250,61 +250,61 @@ struct dvb_frontend_event { * don't insert random new commands and break backwards * binary compatability. */ -typedef enum tv_cmd_types { - TV_SEQ_UNDEFINED, - TV_SEQ_START, - TV_SEQ_CONTINUE, - TV_SEQ_COMPLETE, - TV_SEQ_TERMINATE, - - TV_SET_FREQUENCY, - TV_SET_MODULATION, - TV_SET_BANDWIDTH, - TV_SET_INVERSION, - TV_SET_DISEQC_MASTER, - TV_SET_SYMBOLRATE, - TV_SET_INNERFEC, - TV_SET_VOLTAGE, - TV_SET_TONE, - TV_SET_PILOT, - TV_SET_ROLLOFF, - - TV_GET_FREQUENCY, - TV_GET_MODULATION, - TV_GET_BANDWIDTH, - TV_GET_INVERSION, - TV_GET_DISEQC_SLAVE_REPLY, - TV_GET_SYMBOLRATE, - TV_GET_INNERFEC, - TV_GET_VOLTAGE, - TV_GET_TONE, - TV_GET_PILOT, - TV_GET_ROLLOFF, +typedef enum dtv_cmd_types { + DTV_SEQ_UNDEFINED, + DTV_SEQ_START, + DTV_SEQ_CONTINUE, + DTV_SEQ_COMPLETE, + DTV_SEQ_TERMINATE, + + DTV_SET_FREQUENCY, + DTV_SET_MODULATION, + DTV_SET_BANDWIDTH, + DTV_SET_INVERSION, + DTV_SET_DISEQC_MASTER, + DTV_SET_SYMBOLRATE, + DTV_SET_INNERFEC, + DTV_SET_VOLTAGE, + DTV_SET_TONE, + DTV_SET_PILOT, + DTV_SET_ROLLOFF, + + DTV_GET_FREQUENCY, + DTV_GET_MODULATION, + DTV_GET_BANDWIDTH, + DTV_GET_INVERSION, + DTV_GET_DISEQC_SLAVE_REPLY, + DTV_GET_SYMBOLRATE, + DTV_GET_INNERFEC, + DTV_GET_VOLTAGE, + DTV_GET_TONE, + DTV_GET_PILOT, + DTV_GET_ROLLOFF, /* Basic enumeration set for querying unlimited capabilities */ - TV_GET_FE_CAPABILITY_COUNT, - TV_GET_FE_CAPABILITY, + DTV_GET_FE_CAPABILITY_COUNT, + DTV_GET_FE_CAPABILITY, /* New commands are always appended */ - TV_SET_DELIVERY_SYSTEM, - TV_GET_DELIVERY_SYSTEM, + DTV_SET_DELIVERY_SYSTEM, + DTV_GET_DELIVERY_SYSTEM, /* ISDB-T */ - TV_SET_ISDB_SEGMENT_NUM, - TV_GET_ISDB_SEGMENT_NUM, - TV_SET_ISDB_SEGMENT_WIDTH, - TV_GET_ISDB_SEGMENT_WIDTH, - TV_GET_ISDB_LAYERA_FEC, - TV_GET_ISDB_LAYERA_MODULATION, - TV_GET_ISDB_LAYERA_SEGMENT_WIDTH, - TV_GET_ISDB_LAYERB_FEC, - TV_GET_ISDB_LAYERB_MODULATION, - TV_GET_ISDB_LAYERB_SEGMENT_WIDTH, - TV_GET_ISDB_LAYERC_FEC, - TV_GET_ISDB_LAYERC_MODULATION, - TV_GET_ISDB_LAYERC_SEGMENT_WIDTH, - -} tv_cmd_types_t; + DTV_SET_ISDB_SEGMENT_NUM, + DTV_GET_ISDB_SEGMENT_NUM, + DTV_SET_ISDB_SEGMENT_WIDTH, + DTV_GET_ISDB_SEGMENT_WIDTH, + DTV_GET_ISDB_LAYERA_FEC, + DTV_GET_ISDB_LAYERA_MODULATION, + DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH, + DTV_GET_ISDB_LAYERB_FEC, + DTV_GET_ISDB_LAYERB_MODULATION, + DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH, + DTV_GET_ISDB_LAYERC_FEC, + DTV_GET_ISDB_LAYERC_MODULATION, + DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + +} dtv_cmd_types_t; typedef enum fe_pilot { PILOT_ON, @@ -337,7 +337,7 @@ typedef enum fe_delivery_system { SYS_DAB, } fe_delivery_system_t; -struct tv_cmds_h { +struct dtv_cmds_h { char *name; /* A display name for debugging purposes */ __u32 cmd; /* A unique ID */ @@ -357,13 +357,13 @@ typedef struct { __u32 len; } buffer; } u; -} tv_property_t; +} dtv_property_t; /* No more than 16 properties during any given ioctl */ -typedef tv_property_t tv_properties_t[16]; +typedef dtv_property_t dtv_properties_t[16]; -#define FE_SET_PROPERTY _IOW('o', 82, tv_properties_t) -#define FE_GET_PROPERTY _IOR('o', 83, tv_properties_t) +#define FE_SET_PROPERTY _IOW('o', 82, dtv_properties_t) +#define FE_GET_PROPERTY _IOR('o', 83, dtv_properties_t) /** -- cgit v1.2.3 From e7fee0f3aa111d42cdcfc1470cfdc21dde0cdbe2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 10:23:01 -0300 Subject: V4L/DVB (8996): S2API: typedefs replaced, _SEQ_'s removed, fixed 16 command arrays replaced After discussion the following changes were made: 1. Removed the typedefs in frontend.h, use structures. 2. In the frontend.h, remove the 16 command limit on the API and switch to a flexible variable length API. For practical reasons a #define limits this to 64, this should be discussed. 3. Changed dvb-core ioctl handing to deal with variable sequences of commands. tune-v0.0.3.c is required to use this API, it contains the interface changes. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index aeace74b536..f667bf377a7 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -251,11 +251,8 @@ struct dvb_frontend_event { * binary compatability. */ typedef enum dtv_cmd_types { - DTV_SEQ_UNDEFINED, - DTV_SEQ_START, - DTV_SEQ_CONTINUE, - DTV_SEQ_COMPLETE, - DTV_SEQ_TERMINATE, + DTV_TUNE, + DTV_CLEAR, DTV_SET_FREQUENCY, DTV_SET_MODULATION, @@ -348,22 +345,32 @@ struct dtv_cmds_h { __u32 reserved:30; /* Align */ }; -typedef struct { +struct dtv_property { __u32 cmd; + __u32 reserved[3]; union { + __s32 valuemin; + __s32 valuemax; __u32 data; struct { __u8 data[32]; __u32 len; + __u32 reserved1[3]; + void *reserved2; } buffer; } u; -} dtv_property_t; +} __attribute__ ((packed)); /* No more than 16 properties during any given ioctl */ -typedef dtv_property_t dtv_properties_t[16]; +struct dtv_properties { + __u32 num; + struct dtv_property *props; +}; + +#define DTV_IOCTL_MAX_MSGS 64 -#define FE_SET_PROPERTY _IOW('o', 82, dtv_properties_t) -#define FE_GET_PROPERTY _IOR('o', 83, dtv_properties_t) +#define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) +#define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) /** -- cgit v1.2.3 From 177b868d93861077619261dcecd0147d1c033026 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 10:34:19 -0300 Subject: V4L/DVB (8997): S2API: Cleanup SYMBOLRATE, INNERFEC -> SYMBOL_RATE, INNER_FEC This is now consistent with the existing API. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index f667bf377a7..bfd670fa16b 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -259,8 +259,8 @@ typedef enum dtv_cmd_types { DTV_SET_BANDWIDTH, DTV_SET_INVERSION, DTV_SET_DISEQC_MASTER, - DTV_SET_SYMBOLRATE, - DTV_SET_INNERFEC, + DTV_SET_SYMBOL_RATE, + DTV_SET_INNER_FEC, DTV_SET_VOLTAGE, DTV_SET_TONE, DTV_SET_PILOT, @@ -271,8 +271,8 @@ typedef enum dtv_cmd_types { DTV_GET_BANDWIDTH, DTV_GET_INVERSION, DTV_GET_DISEQC_SLAVE_REPLY, - DTV_GET_SYMBOLRATE, - DTV_GET_INNERFEC, + DTV_GET_SYMBOL_RATE, + DTV_GET_INNER_FEC, DTV_GET_VOLTAGE, DTV_GET_TONE, DTV_GET_PILOT, -- cgit v1.2.3 From 65af619d84ee2d3a1faacbbeded374d0b313d3a9 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Thu, 11 Sep 2008 21:08:59 -0300 Subject: V4L/DVB (8998): s2api: restore DTV_UNDEFINED Signed-off-by: Steven Toth Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index bfd670fa16b..915edd319f3 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -251,6 +251,7 @@ struct dvb_frontend_event { * binary compatability. */ typedef enum dtv_cmd_types { + DTV_UNDEFINED, DTV_TUNE, DTV_CLEAR, -- cgit v1.2.3 From d7c1500183bc138b634377ed90c046e722b887d8 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 12 Sep 2008 00:33:04 -0300 Subject: V4L/DVB (9001): S2API: ISDBT_SEGMENT_NUM -> ISDBT_SEGMENT_IDX Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 915edd319f3..e4f211735ef 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -288,8 +288,8 @@ typedef enum dtv_cmd_types { DTV_GET_DELIVERY_SYSTEM, /* ISDB-T */ - DTV_SET_ISDB_SEGMENT_NUM, - DTV_GET_ISDB_SEGMENT_NUM, + DTV_SET_ISDB_SEGMENT_IDX, + DTV_GET_ISDB_SEGMENT_IDX, DTV_SET_ISDB_SEGMENT_WIDTH, DTV_GET_ISDB_SEGMENT_WIDTH, DTV_GET_ISDB_LAYERA_FEC, -- cgit v1.2.3 From 363429a089590f3f4071ebc492b3712fdcba770b Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 12 Sep 2008 01:34:28 -0300 Subject: V4L/DVB (9003): S2API: Remove the DTV_SET_ and DTV_GET_ prefixes The API now assumes that ioctl calls for FE_SET_PROPERTY and all set commands, and FE_GET_PROPERTY are get commands. Simplification. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 67 ++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 40 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index e4f211735ef..05bdec9bc5a 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -255,52 +255,39 @@ typedef enum dtv_cmd_types { DTV_TUNE, DTV_CLEAR, - DTV_SET_FREQUENCY, - DTV_SET_MODULATION, - DTV_SET_BANDWIDTH, - DTV_SET_INVERSION, - DTV_SET_DISEQC_MASTER, - DTV_SET_SYMBOL_RATE, - DTV_SET_INNER_FEC, - DTV_SET_VOLTAGE, - DTV_SET_TONE, - DTV_SET_PILOT, - DTV_SET_ROLLOFF, - - DTV_GET_FREQUENCY, - DTV_GET_MODULATION, - DTV_GET_BANDWIDTH, - DTV_GET_INVERSION, - DTV_GET_DISEQC_SLAVE_REPLY, - DTV_GET_SYMBOL_RATE, - DTV_GET_INNER_FEC, - DTV_GET_VOLTAGE, - DTV_GET_TONE, - DTV_GET_PILOT, - DTV_GET_ROLLOFF, + DTV_FREQUENCY, + DTV_MODULATION, + DTV_BANDWIDTH, + DTV_INVERSION, + DTV_DISEQC_MASTER, + DTV_SYMBOL_RATE, + DTV_INNER_FEC, + DTV_VOLTAGE, + DTV_TONE, + DTV_PILOT, + DTV_ROLLOFF, + + DTV_DISEQC_SLAVE_REPLY, /* Basic enumeration set for querying unlimited capabilities */ - DTV_GET_FE_CAPABILITY_COUNT, - DTV_GET_FE_CAPABILITY, + DTV_FE_CAPABILITY_COUNT, + DTV_FE_CAPABILITY, /* New commands are always appended */ - DTV_SET_DELIVERY_SYSTEM, - DTV_GET_DELIVERY_SYSTEM, + DTV_DELIVERY_SYSTEM, /* ISDB-T */ - DTV_SET_ISDB_SEGMENT_IDX, - DTV_GET_ISDB_SEGMENT_IDX, - DTV_SET_ISDB_SEGMENT_WIDTH, - DTV_GET_ISDB_SEGMENT_WIDTH, - DTV_GET_ISDB_LAYERA_FEC, - DTV_GET_ISDB_LAYERA_MODULATION, - DTV_GET_ISDB_LAYERA_SEGMENT_WIDTH, - DTV_GET_ISDB_LAYERB_FEC, - DTV_GET_ISDB_LAYERB_MODULATION, - DTV_GET_ISDB_LAYERB_SEGMENT_WIDTH, - DTV_GET_ISDB_LAYERC_FEC, - DTV_GET_ISDB_LAYERC_MODULATION, - DTV_GET_ISDB_LAYERC_SEGMENT_WIDTH, + DTV_ISDB_SEGMENT_IDX, + DTV_ISDB_SEGMENT_WIDTH, + DTV_ISDB_LAYERA_FEC, + DTV_ISDB_LAYERA_MODULATION, + DTV_ISDB_LAYERA_SEGMENT_WIDTH, + DTV_ISDB_LAYERB_FEC, + DTV_ISDB_LAYERB_MODULATION, + DTV_ISDB_LAYERB_SEGMENT_WIDTH, + DTV_ISDB_LAYERC_FEC, + DTV_ISDB_LAYERC_MODULATION, + DTV_ISDB_LAYERC_SEGMENT_WIDTH, } dtv_cmd_types_t; -- cgit v1.2.3 From 75b7f9437b1cf63750bb58efaaeb6d72d04b3c7f Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Sat, 13 Sep 2008 16:56:34 -0300 Subject: V4L/DVB (9007): S2API: Changed bandwidth to be expressed in HZ Also added some compat code for the older API. Added more ISDB message/command suggestions, current not connected in dvb-core. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 05bdec9bc5a..4f3fd641ccb 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -257,7 +257,12 @@ typedef enum dtv_cmd_types { DTV_FREQUENCY, DTV_MODULATION, - DTV_BANDWIDTH, + + /* XXX PB: I would like to have field which describes the + * bandwidth of a channel in Hz or kHz - maybe we can remove the + * DTV_BANDWIDTH now and put a compat layer */ + DTV_BANDWIDTH_HZ, + DTV_INVERSION, DTV_DISEQC_MASTER, DTV_SYMBOL_RATE, @@ -276,18 +281,34 @@ typedef enum dtv_cmd_types { /* New commands are always appended */ DTV_DELIVERY_SYSTEM, - /* ISDB-T */ + /* ISDB */ + /* maybe a dup of DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID ??? */ DTV_ISDB_SEGMENT_IDX, - DTV_ISDB_SEGMENT_WIDTH, + DTV_ISDB_SEGMENT_WIDTH, /* 1, 3 or 13 ??? */ + + /* the central segment can be received independently or 1/3 seg in SB-mode */ + DTV_ISDB_PARTIAL_RECEPTION, + /* sound broadcasting is used 0 = 13segment, 1 = 1 or 3 see DTV_ISDB_PARTIAL_RECEPTION */ + DTV_ISDB_SOUND_BROADCASTING, + + /* only used in SB */ + /* determines the initial PRBS of the segment (to match with 13seg channel) */ + DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID, + DTV_ISDB_LAYERA_FEC, DTV_ISDB_LAYERA_MODULATION, DTV_ISDB_LAYERA_SEGMENT_WIDTH, + DTV_ISDB_LAYERA_TIME_INTERLEAVER, + DTV_ISDB_LAYERB_FEC, DTV_ISDB_LAYERB_MODULATION, DTV_ISDB_LAYERB_SEGMENT_WIDTH, + DTV_ISDB_LAYERB_TIME_INTERLEAVING, + DTV_ISDB_LAYERC_FEC, DTV_ISDB_LAYERC_MODULATION, DTV_ISDB_LAYERC_SEGMENT_WIDTH, + DTV_ISDB_LAYERC_TIME_INTERLEAVING, } dtv_cmd_types_t; -- cgit v1.2.3 From fc6e8c284bcb23ac7a576b7959803168398e390a Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 23 Sep 2008 22:14:33 -0300 Subject: V4L/DVB (9024): S2API: Cleanup dtv_property remove unwanted fields. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 4f3fd641ccb..71f25f5bf37 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -358,8 +358,6 @@ struct dtv_property { __u32 cmd; __u32 reserved[3]; union { - __s32 valuemin; - __s32 valuemax; __u32 data; struct { __u8 data[32]; -- cgit v1.2.3 From 8316568930074723bdc47d6777f822be0422a5b7 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Tue, 23 Sep 2008 22:21:26 -0300 Subject: V4L/DVB (9025): S2API: Deactivate the ISDB-T definitions We don't want to push the ISDB-T definitions into the kernel until we have a high level of confidence in the ISDB-T API. More testing is required before this code is released. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 30 ------------------------------ 1 file changed, 30 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 71f25f5bf37..c822bc156c4 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -280,36 +280,6 @@ typedef enum dtv_cmd_types { /* New commands are always appended */ DTV_DELIVERY_SYSTEM, - - /* ISDB */ - /* maybe a dup of DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID ??? */ - DTV_ISDB_SEGMENT_IDX, - DTV_ISDB_SEGMENT_WIDTH, /* 1, 3 or 13 ??? */ - - /* the central segment can be received independently or 1/3 seg in SB-mode */ - DTV_ISDB_PARTIAL_RECEPTION, - /* sound broadcasting is used 0 = 13segment, 1 = 1 or 3 see DTV_ISDB_PARTIAL_RECEPTION */ - DTV_ISDB_SOUND_BROADCASTING, - - /* only used in SB */ - /* determines the initial PRBS of the segment (to match with 13seg channel) */ - DTV_ISDB_SOUND_BROADCASTING_SUBCHANNEL_ID, - - DTV_ISDB_LAYERA_FEC, - DTV_ISDB_LAYERA_MODULATION, - DTV_ISDB_LAYERA_SEGMENT_WIDTH, - DTV_ISDB_LAYERA_TIME_INTERLEAVER, - - DTV_ISDB_LAYERB_FEC, - DTV_ISDB_LAYERB_MODULATION, - DTV_ISDB_LAYERB_SEGMENT_WIDTH, - DTV_ISDB_LAYERB_TIME_INTERLEAVING, - - DTV_ISDB_LAYERC_FEC, - DTV_ISDB_LAYERC_MODULATION, - DTV_ISDB_LAYERC_SEGMENT_WIDTH, - DTV_ISDB_LAYERC_TIME_INTERLEAVING, - } dtv_cmd_types_t; typedef enum fe_pilot { -- cgit v1.2.3 From 459702bf98ae2bd20bad1e271c615aca4972c609 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 26 Sep 2008 00:04:52 -0300 Subject: V4L/DVB (9070): S2API: Removed the typedef for the commands, used defines instead. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 57 +++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index c822bc156c4..7c17c71edb5 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -246,41 +246,28 @@ struct dvb_frontend_event { struct dvb_frontend_parameters parameters; }; -/* TODO: Turn this into a series of defines, so future maintainers - * don't insert random new commands and break backwards - * binary compatability. - */ -typedef enum dtv_cmd_types { - DTV_UNDEFINED, - DTV_TUNE, - DTV_CLEAR, - - DTV_FREQUENCY, - DTV_MODULATION, - - /* XXX PB: I would like to have field which describes the - * bandwidth of a channel in Hz or kHz - maybe we can remove the - * DTV_BANDWIDTH now and put a compat layer */ - DTV_BANDWIDTH_HZ, - - DTV_INVERSION, - DTV_DISEQC_MASTER, - DTV_SYMBOL_RATE, - DTV_INNER_FEC, - DTV_VOLTAGE, - DTV_TONE, - DTV_PILOT, - DTV_ROLLOFF, - - DTV_DISEQC_SLAVE_REPLY, - - /* Basic enumeration set for querying unlimited capabilities */ - DTV_FE_CAPABILITY_COUNT, - DTV_FE_CAPABILITY, - - /* New commands are always appended */ - DTV_DELIVERY_SYSTEM, -} dtv_cmd_types_t; +/* S2API Commands */ +#define DTV_UNDEFINED 0 +#define DTV_TUNE 1 +#define DTV_CLEAR 2 +#define DTV_FREQUENCY 3 +#define DTV_MODULATION 4 +#define DTV_BANDWIDTH_HZ 5 +#define DTV_INVERSION 6 +#define DTV_DISEQC_MASTER 7 +#define DTV_SYMBOL_RATE 8 +#define DTV_INNER_FEC 9 +#define DTV_VOLTAGE 10 +#define DTV_TONE 11 +#define DTV_PILOT 12 +#define DTV_ROLLOFF 13 +#define DTV_DISEQC_SLAVE_REPLY 14 + +/* Basic enumeration set for querying unlimited capabilities */ +#define DTV_FE_CAPABILITY_COUNT 15 +#define DTV_FE_CAPABILITY 16 +#define DTV_DELIVERY_SYSTEM 17 + typedef enum fe_pilot { PILOT_ON, -- cgit v1.2.3 From d48cb402a1ba48c4ad4a36c3c561386027318459 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 26 Sep 2008 00:16:25 -0300 Subject: V4L/DVB (9071): S2API: Implement result codes for individual commands This allows application developers to determine which particular command in a sequence is invalid, or failing with error. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 7c17c71edb5..b561626fc8a 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -323,6 +323,7 @@ struct dtv_property { void *reserved2; } buffer; } u; + int result; } __attribute__ ((packed)); /* No more than 16 properties during any given ioctl */ -- cgit v1.2.3 From eacf8d8d6bc6798f6870a2cf2c159bfcde3759ac Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Fri, 26 Sep 2008 00:29:49 -0300 Subject: V4L/DVB (9072): S2API: Add DTV_API_VERSION command This allows application developers to query the dvb-core API version dynamically, helping developers understand whether certain features will be available. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 1 + include/linux/dvb/version.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index b561626fc8a..eb98f8c37ca 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -268,6 +268,7 @@ struct dvb_frontend_event { #define DTV_FE_CAPABILITY 16 #define DTV_DELIVERY_SYSTEM 17 +#define DTV_API_VERSION 35 typedef enum fe_pilot { PILOT_ON, diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h index 126e0c26cb0..25b823b8173 100644 --- a/include/linux/dvb/version.h +++ b/include/linux/dvb/version.h @@ -23,7 +23,7 @@ #ifndef _DVBVERSION_H_ #define _DVBVERSION_H_ -#define DVB_API_VERSION 3 -#define DVB_API_VERSION_MINOR 2 +#define DVB_API_VERSION 5 +#define DVB_API_VERSION_MINOR 0 #endif /*_DVBVERSION_H_*/ -- cgit v1.2.3 From 46eaa6702016e3ac9a188172a2c309d6ca1be1cd Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sun, 12 Oct 2008 15:06:29 +0200 Subject: x86: memory corruption check - cleanup Move the prototypes from the generic kernel.h header to the more appropriate include/asm-x86/bios_ebda.h header file. Also, remove the check from the power management code - this is a pure x86 matter for now. Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 50873b21178..2651f805ba6 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -240,23 +240,6 @@ extern const char *print_tainted(void); extern void add_taint(unsigned); extern int root_mountflags; -#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION -/* - * This is obviously not a great place for this, but we want to be - * able to scatter it around anywhere in the kernel. - */ -void check_for_bios_corruption(void); -void start_periodic_check_for_corruption(void); -#else -static inline void check_for_bios_corruption(void) -{ -} - -static inline void start_periodic_check_for_corruption(void) -{ -} -#endif - /* Values used for system_state */ extern enum system_states { SYSTEM_BOOTING, -- cgit v1.2.3 From 0dab9cfa17179d1f5b067a32a3bca06cd31a3149 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 12 Oct 2008 07:10:50 +0300 Subject: add key_revoke() dummy for KEYS=n This fixes the following build error with CONFIG_KEYS=n, caused by commit dfd15c46a6c2cafb006183c0c14f07e59eee4ac0 ("cifs: explicitly revoke SPNEGO key after session setup"): CC [M] fs/cifs/sess.o fs/cifs/sess.c: In function 'CIFS_SessSetup': fs/cifs/sess.c:628: error: implicit declaration of function 'key_revoke' make[3]: *** [fs/cifs/sess.o] Error 1 Signed-off-by: Adrian Bunk Acked-by: Jeff Layton Signed-off-by: Linus Torvalds --- include/linux/key.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/key.h b/include/linux/key.h index c45c962d1cc..1b70e35a71e 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -299,6 +299,7 @@ extern void key_init(void); #define key_validate(k) 0 #define key_serial(k) 0 #define key_get(k) ({ NULL; }) +#define key_revoke(k) do { } while(0) #define key_put(k) do { } while(0) #define key_ref_put(k) do { } while(0) #define make_key_ref(k, p) ({ NULL; }) -- cgit v1.2.3 From 92562927826fceb2f8e69c89e28161b8c1e0b125 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Tue, 7 Oct 2008 14:00:12 -0400 Subject: integrity: special fs magic Discussion on the mailing list questioned the use of these magic values in userspace, concluding these values are already exported to userspace via statfs and their correct/incorrect usage is left up to the userspace application. - Move special fs magic number definitions to magic.h - Add magic.h include Signed-off-by: Mimi Zohar Reviewed-by: James Morris Signed-off-by: James Morris --- include/linux/magic.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/magic.h b/include/linux/magic.h index 1fa0c2ce4de..f7f3fdddbef 100644 --- a/include/linux/magic.h +++ b/include/linux/magic.h @@ -6,6 +6,10 @@ #define AFS_SUPER_MAGIC 0x5346414F #define AUTOFS_SUPER_MAGIC 0x0187 #define CODA_SUPER_MAGIC 0x73757245 +#define DEBUGFS_MAGIC 0x64626720 +#define SYSFS_MAGIC 0x62656572 +#define SECURITYFS_MAGIC 0x73636673 +#define TMPFS_MAGIC 0x01021994 #define EFS_SUPER_MAGIC 0x414A53 #define EXT2_SUPER_MAGIC 0xEF53 #define EXT3_SUPER_MAGIC 0xEF53 -- cgit v1.2.3 From 64b60e096fa391c56f93e6216115e6757bf86b7e Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Fri, 10 Oct 2008 04:43:17 +0000 Subject: of: Add new helper of_parse_phandles_with_args() The helper is factored out of of_get_gpio(). Will be used by the QE pin multiplexing functions (they need to parse the gpios = <> too). Signed-off-by: Anton Vorontsov Signed-off-by: Benjamin Herrenschmidt --- include/linux/of.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/of.h b/include/linux/of.h index 79886ade070..e2488f5e7cb 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -71,5 +71,8 @@ extern int of_n_size_cells(struct device_node *np); extern const struct of_device_id *of_match_node( const struct of_device_id *matches, const struct device_node *node); extern int of_modalias_node(struct device_node *node, char *modalias, int len); +extern int of_parse_phandles_with_args(struct device_node *np, + const char *list_name, const char *cells_name, int index, + struct device_node **out_node, const void **out_args); #endif /* _LINUX_OF_H */ -- cgit v1.2.3 From 6283815d1853b7daf31dc4adb83e5c1dc9568251 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 13 Oct 2008 11:55:12 +1100 Subject: md: linear: Represent dev_info->size and dev_info->offset in sectors. Rename them to num_sectors and start_sector which is more descriptive. Signed-off-by: Andre Noll Signed-off-by: NeilBrown --- include/linux/raid/linear.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h index 7e375111d00..87090e98529 100644 --- a/include/linux/raid/linear.h +++ b/include/linux/raid/linear.h @@ -5,8 +5,8 @@ struct dev_info { mdk_rdev_t *rdev; - sector_t size; - sector_t offset; + sector_t num_sectors; + sector_t start_sector; }; typedef struct dev_info dev_info_t; -- cgit v1.2.3 From ab5bd5cbc8d4b868378d062eed3d4240930fbb86 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Mon, 13 Oct 2008 11:55:12 +1100 Subject: md: Convert remaining 1k representations in linear.c to sectors. This patch renames hash_spacing and preshift to spacing and sector_shift respectively with the following change of semantics: Case 1: (sizeof(sector_t) <= sizeof(u32)). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In this case, we have sector_shift = preshift = 0 and spacing = 2 * hash_spacing. Hence, the index for the hash table which is computed by the new code in which_dev() as sector / spacing equals the old value which was (sector/2) / hash_spacing. Note also that the value of nb_zone stays the same because both sz and base double. Case 2: (sizeof(sector_t) > sizeof(u32)). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (aka the shifting dance case). Here we have sector_shift = preshift + 1 and spacing = 2 * hash_spacing during the computation of nb_zone and curr_sector, but spacing = hash_spacing in which_dev() because in the last hunk of the patch for linear.c we shift down conf->spacing (= 2 * hash_spacing) by one more bit than in the old code. Hence in the computation of nb_zone, sz and base have the same value as before, so nb_zone is not affected. Also curr_sector in the next hunk stays the same. In which_dev() the hash table index is computed as (sector >> sector_shift) / spacing In view of sector_shift = preshift + 1 and spacing = hash_spacing, this equals ((sector/2) >> preshift) / hash_spacing which is the value computed by the old code. Signed-off-by: Andre Noll Signed-off-by: NeilBrown --- include/linux/raid/linear.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/linear.h b/include/linux/raid/linear.h index 87090e98529..f38b9c586af 100644 --- a/include/linux/raid/linear.h +++ b/include/linux/raid/linear.h @@ -15,9 +15,11 @@ struct linear_private_data { struct linear_private_data *prev; /* earlier version */ dev_info_t **hash_table; - sector_t hash_spacing; + sector_t spacing; sector_t array_sectors; - int preshift; /* shift before dividing by hash_spacing */ + int sector_shift; /* shift before dividing + * by spacing + */ dev_info_t disks[0]; }; -- cgit v1.2.3 From fb4d8c76e56a887b9eee99fbc55fe82b18625d30 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 13 Oct 2008 11:55:12 +1100 Subject: md: Remove unnecessary #includes, #defines, and function declarations. A lot of cruft has gathered over the years. Time to remove it. Signed-off-by: NeilBrown --- include/linux/raid/md.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index dc0e3fcb9f2..bb727fa1ce7 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -19,27 +19,7 @@ #define _MD_H #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include /* * 'md_p.h' holds the 'physical' layout of RAID devices @@ -83,10 +63,8 @@ extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_check_recovery(mddev_t *mddev); extern void md_write_start(mddev_t *mddev, struct bio *bi); extern void md_write_end(mddev_t *mddev); -extern void md_handle_safemode(mddev_t *mddev); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev); -extern void md_unplug_mddev(mddev_t *mddev); extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, sector_t sector, int size, struct page *page); -- cgit v1.2.3 From d710e13812600037a723a673dc5c96a071de98d3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 13 Oct 2008 11:55:12 +1100 Subject: md: remove space after function name in declaration and call. Having function (args) instead of function(args) make is harder to search for calls of particular functions. So remove all those spaces. Signed-off-by: NeilBrown --- include/linux/raid/md.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h index bb727fa1ce7..82bea14cae1 100644 --- a/include/linux/raid/md.h +++ b/include/linux/raid/md.h @@ -54,17 +54,17 @@ extern int mdp_major; -extern int register_md_personality (struct mdk_personality *p); -extern int unregister_md_personality (struct mdk_personality *p); -extern mdk_thread_t * md_register_thread (void (*run) (mddev_t *mddev), +extern int register_md_personality(struct mdk_personality *p); +extern int unregister_md_personality(struct mdk_personality *p); +extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev), mddev_t *mddev, const char *name); -extern void md_unregister_thread (mdk_thread_t *thread); +extern void md_unregister_thread(mdk_thread_t *thread); extern void md_wakeup_thread(mdk_thread_t *thread); extern void md_check_recovery(mddev_t *mddev); extern void md_write_start(mddev_t *mddev, struct bio *bi); extern void md_write_end(mddev_t *mddev); extern void md_done_sync(mddev_t *mddev, int blocks, int ok); -extern void md_error (mddev_t *mddev, mdk_rdev_t *rdev); +extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev); extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, sector_t sector, int size, struct page *page); -- cgit v1.2.3 From 6000a368cd8e6da1caf101411bdb494cd6fb8b09 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Tue, 19 Aug 2008 18:45:30 -0500 Subject: [SCSI] block: separate failfast into multiple bits. Multipath is best at handling transport errors. If it gets a device error then there is not much the multipath layer can do. It will just access the same device but from a different path. This patch breaks up failfast into device, transport and driver errors. The multipath layers (md and dm mutlipath) only ask the lower levels to fast fail transport errors. The user of failfast, read ahead, will ask to fast fail on all errors. Note that blk_noretry_request will return true if any failfast bit is set. This allows drivers that do not support the multipath failfast bits to continue to fail on any failfast error like before. Drivers like scsi that are able to fail fast specific errors can check for the specific fail fast type. In the next patch I will convert scsi. Signed-off-by: Mike Christie Cc: Jens Axboe Signed-off-by: James Bottomley --- include/linux/bio.h | 26 +++++++++++++++++--------- include/linux/blkdev.h | 15 ++++++++++++--- 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index ff5b4cf9e2d..1beda208cbf 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -129,25 +129,30 @@ struct bio { * bit 2 -- barrier * Insert a serialization point in the IO queue, forcing previously * submitted IO to be completed before this oen is issued. - * bit 3 -- fail fast, don't want low level driver retries - * bit 4 -- synchronous I/O hint: the block layer will unplug immediately + * bit 3 -- synchronous I/O hint: the block layer will unplug immediately * Note that this does NOT indicate that the IO itself is sync, just * that the block layer will not postpone issue of this IO by plugging. - * bit 5 -- metadata request + * bit 4 -- metadata request * Used for tracing to differentiate metadata and data IO. May also * get some preferential treatment in the IO scheduler - * bit 6 -- discard sectors + * bit 5 -- discard sectors * Informs the lower level device that this range of sectors is no longer * used by the file system and may thus be freed by the device. Used * for flash based storage. + * bit 6 -- fail fast device errors + * bit 7 -- fail fast transport errors + * bit 8 -- fail fast driver errors + * Don't want driver retries for any fast fail whatever the reason. */ #define BIO_RW 0 /* Must match RW in req flags (blkdev.h) */ #define BIO_RW_AHEAD 1 /* Must match FAILFAST in req flags */ #define BIO_RW_BARRIER 2 -#define BIO_RW_FAILFAST 3 -#define BIO_RW_SYNC 4 -#define BIO_RW_META 5 -#define BIO_RW_DISCARD 6 +#define BIO_RW_SYNC 3 +#define BIO_RW_META 4 +#define BIO_RW_DISCARD 5 +#define BIO_RW_FAILFAST_DEV 6 +#define BIO_RW_FAILFAST_TRANSPORT 7 +#define BIO_RW_FAILFAST_DRIVER 8 /* * upper 16 bits of bi_rw define the io priority of this bio @@ -174,7 +179,10 @@ struct bio { #define bio_sectors(bio) ((bio)->bi_size >> 9) #define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) #define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) -#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) +#define bio_failfast_dev(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DEV)) +#define bio_failfast_transport(bio) \ + ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_TRANSPORT)) +#define bio_failfast_driver(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST_DRIVER)) #define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) #define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) #define bio_discard(bio) ((bio)->bi_rw & (1 << BIO_RW_DISCARD)) diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a92d9e4ea96..f3491d22526 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -87,7 +87,9 @@ enum { */ enum rq_flag_bits { __REQ_RW, /* not set, read. set, write */ - __REQ_FAILFAST, /* no low level driver retries */ + __REQ_FAILFAST_DEV, /* no driver retries of device errors */ + __REQ_FAILFAST_TRANSPORT, /* no driver retries of transport errors */ + __REQ_FAILFAST_DRIVER, /* no driver retries of driver errors */ __REQ_DISCARD, /* request to discard sectors */ __REQ_SORTED, /* elevator knows about this request */ __REQ_SOFTBARRIER, /* may not be passed by ioscheduler */ @@ -111,8 +113,10 @@ enum rq_flag_bits { }; #define REQ_RW (1 << __REQ_RW) +#define REQ_FAILFAST_DEV (1 << __REQ_FAILFAST_DEV) +#define REQ_FAILFAST_TRANSPORT (1 << __REQ_FAILFAST_TRANSPORT) +#define REQ_FAILFAST_DRIVER (1 << __REQ_FAILFAST_DRIVER) #define REQ_DISCARD (1 << __REQ_DISCARD) -#define REQ_FAILFAST (1 << __REQ_FAILFAST) #define REQ_SORTED (1 << __REQ_SORTED) #define REQ_SOFTBARRIER (1 << __REQ_SOFTBARRIER) #define REQ_HARDBARRIER (1 << __REQ_HARDBARRIER) @@ -560,7 +564,12 @@ enum { #define blk_special_request(rq) ((rq)->cmd_type == REQ_TYPE_SPECIAL) #define blk_sense_request(rq) ((rq)->cmd_type == REQ_TYPE_SENSE) -#define blk_noretry_request(rq) ((rq)->cmd_flags & REQ_FAILFAST) +#define blk_failfast_dev(rq) ((rq)->cmd_flags & REQ_FAILFAST_DEV) +#define blk_failfast_transport(rq) ((rq)->cmd_flags & REQ_FAILFAST_TRANSPORT) +#define blk_failfast_driver(rq) ((rq)->cmd_flags & REQ_FAILFAST_DRIVER) +#define blk_noretry_request(rq) (blk_failfast_dev(rq) || \ + blk_failfast_transport(rq) || \ + blk_failfast_driver(rq)) #define blk_rq_started(rq) ((rq)->cmd_flags & REQ_STARTED) #define blk_account_rq(rq) (blk_rq_started(rq) && (blk_fs_request(rq) || blk_discard_rq(rq))) -- cgit v1.2.3 From 69fd3a8d098faf41a04930afa83757c0555ee360 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Sun, 12 Oct 2008 16:18:36 +0200 Subject: [MTD] remove unused mtd parameter in of_mtd_parse_partitions() Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: David Woodhouse --- include/linux/mtd/partitions.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 5014f7a9f5d..c92b4d43960 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -73,7 +73,6 @@ struct device; struct device_node; int __devinit of_mtd_parse_partitions(struct device *dev, - struct mtd_info *mtd, struct device_node *node, struct mtd_partition **pparts); -- cgit v1.2.3 From 82d7669dc3c0e795c24111fed88e9d5d70f209e0 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 6 Oct 2008 20:44:04 -0300 Subject: V4L/DVB (9173): S2API: Remove the hardcoded command limit during validation This means that when developers add new commands then they'll be see the DTV_MAX_COMMAND define and will be more likely to modify it, without having to modify the command validation code. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index eb98f8c37ca..1cfcd1a86e8 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -270,6 +270,8 @@ struct dvb_frontend_event { #define DTV_API_VERSION 35 +#define DTV_MAX_COMMAND DTV_API_VERSION + typedef enum fe_pilot { PILOT_ON, PILOT_OFF, -- cgit v1.2.3 From 0a6393ae21d58e85882185ce1e6b0fe28ff2dfa6 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 6 Oct 2008 21:06:48 -0300 Subject: V4L/DVB (9177): S2API: Change _8PSK / _16APSK to PSK_8 and APSK_16 ... and cleanup any drivers using them. I've also removed NBC_QPSK and modified the cx24116 driver to check the delivery_type also, removing some excess namespace baggage. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 1cfcd1a86e8..291dd8e5e58 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -164,9 +164,8 @@ typedef enum fe_modulation { QAM_AUTO, VSB_8, VSB_16, - _8PSK, - _16APSK, - NBC_QPSK, + PSK_8, + APSK_16, DQPSK, } fe_modulation_t; -- cgit v1.2.3 From cc7d705e7a2c28ae1bd8b2fd29524277262967ab Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 6 Oct 2008 21:31:48 -0300 Subject: V4L/DVB (9179): S2API: frontend.h cleanup Reviewing the code briefly and saw this. You can't change more than DTV_IOCTL_MAX_MSGS at once, not 16. Signed-off-by: Brandon Philips Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 291dd8e5e58..3d4fab495fb 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -328,14 +328,14 @@ struct dtv_property { int result; } __attribute__ ((packed)); -/* No more than 16 properties during any given ioctl */ +/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */ +#define DTV_IOCTL_MAX_MSGS 64 + struct dtv_properties { __u32 num; struct dtv_property *props; }; -#define DTV_IOCTL_MAX_MSGS 64 - #define FE_SET_PROPERTY _IOW('o', 82, struct dtv_properties) #define FE_GET_PROPERTY _IOR('o', 83, struct dtv_properties) -- cgit v1.2.3 From a4de91be46b73ec6743b9d76155550e49507723c Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 6 Oct 2008 21:55:46 -0300 Subject: V4L/DVB (9180): S2API: Added support for DTV_CODE_RATE_HP/LP Reports from users that using the new API for tuning DTV was failing, and the cache was missing some essential items. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 3d4fab495fb..6675edfab3f 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -268,8 +268,11 @@ struct dvb_frontend_event { #define DTV_DELIVERY_SYSTEM 17 #define DTV_API_VERSION 35 +#define DTV_API_VERSION 35 +#define DTV_CODE_RATE_HP 36 +#define DTV_CODE_RATE_LP 37 -#define DTV_MAX_COMMAND DTV_API_VERSION +#define DTV_MAX_COMMAND DTV_CODE_RATE_LP typedef enum fe_pilot { PILOT_ON, -- cgit v1.2.3 From b87625f0ccbbc67efba356e73502fa9bbb784b1c Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 6 Oct 2008 21:56:59 -0300 Subject: V4L/DVB (9181): S2API: Add support fot DTV_GUARD_INTERVAL and DTV_TRANSMISSION_MODE Tuning DVB-T via the S2API was failing, missing some essential items. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 6675edfab3f..5578fba208f 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -271,8 +271,10 @@ struct dvb_frontend_event { #define DTV_API_VERSION 35 #define DTV_CODE_RATE_HP 36 #define DTV_CODE_RATE_LP 37 +#define DTV_GUARD_INTERVAL 38 +#define DTV_TRANSMISSION_MODE 39 -#define DTV_MAX_COMMAND DTV_CODE_RATE_LP +#define DTV_MAX_COMMAND DTV_TRANSMISSION_MODE typedef enum fe_pilot { PILOT_ON, -- cgit v1.2.3 From ef526f4246f566370218bb6e639f7549244ca5a2 Mon Sep 17 00:00:00 2001 From: Steven Toth Date: Mon, 6 Oct 2008 22:01:47 -0300 Subject: V4L/DVB (9182): S2API: Added support for DTV_HIERARCHY A user tuning DVB-T via the S2API reports that this was not implemented, and his tuning was failing. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 5578fba208f..e185627219e 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -273,8 +273,9 @@ struct dvb_frontend_event { #define DTV_CODE_RATE_LP 37 #define DTV_GUARD_INTERVAL 38 #define DTV_TRANSMISSION_MODE 39 +#define DTV_HIERARCHY 40 -#define DTV_MAX_COMMAND DTV_TRANSMISSION_MODE +#define DTV_MAX_COMMAND DTV_HIERARCHY typedef enum fe_pilot { PILOT_ON, -- cgit v1.2.3 From a52f68c648585ff615175269d8f6cbcbb08d7f4d Mon Sep 17 00:00:00 2001 From: Darron Broad Date: Tue, 7 Oct 2008 17:30:45 -0300 Subject: V4L/DVB (9185): S2API: Ensure we have a reasonable ROLLOFF default Non-initialised cache values get a reasonble default. Signed-off-by: Darron Broad Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index e185627219e..6e4ace27027 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -284,9 +284,9 @@ typedef enum fe_pilot { } fe_pilot_t; typedef enum fe_rolloff { + ROLLOFF_35, /* Implied value in DVB-S, default for DVB-S2 */ ROLLOFF_20, ROLLOFF_25, - ROLLOFF_35, ROLLOFF_AUTO, } fe_rolloff_t; -- cgit v1.2.3 From d945b697d0eea5a811ec299c5f1a25889bb0242b Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 16 Sep 2008 16:23:28 -0700 Subject: Automatic MODULE_ALIAS() for DMI match tables. This makes modpost handle MODULE_DEVICE_TABLE(dmi, xxxx). I had to change the string pointers in the match table to char arrays, and picked a size of 79 bytes almost at random -- do we need to make it bigger than that? I was a bit concerned about the 'bloat' this introduces into the match tables, but they should all be __initdata so it shouldn't matter too much. (Actually, modpost does go through the relocations and look at most of them; it wouldn't be impossible to make it handle string pointers -- but doesn't seem to be worth the effort, since they're __initdata). Signed-off-by: David Woodhouse --- include/linux/dmi.h | 41 ++--------------------------------- include/linux/mod_devicetable.h | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 39 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 2a063b64133..e5084eb5943 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -2,29 +2,9 @@ #define __DMI_H__ #include +#include -enum dmi_field { - DMI_NONE, - DMI_BIOS_VENDOR, - DMI_BIOS_VERSION, - DMI_BIOS_DATE, - DMI_SYS_VENDOR, - DMI_PRODUCT_NAME, - DMI_PRODUCT_VERSION, - DMI_PRODUCT_SERIAL, - DMI_PRODUCT_UUID, - DMI_BOARD_VENDOR, - DMI_BOARD_NAME, - DMI_BOARD_VERSION, - DMI_BOARD_SERIAL, - DMI_BOARD_ASSET_TAG, - DMI_CHASSIS_VENDOR, - DMI_CHASSIS_TYPE, - DMI_CHASSIS_VERSION, - DMI_CHASSIS_SERIAL, - DMI_CHASSIS_ASSET_TAG, - DMI_STRING_MAX, -}; +/* enum dmi_field is in mod_devicetable.h */ enum dmi_device_type { DMI_DEV_TYPE_ANY = 0, @@ -48,23 +28,6 @@ struct dmi_header { u16 handle; }; -/* - * DMI callbacks for problem boards - */ -struct dmi_strmatch { - u8 slot; - char *substr; -}; - -struct dmi_system_id { - int (*callback)(const struct dmi_system_id *); - const char *ident; - struct dmi_strmatch matches[4]; - void *driver_data; -}; - -#define DMI_MATCH(a, b) { a, b } - struct dmi_device { struct list_head list; int type; diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index c4db5827963..3481a7d5bc0 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -388,5 +388,52 @@ struct i2c_device_id { __attribute__((aligned(sizeof(kernel_ulong_t)))); }; +/* dmi */ +enum dmi_field { + DMI_NONE, + DMI_BIOS_VENDOR, + DMI_BIOS_VERSION, + DMI_BIOS_DATE, + DMI_SYS_VENDOR, + DMI_PRODUCT_NAME, + DMI_PRODUCT_VERSION, + DMI_PRODUCT_SERIAL, + DMI_PRODUCT_UUID, + DMI_BOARD_VENDOR, + DMI_BOARD_NAME, + DMI_BOARD_VERSION, + DMI_BOARD_SERIAL, + DMI_BOARD_ASSET_TAG, + DMI_CHASSIS_VENDOR, + DMI_CHASSIS_TYPE, + DMI_CHASSIS_VERSION, + DMI_CHASSIS_SERIAL, + DMI_CHASSIS_ASSET_TAG, + DMI_STRING_MAX, +}; + +struct dmi_strmatch { + unsigned char slot; + char substr[79]; +}; + +#ifndef __KERNEL__ +struct dmi_system_id { + kernel_ulong_t callback; + kernel_ulong_t ident; + struct dmi_strmatch matches[4]; + kernel_ulong_t driver_data + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; +#else +struct dmi_system_id { + int (*callback)(const struct dmi_system_id *); + const char *ident; + struct dmi_strmatch matches[4]; + void *driver_data; +}; +#endif + +#define DMI_MATCH(a, b) { a, b } #endif /* LINUX_MOD_DEVICETABLE_H */ -- cgit v1.2.3 From 0c8946d97ae7d2d6691f8290a10faa63453b63f8 Mon Sep 17 00:00:00 2001 From: David Miller Date: Mon, 13 Oct 2008 10:35:23 +0100 Subject: serial: Make uart_port's ioport "unsigned long". Otherwise the top 32-bits of the resource value get chopped off on 64-bit systems, and the resulting I/O accesses go to random places. Thanks to testing and debugging by Josip Rodin, which helped track this down. Signed-off-by: David S. Miller Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/serial_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 3b2f6c04855..e27f216361f 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -241,7 +241,7 @@ typedef unsigned int __bitwise__ upf_t; struct uart_port { spinlock_t lock; /* port lock */ - unsigned int iobase; /* in/out[bwl] */ + unsigned long iobase; /* in/out[bwl] */ unsigned char __iomem *membase; /* read/write[bwl] */ unsigned int irq; /* irq number */ unsigned int uartclk; /* base uart clock */ -- cgit v1.2.3 From e04957365b21066285557e42ffe16d8330d46c02 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:36:58 +0100 Subject: tty: split the buffering from tty_io The two are basically independent chunks of code so lets split them up for readability and sanity. It also makes the API boundaries much clearer. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 0cbec74ec08..7271c6247d8 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -347,6 +347,9 @@ extern void __do_SAK(struct tty_struct *tty); extern void disassociate_ctty(int priv); extern void no_tty(void); extern void tty_flip_buffer_push(struct tty_struct *tty); +extern void tty_buffer_free_all(struct tty_struct *tty); +extern void tty_buffer_flush(struct tty_struct *tty); +extern void tty_buffer_init(struct tty_struct *tty); extern speed_t tty_get_baud_rate(struct tty_struct *tty); extern speed_t tty_termios_baud_rate(struct ktermios *termios); extern speed_t tty_termios_input_baud_rate(struct ktermios *termios); -- cgit v1.2.3 From 348eb12e5598be97400c749d3d93a71856ae0b2b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:37:17 +0100 Subject: pps: Reserve a line discipline number for PPS Add a new line discipline for "pulse per second" devices connected to a serial port. Signed-off-by: Rodolfo Giometti Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 7271c6247d8..e3612c3ac19 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -23,7 +23,7 @@ */ #define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ #define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ -#define NR_LDISCS 18 +#define NR_LDISCS 19 /* line disciplines */ #define N_TTY 0 @@ -45,6 +45,7 @@ #define N_HCI 15 /* Bluetooth HCI UART */ #define N_GIGASET_M101 16 /* Siemens Gigaset M101 serial DECT adapter */ #define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ +#define N_PPS 18 /* Pulse per Second */ /* * This character is the same as _POSIX_VDISABLE: it cannot be used as -- cgit v1.2.3 From 9c9f4ded90a59eee84e15f5fd38c03d60184e112 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:37:26 +0100 Subject: tty: Add a kref count Introduce a kref to the tty structure and use it to protect the tty->signal tty references. For now we don't introduce it for anything else. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index e3612c3ac19..b6e6c26883e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -209,6 +209,7 @@ struct tty_operations; struct tty_struct { int magic; + struct kref kref; struct tty_driver *driver; const struct tty_operations *ops; int index; @@ -311,6 +312,23 @@ extern int kmsg_redirect; extern void console_init(void); extern int vcs_init(void); +/** + * tty_kref_get - get a tty reference + * @tty: tty device + * + * Return a new reference to a tty object. The caller must hold + * sufficient locks/counts to ensure that their existing reference cannot + * go away + */ + +extern inline struct tty_struct *tty_kref_get(struct tty_struct *tty) +{ + if (tty) + kref_get(&tty->kref); + return tty; +} +extern void tty_kref_put(struct tty_struct *tty); + extern int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, const char *routine); extern char *tty_name(struct tty_struct *tty, char *buf); -- cgit v1.2.3 From c26c56c0f40e200e61d1390629c806f6adaffbcc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:37:48 +0100 Subject: tty: Cris has a nice RS485 ioctl so we should steal it JP Tosoni observed: "About a RS485 ioctl: could you consider the attached files which are already in the Linux kernel (in include/asm-cris). They define a TIOCSERSETRS485 (ioctl.h), and the data structure (rs485.h) with allows to specify timings. Sounds just like what we want ?" and he's right: sort of. Rework the structure to use flag bits and make the time delay a fixed sized field so we don't get 32/64bit problems. Add the ioctls to x86 so that people know what to add to their platform of choice. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/serial.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/serial.h b/include/linux/serial.h index deb714314fb..1ea8d9265bf 100644 --- a/include/linux/serial.h +++ b/include/linux/serial.h @@ -173,6 +173,22 @@ struct serial_icounter_struct { int reserved[9]; }; +/* + * Serial interface for controlling RS485 settings on chips with suitable + * support. Set with TIOCSRS485 and get with TIOCGRS485 if supported by your + * platform. The set function returns the new state, with any unsupported bits + * reverted appropriately. + */ + +struct serial_rs485 { + __u32 flags; /* RS485 feature flags */ +#define SER_RS485_ENABLED (1 << 0) +#define SER_RS485_RTS_ON_SEND (1 << 1) +#define SER_RS485_RTS_AFTER_SEND (1 << 2) + __u32 delay_rts_before_send; /* Milliseconds */ + __u32 padding[6]; /* Memory is cheap, new structs + are a royal PITA .. */ +}; #ifdef __KERNEL__ #include -- cgit v1.2.3 From 1d65b4a088de407e99714fdc27862449db04fb5c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:38:18 +0100 Subject: tty: Add termiox We need a way to describe the various additional modes and flow control features that random weird hardware shows up and software such as wine wants to emulate as Windows supports them. TCGETX/TCSETX and the termiox ioctl are a SYS5 extension that we might as well adopt. This patches adds the structures and the basic ioctl interfaces when the TCGETX etc defines are added for an architecture. Drivers wishing to use this stuff need to add new methods. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/termios.h | 15 +++++++++++++++ include/linux/tty.h | 1 + include/linux/tty_driver.h | 9 +++++++++ 3 files changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/termios.h b/include/linux/termios.h index 478662889f4..2acd0c1f8a2 100644 --- a/include/linux/termios.h +++ b/include/linux/termios.h @@ -4,4 +4,19 @@ #include #include +#define NFF 5 + +struct termiox +{ + __u16 x_hflag; + __u16 x_cflag; + __u16 x_rflag[NFF]; + __u16 x_sflag; +}; + +#define RTSXOFF 0x0001 /* RTS flow control on input */ +#define CTSXON 0x0002 /* CTS flow control on output */ +#define DTRXOFF 0x0004 /* DTR flow control on input */ +#define DSRXON 0x0008 /* DCD flow control on output */ + #endif diff --git a/include/linux/tty.h b/include/linux/tty.h index b6e6c26883e..b64d10b6654 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -219,6 +219,7 @@ struct tty_struct { spinlock_t ctrl_lock; /* Termios values are protected by the termios mutex */ struct ktermios *termios, *termios_locked; + struct termiox *termiox; /* May be NULL for unsupported */ char name[64]; struct pid *pgrp; /* Protected by ctrl lock */ struct pid *session; diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 16d27944c32..ac6e58e26b7 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -180,6 +180,14 @@ * not force errors here if they are not resizable objects (eg a serial * line). See tty_do_resize() if you need to wrap the standard method * in your own logic - the usual case. + * + * void (*set_termiox)(struct tty_struct *tty, struct termiox *new); + * + * Called when the device receives a termiox based ioctl. Passes down + * the requested data from user space. This method will not be invoked + * unless the tty also has a valid tty->termiox pointer. + * + * Optional: Called under the termios lock */ #include @@ -220,6 +228,7 @@ struct tty_operations { unsigned int set, unsigned int clear); int (*resize)(struct tty_struct *tty, struct tty_struct *real_tty, struct winsize *ws); + int (*set_termiox)(struct tty_struct *tty, struct termiox *tnew); #ifdef CONFIG_CONSOLE_POLL int (*poll_init)(struct tty_driver *driver, int line, char *options); int (*poll_get_char)(struct tty_driver *driver, int line); -- cgit v1.2.3 From 4a90f09b20f4622dcbff1f0e1e6bae1704f8ad8c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:39:46 +0100 Subject: tty: usb-serial krefs Use kref in the USB serial drivers so that we don't free tty structures from under the URB receive handlers as has historically been the case if you were unlucky. This also gives us a framework for general tty drivers to use tty_port objects and refcount. Contains two err->dev_err changes merged together to fix clashes in the -next tree. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index b64d10b6654..c30ed8d3bcb 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -182,6 +182,7 @@ struct signal_struct; struct tty_port { struct tty_struct *tty; /* Back pointer */ + spinlock_t lock; /* Lock protecting tty field */ int blocked_open; /* Waiting to open */ int count; /* Usage count */ wait_queue_head_t open_wait; /* Open waiters */ @@ -405,6 +406,8 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay); extern void tty_port_init(struct tty_port *port); extern int tty_port_alloc_xmit_buf(struct tty_port *port); extern void tty_port_free_xmit_buf(struct tty_port *port); +extern struct tty_struct *tty_port_tty_get(struct tty_port *port); +extern void tty_port_tty_set(struct tty_port *port, struct tty_struct *tty); extern int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc); extern int tty_unregister_ldisc(int disc); -- cgit v1.2.3 From 2cb5998b5f0ccc886fdda3509059eef297b49577 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:40:30 +0100 Subject: tty: the vhangup syscall is racy We now have the infrastructure to sort this out but rather than teaching the syscall tty lock rules we move the hard work into a tty helper Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index c30ed8d3bcb..e00393a3d1c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -361,6 +361,7 @@ extern int is_ignored(int sig); extern int tty_signal(int sig, struct tty_struct *tty); extern void tty_hangup(struct tty_struct *tty); extern void tty_vhangup(struct tty_struct *tty); +extern void tty_vhangup_self(void); extern void tty_unhangup(struct file *filp); extern int tty_hung_up_p(struct file *filp); extern void do_SAK(struct tty_struct *tty); -- cgit v1.2.3 From feebed6515a113eeb33919e9557a8b9710ea627c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:41:30 +0100 Subject: tty: shutdown method Right now there are various drivers that try to use tty->count to know when they get the final close. Aristeau Rozanski showed while debugging the vt sysfs race that this isn't entirely safe. Instead of driver side tricks to work around this introduce a shutdown which is called when the tty is being destructed. This also means that the shutdown method is tied into the refcounting. Use this to rework the console close/sysfs logic. Remove lots of special case code from the tty core code. The pty code can now have a shutdown() method that replaces the special case hackery in the tree free up paths. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 3 ++- include/linux/tty_driver.h | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index e00393a3d1c..6e39c705b9b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -354,7 +354,8 @@ extern void tty_throttle(struct tty_struct *tty); extern void tty_unthrottle(struct tty_struct *tty); extern int tty_do_resize(struct tty_struct *tty, struct tty_struct *real_tty, struct winsize *ws); - +extern void tty_shutdown(struct tty_struct *tty); +extern void tty_free_termios(struct tty_struct *tty); extern int is_current_pgrp_orphaned(void); extern struct pid *tty_get_pgrp(struct tty_struct *tty); extern int is_ignored(int sig); diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index ac6e58e26b7..2322313a858 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -21,6 +21,11 @@ * * Required method. * + * void (*shutdown)(struct tty_struct * tty); + * + * This routine is called when a particular tty device is closed for + * the last time freeing up the resources. + * * int (*write)(struct tty_struct * tty, * const unsigned char *buf, int count); * @@ -200,6 +205,7 @@ struct tty_driver; struct tty_operations { int (*open)(struct tty_struct * tty, struct file * filp); void (*close)(struct tty_struct * tty, struct file * filp); + void (*shutdown)(struct tty_struct *tty); int (*write)(struct tty_struct * tty, const unsigned char *buf, int count); int (*put_char)(struct tty_struct *tty, unsigned char ch); -- cgit v1.2.3 From d81ed10307027e1643a65ab5fe17cc01233d376d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:41:42 +0100 Subject: tty: Remove more special casing and out of place code Carry on pushing code out of tty_io when it belongs to other drivers. I'm not 100% happy with some of this and it will be worth revisiting some of the exports later when the restructuring work is done. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 6 ++++++ include/linux/vt_kern.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 6e39c705b9b..6cc7ccc93c6 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -314,6 +314,8 @@ extern int kmsg_redirect; extern void console_init(void); extern int vcs_init(void); +extern struct class *tty_class; + /** * tty_kref_get - get a tty reference * @tty: tty device @@ -398,6 +400,10 @@ extern int tty_perform_flush(struct tty_struct *tty, unsigned long arg); extern dev_t tty_devnum(struct tty_struct *tty); extern void proc_clear_tty(struct task_struct *p); extern struct tty_struct *get_current_tty(void); +extern void tty_default_fops(struct file_operations *fops); +extern int tty_init_dev(struct tty_driver *driver, int idx, + struct tty_struct **ret_tty, int first_ok); +extern void tty_release_dev(struct file *filp); extern struct mutex tty_mutex; diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 1cbd0a7db4e..2f1113467f7 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -96,7 +96,7 @@ void change_console(struct vc_data *new_vc); void reset_vc(struct vc_data *vc); extern int unbind_con_driver(const struct consw *csw, int first, int last, int deflt); -int vty_init(void); +int vty_init(const struct file_operations *console_fops); /* * vc_screen.c shares this temporary buffer with the console write code so that -- cgit v1.2.3 From 99f1fe189daf8e99a847e420567e49dd7ee2aae7 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:42:00 +0100 Subject: tty: Clean up the tty_init_dev changes further Fix up the naming, style and extract some bits of code into the driver specific code Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty_driver.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 2322313a858..2c5c35c4656 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -7,6 +7,14 @@ * defined; unless noted otherwise, they are optional, and can be * filled in with a null pointer. * + * struct tty_struct * (*lookup)(struct tty_driver *self, int idx) + * + * Return the tty device corresponding to idx, NULL if there is not + * one currently in use and an ERR_PTR value on error. Called under + * tty_mutex (for now!) + * + * Optional method. Default behaviour is to use the ttys array + * * int (*open)(struct tty_struct * tty, struct file * filp); * * This routine is called when a particular tty device is opened. @@ -203,6 +211,7 @@ struct tty_struct; struct tty_driver; struct tty_operations { + struct tty_struct * (*lookup)(struct tty_driver *driver, int idx); int (*open)(struct tty_struct * tty, struct file * filp); void (*close)(struct tty_struct * tty, struct file * filp); void (*shutdown)(struct tty_struct *tty); -- cgit v1.2.3 From 7d7b93c1452f381350dbaf276a63357fa6559e6d Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:42:09 +0100 Subject: tty: kref the tty driver object Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty_driver.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 2c5c35c4656..ba891dd2355 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -253,6 +253,7 @@ struct tty_operations { struct tty_driver { int magic; /* magic number for this structure */ + struct kref kref; /* Reference management */ struct cdev cdev; struct module *owner; const char *driver_name; @@ -266,7 +267,6 @@ struct tty_driver { short subtype; /* subtype of tty driver */ struct ktermios init_termios; /* Initial termios */ int flags; /* tty driver flags */ - int refcount; /* for loadable tty drivers */ struct proc_dir_entry *proc_entry; /* /proc fs entry */ struct tty_driver *other; /* only used for the PTY driver */ @@ -288,12 +288,19 @@ struct tty_driver { extern struct list_head tty_drivers; -struct tty_driver *alloc_tty_driver(int lines); -void put_tty_driver(struct tty_driver *driver); -void tty_set_operations(struct tty_driver *driver, +extern struct tty_driver *alloc_tty_driver(int lines); +extern void put_tty_driver(struct tty_driver *driver); +extern void tty_set_operations(struct tty_driver *driver, const struct tty_operations *op); extern struct tty_driver *tty_find_polling_driver(char *name, int *line); +extern void tty_driver_kref_put(struct tty_driver *driver); +extern inline struct tty_driver *tty_driver_kref_get(struct tty_driver *d) +{ + kref_get(&d->kref); + return d; +} + /* tty driver magic number */ #define TTY_DRIVER_MAGIC 0x5402 -- cgit v1.2.3 From 8b0a88d5912ab549d5adac2c8498ecdaae5319a5 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:42:19 +0100 Subject: tty: More driver operations We have the lookup operation abstracted which is nice for pty cleanup but we really want to abstract the add/remove entries as well so that we can pull the pty code out of the tty core and create a clear defined interface for the tty driver table. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty_driver.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index ba891dd2355..005d06ad46a 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -15,6 +15,20 @@ * * Optional method. Default behaviour is to use the ttys array * + * int (*install)(struct tty_driver *self, struct tty_struct *tty) + * + * Install a new tty into the tty driver internal tables. Used in + * conjunction with lookup and remove methods. + * + * Optional method. Default behaviour is to use the ttys array + * + * void (*remove)(struct tty_driver *self, struct tty_struct *tty) + * + * Remove a closed tty from the tty driver internal tables. Used in + * conjunction with lookup and remove methods. + * + * Optional method. Default behaviour is to use the ttys array + * * int (*open)(struct tty_struct * tty, struct file * filp); * * This routine is called when a particular tty device is opened. @@ -212,6 +226,8 @@ struct tty_driver; struct tty_operations { struct tty_struct * (*lookup)(struct tty_driver *driver, int idx); + int (*install)(struct tty_driver *driver, struct tty_struct *tty); + void (*remove)(struct tty_driver *driver, struct tty_struct *tty); int (*open)(struct tty_struct * tty, struct file * filp); void (*close)(struct tty_struct * tty, struct file * filp); void (*shutdown)(struct tty_struct *tty); -- cgit v1.2.3 From 73ec06fc5f5c8e1097a7a4a4ab2d7c6c3a007e81 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:42:29 +0100 Subject: tty: Finish fixing up the init_dev interface to use ERR_PTR Original suggestion and proposal from Sukadev Bhattiprolu. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 6cc7ccc93c6..54523a37e95 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -401,8 +401,8 @@ extern dev_t tty_devnum(struct tty_struct *tty); extern void proc_clear_tty(struct task_struct *p); extern struct tty_struct *get_current_tty(void); extern void tty_default_fops(struct file_operations *fops); -extern int tty_init_dev(struct tty_driver *driver, int idx, - struct tty_struct **ret_tty, int first_ok); +extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, + int first_ok); extern void tty_release_dev(struct file *filp); extern struct mutex tty_mutex; -- cgit v1.2.3 From bf970ee46e0fb363c8df4393229121d54330a98e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:42:39 +0100 Subject: tty: extract the pty init time special cases The majority of the remaining init_dev code is pty special cases. We refactor this code into the driver->install method. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 54523a37e95..3c7c75794a4 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -401,9 +401,14 @@ extern dev_t tty_devnum(struct tty_struct *tty); extern void proc_clear_tty(struct task_struct *p); extern struct tty_struct *get_current_tty(void); extern void tty_default_fops(struct file_operations *fops); +extern struct tty_struct *alloc_tty_struct(void); +extern void free_tty_struct(struct tty_struct *tty); +extern void initialize_tty_struct(struct tty_struct *tty, + struct tty_driver *driver, int idx); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, int first_ok); extern void tty_release_dev(struct file *filp); +extern int tty_init_termios(struct tty_struct *tty); extern struct mutex tty_mutex; -- cgit v1.2.3 From 15f1a6338ddd4e69fff965d4b3a0e1bfb7a13d9c Mon Sep 17 00:00:00 2001 From: Sukadev Bhattiprolu Date: Mon, 13 Oct 2008 10:42:59 +0100 Subject: Add an instance parameter devpts interfaces Pass-in 'inode' or 'tty' parameter to devpts interfaces. With multiple devpts instances, these parameters will be used in subsequent patches to identify the instance of devpts mounted. The parameters also help simplify devpts implementation. Changelog[v3]: - minor changes due to merge with ttydev updates - rename parameters to emphasize they are ptmx or pts inodes - pass-in tty_struct * to devpts_pty_kill() (this will help cleanup the get_node() call in a subsequent patch) Signed-off-by: Sukadev Bhattiprolu Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/devpts_fs.h | 31 +++++++++++++++++++++---------- include/linux/tty_driver.h | 3 ++- 2 files changed, 23 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h index 154769cad3f..5ce0e5fd712 100644 --- a/include/linux/devpts_fs.h +++ b/include/linux/devpts_fs.h @@ -17,20 +17,31 @@ #ifdef CONFIG_UNIX98_PTYS -int devpts_new_index(void); -void devpts_kill_index(int idx); -int devpts_pty_new(struct tty_struct *tty); /* mknod in devpts */ -struct tty_struct *devpts_get_tty(int number); /* get tty structure */ -void devpts_pty_kill(int number); /* unlink */ +int devpts_new_index(struct inode *ptmx_inode); +void devpts_kill_index(struct inode *ptmx_inode, int idx); +/* mknod in devpts */ +int devpts_pty_new(struct inode *ptmx_inode, struct tty_struct *tty); +/* get tty structure */ +struct tty_struct *devpts_get_tty(struct inode *pts_inode, int number); +/* unlink */ +void devpts_pty_kill(struct tty_struct *tty); #else /* Dummy stubs in the no-pty case */ -static inline int devpts_new_index(void) { return -EINVAL; } -static inline void devpts_kill_index(int idx) { } -static inline int devpts_pty_new(struct tty_struct *tty) { return -EINVAL; } -static inline struct tty_struct *devpts_get_tty(int number) { return NULL; } -static inline void devpts_pty_kill(int number) { } +static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; } +static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { } +static inline int devpts_pty_new(struct inode *ptmx_inode, + struct tty_struct *tty) +{ + return -EINVAL; +} +static inline struct tty_struct *devpts_get_tty(struct inode *pts_inode, + int number) +{ + return NULL; +} +static inline void devpts_pty_kill(struct tty_struct *tty) { } #endif diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 005d06ad46a..78416b90158 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -225,7 +225,8 @@ struct tty_struct; struct tty_driver; struct tty_operations { - struct tty_struct * (*lookup)(struct tty_driver *driver, int idx); + struct tty_struct * (*lookup)(struct tty_driver *driver, + struct inode *inode, int idx); int (*install)(struct tty_driver *driver, struct tty_struct *tty); void (*remove)(struct tty_driver *driver, struct tty_struct *tty); int (*open)(struct tty_struct * tty, struct file * filp); -- cgit v1.2.3 From 47afa7a5a8a8fb9e60cdb6a3bd612e07c37e9d90 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 10:44:17 +0100 Subject: tty: some ICANON magic is in the wrong places Move the set up on ldisc change into the ldisc Move the INQ/OUTQ cases into the driver not in shared ioctl code where it gives bogus answers for other ldisc values Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/tty.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index 3c7c75794a4..3b8121d4e36 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -466,7 +466,7 @@ static inline void tty_audit_push_task(struct task_struct *tsk, #endif /* tty_ioctl.c */ -extern int n_tty_ioctl(struct tty_struct *tty, struct file *file, +extern int n_tty_ioctl_helper(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); /* serial.c */ -- cgit v1.2.3 From a447c0932445f92ce6f4c1bd020f62c5097a7842 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Mon, 13 Oct 2008 10:46:57 +0100 Subject: vfs: Use const for kernel parser table This is a much better version of a previous patch to make the parser tables constant. Rather than changing the typedef, we put the "const" in all the various places where its required, allowing the __initconst exception for nfsroot which was the cause of the previous trouble. This was posted for review some time ago and I believe its been in -mm since then. Signed-off-by: Steven Whitehouse Cc: Alexander Viro Signed-off-by: Linus Torvalds --- include/linux/parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/parser.h b/include/linux/parser.h index 7dcd0507575..ea2281e726f 100644 --- a/include/linux/parser.h +++ b/include/linux/parser.h @@ -25,7 +25,7 @@ typedef struct { char *to; } substring_t; -int match_token(char *, match_table_t table, substring_t args[]); +int match_token(char *, const match_table_t table, substring_t args[]); int match_int(substring_t *, int *result); int match_octal(substring_t *, int *result); int match_hex(substring_t *, int *result); -- cgit v1.2.3 From b14c72127fbe8f97e49de7437520175673f7306a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:30 +0200 Subject: ide: drop dsc_handle argument from ide_pc_intr() * Add 'int dsc' argument to ->pc_callback method. * Call ide_tape_handle_dsc() internally in ide_tape_callback() if dsc argument is set and update ide_pc_intr() accordingly. There should be no functional changes caused by this patch. Cc: Borislav Petkov Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a9d82d6e6bd..93fd2bc17bf 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -485,7 +485,7 @@ struct ide_drive_s { struct completion gendev_rel_comp; /* to deal with device release() */ /* callback for packet commands */ - void (*pc_callback)(struct ide_drive_s *); + void (*pc_callback)(struct ide_drive_s *, int); unsigned long atapi_flags; }; @@ -1174,7 +1174,7 @@ int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - void (*retry_pc)(ide_drive_t *), void (*dsc_handle)(ide_drive_t *), + void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, -- cgit v1.2.3 From 2b9efba48283f34083df6bc53f6752fba4e4d409 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: add pointer to the current packet command to ide_drive_t * Add pointer to the current packet command (struct ide_atapi_pc *pc) to ide_drive_t and use it instead of the pointer in struct ide_*_obj. * Use drive->pc in ide_{issue,transfer}_pc() and ide_pc_intr() instead of 'pc' argument. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 93fd2bc17bf..98d29df1ee0 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -322,6 +322,7 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; +struct ide_atapi_pc; struct ide_devset; struct ide_driver_s; @@ -484,6 +485,9 @@ struct ide_drive_s { struct device gendev; struct completion gendev_rel_comp; /* to deal with device release() */ + /* current packet command */ + struct ide_atapi_pc *pc; + /* callback for packet commands */ void (*pc_callback)(struct ide_drive_s *, int); @@ -1171,15 +1175,15 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); -ide_startstop_t ide_transfer_pc(ide_drive_t *, struct ide_atapi_pc *, +ide_startstop_t ide_transfer_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); -ide_startstop_t ide_issue_pc(ide_drive_t *, struct ide_atapi_pc *, +ide_startstop_t ide_issue_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -- cgit v1.2.3 From 844b9468523c8c2c45b90df4efcabcbe4926b5ab Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: drop 'timeout' and 'expiry' arguments from ide_pc_intr() * Move idescsi_expiry() to ide-atapi.c. * Move get_timeout() to . * Drop 'timeout' and 'expiry' arguments from ide_pc_intr(). While at it: * idescsi_expiry() -> ide_scsi_expiry() * get_timeout() -> ide_scsi_get_timeout() There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 98d29df1ee0..3bf2bf0a56d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1175,8 +1175,14 @@ int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, - ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, +static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) +{ + return max_t(unsigned long, WAIT_CMD, pc->timeout - jiffies); +} + +int ide_scsi_expiry(ide_drive_t *); + +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, -- cgit v1.2.3 From 67c56364df843fb9e3ed1af014b8fbe4b22ff25d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:31 +0200 Subject: ide: add request_sense_{pc,rq} to ide_drive_t Add 'struct ide_atapi_pc request_sense_pc' and 'request request_sense_rq' to ide_drive_t and use them instead of fields in struct ide_{floppy,tape}_obj. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 134 ++++++++++++++++++++++++++-------------------------- 1 file changed, 68 insertions(+), 66 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 3bf2bf0a56d..908b4fc9772 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -322,7 +322,71 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; -struct ide_atapi_pc; +/* ATAPI packet command flags */ +enum { + /* set when an error is considered normal - no retry (ide-tape) */ + PC_FLAG_ABORT = (1 << 0), + PC_FLAG_SUPPRESS_ERROR = (1 << 1), + PC_FLAG_WAIT_FOR_DSC = (1 << 2), + PC_FLAG_DMA_OK = (1 << 3), + PC_FLAG_DMA_IN_PROGRESS = (1 << 4), + PC_FLAG_DMA_ERROR = (1 << 5), + PC_FLAG_WRITING = (1 << 6), + /* command timed out */ + PC_FLAG_TIMEDOUT = (1 << 7), +}; + +/* + * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. + * This is used for several packet commands (not for READ/WRITE commands). + */ +#define IDE_PC_BUFFER_SIZE 256 + +struct ide_atapi_pc { + /* actual packet bytes */ + u8 c[12]; + /* incremented on each retry */ + int retries; + int error; + + /* bytes to transfer */ + int req_xfer; + /* bytes actually transferred */ + int xferred; + + /* data buffer */ + u8 *buf; + /* current buffer position */ + u8 *cur_pos; + int buf_size; + /* missing/available data on the current buffer */ + int b_count; + + /* the corresponding request */ + struct request *rq; + + unsigned long flags; + + /* + * those are more or less driver-specific and some of them are subject + * to change/removal later. + */ + u8 pc_buf[IDE_PC_BUFFER_SIZE]; + + /* idetape only */ + struct idetape_bh *bh; + char *b_data; + + /* idescsi only for now */ + struct scatterlist *sg; + unsigned int sg_cnt; + + struct scsi_cmnd *scsi_cmd; + void (*done) (struct scsi_cmnd *); + + unsigned long timeout; +}; + struct ide_devset; struct ide_driver_s; @@ -492,6 +556,9 @@ struct ide_drive_s { void (*pc_callback)(struct ide_drive_s *, int); unsigned long atapi_flags; + + struct ide_atapi_pc request_sense_pc; + struct request request_sense_rq; }; typedef struct ide_drive_s ide_drive_t; @@ -768,71 +835,6 @@ ide_decl_devset(pio_mode); ide_decl_devset(unmaskirq); ide_decl_devset(using_dma); -/* ATAPI packet command flags */ -enum { - /* set when an error is considered normal - no retry (ide-tape) */ - PC_FLAG_ABORT = (1 << 0), - PC_FLAG_SUPPRESS_ERROR = (1 << 1), - PC_FLAG_WAIT_FOR_DSC = (1 << 2), - PC_FLAG_DMA_OK = (1 << 3), - PC_FLAG_DMA_IN_PROGRESS = (1 << 4), - PC_FLAG_DMA_ERROR = (1 << 5), - PC_FLAG_WRITING = (1 << 6), - /* command timed out */ - PC_FLAG_TIMEDOUT = (1 << 7), -}; - -/* - * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. - * This is used for several packet commands (not for READ/WRITE commands). - */ -#define IDE_PC_BUFFER_SIZE 256 - -struct ide_atapi_pc { - /* actual packet bytes */ - u8 c[12]; - /* incremented on each retry */ - int retries; - int error; - - /* bytes to transfer */ - int req_xfer; - /* bytes actually transferred */ - int xferred; - - /* data buffer */ - u8 *buf; - /* current buffer position */ - u8 *cur_pos; - int buf_size; - /* missing/available data on the current buffer */ - int b_count; - - /* the corresponding request */ - struct request *rq; - - unsigned long flags; - - /* - * those are more or less driver-specific and some of them are subject - * to change/removal later. - */ - u8 pc_buf[IDE_PC_BUFFER_SIZE]; - - /* idetape only */ - struct idetape_bh *bh; - char *b_data; - - /* idescsi only for now */ - struct scatterlist *sg; - unsigned int sg_cnt; - - struct scsi_cmnd *scsi_cmd; - void (*done) (struct scsi_cmnd *); - - unsigned long timeout; -}; - #ifdef CONFIG_IDE_PROC_FS /* * /proc/ide interface -- cgit v1.2.3 From 6b0da28b2d0f4f4e2c55689fc062db569075ff60 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ide_retry_pc() helper * Add ide_create_request_sense_cmd() and ide_retry_pc() helpers and convert ide-{atapi,floppy,tape}.c to use them. * Remove no longer used ide*_create_request_sense_cmd(), ide*_retry_pc() and 'retry_pc' argument from ide_pc_intr(). * Make ide_queue_pc_head() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 908b4fc9772..d88cced0d02 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1169,13 +1169,13 @@ enum { REQ_IDETAPE_WRITE = (1 << 3), }; -void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, - struct request *); int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); int ide_set_media_lock(ide_drive_t *, struct gendisk *, int); +void ide_create_request_sense_cmd(ide_drive_t *, struct ide_atapi_pc *); +void ide_retry_pc(ide_drive_t *, struct gendisk *); static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) { @@ -1186,7 +1186,6 @@ int ide_scsi_expiry(ide_drive_t *); ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - void (*retry_pc)(ide_drive_t *), int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, int)); ide_startstop_t ide_transfer_pc(ide_drive_t *, -- cgit v1.2.3 From 85e39035ca381846b031690f4d1ac1f0660da0a2 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: add ->pc_{update,io}_buffers methods Add ->pc_{update,io}_buffers methods to ide_drive_t and use them instead of {update,io}_buffers ide_pc_intr() arguments. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index d88cced0d02..f7fc53d1a81 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -555,6 +555,10 @@ struct ide_drive_s { /* callback for packet commands */ void (*pc_callback)(struct ide_drive_s *, int); + void (*pc_update_buffers)(struct ide_drive_s *, struct ide_atapi_pc *); + int (*pc_io_buffers)(struct ide_drive_s *, struct ide_atapi_pc *, + unsigned int, int); + unsigned long atapi_flags; struct ide_atapi_pc request_sense_pc; @@ -1184,10 +1188,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler, - void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), - int (*io_buffers)(ide_drive_t *, struct ide_atapi_pc *, unsigned int, - int)); +ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler); ide_startstop_t ide_transfer_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); ide_startstop_t ide_issue_pc(ide_drive_t *, -- cgit v1.2.3 From aa5d2de7b080873f6d9ac3aede423c9713bf0caa Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_pc_intr() static * Always use ide_pc_intr as a handler in ide_pc_intr(). * Remove no longer used ide*_pc_intr() and 'handler' argument from ide_{transfer_pc,pc_intr}(). * Make ide_pc_intr() static. There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index f7fc53d1a81..449a1094700 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1188,9 +1188,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_pc_intr(ide_drive_t *drive, ide_handler_t *handler); -ide_startstop_t ide_transfer_pc(ide_drive_t *, - ide_handler_t *, unsigned int, ide_expiry_t *); +ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *); ide_startstop_t ide_issue_pc(ide_drive_t *, ide_handler_t *, unsigned int, ide_expiry_t *); -- cgit v1.2.3 From baf08f0be6d986521bb2fbdc7af51fc4847da734 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:32 +0200 Subject: ide: make ide_transfer_pc() static * Move ->ticks field from struct ide_floppy_obj to ide_drive_t. * Move idefloppy_transfer_pc() to ide-atapi.c and make ide_transfer_pc() use it. * Always use ide_transfer_pc as a handler in ide_issue_pc(). * Remove no longer used idefloppy_start_pc_transfer(), ide*_transfer_pc() and 'handler' argument from ide_issue_pc(). * Make ide_transfer_pc() static. While at it: * idefloppy_transfer_pc() -> ide_delayed_transfer_pc() * IDEFLOPPY_TICKS_DELAY -> IDEFLOPPY_PC_DELAY * ->ticks -> ->pc_delay There should be no functional changes caused by this patch. Cc: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 449a1094700..85cb96c1fd6 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -531,6 +531,9 @@ struct ide_drive_s { u8 bios_head; /* BIOS/fdisk/LILO number of heads */ u8 bios_sect; /* BIOS/fdisk/LILO sectors per track */ + /* delay this long before sending packet command */ + u8 pc_delay; + unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ unsigned int cyl; /* "real" number of cyls */ unsigned int drive_data; /* used by set_pio_mode/selectproc */ @@ -1188,9 +1191,7 @@ static inline unsigned long ide_scsi_get_timeout(struct ide_atapi_pc *pc) int ide_scsi_expiry(ide_drive_t *); -ide_startstop_t ide_transfer_pc(ide_drive_t *, unsigned int, ide_expiry_t *); -ide_startstop_t ide_issue_pc(ide_drive_t *, - ide_handler_t *, unsigned int, ide_expiry_t *); +ide_startstop_t ide_issue_pc(ide_drive_t *, unsigned int, ide_expiry_t *); ide_startstop_t do_rw_taskfile(ide_drive_t *, ide_task_t *); -- cgit v1.2.3 From 5aeddf907f149cae7e19b7c23ccea3823d00698c Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:34 +0200 Subject: ide: unify conversion macros Introduce to_ide_drv() and ide_drv_g() macros and replace the respective definitions of similar ones in each driver. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 85cb96c1fd6..350ef47ed61 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -570,7 +570,13 @@ struct ide_drive_s { typedef struct ide_drive_s ide_drive_t; -#define to_ide_device(dev)container_of(dev, ide_drive_t, gendev) +#define to_ide_device(dev) container_of(dev, ide_drive_t, gendev) + +#define to_ide_drv(obj, cont_type) \ + container_of(obj, struct cont_type, kref) + +#define ide_drv_g(disk, cont_type) \ + container_of((disk)->private_data, struct cont_type, driver) struct ide_task_s; struct ide_port_info; -- cgit v1.2.3 From b22b2ca4ff0730b14d14bcc36bd1b84873557512 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:34 +0200 Subject: ide: add drive->debug_mask switch Add a debugging on/off switch for controlling driver debugging messages dynamically. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 350ef47ed61..fcd98e1d186 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -545,6 +545,9 @@ struct ide_drive_s { int lun; /* logical unit */ int crc_count; /* crc counter to reduce drive speed */ + + unsigned long debug_mask; /* debugging levels switch */ + #ifdef CONFIG_BLK_DEV_IDEACPI struct ide_acpi_drive_link *acpidata; #endif -- cgit v1.2.3 From e1c7c4641aae8d278fca62b3b5cffad3a8dcb0a4 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:35 +0200 Subject: ide: add a driver-wide debugging macro Add __ide_debug_log() debugging macro which is controlled by drive->debug_mask. The macro has to have the macro DRV_NAME defined in each driver before use. Also, add different debugging levels depending on the functionality debugged. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index fcd98e1d186..02c4c642e6a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -927,6 +927,26 @@ static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t * #define PROC_IDE_READ_RETURN(page,start,off,count,eof,len) return 0; #endif +enum { + /* enter/exit functions */ + IDE_DBG_FUNC = (1 << 0), + /* sense key/asc handling */ + IDE_DBG_SENSE = (1 << 1), + /* packet commands handling */ + IDE_DBG_PC = (1 << 2), + /* request handling */ + IDE_DBG_RQ = (1 << 3), + /* driver probing/setup */ + IDE_DBG_PROBE = (1 << 4), +}; + +/* DRV_NAME has to be defined in the driver before using the macro below */ +#define __ide_debug_log(lvl, fmt, args...) \ +{ \ + if (unlikely(drive->debug_mask & lvl)) \ + printk(KERN_INFO DRV_NAME ": " fmt, ## args); \ +} + /* * Power Management step value (rq->pm->pm_step). * -- cgit v1.2.3 From 35c137531245118962eb40a550661afe317bec03 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:36 +0200 Subject: ide-disk: set_addressing() fixes * Return -EIO if arg > 0 and LBA48 is unsupported. * No need to reset ->addressing. * Make ->addressing a single bit flag. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 02c4c642e6a..90d53c99fe9 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -509,7 +509,7 @@ struct ide_drive_s { unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ unsigned post_reset : 1; unsigned udma33_warned : 1; - unsigned addressing : 2; /* 0=28-bit, 1=48-bit, 2=48-bit doing 28-bit */ + unsigned addressing : 1; /* 0=28-bit, 1=48-bit */ unsigned wcache : 1; /* status of write cache */ unsigned nowerr : 1; /* used for ignoring ATA_DF */ -- cgit v1.2.3 From 97100fc816badbbc162644cfde7ad39ae9211fb4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:36 +0200 Subject: ide: add device flags Add 'unsigned long dev_flags' to ide_drive_t and convert bitfields to IDE_DFLAG_* flags. While at it: - IDE_DFLAG_ADDRESSING -> IDE_DFLAG_LBA48 - fixup some comments - remove needless g->flags zeroing from ide*_probe() There should be no functional changes caused by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 100 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 27 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 90d53c99fe9..b538d2e6dcb 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -459,6 +459,55 @@ enum { IDE_AFLAG_NO_AUTOCLOSE = (1 << 29), }; +/* device flags */ +enum { + /* restore settings after device reset */ + IDE_DFLAG_KEEP_SETTINGS = (1 << 0), + /* device is using DMA for read/write */ + IDE_DFLAG_USING_DMA = (1 << 1), + /* okay to unmask other IRQs */ + IDE_DFLAG_UNMASK = (1 << 2), + /* don't attempt flushes */ + IDE_DFLAG_NOFLUSH = (1 << 3), + /* DSC overlap */ + IDE_DFLAG_DSC_OVERLAP = (1 << 4), + /* give potential excess bandwidth */ + IDE_DFLAG_NICE1 = (1 << 5), + /* device is physically present */ + IDE_DFLAG_PRESENT = (1 << 6), + /* device ejected hint */ + IDE_DFLAG_DEAD = (1 << 7), + /* id read from device (synthetic if not set) */ + IDE_DFLAG_ID_READ = (1 << 8), + IDE_DFLAG_NOPROBE = (1 << 9), + /* need to do check_media_change() */ + IDE_DFLAG_REMOVABLE = (1 << 10), + /* needed for removable devices */ + IDE_DFLAG_ATTACH = (1 << 11), + IDE_DFLAG_FORCED_GEOM = (1 << 12), + /* disallow setting unmask bit */ + IDE_DFLAG_NO_UNMASK = (1 << 13), + /* disallow enabling 32-bit I/O */ + IDE_DFLAG_NO_IO_32BIT = (1 << 14), + /* for removable only: door lock/unlock works */ + IDE_DFLAG_DOORLOCKING = (1 << 15), + /* disallow DMA */ + IDE_DFLAG_NODMA = (1 << 16), + /* powermanagment told us not to do anything, so sleep nicely */ + IDE_DFLAG_BLOCKED = (1 << 17), + /* ide-scsi emulation */ + IDE_DFLAG_SCSI = (1 << 18), + /* sleeping & sleep field valid */ + IDE_DFLAG_SLEEPING = (1 << 19), + IDE_DFLAG_POST_RESET = (1 << 20), + IDE_DFLAG_UDMA33_WARNED = (1 << 21), + IDE_DFLAG_LBA48 = (1 << 22), + /* status of write cache */ + IDE_DFLAG_WCACHE = (1 << 23), + /* used for ignoring ATA_DF */ + IDE_DFLAG_NOWERR = (1 << 24), +}; + struct ide_drive_s { char name[4]; /* drive name, such as "hda" */ char driver_req[10]; /* requests specific driver */ @@ -475,6 +524,8 @@ struct ide_drive_s { #endif struct hwif_s *hwif; /* actually (ide_hwif_t *) */ + unsigned long dev_flags; + unsigned long sleep; /* sleep until this time */ unsigned long service_start; /* time we started last request */ unsigned long service_time; /* service time of last request */ @@ -487,32 +538,6 @@ struct ide_drive_s { u8 state; /* retry state */ u8 waiting_for_dma; /* dma currently in progress */ - unsigned keep_settings : 1; /* restore settings after drive reset */ - unsigned using_dma : 1; /* disk is using dma for read/write */ - unsigned unmask : 1; /* okay to unmask other irqs */ - unsigned noflush : 1; /* don't attempt flushes */ - unsigned dsc_overlap : 1; /* DSC overlap */ - unsigned nice1 : 1; /* give potential excess bandwidth */ - unsigned present : 1; /* drive is physically present */ - unsigned dead : 1; /* device ejected hint */ - unsigned id_read : 1; /* 1=id read from disk 0 = synthetic */ - unsigned noprobe : 1; /* from: hdx=noprobe */ - unsigned removable : 1; /* 1 if need to do check_media_change */ - unsigned attach : 1; /* needed for removable devices */ - unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ - unsigned no_unmask : 1; /* disallow setting unmask bit */ - unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ - unsigned doorlocking : 1; /* for removable only: door lock/unlock works */ - unsigned nodma : 1; /* disallow DMA */ - unsigned blocked : 1; /* 1=powermanagment told us not to do anything, so sleep nicely */ - unsigned scsi : 1; /* 0=default, 1=ide-scsi emulation */ - unsigned sleeping : 1; /* 1=sleeping & sleep field valid */ - unsigned post_reset : 1; - unsigned udma33_warned : 1; - unsigned addressing : 1; /* 0=28-bit, 1=48-bit */ - unsigned wcache : 1; /* status of write cache */ - unsigned nowerr : 1; /* used for ignoring ATA_DF */ - u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ u8 current_speed; /* current transfer rate set */ @@ -826,6 +851,22 @@ static int set_##name(ide_drive_t *drive, int arg) \ return 0; \ } +#define ide_devset_get_flag(name, flag) \ +static int get_##name(ide_drive_t *drive) \ +{ \ + return !!(drive->dev_flags & flag); \ +} + +#define ide_devset_set_flag(name, flag) \ +static int set_##name(ide_drive_t *drive, int arg) \ +{ \ + if (arg) \ + drive->dev_flags |= flag; \ + else \ + drive->dev_flags &= ~flag; \ + return 0; \ +} + #define __IDE_DEVSET(_name, _flags, _get, _set) \ const struct ide_devset ide_devset_##_name = \ __DEVSET(_flags, _get, _set) @@ -861,6 +902,11 @@ ide_devset_get(_name, _field); \ ide_devset_set(_name, _field); \ IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) +#define ide_devset_rw_flag(_name, _field) \ +ide_devset_get_flag(_name, _field); \ +ide_devset_set_flag(_name, _field); \ +IDE_DEVSET(_name, DS_SYNC, get_##_name, set_##_name) + struct ide_proc_devset { const char *name; const struct ide_devset *setting; @@ -1587,6 +1633,6 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive) { ide_drive_t *peer = &drive->hwif->drives[(drive->dn ^ 1) & 1]; - return peer->present ? peer : NULL; + return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL; } #endif /* _IDE_H */ -- cgit v1.2.3 From c39220483ebe6871fb129d4b2236cd95290c41fc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: DMA_PIO_RETRY -> IDE_DFLAG_DMA_PIO_RETRY Add IDE_DFLAG_DMA_PIO_RETRY and use it instead of ide_drive_t.state + DMA_PIO_RETRY. There should be no functional changes cause by this patch. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index b538d2e6dcb..230bd9dd851 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -48,12 +48,6 @@ typedef unsigned char byte; /* used everywhere */ #define ERROR_RESET 3 /* Reset controller every 4th retry */ #define ERROR_RECAL 1 /* Recalibrate every 2nd retry */ -/* - * state flags - */ - -#define DMA_PIO_RETRY 1 /* retrying in PIO */ - #define HWIF(drive) ((ide_hwif_t *)((drive)->hwif)) #define HWGROUP(drive) ((ide_hwgroup_t *)(HWIF(drive)->hwgroup)) @@ -506,6 +500,8 @@ enum { IDE_DFLAG_WCACHE = (1 << 23), /* used for ignoring ATA_DF */ IDE_DFLAG_NOWERR = (1 << 24), + /* retrying in PIO */ + IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), }; struct ide_drive_s { @@ -535,7 +531,6 @@ struct ide_drive_s { select_t select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ - u8 state; /* retry state */ u8 waiting_for_dma; /* dma currently in progress */ u8 quirk_list; /* considered quirky, set for a specific host */ -- cgit v1.2.3 From 0ae4b3199ab1b6d511c6e0948e92049c272a346a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: remove superfluous ->media field from ide_driver_t Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 230bd9dd851..7fd1ec13551 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1029,7 +1029,6 @@ enum { */ struct ide_driver_s { const char *version; - u8 media; ide_startstop_t (*do_request)(ide_drive_t *, struct request *, sector_t); int (*end_request)(ide_drive_t *, int, int); ide_startstop_t (*error)(ide_drive_t *, struct request *rq, u8, u8); -- cgit v1.2.3 From e4634d4ef04fe6d7b114b612e5b71a84187ce76a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:37 +0200 Subject: ide: remove superfluous ->dma field from ide_hwif_t Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 7fd1ec13551..fdec0108dba 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -756,8 +756,6 @@ typedef struct hwif_s { void *hwif_data; /* extra hwif data */ - unsigned dma; - #ifdef CONFIG_BLK_DEV_IDEACPI struct ide_acpi_hwif_link *acpidata; #endif -- cgit v1.2.3 From d1d76714e2f0c520b6c2a84ab5b050d0b3244949 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:38 +0200 Subject: ide: fix HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices Add IDE_DFLAG_LBA device flag and use it instead of ->select.b.lba. Since ->tf_load uses ->select.all for ATA Device/Head register this fixes HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index fdec0108dba..cf7ec3a9d17 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -502,6 +502,7 @@ enum { IDE_DFLAG_NOWERR = (1 << 24), /* retrying in PIO */ IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), + IDE_DFLAG_LBA = (1 << 26), }; struct ide_drive_s { -- cgit v1.2.3 From 0d346ba0730d84f04022f9f984d3f606f69cef37 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:38 +0200 Subject: ide: sanitize ide*_pm_* enums * Move ide*_pm_* enums from ide-io.c to . * idedisk_pm_* -> ide_pm_* * ide_pm_state_* -> ide_pm_* * No need to set ide_pm_* enums to the fixed values. * Uppercase ide_pm_* enums. * Fix/update comments. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index cf7ec3a9d17..02984f1f041 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -988,36 +988,34 @@ enum { } /* - * Power Management step value (rq->pm->pm_step). + * Power Management state machine (rq->pm->pm_step). * - * The step value starts at 0 (ide_pm_state_start_suspend) for a - * suspend operation or 1000 (ide_pm_state_start_resume) for a - * resume operation. - * - * For each step, the core calls the subdriver start_power_step() first. + * For each step, the core calls ide_start_power_step() first. * This can return: * - ide_stopped : In this case, the core calls us back again unless * step have been set to ide_power_state_completed. * - ide_started : In this case, the channel is left busy until an * async event (interrupt) occurs. - * Typically, start_power_step() will issue a taskfile request with + * Typically, ide_start_power_step() will issue a taskfile request with * do_rw_taskfile(). * - * Upon reception of the interrupt, the core will call complete_power_step() + * Upon reception of the interrupt, the core will call ide_complete_power_step() * with the error code if any. This routine should update the step value * and return. It should not start a new request. The core will call - * start_power_step for the new step value, unless step have been set to - * ide_power_state_completed. - * - * Subdrivers are expected to define their own additional power - * steps from 1..999 for suspend and from 1001..1999 for resume, - * other values are reserved for future use. + * ide_start_power_step() for the new step value, unless step have been + * set to IDE_PM_COMPLETED. */ - enum { - ide_pm_state_completed = -1, - ide_pm_state_start_suspend = 0, - ide_pm_state_start_resume = 1000, + IDE_PM_START_SUSPEND, + IDE_PM_FLUSH_CACHE = IDE_PM_START_SUSPEND, + IDE_PM_STANDBY, + + IDE_PM_START_RESUME, + IDE_PM_RESTORE_PIO = IDE_PM_START_RESUME, + IDE_PM_IDLE, + IDE_PM_RESTORE_DMA, + + IDE_PM_COMPLETED, }; /* -- cgit v1.2.3 From 7f612f272ad8abe82411f368bfacf793b466e1b3 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:40 +0200 Subject: ide: remove [ata_]select_t * Use 'drive->dn & 1' in ide_init_disk(). * remove [ata_]select_t. While at it: * Use ATA_DEVICE_OBS define in ide_port_init_devices_data(). Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 32 +------------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 02984f1f041..3e418b996ef 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -278,36 +278,6 @@ typedef union { } b; } special_t; -/* - * ATA-IDE Select Register, aka Device-Head - * - * head : always zeros here - * unit : drive select number: 0/1 - * bit5 : always 1 - * lba : using LBA instead of CHS - * bit7 : always 1 - */ -typedef union { - unsigned all : 8; - struct { -#if defined(__LITTLE_ENDIAN_BITFIELD) - unsigned head : 4; - unsigned unit : 1; - unsigned bit5 : 1; - unsigned lba : 1; - unsigned bit7 : 1; -#elif defined(__BIG_ENDIAN_BITFIELD) - unsigned bit7 : 1; - unsigned lba : 1; - unsigned bit5 : 1; - unsigned unit : 1; - unsigned head : 4; -#else -#error "Please fix " -#endif - } b; -} select_t, ata_select_t; - /* * Status returned from various ide_ functions */ @@ -529,8 +499,8 @@ struct ide_drive_s { unsigned long timeout; /* max time to wait for irq */ special_t special; /* special action flags */ - select_t select; /* basic drive/head select reg value */ + u8 select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ u8 waiting_for_dma; /* dma currently in progress */ -- cgit v1.2.3 From 6982daf71ca9a0b0c36043315e1968b3cb709b7c Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:40 +0200 Subject: ide: convert 'pio_mode' device setting to use DS_SYNC flag * Convert 'pio_mode' device setting to use DS_SYNC flag. * Remove unused special_t.b.{set_tune,serviced} and ide_drive_t.tune_req. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 3e418b996ef..a5e1888b1da 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -262,8 +262,6 @@ static inline int __ide_default_irq(unsigned long base) * set_geometry : respecify drive geometry * recalibrate : seek to cyl 0 * set_multmode : set multmode count - * set_tune : tune interface for drive - * serviced : service command * reserved : unused */ typedef union { @@ -272,9 +270,7 @@ typedef union { unsigned set_geometry : 1; unsigned recalibrate : 1; unsigned set_multmode : 1; - unsigned set_tune : 1; - unsigned serviced : 1; - unsigned reserved : 3; + unsigned reserved : 5; } b; } special_t; @@ -514,7 +510,6 @@ struct ide_drive_s { u8 ready_stat; /* min status value for drive ready */ u8 mult_count; /* current multiple sector setting */ u8 mult_req; /* requested multiple sector setting */ - u8 tune_req; /* requested drive tuning setting */ u8 io_32bit; /* 0=16-bit, 1=32-bit, 2/3=32bit+sync */ u8 bad_wstat; /* used for ignoring ATA_DF */ u8 head; /* "real" number of heads */ -- cgit v1.2.3 From d6ff9f64e68d23feab44efa07cc6aee01f3ef32b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:41 +0200 Subject: ide: merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr() * Add 'struct task_s' to ide_hwif_t and init it to the current command in do_rw_taskfile(). * Merge all TASKFILE_NO_DATA data phase handlers into taskfile_no_intr(). Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 211 ++++++++++++++++++++++++++-------------------------- 1 file changed, 106 insertions(+), 105 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index a5e1888b1da..14d489c2e5a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -282,6 +282,110 @@ typedef enum { ide_started, /* a drive operation was started, handler was set */ } ide_startstop_t; +enum { + IDE_TFLAG_LBA48 = (1 << 0), + IDE_TFLAG_FLAGGED = (1 << 2), + IDE_TFLAG_OUT_DATA = (1 << 3), + IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), + IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), + IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), + IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), + IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), + IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | + IDE_TFLAG_OUT_HOB_NSECT | + IDE_TFLAG_OUT_HOB_LBAL | + IDE_TFLAG_OUT_HOB_LBAM | + IDE_TFLAG_OUT_HOB_LBAH, + IDE_TFLAG_OUT_FEATURE = (1 << 9), + IDE_TFLAG_OUT_NSECT = (1 << 10), + IDE_TFLAG_OUT_LBAL = (1 << 11), + IDE_TFLAG_OUT_LBAM = (1 << 12), + IDE_TFLAG_OUT_LBAH = (1 << 13), + IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | + IDE_TFLAG_OUT_NSECT | + IDE_TFLAG_OUT_LBAL | + IDE_TFLAG_OUT_LBAM | + IDE_TFLAG_OUT_LBAH, + IDE_TFLAG_OUT_DEVICE = (1 << 14), + IDE_TFLAG_WRITE = (1 << 15), + IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), + IDE_TFLAG_IN_DATA = (1 << 17), + IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), + IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), + IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), + IDE_TFLAG_IN_HOB_NSECT = (1 << 21), + IDE_TFLAG_IN_HOB_LBAL = (1 << 22), + IDE_TFLAG_IN_HOB_LBAM = (1 << 23), + IDE_TFLAG_IN_HOB_LBAH = (1 << 24), + IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | + IDE_TFLAG_IN_HOB_LBAM | + IDE_TFLAG_IN_HOB_LBAH, + IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE | + IDE_TFLAG_IN_HOB_NSECT | + IDE_TFLAG_IN_HOB_LBA, + IDE_TFLAG_IN_FEATURE = (1 << 1), + IDE_TFLAG_IN_NSECT = (1 << 25), + IDE_TFLAG_IN_LBAL = (1 << 26), + IDE_TFLAG_IN_LBAM = (1 << 27), + IDE_TFLAG_IN_LBAH = (1 << 28), + IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | + IDE_TFLAG_IN_LBAM | + IDE_TFLAG_IN_LBAH, + IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | + IDE_TFLAG_IN_LBA, + IDE_TFLAG_IN_DEVICE = (1 << 29), + IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | + IDE_TFLAG_IN_HOB, + IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | + IDE_TFLAG_IN_TF, + IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | + IDE_TFLAG_IN_DEVICE, + /* force 16-bit I/O operations */ + IDE_TFLAG_IO_16BIT = (1 << 30), + /* ide_task_t was allocated using kmalloc() */ + IDE_TFLAG_DYN = (1 << 31), +}; + +struct ide_taskfile { + u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ + + u8 hob_feature; /* 1-5: additional data to support LBA48 */ + u8 hob_nsect; + u8 hob_lbal; + u8 hob_lbam; + u8 hob_lbah; + + u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ + + union { /*  7: */ + u8 error; /* read: error */ + u8 feature; /* write: feature */ + }; + + u8 nsect; /* 8: number of sectors */ + u8 lbal; /* 9: LBA low */ + u8 lbam; /* 10: LBA mid */ + u8 lbah; /* 11: LBA high */ + + u8 device; /* 12: device select */ + + union { /* 13: */ + u8 status; /*  read: status  */ + u8 command; /* write: command */ + }; +}; + +typedef struct ide_task_s { + union { + struct ide_taskfile tf; + u8 tf_array[14]; + }; + u32 tf_flags; + int data_phase; + struct request *rq; /* copy of request */ + void *special; /* valid_t generally */ +} ide_task_t; + /* ATAPI packet command flags */ enum { /* set when an error is considered normal - no retry (ide-tape) */ @@ -567,7 +671,6 @@ typedef struct ide_drive_s ide_drive_t; #define ide_drv_g(disk, cont_type) \ container_of((disk)->private_data, struct cont_type, driver) -struct ide_task_s; struct ide_port_info; struct ide_tp_ops { @@ -694,6 +797,8 @@ typedef struct hwif_s { /* data phase of the active command (currently only valid for PIO/DMA) */ int data_phase; + struct ide_task_s task; /* current command */ + unsigned int nsect; unsigned int nleft; struct scatterlist *cursg; @@ -1059,110 +1164,6 @@ extern void ide_do_drive_cmd(ide_drive_t *, struct request *); extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); -enum { - IDE_TFLAG_LBA48 = (1 << 0), - IDE_TFLAG_FLAGGED = (1 << 2), - IDE_TFLAG_OUT_DATA = (1 << 3), - IDE_TFLAG_OUT_HOB_FEATURE = (1 << 4), - IDE_TFLAG_OUT_HOB_NSECT = (1 << 5), - IDE_TFLAG_OUT_HOB_LBAL = (1 << 6), - IDE_TFLAG_OUT_HOB_LBAM = (1 << 7), - IDE_TFLAG_OUT_HOB_LBAH = (1 << 8), - IDE_TFLAG_OUT_HOB = IDE_TFLAG_OUT_HOB_FEATURE | - IDE_TFLAG_OUT_HOB_NSECT | - IDE_TFLAG_OUT_HOB_LBAL | - IDE_TFLAG_OUT_HOB_LBAM | - IDE_TFLAG_OUT_HOB_LBAH, - IDE_TFLAG_OUT_FEATURE = (1 << 9), - IDE_TFLAG_OUT_NSECT = (1 << 10), - IDE_TFLAG_OUT_LBAL = (1 << 11), - IDE_TFLAG_OUT_LBAM = (1 << 12), - IDE_TFLAG_OUT_LBAH = (1 << 13), - IDE_TFLAG_OUT_TF = IDE_TFLAG_OUT_FEATURE | - IDE_TFLAG_OUT_NSECT | - IDE_TFLAG_OUT_LBAL | - IDE_TFLAG_OUT_LBAM | - IDE_TFLAG_OUT_LBAH, - IDE_TFLAG_OUT_DEVICE = (1 << 14), - IDE_TFLAG_WRITE = (1 << 15), - IDE_TFLAG_FLAGGED_SET_IN_FLAGS = (1 << 16), - IDE_TFLAG_IN_DATA = (1 << 17), - IDE_TFLAG_CUSTOM_HANDLER = (1 << 18), - IDE_TFLAG_DMA_PIO_FALLBACK = (1 << 19), - IDE_TFLAG_IN_HOB_FEATURE = (1 << 20), - IDE_TFLAG_IN_HOB_NSECT = (1 << 21), - IDE_TFLAG_IN_HOB_LBAL = (1 << 22), - IDE_TFLAG_IN_HOB_LBAM = (1 << 23), - IDE_TFLAG_IN_HOB_LBAH = (1 << 24), - IDE_TFLAG_IN_HOB_LBA = IDE_TFLAG_IN_HOB_LBAL | - IDE_TFLAG_IN_HOB_LBAM | - IDE_TFLAG_IN_HOB_LBAH, - IDE_TFLAG_IN_HOB = IDE_TFLAG_IN_HOB_FEATURE | - IDE_TFLAG_IN_HOB_NSECT | - IDE_TFLAG_IN_HOB_LBA, - IDE_TFLAG_IN_FEATURE = (1 << 1), - IDE_TFLAG_IN_NSECT = (1 << 25), - IDE_TFLAG_IN_LBAL = (1 << 26), - IDE_TFLAG_IN_LBAM = (1 << 27), - IDE_TFLAG_IN_LBAH = (1 << 28), - IDE_TFLAG_IN_LBA = IDE_TFLAG_IN_LBAL | - IDE_TFLAG_IN_LBAM | - IDE_TFLAG_IN_LBAH, - IDE_TFLAG_IN_TF = IDE_TFLAG_IN_NSECT | - IDE_TFLAG_IN_LBA, - IDE_TFLAG_IN_DEVICE = (1 << 29), - IDE_TFLAG_HOB = IDE_TFLAG_OUT_HOB | - IDE_TFLAG_IN_HOB, - IDE_TFLAG_TF = IDE_TFLAG_OUT_TF | - IDE_TFLAG_IN_TF, - IDE_TFLAG_DEVICE = IDE_TFLAG_OUT_DEVICE | - IDE_TFLAG_IN_DEVICE, - /* force 16-bit I/O operations */ - IDE_TFLAG_IO_16BIT = (1 << 30), - /* ide_task_t was allocated using kmalloc() */ - IDE_TFLAG_DYN = (1 << 31), -}; - -struct ide_taskfile { - u8 hob_data; /* 0: high data byte (for TASKFILE IOCTL) */ - - u8 hob_feature; /* 1-5: additional data to support LBA48 */ - u8 hob_nsect; - u8 hob_lbal; - u8 hob_lbam; - u8 hob_lbah; - - u8 data; /* 6: low data byte (for TASKFILE IOCTL) */ - - union { /*  7: */ - u8 error; /* read: error */ - u8 feature; /* write: feature */ - }; - - u8 nsect; /* 8: number of sectors */ - u8 lbal; /* 9: LBA low */ - u8 lbam; /* 10: LBA mid */ - u8 lbah; /* 11: LBA high */ - - u8 device; /* 12: device select */ - - union { /* 13: */ - u8 status; /*  read: status  */ - u8 command; /* write: command */ - }; -}; - -typedef struct ide_task_s { - union { - struct ide_taskfile tf; - u8 tf_array[14]; - }; - u32 tf_flags; - int data_phase; - struct request *rq; /* copy of request */ - void *special; /* valid_t generally */ -} ide_task_t; - void ide_tf_dump(const char *, struct ide_taskfile *); void ide_exec_command(ide_hwif_t *, u8); -- cgit v1.2.3 From bfa7d8e55f0c5ae22ef57eb22942c74fdde7b9bd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:42 +0200 Subject: ide: ->ide_dma_clear_irq() -> ->clear_irq() * Rename ->ide_dma_clear_irq method to ->clear_irq and move it from ide_hwif_t to struct ide_port_ops. * Move ->waiting_for_dma check inside ->clear_irq method. * Move ->dma_base check inside ->clear_irq method. piix.c: * Add ich_port_ops and remove init_hwif_ich() wrapper. There should be no functional changes caused by this patch. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 14d489c2e5a..37a4344f384 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -704,6 +704,7 @@ extern const struct ide_tp_ops default_tp_ops; * @resetproc: routine to reset controller after a disk reset * @maskproc: special host masking for drive selection * @quirkproc: check host's drive quirk list + * @clear_irq: clear IRQ * * @mdma_filter: filter MDMA modes * @udma_filter: filter UDMA modes @@ -720,6 +721,7 @@ struct ide_port_ops { void (*resetproc)(ide_drive_t *); void (*maskproc)(ide_drive_t *, int); void (*quirkproc)(ide_drive_t *); + void (*clear_irq)(ide_drive_t *); u8 (*mdma_filter)(ide_drive_t *); u8 (*udma_filter)(ide_drive_t *); @@ -782,8 +784,6 @@ typedef struct hwif_s { const struct ide_port_ops *port_ops; const struct ide_dma_ops *dma_ops; - void (*ide_dma_clear_irq)(ide_drive_t *drive); - /* dma physical region descriptor table (cpu view) */ unsigned int *dmatable_cpu; /* dma physical region descriptor table (dma view) */ -- cgit v1.2.3 From a36223b0dc14606b5c80aacbbe6288133693a841 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:43 +0200 Subject: ide: remove ide_host_alloc_all() * Remove no longer used ide_host_alloc_all(). * Add MAX_HOST_PORTS define and use it instead of MAX_HWIFS as the maximum number of host ports possible. Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 37a4344f384..86fa030e802 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -832,8 +832,10 @@ typedef struct hwif_s { #endif } ____cacheline_internodealigned_in_smp ide_hwif_t; +#define MAX_HOST_PORTS 4 + struct ide_host { - ide_hwif_t *ports[MAX_HWIFS]; + ide_hwif_t *ports[MAX_HOST_PORTS]; unsigned int n_ports; struct device *dev[2]; unsigned int (*init_chipset)(struct pci_dev *); @@ -1479,7 +1481,6 @@ void ide_undecoded_slave(ide_drive_t *); void ide_port_apply_params(ide_hwif_t *); -struct ide_host *ide_host_alloc_all(const struct ide_port_info *, hw_regs_t **); struct ide_host *ide_host_alloc(const struct ide_port_info *, hw_regs_t **); void ide_host_free(struct ide_host *); int ide_host_register(struct ide_host *, const struct ide_port_info *, -- cgit v1.2.3 From f87904898e91923a91b925078ac933f05076c7fd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:45 +0200 Subject: ide-disk: move all ioctl handling to ide-disk_ioctl.c While at it: - idedisk_ioctl() -> ide_disk_ioctl() Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 86fa030e802..7ce245e6c6a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -946,8 +946,11 @@ IDE_DEVSET(_name, 0, get_##_func, set_##_func) #define ide_devset_w(_name, _func) \ IDE_DEVSET(_name, 0, NULL, set_##_func) -#define ide_devset_rw_sync(_name, _func) \ -IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) +#define ide_ext_devset_rw(_name, _func) \ +__IDE_DEVSET(_name, 0, get_##_func, set_##_func) + +#define ide_ext_devset_rw_sync(_name, _func) \ +__IDE_DEVSET(_name, DS_SYNC, get_##_func, set_##_func) #define ide_decl_devset(_name) \ extern const struct ide_devset ide_devset_##_name -- cgit v1.2.3 From 653bcf5292a9ac4ffc07315198f0ef995e0646a8 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: __ide_dma_end() -> ide_dma_end() While at it: - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 7ce245e6c6a..22f7451f7b4 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1435,7 +1435,7 @@ void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); -extern int __ide_dma_end(ide_drive_t *); +int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); extern void ide_dma_lost_irq(ide_drive_t *); extern void ide_dma_timeout(ide_drive_t *); -- cgit v1.2.3 From de23ec9ca82357e6d337a2263befb1a65cf19c83 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Make ide_dma_lost_irq() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n and convert {ics,au1xxx-}ide.c to use it. While at it: - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 22f7451f7b4..ae4a25d2b06 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1437,11 +1437,12 @@ void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); -extern void ide_dma_lost_irq(ide_drive_t *); extern void ide_dma_timeout(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ +void ide_dma_lost_irq(ide_drive_t *); + #else static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } -- cgit v1.2.3 From ffa15a6915b7f6f6f69b4a66e1100a9c68d11250 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:46 +0200 Subject: ide: make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n Make ide_dma_timeout() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n and convert {ics,au1xxx-}ide.c to use it. While at it: - dump ATA Status register content on error - use EXPORT_SYMBOL_GPL() to match the rest of SFF DMA functions Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ae4a25d2b06..39aaff8ff45 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1437,11 +1437,11 @@ void ide_dma_exec_cmd(ide_drive_t *, u8); extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); -extern void ide_dma_timeout(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ void ide_dma_lost_irq(ide_drive_t *); +void ide_dma_timeout(ide_drive_t *); #else static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } -- cgit v1.2.3 From 2bbd57cad3d72334c9fcc4e229a5a5b04dc6aebc Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:47 +0200 Subject: ide: switch to DMA-mapping API part #2 Follow-up to commit 5c05ff68b9a9b40a9be949497e0aa980185565cf ("ide: switch to DMA-mapping API"): * pci_{alloc,free}_consistent() -> dma_{alloc,free}_coherent() in ide_{allocate,release}_dma_engine(). * Add ->prd_max_nents and ->prd_ent_size fields to ide_hwif_t (+ set default values in ide_allocate_dma_engine()). * Make ide_{allocate,release}_dma_engine() available also for CONFIG_BLK_DEV_IDEDMA_SFF=n. Then convert au1xxx-ide.c, scc_pata.c and sgiioc4.c to use them. * Add missing ->init_dma method to scc_pata. This patch also fixes: - ->dmatable_cpu leak for au1xxx-ide - too early realease of ->dmatable_cpu for scc_pata - wrong amount of ->dmatable_cpu memory being freed for sgiioc4 While at it: - remove superfluous ->dma_base check from ide_unregister() - return -ENOMEM on error in ide_release_dma_engine() - beautify error message in ide_release_dma_engine() Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 39aaff8ff45..8121aa9240c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -788,6 +788,12 @@ typedef struct hwif_s { unsigned int *dmatable_cpu; /* dma physical region descriptor table (dma view) */ dma_addr_t dmatable_dma; + + /* maximum number of PRD table entries */ + int prd_max_nents; + /* PRD entry size in bytes */ + int prd_ent_size; + /* Scatter-gather list used to build the above */ struct scatterlist *sg_table; int sg_max_nents; /* Maximum number of entries in it */ @@ -1423,14 +1429,14 @@ int ide_set_dma(ide_drive_t *); void ide_check_dma_crc(ide_drive_t *); ide_startstop_t ide_dma_intr(ide_drive_t *); +int ide_allocate_dma_engine(ide_hwif_t *); +void ide_release_dma_engine(ide_hwif_t *); + int ide_build_sglist(ide_drive_t *, struct request *); void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF extern int ide_build_dmatable(ide_drive_t *, struct request *); -int ide_allocate_dma_engine(ide_hwif_t *); -void ide_release_dma_engine(ide_hwif_t *); - void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); void ide_dma_exec_cmd(ide_drive_t *, u8); @@ -1453,11 +1459,8 @@ static inline void ide_dma_on(ide_drive_t *drive) { ; } static inline void ide_dma_verbose(ide_drive_t *drive) { ; } static inline int ide_set_dma(ide_drive_t *drive) { return 1; } static inline void ide_check_dma_crc(ide_drive_t *drive) { ; } -#endif /* CONFIG_BLK_DEV_IDEDMA */ - -#ifndef CONFIG_BLK_DEV_IDEDMA_SFF static inline void ide_release_dma_engine(ide_hwif_t *hwif) { ; } -#endif +#endif /* CONFIG_BLK_DEV_IDEDMA */ #ifdef CONFIG_BLK_DEV_IDEACPI extern int ide_acpi_exec_tfs(ide_drive_t *drive); -- cgit v1.2.3 From 2dbe7e919eb696c86790797f8a814bef19a0d50a Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 13 Oct 2008 21:39:47 +0200 Subject: ide: move SFF DMA code to ide-dma-sff.c Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 8121aa9240c..5a39dab2cc9 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1412,6 +1412,7 @@ struct drive_list_entry { int ide_in_drive_list(u16 *, const struct drive_list_entry *); #ifdef CONFIG_BLK_DEV_IDEDMA +int ide_dma_good_drive(ide_drive_t *); int __ide_dma_bad_drive(ide_drive_t *); int ide_id_dma_bug(ide_drive_t *); @@ -1436,6 +1437,7 @@ int ide_build_sglist(ide_drive_t *, struct request *); void ide_destroy_dmatable(ide_drive_t *); #ifdef CONFIG_BLK_DEV_IDEDMA_SFF +int config_drive_for_dma(ide_drive_t *); extern int ide_build_dmatable(ide_drive_t *, struct request *); void ide_dma_host_set(ide_drive_t *, int); extern int ide_dma_setup(ide_drive_t *); @@ -1444,6 +1446,8 @@ extern void ide_dma_start(ide_drive_t *); int ide_dma_end(ide_drive_t *); int ide_dma_test_irq(ide_drive_t *); extern const struct ide_dma_ops sff_dma_ops; +#else +static inline int config_drive_for_dma(ide_drive_t *drive) { return 0; } #endif /* CONFIG_BLK_DEV_IDEDMA_SFF */ void ide_dma_lost_irq(ide_drive_t *); -- cgit v1.2.3 From 0a9b6f8864362e31e348b12922a92b48b1b8cc94 Mon Sep 17 00:00:00 2001 From: Borislav Petkov Date: Mon, 13 Oct 2008 21:39:49 +0200 Subject: ide: add ide_drive_t.dma flag This flag is to accomodate ide-cd functionality into ide atapi. There should be no functionality change resulting from this patch. Signed-off-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 5a39dab2cc9..8247b286838 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -603,6 +603,7 @@ struct ide_drive_s { u8 select; /* basic drive/head select reg value */ u8 retry_pio; /* retrying dma capable host in pio */ u8 waiting_for_dma; /* dma currently in progress */ + u8 dma; /* atapi dma flag */ u8 quirk_list; /* considered quirky, set for a specific host */ u8 init_speed; /* transfer rate set at boot */ -- cgit v1.2.3 From 4abdc6ee7c47a1a6e12f95717e461baeebee5df7 Mon Sep 17 00:00:00 2001 From: Elias Oltmanns Date: Mon, 13 Oct 2008 21:39:50 +0200 Subject: ide: Implement disk shock protection support (v4) On user request (through sysfs), the IDLE IMMEDIATE command with UNLOAD FEATURE as specified in ATA-7 is issued to the device and processing of the request queue is stopped thereafter until the specified timeout expires or user space asks to resume normal operation. This is supposed to prevent the heads of a hard drive from accidentally crashing onto the platter when a heavy shock is anticipated (like a falling laptop expected to hit the floor). Port resets are deferred whenever a device on that port is in the parked state. v3: Elias Oltmanns wrote: [...] > >> 1. Make sure that no negative value is being passed to > >> jiffies_to_msecs() in ide_park_show(). > >> 2. Drop the superfluous variable hwif in ide_special_rq(). > >> 3. Skip initialisation of task and tf in ide_special_rq() if we are not > >> handling a (un)park request. > > > > Well, #3 should have been done differently because we donn't want to > > check for REQ_(UN)?PARK_HEADS more often than is necessary. > > While preparing the backport to 2.6.27, it has just occurred to me that > we need to clear the IDE_DFLAG_PARKED flag in ide_disk_pre_reset() > because this flag must not be set after *any* sort of access to the > device. v4: Fix a memory leak due to a missing blk_put_request() in issue_park_cmd(). Additionally, we should plug the queue when enqueueing the unpark request because there is no guarantee that the park timeout has not expired by then. Even though the chance for that to happen is very slim, the request might end up hanging in the queue until the next I/O operation is queued up. While at it, clean up the code a little: - make issue_park_cmd() a function of type void since nobody cares for the return value anyway; - use blk_start_queueing() instead of __blk_run_queue() since we don't have to worry about recursion; - remove a superfluous pointer deference in task_no_data_intr(). Signed-off-by: Elias Oltmanns Cc: Jeff Garzik , Cc: Randy Dunlap Cc: Tejun Heo Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 8247b286838..c47e371554c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -156,6 +156,8 @@ enum { */ #define REQ_DRIVE_RESET 0x20 #define REQ_DEVSET_EXEC 0x21 +#define REQ_PARK_HEADS 0x22 +#define REQ_UNPARK_HEADS 0x23 /* * Check for an interrupt and acknowledge the interrupt status @@ -573,6 +575,10 @@ enum { /* retrying in PIO */ IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), IDE_DFLAG_LBA = (1 << 26), + /* don't unload heads */ + IDE_DFLAG_NO_UNLOAD = (1 << 27), + /* heads unloaded, please don't reset port */ + IDE_DFLAG_PARKED = (1 << 28) }; struct ide_drive_s { @@ -1207,6 +1213,13 @@ int ide_check_atapi_device(ide_drive_t *, const char *); void ide_init_pc(struct ide_atapi_pc *); +/* Disk head parking */ +extern wait_queue_head_t ide_park_wq; +ssize_t ide_park_show(struct device *dev, struct device_attribute *attr, + char *buf); +ssize_t ide_park_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len); + /* * Special requests for ide-tape block device strategy routine. * -- cgit v1.2.3 From a5766f11cfd3a0c03450d99c8fe548c2940be884 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 10 Oct 2008 13:22:20 +0100 Subject: regulator: core - Rework machine API to remove string based functions. This improves the machine level API in order to configure regulator constraints and consumers as platform data and removes the old string based API that required several calls to set up each regulator. The intention is to create a struct regulator_init_data, populate it's fields with constraints, consumers devices, etc and then register the regulator device from board.c in the standard Linux way. e.g. regulator LDO2 (supplying codec and sim) platform data. /* regulator LDO2 consumer devices */ static struct regulator_consumer_supply ldo2_consumers[] = { { .dev = &platform_audio_device.dev, .supply = "codec_avdd", }, { .dev = &platform_sim_device.dev, .supply = "sim_vcc", } }; /* regulator LDO2 constraints */ static struct regulator_init_data ldo2_data = { .constraints = { .min_uV = 3300000, .max_uV = 3300000, .valid_modes_mask = REGULATOR_MODE_NORMAL, .apply_uV = 1, }, .num_consumer_supplies = ARRAY_SIZE(ldo2_consumers), .consumer_supplies = ldo2_consumers, }; /* machine regulator devices with thier consumers and constraints */ static struct platform_device wm8350_regulator_devices[] = { { .name = "wm8350-regulator", .id = WM8350_LDO_2, .dev = { .platform_data = &ldo2_data, }, }, }; Changes in detail:- o Removed all const char* regulator config functions in machine API. o Created new struct regulator_init_data to contain regulator machine configuration constraints and consmuers. o Changed set_supply(), set_machine_constraints(), set_consumer_device_supply() to remove their string identifier parameters. Also made them static and moved functions nearer top of core.c. o Removed no longer used inline func to_rdev() o Added regulator_get_init_drvdata() to retrieve init data. o Added struct device* as parameter to regulator_register(). o Changed my email address. Signed-off-by: Eric Miao Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/regulator/driver.h | 8 +++++--- include/linux/regulator/machine.h | 30 ++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 1d712c7172a..bc01b42a858 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -18,8 +18,8 @@ #include #include -struct regulator_constraints; struct regulator_dev; +struct regulator_init_data; /** * struct regulator_ops - regulator operations. @@ -85,15 +85,17 @@ struct regulator_desc { struct module *owner; }; - struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, - void *reg_data); + struct device *dev, void *driver_data); void regulator_unregister(struct regulator_dev *rdev); int regulator_notifier_call_chain(struct regulator_dev *rdev, unsigned long event, void *data); void *rdev_get_drvdata(struct regulator_dev *rdev); +struct device *rdev_get_dev(struct regulator_dev *rdev); int rdev_get_id(struct regulator_dev *rdev); +void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); + #endif diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index 11e737dbfcf..c6d69331a81 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -89,15 +89,33 @@ struct regulation_constraints { unsigned apply_uV:1; /* apply uV constraint iff min == max */ }; -int regulator_set_supply(const char *regulator, const char *regulator_supply); +/** + * struct regulator_consumer_supply - supply -> device mapping + * + * This maps a supply name to a device. + */ +struct regulator_consumer_supply { + struct device *dev; /* consumer */ + const char *supply; /* consumer supply - e.g. "vcc" */ +}; -const char *regulator_get_supply(const char *regulator); +/** + * struct regulator_init_data - regulator platform initialisation data. + * + * Initialisation constraints, our supply and consumers supplies. + */ +struct regulator_init_data { + struct device *supply_regulator_dev; /* or NULL for LINE */ -int regulator_set_machine_constraints(const char *regulator, - struct regulation_constraints *constraints); + struct regulation_constraints constraints; -int regulator_set_device_supply(const char *regulator, struct device *dev, - const char *supply); + int num_consumer_supplies; + struct regulator_consumer_supply *consumer_supplies; + + /* optional regulator machine specific init */ + int (*regulator_init)(void *driver_data); + void *driver_data; /* core does not touch this */ +}; int regulator_suspend_prepare(suspend_state_t state); -- cgit v1.2.3 From 3de89609a82aa68f543cba263eb28725e0fde511 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 9 Sep 2008 16:21:17 +0100 Subject: regulator: Fix typo Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/regulator/driver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index bc01b42a858..e37d8056198 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -51,7 +51,7 @@ struct regulator_ops { int output_uV, int load_uA); /* the operations below are for configuration of regulator state when - * it's parent PMIC enters a global STANBY/HIBERNATE state */ + * its parent PMIC enters a global STANDBY/HIBERNATE state */ /* set regulator suspend voltage */ int (*set_suspend_voltage) (struct regulator_dev *, int uV); -- cgit v1.2.3 From 1d9f9f040035da73d6ee5d2b3b3a25483a980da3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 10 Sep 2008 18:58:42 +0100 Subject: mfd: Core support for the WM8400 AudioPlus HiFi CODEC and PMU The WM8400 is a highly integrated audio CODEC and power management unit optimised for use in mobile multimedia applications. This patch adds core support for the WM8400 to the MFD subsystem. Both I2C and SPI access are supported by the hardware but currently only I2C access is implemented. The code is structured to allow SPI support to be slotted in later. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8400-audio.h | 1186 ++++++++++++++++++++++++++++++++++++ include/linux/mfd/wm8400-private.h | 935 ++++++++++++++++++++++++++++ 2 files changed, 2121 insertions(+) create mode 100644 include/linux/mfd/wm8400-audio.h create mode 100644 include/linux/mfd/wm8400-private.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8400-audio.h b/include/linux/mfd/wm8400-audio.h new file mode 100644 index 00000000000..b6640e01804 --- /dev/null +++ b/include/linux/mfd/wm8400-audio.h @@ -0,0 +1,1186 @@ +/* + * wm8400 private definitions for audio + * + * Copyright 2008 Wolfson Microelectronics plc + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_MFD_WM8400_AUDIO_H +#define __LINUX_MFD_WM8400_AUDIO_H + +#include + +/* + * R2 (0x02) - Power Management (1) + */ +#define WM8400_CODEC_ENA 0x8000 /* CODEC_ENA */ +#define WM8400_CODEC_ENA_MASK 0x8000 /* CODEC_ENA */ +#define WM8400_CODEC_ENA_SHIFT 15 /* CODEC_ENA */ +#define WM8400_CODEC_ENA_WIDTH 1 /* CODEC_ENA */ +#define WM8400_SYSCLK_ENA 0x4000 /* SYSCLK_ENA */ +#define WM8400_SYSCLK_ENA_MASK 0x4000 /* SYSCLK_ENA */ +#define WM8400_SYSCLK_ENA_SHIFT 14 /* SYSCLK_ENA */ +#define WM8400_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ +#define WM8400_SPK_MIX_ENA 0x2000 /* SPK_MIX_ENA */ +#define WM8400_SPK_MIX_ENA_MASK 0x2000 /* SPK_MIX_ENA */ +#define WM8400_SPK_MIX_ENA_SHIFT 13 /* SPK_MIX_ENA */ +#define WM8400_SPK_MIX_ENA_WIDTH 1 /* SPK_MIX_ENA */ +#define WM8400_SPK_ENA 0x1000 /* SPK_ENA */ +#define WM8400_SPK_ENA_MASK 0x1000 /* SPK_ENA */ +#define WM8400_SPK_ENA_SHIFT 12 /* SPK_ENA */ +#define WM8400_SPK_ENA_WIDTH 1 /* SPK_ENA */ +#define WM8400_OUT3_ENA 0x0800 /* OUT3_ENA */ +#define WM8400_OUT3_ENA_MASK 0x0800 /* OUT3_ENA */ +#define WM8400_OUT3_ENA_SHIFT 11 /* OUT3_ENA */ +#define WM8400_OUT3_ENA_WIDTH 1 /* OUT3_ENA */ +#define WM8400_OUT4_ENA 0x0400 /* OUT4_ENA */ +#define WM8400_OUT4_ENA_MASK 0x0400 /* OUT4_ENA */ +#define WM8400_OUT4_ENA_SHIFT 10 /* OUT4_ENA */ +#define WM8400_OUT4_ENA_WIDTH 1 /* OUT4_ENA */ +#define WM8400_LOUT_ENA 0x0200 /* LOUT_ENA */ +#define WM8400_LOUT_ENA_MASK 0x0200 /* LOUT_ENA */ +#define WM8400_LOUT_ENA_SHIFT 9 /* LOUT_ENA */ +#define WM8400_LOUT_ENA_WIDTH 1 /* LOUT_ENA */ +#define WM8400_ROUT_ENA 0x0100 /* ROUT_ENA */ +#define WM8400_ROUT_ENA_MASK 0x0100 /* ROUT_ENA */ +#define WM8400_ROUT_ENA_SHIFT 8 /* ROUT_ENA */ +#define WM8400_ROUT_ENA_WIDTH 1 /* ROUT_ENA */ +#define WM8400_MIC1BIAS_ENA 0x0010 /* MIC1BIAS_ENA */ +#define WM8400_MIC1BIAS_ENA_MASK 0x0010 /* MIC1BIAS_ENA */ +#define WM8400_MIC1BIAS_ENA_SHIFT 4 /* MIC1BIAS_ENA */ +#define WM8400_MIC1BIAS_ENA_WIDTH 1 /* MIC1BIAS_ENA */ +#define WM8400_VMID_MODE_MASK 0x0006 /* VMID_MODE - [2:1] */ +#define WM8400_VMID_MODE_SHIFT 1 /* VMID_MODE - [2:1] */ +#define WM8400_VMID_MODE_WIDTH 2 /* VMID_MODE - [2:1] */ +#define WM8400_VREF_ENA 0x0001 /* VREF_ENA */ +#define WM8400_VREF_ENA_MASK 0x0001 /* VREF_ENA */ +#define WM8400_VREF_ENA_SHIFT 0 /* VREF_ENA */ +#define WM8400_VREF_ENA_WIDTH 1 /* VREF_ENA */ + +/* + * R3 (0x03) - Power Management (2) + */ +#define WM8400_FLL_ENA 0x8000 /* FLL_ENA */ +#define WM8400_FLL_ENA_MASK 0x8000 /* FLL_ENA */ +#define WM8400_FLL_ENA_SHIFT 15 /* FLL_ENA */ +#define WM8400_FLL_ENA_WIDTH 1 /* FLL_ENA */ +#define WM8400_TSHUT_ENA 0x4000 /* TSHUT_ENA */ +#define WM8400_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */ +#define WM8400_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */ +#define WM8400_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */ +#define WM8400_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */ +#define WM8400_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */ +#define WM8400_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */ +#define WM8400_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */ +#define WM8400_OPCLK_ENA 0x0800 /* OPCLK_ENA */ +#define WM8400_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ +#define WM8400_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ +#define WM8400_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8400_AINL_ENA 0x0200 /* AINL_ENA */ +#define WM8400_AINL_ENA_MASK 0x0200 /* AINL_ENA */ +#define WM8400_AINL_ENA_SHIFT 9 /* AINL_ENA */ +#define WM8400_AINL_ENA_WIDTH 1 /* AINL_ENA */ +#define WM8400_AINR_ENA 0x0100 /* AINR_ENA */ +#define WM8400_AINR_ENA_MASK 0x0100 /* AINR_ENA */ +#define WM8400_AINR_ENA_SHIFT 8 /* AINR_ENA */ +#define WM8400_AINR_ENA_WIDTH 1 /* AINR_ENA */ +#define WM8400_LIN34_ENA 0x0080 /* LIN34_ENA */ +#define WM8400_LIN34_ENA_MASK 0x0080 /* LIN34_ENA */ +#define WM8400_LIN34_ENA_SHIFT 7 /* LIN34_ENA */ +#define WM8400_LIN34_ENA_WIDTH 1 /* LIN34_ENA */ +#define WM8400_LIN12_ENA 0x0040 /* LIN12_ENA */ +#define WM8400_LIN12_ENA_MASK 0x0040 /* LIN12_ENA */ +#define WM8400_LIN12_ENA_SHIFT 6 /* LIN12_ENA */ +#define WM8400_LIN12_ENA_WIDTH 1 /* LIN12_ENA */ +#define WM8400_RIN34_ENA 0x0020 /* RIN34_ENA */ +#define WM8400_RIN34_ENA_MASK 0x0020 /* RIN34_ENA */ +#define WM8400_RIN34_ENA_SHIFT 5 /* RIN34_ENA */ +#define WM8400_RIN34_ENA_WIDTH 1 /* RIN34_ENA */ +#define WM8400_RIN12_ENA 0x0010 /* RIN12_ENA */ +#define WM8400_RIN12_ENA_MASK 0x0010 /* RIN12_ENA */ +#define WM8400_RIN12_ENA_SHIFT 4 /* RIN12_ENA */ +#define WM8400_RIN12_ENA_WIDTH 1 /* RIN12_ENA */ +#define WM8400_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8400_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8400_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8400_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8400_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8400_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8400_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8400_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R4 (0x04) - Power Management (3) + */ +#define WM8400_LON_ENA 0x2000 /* LON_ENA */ +#define WM8400_LON_ENA_MASK 0x2000 /* LON_ENA */ +#define WM8400_LON_ENA_SHIFT 13 /* LON_ENA */ +#define WM8400_LON_ENA_WIDTH 1 /* LON_ENA */ +#define WM8400_LOP_ENA 0x1000 /* LOP_ENA */ +#define WM8400_LOP_ENA_MASK 0x1000 /* LOP_ENA */ +#define WM8400_LOP_ENA_SHIFT 12 /* LOP_ENA */ +#define WM8400_LOP_ENA_WIDTH 1 /* LOP_ENA */ +#define WM8400_RON_ENA 0x0800 /* RON_ENA */ +#define WM8400_RON_ENA_MASK 0x0800 /* RON_ENA */ +#define WM8400_RON_ENA_SHIFT 11 /* RON_ENA */ +#define WM8400_RON_ENA_WIDTH 1 /* RON_ENA */ +#define WM8400_ROP_ENA 0x0400 /* ROP_ENA */ +#define WM8400_ROP_ENA_MASK 0x0400 /* ROP_ENA */ +#define WM8400_ROP_ENA_SHIFT 10 /* ROP_ENA */ +#define WM8400_ROP_ENA_WIDTH 1 /* ROP_ENA */ +#define WM8400_LOPGA_ENA 0x0080 /* LOPGA_ENA */ +#define WM8400_LOPGA_ENA_MASK 0x0080 /* LOPGA_ENA */ +#define WM8400_LOPGA_ENA_SHIFT 7 /* LOPGA_ENA */ +#define WM8400_LOPGA_ENA_WIDTH 1 /* LOPGA_ENA */ +#define WM8400_ROPGA_ENA 0x0040 /* ROPGA_ENA */ +#define WM8400_ROPGA_ENA_MASK 0x0040 /* ROPGA_ENA */ +#define WM8400_ROPGA_ENA_SHIFT 6 /* ROPGA_ENA */ +#define WM8400_ROPGA_ENA_WIDTH 1 /* ROPGA_ENA */ +#define WM8400_LOMIX_ENA 0x0020 /* LOMIX_ENA */ +#define WM8400_LOMIX_ENA_MASK 0x0020 /* LOMIX_ENA */ +#define WM8400_LOMIX_ENA_SHIFT 5 /* LOMIX_ENA */ +#define WM8400_LOMIX_ENA_WIDTH 1 /* LOMIX_ENA */ +#define WM8400_ROMIX_ENA 0x0010 /* ROMIX_ENA */ +#define WM8400_ROMIX_ENA_MASK 0x0010 /* ROMIX_ENA */ +#define WM8400_ROMIX_ENA_SHIFT 4 /* ROMIX_ENA */ +#define WM8400_ROMIX_ENA_WIDTH 1 /* ROMIX_ENA */ +#define WM8400_DACL_ENA 0x0002 /* DACL_ENA */ +#define WM8400_DACL_ENA_MASK 0x0002 /* DACL_ENA */ +#define WM8400_DACL_ENA_SHIFT 1 /* DACL_ENA */ +#define WM8400_DACL_ENA_WIDTH 1 /* DACL_ENA */ +#define WM8400_DACR_ENA 0x0001 /* DACR_ENA */ +#define WM8400_DACR_ENA_MASK 0x0001 /* DACR_ENA */ +#define WM8400_DACR_ENA_SHIFT 0 /* DACR_ENA */ +#define WM8400_DACR_ENA_WIDTH 1 /* DACR_ENA */ + +/* + * R5 (0x05) - Audio Interface (1) + */ +#define WM8400_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */ +#define WM8400_AIFADCL_SRC_MASK 0x8000 /* AIFADCL_SRC */ +#define WM8400_AIFADCL_SRC_SHIFT 15 /* AIFADCL_SRC */ +#define WM8400_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */ +#define WM8400_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */ +#define WM8400_AIFADCR_SRC_MASK 0x4000 /* AIFADCR_SRC */ +#define WM8400_AIFADCR_SRC_SHIFT 14 /* AIFADCR_SRC */ +#define WM8400_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */ +#define WM8400_AIFADC_TDM 0x2000 /* AIFADC_TDM */ +#define WM8400_AIFADC_TDM_MASK 0x2000 /* AIFADC_TDM */ +#define WM8400_AIFADC_TDM_SHIFT 13 /* AIFADC_TDM */ +#define WM8400_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */ +#define WM8400_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */ +#define WM8400_AIFADC_TDM_CHAN_MASK 0x1000 /* AIFADC_TDM_CHAN */ +#define WM8400_AIFADC_TDM_CHAN_SHIFT 12 /* AIFADC_TDM_CHAN */ +#define WM8400_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */ +#define WM8400_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */ +#define WM8400_AIF_BCLK_INV_MASK 0x0100 /* AIF_BCLK_INV */ +#define WM8400_AIF_BCLK_INV_SHIFT 8 /* AIF_BCLK_INV */ +#define WM8400_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */ +#define WM8400_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */ +#define WM8400_AIF_LRCLK_INV_MASK 0x0080 /* AIF_LRCLK_INV */ +#define WM8400_AIF_LRCLK_INV_SHIFT 7 /* AIF_LRCLK_INV */ +#define WM8400_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */ +#define WM8400_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */ +#define WM8400_AIF_WL_SHIFT 5 /* AIF_WL - [6:5] */ +#define WM8400_AIF_WL_WIDTH 2 /* AIF_WL - [6:5] */ +#define WM8400_AIF_WL_16BITS (0 << 5) +#define WM8400_AIF_WL_20BITS (1 << 5) +#define WM8400_AIF_WL_24BITS (2 << 5) +#define WM8400_AIF_WL_32BITS (3 << 5) +#define WM8400_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */ +#define WM8400_AIF_FMT_SHIFT 3 /* AIF_FMT - [4:3] */ +#define WM8400_AIF_FMT_WIDTH 2 /* AIF_FMT - [4:3] */ +#define WM8400_AIF_FMT_RIGHTJ (0 << 3) +#define WM8400_AIF_FMT_LEFTJ (1 << 3) +#define WM8400_AIF_FMT_I2S (2 << 3) +#define WM8400_AIF_FMT_DSP (3 << 3) + +/* + * R6 (0x06) - Audio Interface (2) + */ +#define WM8400_DACL_SRC 0x8000 /* DACL_SRC */ +#define WM8400_DACL_SRC_MASK 0x8000 /* DACL_SRC */ +#define WM8400_DACL_SRC_SHIFT 15 /* DACL_SRC */ +#define WM8400_DACL_SRC_WIDTH 1 /* DACL_SRC */ +#define WM8400_DACR_SRC 0x4000 /* DACR_SRC */ +#define WM8400_DACR_SRC_MASK 0x4000 /* DACR_SRC */ +#define WM8400_DACR_SRC_SHIFT 14 /* DACR_SRC */ +#define WM8400_DACR_SRC_WIDTH 1 /* DACR_SRC */ +#define WM8400_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */ +#define WM8400_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */ +#define WM8400_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */ +#define WM8400_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */ +#define WM8400_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */ +#define WM8400_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */ +#define WM8400_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */ +#define WM8400_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */ +#define WM8400_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */ +#define WM8400_DAC_BOOST_SHIFT 10 /* DAC_BOOST - [11:10] */ +#define WM8400_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [11:10] */ +#define WM8400_DAC_COMP 0x0010 /* DAC_COMP */ +#define WM8400_DAC_COMP_MASK 0x0010 /* DAC_COMP */ +#define WM8400_DAC_COMP_SHIFT 4 /* DAC_COMP */ +#define WM8400_DAC_COMP_WIDTH 1 /* DAC_COMP */ +#define WM8400_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */ +#define WM8400_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */ +#define WM8400_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */ +#define WM8400_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */ +#define WM8400_ADC_COMP 0x0004 /* ADC_COMP */ +#define WM8400_ADC_COMP_MASK 0x0004 /* ADC_COMP */ +#define WM8400_ADC_COMP_SHIFT 2 /* ADC_COMP */ +#define WM8400_ADC_COMP_WIDTH 1 /* ADC_COMP */ +#define WM8400_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */ +#define WM8400_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */ +#define WM8400_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */ +#define WM8400_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */ +#define WM8400_LOOPBACK 0x0001 /* LOOPBACK */ +#define WM8400_LOOPBACK_MASK 0x0001 /* LOOPBACK */ +#define WM8400_LOOPBACK_SHIFT 0 /* LOOPBACK */ +#define WM8400_LOOPBACK_WIDTH 1 /* LOOPBACK */ + +/* + * R7 (0x07) - Clocking (1) + */ +#define WM8400_TOCLK_RATE 0x8000 /* TOCLK_RATE */ +#define WM8400_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */ +#define WM8400_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */ +#define WM8400_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */ +#define WM8400_TOCLK_ENA 0x4000 /* TOCLK_ENA */ +#define WM8400_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */ +#define WM8400_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */ +#define WM8400_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ +#define WM8400_OPCLKDIV_MASK 0x1E00 /* OPCLKDIV - [12:9] */ +#define WM8400_OPCLKDIV_SHIFT 9 /* OPCLKDIV - [12:9] */ +#define WM8400_OPCLKDIV_WIDTH 4 /* OPCLKDIV - [12:9] */ +#define WM8400_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */ +#define WM8400_DCLKDIV_SHIFT 6 /* DCLKDIV - [8:6] */ +#define WM8400_DCLKDIV_WIDTH 3 /* DCLKDIV - [8:6] */ +#define WM8400_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */ +#define WM8400_BCLK_DIV_SHIFT 1 /* BCLK_DIV - [4:1] */ +#define WM8400_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [4:1] */ + +/* + * R8 (0x08) - Clocking (2) + */ +#define WM8400_MCLK_SRC 0x8000 /* MCLK_SRC */ +#define WM8400_MCLK_SRC_MASK 0x8000 /* MCLK_SRC */ +#define WM8400_MCLK_SRC_SHIFT 15 /* MCLK_SRC */ +#define WM8400_MCLK_SRC_WIDTH 1 /* MCLK_SRC */ +#define WM8400_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */ +#define WM8400_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */ +#define WM8400_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */ +#define WM8400_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */ +#define WM8400_CLK_FORCE 0x2000 /* CLK_FORCE */ +#define WM8400_CLK_FORCE_MASK 0x2000 /* CLK_FORCE */ +#define WM8400_CLK_FORCE_SHIFT 13 /* CLK_FORCE */ +#define WM8400_CLK_FORCE_WIDTH 1 /* CLK_FORCE */ +#define WM8400_MCLK_DIV_MASK 0x1800 /* MCLK_DIV - [12:11] */ +#define WM8400_MCLK_DIV_SHIFT 11 /* MCLK_DIV - [12:11] */ +#define WM8400_MCLK_DIV_WIDTH 2 /* MCLK_DIV - [12:11] */ +#define WM8400_MCLK_INV 0x0400 /* MCLK_INV */ +#define WM8400_MCLK_INV_MASK 0x0400 /* MCLK_INV */ +#define WM8400_MCLK_INV_SHIFT 10 /* MCLK_INV */ +#define WM8400_MCLK_INV_WIDTH 1 /* MCLK_INV */ +#define WM8400_ADC_CLKDIV_MASK 0x00E0 /* ADC_CLKDIV - [7:5] */ +#define WM8400_ADC_CLKDIV_SHIFT 5 /* ADC_CLKDIV - [7:5] */ +#define WM8400_ADC_CLKDIV_WIDTH 3 /* ADC_CLKDIV - [7:5] */ +#define WM8400_DAC_CLKDIV_MASK 0x001C /* DAC_CLKDIV - [4:2] */ +#define WM8400_DAC_CLKDIV_SHIFT 2 /* DAC_CLKDIV - [4:2] */ +#define WM8400_DAC_CLKDIV_WIDTH 3 /* DAC_CLKDIV - [4:2] */ + +/* + * R9 (0x09) - Audio Interface (3) + */ +#define WM8400_AIF_MSTR1 0x8000 /* AIF_MSTR1 */ +#define WM8400_AIF_MSTR1_MASK 0x8000 /* AIF_MSTR1 */ +#define WM8400_AIF_MSTR1_SHIFT 15 /* AIF_MSTR1 */ +#define WM8400_AIF_MSTR1_WIDTH 1 /* AIF_MSTR1 */ +#define WM8400_AIF_MSTR2 0x4000 /* AIF_MSTR2 */ +#define WM8400_AIF_MSTR2_MASK 0x4000 /* AIF_MSTR2 */ +#define WM8400_AIF_MSTR2_SHIFT 14 /* AIF_MSTR2 */ +#define WM8400_AIF_MSTR2_WIDTH 1 /* AIF_MSTR2 */ +#define WM8400_AIF_SEL 0x2000 /* AIF_SEL */ +#define WM8400_AIF_SEL_MASK 0x2000 /* AIF_SEL */ +#define WM8400_AIF_SEL_SHIFT 13 /* AIF_SEL */ +#define WM8400_AIF_SEL_WIDTH 1 /* AIF_SEL */ +#define WM8400_ADCLRC_DIR 0x0800 /* ADCLRC_DIR */ +#define WM8400_ADCLRC_DIR_MASK 0x0800 /* ADCLRC_DIR */ +#define WM8400_ADCLRC_DIR_SHIFT 11 /* ADCLRC_DIR */ +#define WM8400_ADCLRC_DIR_WIDTH 1 /* ADCLRC_DIR */ +#define WM8400_ADCLRC_RATE_MASK 0x07FF /* ADCLRC_RATE - [10:0] */ +#define WM8400_ADCLRC_RATE_SHIFT 0 /* ADCLRC_RATE - [10:0] */ +#define WM8400_ADCLRC_RATE_WIDTH 11 /* ADCLRC_RATE - [10:0] */ + +/* + * R10 (0x0A) - Audio Interface (4) + */ +#define WM8400_ALRCGPIO1 0x8000 /* ALRCGPIO1 */ +#define WM8400_ALRCGPIO1_MASK 0x8000 /* ALRCGPIO1 */ +#define WM8400_ALRCGPIO1_SHIFT 15 /* ALRCGPIO1 */ +#define WM8400_ALRCGPIO1_WIDTH 1 /* ALRCGPIO1 */ +#define WM8400_ALRCBGPIO6 0x4000 /* ALRCBGPIO6 */ +#define WM8400_ALRCBGPIO6_MASK 0x4000 /* ALRCBGPIO6 */ +#define WM8400_ALRCBGPIO6_SHIFT 14 /* ALRCBGPIO6 */ +#define WM8400_ALRCBGPIO6_WIDTH 1 /* ALRCBGPIO6 */ +#define WM8400_AIF_TRIS 0x2000 /* AIF_TRIS */ +#define WM8400_AIF_TRIS_MASK 0x2000 /* AIF_TRIS */ +#define WM8400_AIF_TRIS_SHIFT 13 /* AIF_TRIS */ +#define WM8400_AIF_TRIS_WIDTH 1 /* AIF_TRIS */ +#define WM8400_DACLRC_DIR 0x0800 /* DACLRC_DIR */ +#define WM8400_DACLRC_DIR_MASK 0x0800 /* DACLRC_DIR */ +#define WM8400_DACLRC_DIR_SHIFT 11 /* DACLRC_DIR */ +#define WM8400_DACLRC_DIR_WIDTH 1 /* DACLRC_DIR */ +#define WM8400_DACLRC_RATE_MASK 0x07FF /* DACLRC_RATE - [10:0] */ +#define WM8400_DACLRC_RATE_SHIFT 0 /* DACLRC_RATE - [10:0] */ +#define WM8400_DACLRC_RATE_WIDTH 11 /* DACLRC_RATE - [10:0] */ + +/* + * R11 (0x0B) - DAC CTRL + */ +#define WM8400_DAC_SDMCLK_RATE 0x2000 /* DAC_SDMCLK_RATE */ +#define WM8400_DAC_SDMCLK_RATE_MASK 0x2000 /* DAC_SDMCLK_RATE */ +#define WM8400_DAC_SDMCLK_RATE_SHIFT 13 /* DAC_SDMCLK_RATE */ +#define WM8400_DAC_SDMCLK_RATE_WIDTH 1 /* DAC_SDMCLK_RATE */ +#define WM8400_AIF_LRCLKRATE 0x0400 /* AIF_LRCLKRATE */ +#define WM8400_AIF_LRCLKRATE_MASK 0x0400 /* AIF_LRCLKRATE */ +#define WM8400_AIF_LRCLKRATE_SHIFT 10 /* AIF_LRCLKRATE */ +#define WM8400_AIF_LRCLKRATE_WIDTH 1 /* AIF_LRCLKRATE */ +#define WM8400_DAC_MONO 0x0200 /* DAC_MONO */ +#define WM8400_DAC_MONO_MASK 0x0200 /* DAC_MONO */ +#define WM8400_DAC_MONO_SHIFT 9 /* DAC_MONO */ +#define WM8400_DAC_MONO_WIDTH 1 /* DAC_MONO */ +#define WM8400_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */ +#define WM8400_DAC_SB_FILT_MASK 0x0100 /* DAC_SB_FILT */ +#define WM8400_DAC_SB_FILT_SHIFT 8 /* DAC_SB_FILT */ +#define WM8400_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */ +#define WM8400_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */ +#define WM8400_DAC_MUTERATE_MASK 0x0080 /* DAC_MUTERATE */ +#define WM8400_DAC_MUTERATE_SHIFT 7 /* DAC_MUTERATE */ +#define WM8400_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ +#define WM8400_DAC_MUTEMODE 0x0040 /* DAC_MUTEMODE */ +#define WM8400_DAC_MUTEMODE_MASK 0x0040 /* DAC_MUTEMODE */ +#define WM8400_DAC_MUTEMODE_SHIFT 6 /* DAC_MUTEMODE */ +#define WM8400_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */ +#define WM8400_DEEMP_MASK 0x0030 /* DEEMP - [5:4] */ +#define WM8400_DEEMP_SHIFT 4 /* DEEMP - [5:4] */ +#define WM8400_DEEMP_WIDTH 2 /* DEEMP - [5:4] */ +#define WM8400_DAC_MUTE 0x0004 /* DAC_MUTE */ +#define WM8400_DAC_MUTE_MASK 0x0004 /* DAC_MUTE */ +#define WM8400_DAC_MUTE_SHIFT 2 /* DAC_MUTE */ +#define WM8400_DAC_MUTE_WIDTH 1 /* DAC_MUTE */ +#define WM8400_DACL_DATINV 0x0002 /* DACL_DATINV */ +#define WM8400_DACL_DATINV_MASK 0x0002 /* DACL_DATINV */ +#define WM8400_DACL_DATINV_SHIFT 1 /* DACL_DATINV */ +#define WM8400_DACL_DATINV_WIDTH 1 /* DACL_DATINV */ +#define WM8400_DACR_DATINV 0x0001 /* DACR_DATINV */ +#define WM8400_DACR_DATINV_MASK 0x0001 /* DACR_DATINV */ +#define WM8400_DACR_DATINV_SHIFT 0 /* DACR_DATINV */ +#define WM8400_DACR_DATINV_WIDTH 1 /* DACR_DATINV */ + +/* + * R12 (0x0C) - Left DAC Digital Volume + */ +#define WM8400_DAC_VU 0x0100 /* DAC_VU */ +#define WM8400_DAC_VU_MASK 0x0100 /* DAC_VU */ +#define WM8400_DAC_VU_SHIFT 8 /* DAC_VU */ +#define WM8400_DAC_VU_WIDTH 1 /* DAC_VU */ +#define WM8400_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */ +#define WM8400_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */ +#define WM8400_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */ + +/* + * R13 (0x0D) - Right DAC Digital Volume + */ +#define WM8400_DAC_VU 0x0100 /* DAC_VU */ +#define WM8400_DAC_VU_MASK 0x0100 /* DAC_VU */ +#define WM8400_DAC_VU_SHIFT 8 /* DAC_VU */ +#define WM8400_DAC_VU_WIDTH 1 /* DAC_VU */ +#define WM8400_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */ +#define WM8400_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */ +#define WM8400_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */ + +/* + * R14 (0x0E) - Digital Side Tone + */ +#define WM8400_ADCL_DAC_SVOL_MASK 0x1E00 /* ADCL_DAC_SVOL - [12:9] */ +#define WM8400_ADCL_DAC_SVOL_SHIFT 9 /* ADCL_DAC_SVOL - [12:9] */ +#define WM8400_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [12:9] */ +#define WM8400_ADCR_DAC_SVOL_MASK 0x01E0 /* ADCR_DAC_SVOL - [8:5] */ +#define WM8400_ADCR_DAC_SVOL_SHIFT 5 /* ADCR_DAC_SVOL - [8:5] */ +#define WM8400_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [8:5] */ +#define WM8400_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */ +#define WM8400_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */ +#define WM8400_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */ +#define WM8400_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */ +#define WM8400_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */ +#define WM8400_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */ + +/* + * R15 (0x0F) - ADC CTRL + */ +#define WM8400_ADC_HPF_ENA 0x0100 /* ADC_HPF_ENA */ +#define WM8400_ADC_HPF_ENA_MASK 0x0100 /* ADC_HPF_ENA */ +#define WM8400_ADC_HPF_ENA_SHIFT 8 /* ADC_HPF_ENA */ +#define WM8400_ADC_HPF_ENA_WIDTH 1 /* ADC_HPF_ENA */ +#define WM8400_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */ +#define WM8400_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */ +#define WM8400_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */ +#define WM8400_ADCL_DATINV 0x0002 /* ADCL_DATINV */ +#define WM8400_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */ +#define WM8400_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */ +#define WM8400_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */ +#define WM8400_ADCR_DATINV 0x0001 /* ADCR_DATINV */ +#define WM8400_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */ +#define WM8400_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */ +#define WM8400_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */ + +/* + * R16 (0x10) - Left ADC Digital Volume + */ +#define WM8400_ADC_VU 0x0100 /* ADC_VU */ +#define WM8400_ADC_VU_MASK 0x0100 /* ADC_VU */ +#define WM8400_ADC_VU_SHIFT 8 /* ADC_VU */ +#define WM8400_ADC_VU_WIDTH 1 /* ADC_VU */ +#define WM8400_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */ +#define WM8400_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */ +#define WM8400_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */ + +/* + * R17 (0x11) - Right ADC Digital Volume + */ +#define WM8400_ADC_VU 0x0100 /* ADC_VU */ +#define WM8400_ADC_VU_MASK 0x0100 /* ADC_VU */ +#define WM8400_ADC_VU_SHIFT 8 /* ADC_VU */ +#define WM8400_ADC_VU_WIDTH 1 /* ADC_VU */ +#define WM8400_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */ +#define WM8400_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */ +#define WM8400_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */ + +/* + * R24 (0x18) - Left Line Input 1&2 Volume + */ +#define WM8400_IPVU 0x0100 /* IPVU */ +#define WM8400_IPVU_MASK 0x0100 /* IPVU */ +#define WM8400_IPVU_SHIFT 8 /* IPVU */ +#define WM8400_IPVU_WIDTH 1 /* IPVU */ +#define WM8400_LI12MUTE 0x0080 /* LI12MUTE */ +#define WM8400_LI12MUTE_MASK 0x0080 /* LI12MUTE */ +#define WM8400_LI12MUTE_SHIFT 7 /* LI12MUTE */ +#define WM8400_LI12MUTE_WIDTH 1 /* LI12MUTE */ +#define WM8400_LI12ZC 0x0040 /* LI12ZC */ +#define WM8400_LI12ZC_MASK 0x0040 /* LI12ZC */ +#define WM8400_LI12ZC_SHIFT 6 /* LI12ZC */ +#define WM8400_LI12ZC_WIDTH 1 /* LI12ZC */ +#define WM8400_LIN12VOL_MASK 0x001F /* LIN12VOL - [4:0] */ +#define WM8400_LIN12VOL_SHIFT 0 /* LIN12VOL - [4:0] */ +#define WM8400_LIN12VOL_WIDTH 5 /* LIN12VOL - [4:0] */ + +/* + * R25 (0x19) - Left Line Input 3&4 Volume + */ +#define WM8400_IPVU 0x0100 /* IPVU */ +#define WM8400_IPVU_MASK 0x0100 /* IPVU */ +#define WM8400_IPVU_SHIFT 8 /* IPVU */ +#define WM8400_IPVU_WIDTH 1 /* IPVU */ +#define WM8400_LI34MUTE 0x0080 /* LI34MUTE */ +#define WM8400_LI34MUTE_MASK 0x0080 /* LI34MUTE */ +#define WM8400_LI34MUTE_SHIFT 7 /* LI34MUTE */ +#define WM8400_LI34MUTE_WIDTH 1 /* LI34MUTE */ +#define WM8400_LI34ZC 0x0040 /* LI34ZC */ +#define WM8400_LI34ZC_MASK 0x0040 /* LI34ZC */ +#define WM8400_LI34ZC_SHIFT 6 /* LI34ZC */ +#define WM8400_LI34ZC_WIDTH 1 /* LI34ZC */ +#define WM8400_LIN34VOL_MASK 0x001F /* LIN34VOL - [4:0] */ +#define WM8400_LIN34VOL_SHIFT 0 /* LIN34VOL - [4:0] */ +#define WM8400_LIN34VOL_WIDTH 5 /* LIN34VOL - [4:0] */ + +/* + * R26 (0x1A) - Right Line Input 1&2 Volume + */ +#define WM8400_IPVU 0x0100 /* IPVU */ +#define WM8400_IPVU_MASK 0x0100 /* IPVU */ +#define WM8400_IPVU_SHIFT 8 /* IPVU */ +#define WM8400_IPVU_WIDTH 1 /* IPVU */ +#define WM8400_RI12MUTE 0x0080 /* RI12MUTE */ +#define WM8400_RI12MUTE_MASK 0x0080 /* RI12MUTE */ +#define WM8400_RI12MUTE_SHIFT 7 /* RI12MUTE */ +#define WM8400_RI12MUTE_WIDTH 1 /* RI12MUTE */ +#define WM8400_RI12ZC 0x0040 /* RI12ZC */ +#define WM8400_RI12ZC_MASK 0x0040 /* RI12ZC */ +#define WM8400_RI12ZC_SHIFT 6 /* RI12ZC */ +#define WM8400_RI12ZC_WIDTH 1 /* RI12ZC */ +#define WM8400_RIN12VOL_MASK 0x001F /* RIN12VOL - [4:0] */ +#define WM8400_RIN12VOL_SHIFT 0 /* RIN12VOL - [4:0] */ +#define WM8400_RIN12VOL_WIDTH 5 /* RIN12VOL - [4:0] */ + +/* + * R27 (0x1B) - Right Line Input 3&4 Volume + */ +#define WM8400_IPVU 0x0100 /* IPVU */ +#define WM8400_IPVU_MASK 0x0100 /* IPVU */ +#define WM8400_IPVU_SHIFT 8 /* IPVU */ +#define WM8400_IPVU_WIDTH 1 /* IPVU */ +#define WM8400_RI34MUTE 0x0080 /* RI34MUTE */ +#define WM8400_RI34MUTE_MASK 0x0080 /* RI34MUTE */ +#define WM8400_RI34MUTE_SHIFT 7 /* RI34MUTE */ +#define WM8400_RI34MUTE_WIDTH 1 /* RI34MUTE */ +#define WM8400_RI34ZC 0x0040 /* RI34ZC */ +#define WM8400_RI34ZC_MASK 0x0040 /* RI34ZC */ +#define WM8400_RI34ZC_SHIFT 6 /* RI34ZC */ +#define WM8400_RI34ZC_WIDTH 1 /* RI34ZC */ +#define WM8400_RIN34VOL_MASK 0x001F /* RIN34VOL - [4:0] */ +#define WM8400_RIN34VOL_SHIFT 0 /* RIN34VOL - [4:0] */ +#define WM8400_RIN34VOL_WIDTH 5 /* RIN34VOL - [4:0] */ + +/* + * R28 (0x1C) - Left Output Volume + */ +#define WM8400_OPVU 0x0100 /* OPVU */ +#define WM8400_OPVU_MASK 0x0100 /* OPVU */ +#define WM8400_OPVU_SHIFT 8 /* OPVU */ +#define WM8400_OPVU_WIDTH 1 /* OPVU */ +#define WM8400_LOZC 0x0080 /* LOZC */ +#define WM8400_LOZC_MASK 0x0080 /* LOZC */ +#define WM8400_LOZC_SHIFT 7 /* LOZC */ +#define WM8400_LOZC_WIDTH 1 /* LOZC */ +#define WM8400_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */ +#define WM8400_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */ +#define WM8400_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */ + +/* + * R29 (0x1D) - Right Output Volume + */ +#define WM8400_OPVU 0x0100 /* OPVU */ +#define WM8400_OPVU_MASK 0x0100 /* OPVU */ +#define WM8400_OPVU_SHIFT 8 /* OPVU */ +#define WM8400_OPVU_WIDTH 1 /* OPVU */ +#define WM8400_ROZC 0x0080 /* ROZC */ +#define WM8400_ROZC_MASK 0x0080 /* ROZC */ +#define WM8400_ROZC_SHIFT 7 /* ROZC */ +#define WM8400_ROZC_WIDTH 1 /* ROZC */ +#define WM8400_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */ +#define WM8400_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */ +#define WM8400_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */ + +/* + * R30 (0x1E) - Line Outputs Volume + */ +#define WM8400_LONMUTE 0x0040 /* LONMUTE */ +#define WM8400_LONMUTE_MASK 0x0040 /* LONMUTE */ +#define WM8400_LONMUTE_SHIFT 6 /* LONMUTE */ +#define WM8400_LONMUTE_WIDTH 1 /* LONMUTE */ +#define WM8400_LOPMUTE 0x0020 /* LOPMUTE */ +#define WM8400_LOPMUTE_MASK 0x0020 /* LOPMUTE */ +#define WM8400_LOPMUTE_SHIFT 5 /* LOPMUTE */ +#define WM8400_LOPMUTE_WIDTH 1 /* LOPMUTE */ +#define WM8400_LOATTN 0x0010 /* LOATTN */ +#define WM8400_LOATTN_MASK 0x0010 /* LOATTN */ +#define WM8400_LOATTN_SHIFT 4 /* LOATTN */ +#define WM8400_LOATTN_WIDTH 1 /* LOATTN */ +#define WM8400_RONMUTE 0x0004 /* RONMUTE */ +#define WM8400_RONMUTE_MASK 0x0004 /* RONMUTE */ +#define WM8400_RONMUTE_SHIFT 2 /* RONMUTE */ +#define WM8400_RONMUTE_WIDTH 1 /* RONMUTE */ +#define WM8400_ROPMUTE 0x0002 /* ROPMUTE */ +#define WM8400_ROPMUTE_MASK 0x0002 /* ROPMUTE */ +#define WM8400_ROPMUTE_SHIFT 1 /* ROPMUTE */ +#define WM8400_ROPMUTE_WIDTH 1 /* ROPMUTE */ +#define WM8400_ROATTN 0x0001 /* ROATTN */ +#define WM8400_ROATTN_MASK 0x0001 /* ROATTN */ +#define WM8400_ROATTN_SHIFT 0 /* ROATTN */ +#define WM8400_ROATTN_WIDTH 1 /* ROATTN */ + +/* + * R31 (0x1F) - Out3/4 Volume + */ +#define WM8400_OUT3MUTE 0x0020 /* OUT3MUTE */ +#define WM8400_OUT3MUTE_MASK 0x0020 /* OUT3MUTE */ +#define WM8400_OUT3MUTE_SHIFT 5 /* OUT3MUTE */ +#define WM8400_OUT3MUTE_WIDTH 1 /* OUT3MUTE */ +#define WM8400_OUT3ATTN 0x0010 /* OUT3ATTN */ +#define WM8400_OUT3ATTN_MASK 0x0010 /* OUT3ATTN */ +#define WM8400_OUT3ATTN_SHIFT 4 /* OUT3ATTN */ +#define WM8400_OUT3ATTN_WIDTH 1 /* OUT3ATTN */ +#define WM8400_OUT4MUTE 0x0002 /* OUT4MUTE */ +#define WM8400_OUT4MUTE_MASK 0x0002 /* OUT4MUTE */ +#define WM8400_OUT4MUTE_SHIFT 1 /* OUT4MUTE */ +#define WM8400_OUT4MUTE_WIDTH 1 /* OUT4MUTE */ +#define WM8400_OUT4ATTN 0x0001 /* OUT4ATTN */ +#define WM8400_OUT4ATTN_MASK 0x0001 /* OUT4ATTN */ +#define WM8400_OUT4ATTN_SHIFT 0 /* OUT4ATTN */ +#define WM8400_OUT4ATTN_WIDTH 1 /* OUT4ATTN */ + +/* + * R32 (0x20) - Left OPGA Volume + */ +#define WM8400_OPVU 0x0100 /* OPVU */ +#define WM8400_OPVU_MASK 0x0100 /* OPVU */ +#define WM8400_OPVU_SHIFT 8 /* OPVU */ +#define WM8400_OPVU_WIDTH 1 /* OPVU */ +#define WM8400_LOPGAZC 0x0080 /* LOPGAZC */ +#define WM8400_LOPGAZC_MASK 0x0080 /* LOPGAZC */ +#define WM8400_LOPGAZC_SHIFT 7 /* LOPGAZC */ +#define WM8400_LOPGAZC_WIDTH 1 /* LOPGAZC */ +#define WM8400_LOPGAVOL_MASK 0x007F /* LOPGAVOL - [6:0] */ +#define WM8400_LOPGAVOL_SHIFT 0 /* LOPGAVOL - [6:0] */ +#define WM8400_LOPGAVOL_WIDTH 7 /* LOPGAVOL - [6:0] */ + +/* + * R33 (0x21) - Right OPGA Volume + */ +#define WM8400_OPVU 0x0100 /* OPVU */ +#define WM8400_OPVU_MASK 0x0100 /* OPVU */ +#define WM8400_OPVU_SHIFT 8 /* OPVU */ +#define WM8400_OPVU_WIDTH 1 /* OPVU */ +#define WM8400_ROPGAZC 0x0080 /* ROPGAZC */ +#define WM8400_ROPGAZC_MASK 0x0080 /* ROPGAZC */ +#define WM8400_ROPGAZC_SHIFT 7 /* ROPGAZC */ +#define WM8400_ROPGAZC_WIDTH 1 /* ROPGAZC */ +#define WM8400_ROPGAVOL_MASK 0x007F /* ROPGAVOL - [6:0] */ +#define WM8400_ROPGAVOL_SHIFT 0 /* ROPGAVOL - [6:0] */ +#define WM8400_ROPGAVOL_WIDTH 7 /* ROPGAVOL - [6:0] */ + +/* + * R34 (0x22) - Speaker Volume + */ +#define WM8400_SPKATTN_MASK 0x0003 /* SPKATTN - [1:0] */ +#define WM8400_SPKATTN_SHIFT 0 /* SPKATTN - [1:0] */ +#define WM8400_SPKATTN_WIDTH 2 /* SPKATTN - [1:0] */ + +/* + * R35 (0x23) - ClassD1 + */ +#define WM8400_CDMODE 0x0100 /* CDMODE */ +#define WM8400_CDMODE_MASK 0x0100 /* CDMODE */ +#define WM8400_CDMODE_SHIFT 8 /* CDMODE */ +#define WM8400_CDMODE_WIDTH 1 /* CDMODE */ +#define WM8400_CLASSD_CLK_SEL 0x0080 /* CLASSD_CLK_SEL */ +#define WM8400_CLASSD_CLK_SEL_MASK 0x0080 /* CLASSD_CLK_SEL */ +#define WM8400_CLASSD_CLK_SEL_SHIFT 7 /* CLASSD_CLK_SEL */ +#define WM8400_CLASSD_CLK_SEL_WIDTH 1 /* CLASSD_CLK_SEL */ +#define WM8400_CD_SRCTRL 0x0040 /* CD_SRCTRL */ +#define WM8400_CD_SRCTRL_MASK 0x0040 /* CD_SRCTRL */ +#define WM8400_CD_SRCTRL_SHIFT 6 /* CD_SRCTRL */ +#define WM8400_CD_SRCTRL_WIDTH 1 /* CD_SRCTRL */ +#define WM8400_SPKNOPOP 0x0020 /* SPKNOPOP */ +#define WM8400_SPKNOPOP_MASK 0x0020 /* SPKNOPOP */ +#define WM8400_SPKNOPOP_SHIFT 5 /* SPKNOPOP */ +#define WM8400_SPKNOPOP_WIDTH 1 /* SPKNOPOP */ +#define WM8400_DBLERATE 0x0010 /* DBLERATE */ +#define WM8400_DBLERATE_MASK 0x0010 /* DBLERATE */ +#define WM8400_DBLERATE_SHIFT 4 /* DBLERATE */ +#define WM8400_DBLERATE_WIDTH 1 /* DBLERATE */ +#define WM8400_LOOPTEST 0x0008 /* LOOPTEST */ +#define WM8400_LOOPTEST_MASK 0x0008 /* LOOPTEST */ +#define WM8400_LOOPTEST_SHIFT 3 /* LOOPTEST */ +#define WM8400_LOOPTEST_WIDTH 1 /* LOOPTEST */ +#define WM8400_HALFABBIAS 0x0004 /* HALFABBIAS */ +#define WM8400_HALFABBIAS_MASK 0x0004 /* HALFABBIAS */ +#define WM8400_HALFABBIAS_SHIFT 2 /* HALFABBIAS */ +#define WM8400_HALFABBIAS_WIDTH 1 /* HALFABBIAS */ +#define WM8400_TRIDEL_MASK 0x0003 /* TRIDEL - [1:0] */ +#define WM8400_TRIDEL_SHIFT 0 /* TRIDEL - [1:0] */ +#define WM8400_TRIDEL_WIDTH 2 /* TRIDEL - [1:0] */ + +/* + * R37 (0x25) - ClassD3 + */ +#define WM8400_DCGAIN_MASK 0x0038 /* DCGAIN - [5:3] */ +#define WM8400_DCGAIN_SHIFT 3 /* DCGAIN - [5:3] */ +#define WM8400_DCGAIN_WIDTH 3 /* DCGAIN - [5:3] */ +#define WM8400_ACGAIN_MASK 0x0007 /* ACGAIN - [2:0] */ +#define WM8400_ACGAIN_SHIFT 0 /* ACGAIN - [2:0] */ +#define WM8400_ACGAIN_WIDTH 3 /* ACGAIN - [2:0] */ + +/* + * R39 (0x27) - Input Mixer1 + */ +#define WM8400_AINLMODE_MASK 0x000C /* AINLMODE - [3:2] */ +#define WM8400_AINLMODE_SHIFT 2 /* AINLMODE - [3:2] */ +#define WM8400_AINLMODE_WIDTH 2 /* AINLMODE - [3:2] */ +#define WM8400_AINRMODE_MASK 0x0003 /* AINRMODE - [1:0] */ +#define WM8400_AINRMODE_SHIFT 0 /* AINRMODE - [1:0] */ +#define WM8400_AINRMODE_WIDTH 2 /* AINRMODE - [1:0] */ + +/* + * R40 (0x28) - Input Mixer2 + */ +#define WM8400_LMP4 0x0080 /* LMP4 */ +#define WM8400_LMP4_MASK 0x0080 /* LMP4 */ +#define WM8400_LMP4_SHIFT 7 /* LMP4 */ +#define WM8400_LMP4_WIDTH 1 /* LMP4 */ +#define WM8400_LMN3 0x0040 /* LMN3 */ +#define WM8400_LMN3_MASK 0x0040 /* LMN3 */ +#define WM8400_LMN3_SHIFT 6 /* LMN3 */ +#define WM8400_LMN3_WIDTH 1 /* LMN3 */ +#define WM8400_LMP2 0x0020 /* LMP2 */ +#define WM8400_LMP2_MASK 0x0020 /* LMP2 */ +#define WM8400_LMP2_SHIFT 5 /* LMP2 */ +#define WM8400_LMP2_WIDTH 1 /* LMP2 */ +#define WM8400_LMN1 0x0010 /* LMN1 */ +#define WM8400_LMN1_MASK 0x0010 /* LMN1 */ +#define WM8400_LMN1_SHIFT 4 /* LMN1 */ +#define WM8400_LMN1_WIDTH 1 /* LMN1 */ +#define WM8400_RMP4 0x0008 /* RMP4 */ +#define WM8400_RMP4_MASK 0x0008 /* RMP4 */ +#define WM8400_RMP4_SHIFT 3 /* RMP4 */ +#define WM8400_RMP4_WIDTH 1 /* RMP4 */ +#define WM8400_RMN3 0x0004 /* RMN3 */ +#define WM8400_RMN3_MASK 0x0004 /* RMN3 */ +#define WM8400_RMN3_SHIFT 2 /* RMN3 */ +#define WM8400_RMN3_WIDTH 1 /* RMN3 */ +#define WM8400_RMP2 0x0002 /* RMP2 */ +#define WM8400_RMP2_MASK 0x0002 /* RMP2 */ +#define WM8400_RMP2_SHIFT 1 /* RMP2 */ +#define WM8400_RMP2_WIDTH 1 /* RMP2 */ +#define WM8400_RMN1 0x0001 /* RMN1 */ +#define WM8400_RMN1_MASK 0x0001 /* RMN1 */ +#define WM8400_RMN1_SHIFT 0 /* RMN1 */ +#define WM8400_RMN1_WIDTH 1 /* RMN1 */ + +/* + * R41 (0x29) - Input Mixer3 + */ +#define WM8400_L34MNB 0x0100 /* L34MNB */ +#define WM8400_L34MNB_MASK 0x0100 /* L34MNB */ +#define WM8400_L34MNB_SHIFT 8 /* L34MNB */ +#define WM8400_L34MNB_WIDTH 1 /* L34MNB */ +#define WM8400_L34MNBST 0x0080 /* L34MNBST */ +#define WM8400_L34MNBST_MASK 0x0080 /* L34MNBST */ +#define WM8400_L34MNBST_SHIFT 7 /* L34MNBST */ +#define WM8400_L34MNBST_WIDTH 1 /* L34MNBST */ +#define WM8400_L12MNB 0x0020 /* L12MNB */ +#define WM8400_L12MNB_MASK 0x0020 /* L12MNB */ +#define WM8400_L12MNB_SHIFT 5 /* L12MNB */ +#define WM8400_L12MNB_WIDTH 1 /* L12MNB */ +#define WM8400_L12MNBST 0x0010 /* L12MNBST */ +#define WM8400_L12MNBST_MASK 0x0010 /* L12MNBST */ +#define WM8400_L12MNBST_SHIFT 4 /* L12MNBST */ +#define WM8400_L12MNBST_WIDTH 1 /* L12MNBST */ +#define WM8400_LDBVOL_MASK 0x0007 /* LDBVOL - [2:0] */ +#define WM8400_LDBVOL_SHIFT 0 /* LDBVOL - [2:0] */ +#define WM8400_LDBVOL_WIDTH 3 /* LDBVOL - [2:0] */ + +/* + * R42 (0x2A) - Input Mixer4 + */ +#define WM8400_R34MNB 0x0100 /* R34MNB */ +#define WM8400_R34MNB_MASK 0x0100 /* R34MNB */ +#define WM8400_R34MNB_SHIFT 8 /* R34MNB */ +#define WM8400_R34MNB_WIDTH 1 /* R34MNB */ +#define WM8400_R34MNBST 0x0080 /* R34MNBST */ +#define WM8400_R34MNBST_MASK 0x0080 /* R34MNBST */ +#define WM8400_R34MNBST_SHIFT 7 /* R34MNBST */ +#define WM8400_R34MNBST_WIDTH 1 /* R34MNBST */ +#define WM8400_R12MNB 0x0020 /* R12MNB */ +#define WM8400_R12MNB_MASK 0x0020 /* R12MNB */ +#define WM8400_R12MNB_SHIFT 5 /* R12MNB */ +#define WM8400_R12MNB_WIDTH 1 /* R12MNB */ +#define WM8400_R12MNBST 0x0010 /* R12MNBST */ +#define WM8400_R12MNBST_MASK 0x0010 /* R12MNBST */ +#define WM8400_R12MNBST_SHIFT 4 /* R12MNBST */ +#define WM8400_R12MNBST_WIDTH 1 /* R12MNBST */ +#define WM8400_RDBVOL_MASK 0x0007 /* RDBVOL - [2:0] */ +#define WM8400_RDBVOL_SHIFT 0 /* RDBVOL - [2:0] */ +#define WM8400_RDBVOL_WIDTH 3 /* RDBVOL - [2:0] */ + +/* + * R43 (0x2B) - Input Mixer5 + */ +#define WM8400_LI2BVOL_MASK 0x01C0 /* LI2BVOL - [8:6] */ +#define WM8400_LI2BVOL_SHIFT 6 /* LI2BVOL - [8:6] */ +#define WM8400_LI2BVOL_WIDTH 3 /* LI2BVOL - [8:6] */ +#define WM8400_LR4BVOL_MASK 0x0038 /* LR4BVOL - [5:3] */ +#define WM8400_LR4BVOL_SHIFT 3 /* LR4BVOL - [5:3] */ +#define WM8400_LR4BVOL_WIDTH 3 /* LR4BVOL - [5:3] */ +#define WM8400_LL4BVOL_MASK 0x0007 /* LL4BVOL - [2:0] */ +#define WM8400_LL4BVOL_SHIFT 0 /* LL4BVOL - [2:0] */ +#define WM8400_LL4BVOL_WIDTH 3 /* LL4BVOL - [2:0] */ + +/* + * R44 (0x2C) - Input Mixer6 + */ +#define WM8400_RI2BVOL_MASK 0x01C0 /* RI2BVOL - [8:6] */ +#define WM8400_RI2BVOL_SHIFT 6 /* RI2BVOL - [8:6] */ +#define WM8400_RI2BVOL_WIDTH 3 /* RI2BVOL - [8:6] */ +#define WM8400_RL4BVOL_MASK 0x0038 /* RL4BVOL - [5:3] */ +#define WM8400_RL4BVOL_SHIFT 3 /* RL4BVOL - [5:3] */ +#define WM8400_RL4BVOL_WIDTH 3 /* RL4BVOL - [5:3] */ +#define WM8400_RR4BVOL_MASK 0x0007 /* RR4BVOL - [2:0] */ +#define WM8400_RR4BVOL_SHIFT 0 /* RR4BVOL - [2:0] */ +#define WM8400_RR4BVOL_WIDTH 3 /* RR4BVOL - [2:0] */ + +/* + * R45 (0x2D) - Output Mixer1 + */ +#define WM8400_LRBLO 0x0080 /* LRBLO */ +#define WM8400_LRBLO_MASK 0x0080 /* LRBLO */ +#define WM8400_LRBLO_SHIFT 7 /* LRBLO */ +#define WM8400_LRBLO_WIDTH 1 /* LRBLO */ +#define WM8400_LLBLO 0x0040 /* LLBLO */ +#define WM8400_LLBLO_MASK 0x0040 /* LLBLO */ +#define WM8400_LLBLO_SHIFT 6 /* LLBLO */ +#define WM8400_LLBLO_WIDTH 1 /* LLBLO */ +#define WM8400_LRI3LO 0x0020 /* LRI3LO */ +#define WM8400_LRI3LO_MASK 0x0020 /* LRI3LO */ +#define WM8400_LRI3LO_SHIFT 5 /* LRI3LO */ +#define WM8400_LRI3LO_WIDTH 1 /* LRI3LO */ +#define WM8400_LLI3LO 0x0010 /* LLI3LO */ +#define WM8400_LLI3LO_MASK 0x0010 /* LLI3LO */ +#define WM8400_LLI3LO_SHIFT 4 /* LLI3LO */ +#define WM8400_LLI3LO_WIDTH 1 /* LLI3LO */ +#define WM8400_LR12LO 0x0008 /* LR12LO */ +#define WM8400_LR12LO_MASK 0x0008 /* LR12LO */ +#define WM8400_LR12LO_SHIFT 3 /* LR12LO */ +#define WM8400_LR12LO_WIDTH 1 /* LR12LO */ +#define WM8400_LL12LO 0x0004 /* LL12LO */ +#define WM8400_LL12LO_MASK 0x0004 /* LL12LO */ +#define WM8400_LL12LO_SHIFT 2 /* LL12LO */ +#define WM8400_LL12LO_WIDTH 1 /* LL12LO */ +#define WM8400_LDLO 0x0001 /* LDLO */ +#define WM8400_LDLO_MASK 0x0001 /* LDLO */ +#define WM8400_LDLO_SHIFT 0 /* LDLO */ +#define WM8400_LDLO_WIDTH 1 /* LDLO */ + +/* + * R46 (0x2E) - Output Mixer2 + */ +#define WM8400_RLBRO 0x0080 /* RLBRO */ +#define WM8400_RLBRO_MASK 0x0080 /* RLBRO */ +#define WM8400_RLBRO_SHIFT 7 /* RLBRO */ +#define WM8400_RLBRO_WIDTH 1 /* RLBRO */ +#define WM8400_RRBRO 0x0040 /* RRBRO */ +#define WM8400_RRBRO_MASK 0x0040 /* RRBRO */ +#define WM8400_RRBRO_SHIFT 6 /* RRBRO */ +#define WM8400_RRBRO_WIDTH 1 /* RRBRO */ +#define WM8400_RLI3RO 0x0020 /* RLI3RO */ +#define WM8400_RLI3RO_MASK 0x0020 /* RLI3RO */ +#define WM8400_RLI3RO_SHIFT 5 /* RLI3RO */ +#define WM8400_RLI3RO_WIDTH 1 /* RLI3RO */ +#define WM8400_RRI3RO 0x0010 /* RRI3RO */ +#define WM8400_RRI3RO_MASK 0x0010 /* RRI3RO */ +#define WM8400_RRI3RO_SHIFT 4 /* RRI3RO */ +#define WM8400_RRI3RO_WIDTH 1 /* RRI3RO */ +#define WM8400_RL12RO 0x0008 /* RL12RO */ +#define WM8400_RL12RO_MASK 0x0008 /* RL12RO */ +#define WM8400_RL12RO_SHIFT 3 /* RL12RO */ +#define WM8400_RL12RO_WIDTH 1 /* RL12RO */ +#define WM8400_RR12RO 0x0004 /* RR12RO */ +#define WM8400_RR12RO_MASK 0x0004 /* RR12RO */ +#define WM8400_RR12RO_SHIFT 2 /* RR12RO */ +#define WM8400_RR12RO_WIDTH 1 /* RR12RO */ +#define WM8400_RDRO 0x0001 /* RDRO */ +#define WM8400_RDRO_MASK 0x0001 /* RDRO */ +#define WM8400_RDRO_SHIFT 0 /* RDRO */ +#define WM8400_RDRO_WIDTH 1 /* RDRO */ + +/* + * R47 (0x2F) - Output Mixer3 + */ +#define WM8400_LLI3LOVOL_MASK 0x01C0 /* LLI3LOVOL - [8:6] */ +#define WM8400_LLI3LOVOL_SHIFT 6 /* LLI3LOVOL - [8:6] */ +#define WM8400_LLI3LOVOL_WIDTH 3 /* LLI3LOVOL - [8:6] */ +#define WM8400_LR12LOVOL_MASK 0x0038 /* LR12LOVOL - [5:3] */ +#define WM8400_LR12LOVOL_SHIFT 3 /* LR12LOVOL - [5:3] */ +#define WM8400_LR12LOVOL_WIDTH 3 /* LR12LOVOL - [5:3] */ +#define WM8400_LL12LOVOL_MASK 0x0007 /* LL12LOVOL - [2:0] */ +#define WM8400_LL12LOVOL_SHIFT 0 /* LL12LOVOL - [2:0] */ +#define WM8400_LL12LOVOL_WIDTH 3 /* LL12LOVOL - [2:0] */ + +/* + * R48 (0x30) - Output Mixer4 + */ +#define WM8400_RRI3ROVOL_MASK 0x01C0 /* RRI3ROVOL - [8:6] */ +#define WM8400_RRI3ROVOL_SHIFT 6 /* RRI3ROVOL - [8:6] */ +#define WM8400_RRI3ROVOL_WIDTH 3 /* RRI3ROVOL - [8:6] */ +#define WM8400_RL12ROVOL_MASK 0x0038 /* RL12ROVOL - [5:3] */ +#define WM8400_RL12ROVOL_SHIFT 3 /* RL12ROVOL - [5:3] */ +#define WM8400_RL12ROVOL_WIDTH 3 /* RL12ROVOL - [5:3] */ +#define WM8400_RR12ROVOL_MASK 0x0007 /* RR12ROVOL - [2:0] */ +#define WM8400_RR12ROVOL_SHIFT 0 /* RR12ROVOL - [2:0] */ +#define WM8400_RR12ROVOL_WIDTH 3 /* RR12ROVOL - [2:0] */ + +/* + * R49 (0x31) - Output Mixer5 + */ +#define WM8400_LRI3LOVOL_MASK 0x01C0 /* LRI3LOVOL - [8:6] */ +#define WM8400_LRI3LOVOL_SHIFT 6 /* LRI3LOVOL - [8:6] */ +#define WM8400_LRI3LOVOL_WIDTH 3 /* LRI3LOVOL - [8:6] */ +#define WM8400_LRBLOVOL_MASK 0x0038 /* LRBLOVOL - [5:3] */ +#define WM8400_LRBLOVOL_SHIFT 3 /* LRBLOVOL - [5:3] */ +#define WM8400_LRBLOVOL_WIDTH 3 /* LRBLOVOL - [5:3] */ +#define WM8400_LLBLOVOL_MASK 0x0007 /* LLBLOVOL - [2:0] */ +#define WM8400_LLBLOVOL_SHIFT 0 /* LLBLOVOL - [2:0] */ +#define WM8400_LLBLOVOL_WIDTH 3 /* LLBLOVOL - [2:0] */ + +/* + * R50 (0x32) - Output Mixer6 + */ +#define WM8400_RLI3ROVOL_MASK 0x01C0 /* RLI3ROVOL - [8:6] */ +#define WM8400_RLI3ROVOL_SHIFT 6 /* RLI3ROVOL - [8:6] */ +#define WM8400_RLI3ROVOL_WIDTH 3 /* RLI3ROVOL - [8:6] */ +#define WM8400_RLBROVOL_MASK 0x0038 /* RLBROVOL - [5:3] */ +#define WM8400_RLBROVOL_SHIFT 3 /* RLBROVOL - [5:3] */ +#define WM8400_RLBROVOL_WIDTH 3 /* RLBROVOL - [5:3] */ +#define WM8400_RRBROVOL_MASK 0x0007 /* RRBROVOL - [2:0] */ +#define WM8400_RRBROVOL_SHIFT 0 /* RRBROVOL - [2:0] */ +#define WM8400_RRBROVOL_WIDTH 3 /* RRBROVOL - [2:0] */ + +/* + * R51 (0x33) - Out3/4 Mixer + */ +#define WM8400_VSEL_MASK 0x0180 /* VSEL - [8:7] */ +#define WM8400_VSEL_SHIFT 7 /* VSEL - [8:7] */ +#define WM8400_VSEL_WIDTH 2 /* VSEL - [8:7] */ +#define WM8400_LI4O3 0x0020 /* LI4O3 */ +#define WM8400_LI4O3_MASK 0x0020 /* LI4O3 */ +#define WM8400_LI4O3_SHIFT 5 /* LI4O3 */ +#define WM8400_LI4O3_WIDTH 1 /* LI4O3 */ +#define WM8400_LPGAO3 0x0010 /* LPGAO3 */ +#define WM8400_LPGAO3_MASK 0x0010 /* LPGAO3 */ +#define WM8400_LPGAO3_SHIFT 4 /* LPGAO3 */ +#define WM8400_LPGAO3_WIDTH 1 /* LPGAO3 */ +#define WM8400_RI4O4 0x0002 /* RI4O4 */ +#define WM8400_RI4O4_MASK 0x0002 /* RI4O4 */ +#define WM8400_RI4O4_SHIFT 1 /* RI4O4 */ +#define WM8400_RI4O4_WIDTH 1 /* RI4O4 */ +#define WM8400_RPGAO4 0x0001 /* RPGAO4 */ +#define WM8400_RPGAO4_MASK 0x0001 /* RPGAO4 */ +#define WM8400_RPGAO4_SHIFT 0 /* RPGAO4 */ +#define WM8400_RPGAO4_WIDTH 1 /* RPGAO4 */ + +/* + * R52 (0x34) - Line Mixer1 + */ +#define WM8400_LLOPGALON 0x0040 /* LLOPGALON */ +#define WM8400_LLOPGALON_MASK 0x0040 /* LLOPGALON */ +#define WM8400_LLOPGALON_SHIFT 6 /* LLOPGALON */ +#define WM8400_LLOPGALON_WIDTH 1 /* LLOPGALON */ +#define WM8400_LROPGALON 0x0020 /* LROPGALON */ +#define WM8400_LROPGALON_MASK 0x0020 /* LROPGALON */ +#define WM8400_LROPGALON_SHIFT 5 /* LROPGALON */ +#define WM8400_LROPGALON_WIDTH 1 /* LROPGALON */ +#define WM8400_LOPLON 0x0010 /* LOPLON */ +#define WM8400_LOPLON_MASK 0x0010 /* LOPLON */ +#define WM8400_LOPLON_SHIFT 4 /* LOPLON */ +#define WM8400_LOPLON_WIDTH 1 /* LOPLON */ +#define WM8400_LR12LOP 0x0004 /* LR12LOP */ +#define WM8400_LR12LOP_MASK 0x0004 /* LR12LOP */ +#define WM8400_LR12LOP_SHIFT 2 /* LR12LOP */ +#define WM8400_LR12LOP_WIDTH 1 /* LR12LOP */ +#define WM8400_LL12LOP 0x0002 /* LL12LOP */ +#define WM8400_LL12LOP_MASK 0x0002 /* LL12LOP */ +#define WM8400_LL12LOP_SHIFT 1 /* LL12LOP */ +#define WM8400_LL12LOP_WIDTH 1 /* LL12LOP */ +#define WM8400_LLOPGALOP 0x0001 /* LLOPGALOP */ +#define WM8400_LLOPGALOP_MASK 0x0001 /* LLOPGALOP */ +#define WM8400_LLOPGALOP_SHIFT 0 /* LLOPGALOP */ +#define WM8400_LLOPGALOP_WIDTH 1 /* LLOPGALOP */ + +/* + * R53 (0x35) - Line Mixer2 + */ +#define WM8400_RROPGARON 0x0040 /* RROPGARON */ +#define WM8400_RROPGARON_MASK 0x0040 /* RROPGARON */ +#define WM8400_RROPGARON_SHIFT 6 /* RROPGARON */ +#define WM8400_RROPGARON_WIDTH 1 /* RROPGARON */ +#define WM8400_RLOPGARON 0x0020 /* RLOPGARON */ +#define WM8400_RLOPGARON_MASK 0x0020 /* RLOPGARON */ +#define WM8400_RLOPGARON_SHIFT 5 /* RLOPGARON */ +#define WM8400_RLOPGARON_WIDTH 1 /* RLOPGARON */ +#define WM8400_ROPRON 0x0010 /* ROPRON */ +#define WM8400_ROPRON_MASK 0x0010 /* ROPRON */ +#define WM8400_ROPRON_SHIFT 4 /* ROPRON */ +#define WM8400_ROPRON_WIDTH 1 /* ROPRON */ +#define WM8400_RL12ROP 0x0004 /* RL12ROP */ +#define WM8400_RL12ROP_MASK 0x0004 /* RL12ROP */ +#define WM8400_RL12ROP_SHIFT 2 /* RL12ROP */ +#define WM8400_RL12ROP_WIDTH 1 /* RL12ROP */ +#define WM8400_RR12ROP 0x0002 /* RR12ROP */ +#define WM8400_RR12ROP_MASK 0x0002 /* RR12ROP */ +#define WM8400_RR12ROP_SHIFT 1 /* RR12ROP */ +#define WM8400_RR12ROP_WIDTH 1 /* RR12ROP */ +#define WM8400_RROPGAROP 0x0001 /* RROPGAROP */ +#define WM8400_RROPGAROP_MASK 0x0001 /* RROPGAROP */ +#define WM8400_RROPGAROP_SHIFT 0 /* RROPGAROP */ +#define WM8400_RROPGAROP_WIDTH 1 /* RROPGAROP */ + +/* + * R54 (0x36) - Speaker Mixer + */ +#define WM8400_LB2SPK 0x0080 /* LB2SPK */ +#define WM8400_LB2SPK_MASK 0x0080 /* LB2SPK */ +#define WM8400_LB2SPK_SHIFT 7 /* LB2SPK */ +#define WM8400_LB2SPK_WIDTH 1 /* LB2SPK */ +#define WM8400_RB2SPK 0x0040 /* RB2SPK */ +#define WM8400_RB2SPK_MASK 0x0040 /* RB2SPK */ +#define WM8400_RB2SPK_SHIFT 6 /* RB2SPK */ +#define WM8400_RB2SPK_WIDTH 1 /* RB2SPK */ +#define WM8400_LI2SPK 0x0020 /* LI2SPK */ +#define WM8400_LI2SPK_MASK 0x0020 /* LI2SPK */ +#define WM8400_LI2SPK_SHIFT 5 /* LI2SPK */ +#define WM8400_LI2SPK_WIDTH 1 /* LI2SPK */ +#define WM8400_RI2SPK 0x0010 /* RI2SPK */ +#define WM8400_RI2SPK_MASK 0x0010 /* RI2SPK */ +#define WM8400_RI2SPK_SHIFT 4 /* RI2SPK */ +#define WM8400_RI2SPK_WIDTH 1 /* RI2SPK */ +#define WM8400_LOPGASPK 0x0008 /* LOPGASPK */ +#define WM8400_LOPGASPK_MASK 0x0008 /* LOPGASPK */ +#define WM8400_LOPGASPK_SHIFT 3 /* LOPGASPK */ +#define WM8400_LOPGASPK_WIDTH 1 /* LOPGASPK */ +#define WM8400_ROPGASPK 0x0004 /* ROPGASPK */ +#define WM8400_ROPGASPK_MASK 0x0004 /* ROPGASPK */ +#define WM8400_ROPGASPK_SHIFT 2 /* ROPGASPK */ +#define WM8400_ROPGASPK_WIDTH 1 /* ROPGASPK */ +#define WM8400_LDSPK 0x0002 /* LDSPK */ +#define WM8400_LDSPK_MASK 0x0002 /* LDSPK */ +#define WM8400_LDSPK_SHIFT 1 /* LDSPK */ +#define WM8400_LDSPK_WIDTH 1 /* LDSPK */ +#define WM8400_RDSPK 0x0001 /* RDSPK */ +#define WM8400_RDSPK_MASK 0x0001 /* RDSPK */ +#define WM8400_RDSPK_SHIFT 0 /* RDSPK */ +#define WM8400_RDSPK_WIDTH 1 /* RDSPK */ + +/* + * R55 (0x37) - Additional Control + */ +#define WM8400_VROI 0x0001 /* VROI */ +#define WM8400_VROI_MASK 0x0001 /* VROI */ +#define WM8400_VROI_SHIFT 0 /* VROI */ +#define WM8400_VROI_WIDTH 1 /* VROI */ + +/* + * R56 (0x38) - AntiPOP1 + */ +#define WM8400_DIS_LLINE 0x0020 /* DIS_LLINE */ +#define WM8400_DIS_LLINE_MASK 0x0020 /* DIS_LLINE */ +#define WM8400_DIS_LLINE_SHIFT 5 /* DIS_LLINE */ +#define WM8400_DIS_LLINE_WIDTH 1 /* DIS_LLINE */ +#define WM8400_DIS_RLINE 0x0010 /* DIS_RLINE */ +#define WM8400_DIS_RLINE_MASK 0x0010 /* DIS_RLINE */ +#define WM8400_DIS_RLINE_SHIFT 4 /* DIS_RLINE */ +#define WM8400_DIS_RLINE_WIDTH 1 /* DIS_RLINE */ +#define WM8400_DIS_OUT3 0x0008 /* DIS_OUT3 */ +#define WM8400_DIS_OUT3_MASK 0x0008 /* DIS_OUT3 */ +#define WM8400_DIS_OUT3_SHIFT 3 /* DIS_OUT3 */ +#define WM8400_DIS_OUT3_WIDTH 1 /* DIS_OUT3 */ +#define WM8400_DIS_OUT4 0x0004 /* DIS_OUT4 */ +#define WM8400_DIS_OUT4_MASK 0x0004 /* DIS_OUT4 */ +#define WM8400_DIS_OUT4_SHIFT 2 /* DIS_OUT4 */ +#define WM8400_DIS_OUT4_WIDTH 1 /* DIS_OUT4 */ +#define WM8400_DIS_LOUT 0x0002 /* DIS_LOUT */ +#define WM8400_DIS_LOUT_MASK 0x0002 /* DIS_LOUT */ +#define WM8400_DIS_LOUT_SHIFT 1 /* DIS_LOUT */ +#define WM8400_DIS_LOUT_WIDTH 1 /* DIS_LOUT */ +#define WM8400_DIS_ROUT 0x0001 /* DIS_ROUT */ +#define WM8400_DIS_ROUT_MASK 0x0001 /* DIS_ROUT */ +#define WM8400_DIS_ROUT_SHIFT 0 /* DIS_ROUT */ +#define WM8400_DIS_ROUT_WIDTH 1 /* DIS_ROUT */ + +/* + * R57 (0x39) - AntiPOP2 + */ +#define WM8400_SOFTST 0x0040 /* SOFTST */ +#define WM8400_SOFTST_MASK 0x0040 /* SOFTST */ +#define WM8400_SOFTST_SHIFT 6 /* SOFTST */ +#define WM8400_SOFTST_WIDTH 1 /* SOFTST */ +#define WM8400_BUFIOEN 0x0008 /* BUFIOEN */ +#define WM8400_BUFIOEN_MASK 0x0008 /* BUFIOEN */ +#define WM8400_BUFIOEN_SHIFT 3 /* BUFIOEN */ +#define WM8400_BUFIOEN_WIDTH 1 /* BUFIOEN */ +#define WM8400_BUFDCOPEN 0x0004 /* BUFDCOPEN */ +#define WM8400_BUFDCOPEN_MASK 0x0004 /* BUFDCOPEN */ +#define WM8400_BUFDCOPEN_SHIFT 2 /* BUFDCOPEN */ +#define WM8400_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */ +#define WM8400_POBCTRL 0x0002 /* POBCTRL */ +#define WM8400_POBCTRL_MASK 0x0002 /* POBCTRL */ +#define WM8400_POBCTRL_SHIFT 1 /* POBCTRL */ +#define WM8400_POBCTRL_WIDTH 1 /* POBCTRL */ +#define WM8400_VMIDTOG 0x0001 /* VMIDTOG */ +#define WM8400_VMIDTOG_MASK 0x0001 /* VMIDTOG */ +#define WM8400_VMIDTOG_SHIFT 0 /* VMIDTOG */ +#define WM8400_VMIDTOG_WIDTH 1 /* VMIDTOG */ + +/* + * R58 (0x3A) - MICBIAS + */ +#define WM8400_MCDSCTH_MASK 0x00C0 /* MCDSCTH - [7:6] */ +#define WM8400_MCDSCTH_SHIFT 6 /* MCDSCTH - [7:6] */ +#define WM8400_MCDSCTH_WIDTH 2 /* MCDSCTH - [7:6] */ +#define WM8400_MCDTHR_MASK 0x0038 /* MCDTHR - [5:3] */ +#define WM8400_MCDTHR_SHIFT 3 /* MCDTHR - [5:3] */ +#define WM8400_MCDTHR_WIDTH 3 /* MCDTHR - [5:3] */ +#define WM8400_MCD 0x0004 /* MCD */ +#define WM8400_MCD_MASK 0x0004 /* MCD */ +#define WM8400_MCD_SHIFT 2 /* MCD */ +#define WM8400_MCD_WIDTH 1 /* MCD */ +#define WM8400_MBSEL 0x0001 /* MBSEL */ +#define WM8400_MBSEL_MASK 0x0001 /* MBSEL */ +#define WM8400_MBSEL_SHIFT 0 /* MBSEL */ +#define WM8400_MBSEL_WIDTH 1 /* MBSEL */ + +/* + * R60 (0x3C) - FLL Control 1 + */ +#define WM8400_FLL_REF_FREQ 0x1000 /* FLL_REF_FREQ */ +#define WM8400_FLL_REF_FREQ_MASK 0x1000 /* FLL_REF_FREQ */ +#define WM8400_FLL_REF_FREQ_SHIFT 12 /* FLL_REF_FREQ */ +#define WM8400_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */ +#define WM8400_FLL_CLK_SRC_MASK 0x0C00 /* FLL_CLK_SRC - [11:10] */ +#define WM8400_FLL_CLK_SRC_SHIFT 10 /* FLL_CLK_SRC - [11:10] */ +#define WM8400_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [11:10] */ +#define WM8400_FLL_FRAC 0x0200 /* FLL_FRAC */ +#define WM8400_FLL_FRAC_MASK 0x0200 /* FLL_FRAC */ +#define WM8400_FLL_FRAC_SHIFT 9 /* FLL_FRAC */ +#define WM8400_FLL_FRAC_WIDTH 1 /* FLL_FRAC */ +#define WM8400_FLL_OSC_ENA 0x0100 /* FLL_OSC_ENA */ +#define WM8400_FLL_OSC_ENA_MASK 0x0100 /* FLL_OSC_ENA */ +#define WM8400_FLL_OSC_ENA_SHIFT 8 /* FLL_OSC_ENA */ +#define WM8400_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */ +#define WM8400_FLL_CTRL_RATE_MASK 0x00E0 /* FLL_CTRL_RATE - [7:5] */ +#define WM8400_FLL_CTRL_RATE_SHIFT 5 /* FLL_CTRL_RATE - [7:5] */ +#define WM8400_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [7:5] */ +#define WM8400_FLL_FRATIO_MASK 0x001F /* FLL_FRATIO - [4:0] */ +#define WM8400_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [4:0] */ +#define WM8400_FLL_FRATIO_WIDTH 5 /* FLL_FRATIO - [4:0] */ + +/* + * R61 (0x3D) - FLL Control 2 + */ +#define WM8400_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */ +#define WM8400_FLL_K_SHIFT 0 /* FLL_K - [15:0] */ +#define WM8400_FLL_K_WIDTH 16 /* FLL_K - [15:0] */ + +/* + * R62 (0x3E) - FLL Control 3 + */ +#define WM8400_FLL_N_MASK 0x03FF /* FLL_N - [9:0] */ +#define WM8400_FLL_N_SHIFT 0 /* FLL_N - [9:0] */ +#define WM8400_FLL_N_WIDTH 10 /* FLL_N - [9:0] */ + +/* + * R63 (0x3F) - FLL Control 4 + */ +#define WM8400_FLL_TRK_GAIN_MASK 0x0078 /* FLL_TRK_GAIN - [6:3] */ +#define WM8400_FLL_TRK_GAIN_SHIFT 3 /* FLL_TRK_GAIN - [6:3] */ +#define WM8400_FLL_TRK_GAIN_WIDTH 4 /* FLL_TRK_GAIN - [6:3] */ +#define WM8400_FLL_OUTDIV_MASK 0x0007 /* FLL_OUTDIV - [2:0] */ +#define WM8400_FLL_OUTDIV_SHIFT 0 /* FLL_OUTDIV - [2:0] */ +#define WM8400_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [2:0] */ + +void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400); + +#endif diff --git a/include/linux/mfd/wm8400-private.h b/include/linux/mfd/wm8400-private.h new file mode 100644 index 00000000000..49042e990f0 --- /dev/null +++ b/include/linux/mfd/wm8400-private.h @@ -0,0 +1,935 @@ +/* + * wm8400 private definitions. + * + * Copyright 2008 Wolfson Microelectronics plc + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_MFD_WM8400_PRIV_H +#define __LINUX_MFD_WM8400_PRIV_H + +#include +#include + +#define WM8400_REGISTER_COUNT 0x55 + +struct wm8400 { + struct device *dev; + + int (*read_dev)(void *data, char reg, int count, u16 *dst); + int (*write_dev)(void *data, char reg, int count, const u16 *src); + + struct mutex io_lock; + void *io_data; + + u16 reg_cache[WM8400_REGISTER_COUNT]; + + struct platform_device regulators[6]; +}; + +/* + * Register values. + */ +#define WM8400_RESET_ID 0x00 +#define WM8400_ID 0x01 +#define WM8400_POWER_MANAGEMENT_1 0x02 +#define WM8400_POWER_MANAGEMENT_2 0x03 +#define WM8400_POWER_MANAGEMENT_3 0x04 +#define WM8400_AUDIO_INTERFACE_1 0x05 +#define WM8400_AUDIO_INTERFACE_2 0x06 +#define WM8400_CLOCKING_1 0x07 +#define WM8400_CLOCKING_2 0x08 +#define WM8400_AUDIO_INTERFACE_3 0x09 +#define WM8400_AUDIO_INTERFACE_4 0x0A +#define WM8400_DAC_CTRL 0x0B +#define WM8400_LEFT_DAC_DIGITAL_VOLUME 0x0C +#define WM8400_RIGHT_DAC_DIGITAL_VOLUME 0x0D +#define WM8400_DIGITAL_SIDE_TONE 0x0E +#define WM8400_ADC_CTRL 0x0F +#define WM8400_LEFT_ADC_DIGITAL_VOLUME 0x10 +#define WM8400_RIGHT_ADC_DIGITAL_VOLUME 0x11 +#define WM8400_GPIO_CTRL_1 0x12 +#define WM8400_GPIO1_GPIO2 0x13 +#define WM8400_GPIO3_GPIO4 0x14 +#define WM8400_GPIO5_GPIO6 0x15 +#define WM8400_GPIOCTRL_2 0x16 +#define WM8400_GPIO_POL 0x17 +#define WM8400_LEFT_LINE_INPUT_1_2_VOLUME 0x18 +#define WM8400_LEFT_LINE_INPUT_3_4_VOLUME 0x19 +#define WM8400_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A +#define WM8400_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B +#define WM8400_LEFT_OUTPUT_VOLUME 0x1C +#define WM8400_RIGHT_OUTPUT_VOLUME 0x1D +#define WM8400_LINE_OUTPUTS_VOLUME 0x1E +#define WM8400_OUT3_4_VOLUME 0x1F +#define WM8400_LEFT_OPGA_VOLUME 0x20 +#define WM8400_RIGHT_OPGA_VOLUME 0x21 +#define WM8400_SPEAKER_VOLUME 0x22 +#define WM8400_CLASSD1 0x23 +#define WM8400_CLASSD3 0x25 +#define WM8400_INPUT_MIXER1 0x27 +#define WM8400_INPUT_MIXER2 0x28 +#define WM8400_INPUT_MIXER3 0x29 +#define WM8400_INPUT_MIXER4 0x2A +#define WM8400_INPUT_MIXER5 0x2B +#define WM8400_INPUT_MIXER6 0x2C +#define WM8400_OUTPUT_MIXER1 0x2D +#define WM8400_OUTPUT_MIXER2 0x2E +#define WM8400_OUTPUT_MIXER3 0x2F +#define WM8400_OUTPUT_MIXER4 0x30 +#define WM8400_OUTPUT_MIXER5 0x31 +#define WM8400_OUTPUT_MIXER6 0x32 +#define WM8400_OUT3_4_MIXER 0x33 +#define WM8400_LINE_MIXER1 0x34 +#define WM8400_LINE_MIXER2 0x35 +#define WM8400_SPEAKER_MIXER 0x36 +#define WM8400_ADDITIONAL_CONTROL 0x37 +#define WM8400_ANTIPOP1 0x38 +#define WM8400_ANTIPOP2 0x39 +#define WM8400_MICBIAS 0x3A +#define WM8400_FLL_CONTROL_1 0x3C +#define WM8400_FLL_CONTROL_2 0x3D +#define WM8400_FLL_CONTROL_3 0x3E +#define WM8400_FLL_CONTROL_4 0x3F +#define WM8400_LDO1_CONTROL 0x41 +#define WM8400_LDO2_CONTROL 0x42 +#define WM8400_LDO3_CONTROL 0x43 +#define WM8400_LDO4_CONTROL 0x44 +#define WM8400_DCDC1_CONTROL_1 0x46 +#define WM8400_DCDC1_CONTROL_2 0x47 +#define WM8400_DCDC2_CONTROL_1 0x48 +#define WM8400_DCDC2_CONTROL_2 0x49 +#define WM8400_INTERFACE 0x4B +#define WM8400_PM_GENERAL 0x4C +#define WM8400_PM_SHUTDOWN_CONTROL 0x4E +#define WM8400_INTERRUPT_STATUS_1 0x4F +#define WM8400_INTERRUPT_STATUS_1_MASK 0x50 +#define WM8400_INTERRUPT_LEVELS 0x51 +#define WM8400_SHUTDOWN_REASON 0x52 +#define WM8400_LINE_CIRCUITS 0x54 + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Reset/ID + */ +#define WM8400_SW_RESET_CHIP_ID_MASK 0xFFFF /* SW_RESET/CHIP_ID - [15:0] */ +#define WM8400_SW_RESET_CHIP_ID_SHIFT 0 /* SW_RESET/CHIP_ID - [15:0] */ +#define WM8400_SW_RESET_CHIP_ID_WIDTH 16 /* SW_RESET/CHIP_ID - [15:0] */ + +/* + * R1 (0x01) - ID + */ +#define WM8400_CHIP_REV_MASK 0x7000 /* CHIP_REV - [14:12] */ +#define WM8400_CHIP_REV_SHIFT 12 /* CHIP_REV - [14:12] */ +#define WM8400_CHIP_REV_WIDTH 3 /* CHIP_REV - [14:12] */ + +/* + * R18 (0x12) - GPIO CTRL 1 + */ +#define WM8400_IRQ 0x1000 /* IRQ */ +#define WM8400_IRQ_MASK 0x1000 /* IRQ */ +#define WM8400_IRQ_SHIFT 12 /* IRQ */ +#define WM8400_IRQ_WIDTH 1 /* IRQ */ +#define WM8400_TEMPOK 0x0800 /* TEMPOK */ +#define WM8400_TEMPOK_MASK 0x0800 /* TEMPOK */ +#define WM8400_TEMPOK_SHIFT 11 /* TEMPOK */ +#define WM8400_TEMPOK_WIDTH 1 /* TEMPOK */ +#define WM8400_MIC1SHRT 0x0400 /* MIC1SHRT */ +#define WM8400_MIC1SHRT_MASK 0x0400 /* MIC1SHRT */ +#define WM8400_MIC1SHRT_SHIFT 10 /* MIC1SHRT */ +#define WM8400_MIC1SHRT_WIDTH 1 /* MIC1SHRT */ +#define WM8400_MIC1DET 0x0200 /* MIC1DET */ +#define WM8400_MIC1DET_MASK 0x0200 /* MIC1DET */ +#define WM8400_MIC1DET_SHIFT 9 /* MIC1DET */ +#define WM8400_MIC1DET_WIDTH 1 /* MIC1DET */ +#define WM8400_FLL_LCK 0x0100 /* FLL_LCK */ +#define WM8400_FLL_LCK_MASK 0x0100 /* FLL_LCK */ +#define WM8400_FLL_LCK_SHIFT 8 /* FLL_LCK */ +#define WM8400_FLL_LCK_WIDTH 1 /* FLL_LCK */ +#define WM8400_GPIO_STATUS_MASK 0x00FF /* GPIO_STATUS - [7:0] */ +#define WM8400_GPIO_STATUS_SHIFT 0 /* GPIO_STATUS - [7:0] */ +#define WM8400_GPIO_STATUS_WIDTH 8 /* GPIO_STATUS - [7:0] */ + +/* + * R19 (0x13) - GPIO1 & GPIO2 + */ +#define WM8400_GPIO2_DEB_ENA 0x8000 /* GPIO2_DEB_ENA */ +#define WM8400_GPIO2_DEB_ENA_MASK 0x8000 /* GPIO2_DEB_ENA */ +#define WM8400_GPIO2_DEB_ENA_SHIFT 15 /* GPIO2_DEB_ENA */ +#define WM8400_GPIO2_DEB_ENA_WIDTH 1 /* GPIO2_DEB_ENA */ +#define WM8400_GPIO2_IRQ_ENA 0x4000 /* GPIO2_IRQ_ENA */ +#define WM8400_GPIO2_IRQ_ENA_MASK 0x4000 /* GPIO2_IRQ_ENA */ +#define WM8400_GPIO2_IRQ_ENA_SHIFT 14 /* GPIO2_IRQ_ENA */ +#define WM8400_GPIO2_IRQ_ENA_WIDTH 1 /* GPIO2_IRQ_ENA */ +#define WM8400_GPIO2_PU 0x2000 /* GPIO2_PU */ +#define WM8400_GPIO2_PU_MASK 0x2000 /* GPIO2_PU */ +#define WM8400_GPIO2_PU_SHIFT 13 /* GPIO2_PU */ +#define WM8400_GPIO2_PU_WIDTH 1 /* GPIO2_PU */ +#define WM8400_GPIO2_PD 0x1000 /* GPIO2_PD */ +#define WM8400_GPIO2_PD_MASK 0x1000 /* GPIO2_PD */ +#define WM8400_GPIO2_PD_SHIFT 12 /* GPIO2_PD */ +#define WM8400_GPIO2_PD_WIDTH 1 /* GPIO2_PD */ +#define WM8400_GPIO2_SEL_MASK 0x0F00 /* GPIO2_SEL - [11:8] */ +#define WM8400_GPIO2_SEL_SHIFT 8 /* GPIO2_SEL - [11:8] */ +#define WM8400_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [11:8] */ +#define WM8400_GPIO1_DEB_ENA 0x0080 /* GPIO1_DEB_ENA */ +#define WM8400_GPIO1_DEB_ENA_MASK 0x0080 /* GPIO1_DEB_ENA */ +#define WM8400_GPIO1_DEB_ENA_SHIFT 7 /* GPIO1_DEB_ENA */ +#define WM8400_GPIO1_DEB_ENA_WIDTH 1 /* GPIO1_DEB_ENA */ +#define WM8400_GPIO1_IRQ_ENA 0x0040 /* GPIO1_IRQ_ENA */ +#define WM8400_GPIO1_IRQ_ENA_MASK 0x0040 /* GPIO1_IRQ_ENA */ +#define WM8400_GPIO1_IRQ_ENA_SHIFT 6 /* GPIO1_IRQ_ENA */ +#define WM8400_GPIO1_IRQ_ENA_WIDTH 1 /* GPIO1_IRQ_ENA */ +#define WM8400_GPIO1_PU 0x0020 /* GPIO1_PU */ +#define WM8400_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */ +#define WM8400_GPIO1_PU_SHIFT 5 /* GPIO1_PU */ +#define WM8400_GPIO1_PU_WIDTH 1 /* GPIO1_PU */ +#define WM8400_GPIO1_PD 0x0010 /* GPIO1_PD */ +#define WM8400_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */ +#define WM8400_GPIO1_PD_SHIFT 4 /* GPIO1_PD */ +#define WM8400_GPIO1_PD_WIDTH 1 /* GPIO1_PD */ +#define WM8400_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */ +#define WM8400_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */ +#define WM8400_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */ + +/* + * R20 (0x14) - GPIO3 & GPIO4 + */ +#define WM8400_GPIO4_DEB_ENA 0x8000 /* GPIO4_DEB_ENA */ +#define WM8400_GPIO4_DEB_ENA_MASK 0x8000 /* GPIO4_DEB_ENA */ +#define WM8400_GPIO4_DEB_ENA_SHIFT 15 /* GPIO4_DEB_ENA */ +#define WM8400_GPIO4_DEB_ENA_WIDTH 1 /* GPIO4_DEB_ENA */ +#define WM8400_GPIO4_IRQ_ENA 0x4000 /* GPIO4_IRQ_ENA */ +#define WM8400_GPIO4_IRQ_ENA_MASK 0x4000 /* GPIO4_IRQ_ENA */ +#define WM8400_GPIO4_IRQ_ENA_SHIFT 14 /* GPIO4_IRQ_ENA */ +#define WM8400_GPIO4_IRQ_ENA_WIDTH 1 /* GPIO4_IRQ_ENA */ +#define WM8400_GPIO4_PU 0x2000 /* GPIO4_PU */ +#define WM8400_GPIO4_PU_MASK 0x2000 /* GPIO4_PU */ +#define WM8400_GPIO4_PU_SHIFT 13 /* GPIO4_PU */ +#define WM8400_GPIO4_PU_WIDTH 1 /* GPIO4_PU */ +#define WM8400_GPIO4_PD 0x1000 /* GPIO4_PD */ +#define WM8400_GPIO4_PD_MASK 0x1000 /* GPIO4_PD */ +#define WM8400_GPIO4_PD_SHIFT 12 /* GPIO4_PD */ +#define WM8400_GPIO4_PD_WIDTH 1 /* GPIO4_PD */ +#define WM8400_GPIO4_SEL_MASK 0x0F00 /* GPIO4_SEL - [11:8] */ +#define WM8400_GPIO4_SEL_SHIFT 8 /* GPIO4_SEL - [11:8] */ +#define WM8400_GPIO4_SEL_WIDTH 4 /* GPIO4_SEL - [11:8] */ +#define WM8400_GPIO3_DEB_ENA 0x0080 /* GPIO3_DEB_ENA */ +#define WM8400_GPIO3_DEB_ENA_MASK 0x0080 /* GPIO3_DEB_ENA */ +#define WM8400_GPIO3_DEB_ENA_SHIFT 7 /* GPIO3_DEB_ENA */ +#define WM8400_GPIO3_DEB_ENA_WIDTH 1 /* GPIO3_DEB_ENA */ +#define WM8400_GPIO3_IRQ_ENA 0x0040 /* GPIO3_IRQ_ENA */ +#define WM8400_GPIO3_IRQ_ENA_MASK 0x0040 /* GPIO3_IRQ_ENA */ +#define WM8400_GPIO3_IRQ_ENA_SHIFT 6 /* GPIO3_IRQ_ENA */ +#define WM8400_GPIO3_IRQ_ENA_WIDTH 1 /* GPIO3_IRQ_ENA */ +#define WM8400_GPIO3_PU 0x0020 /* GPIO3_PU */ +#define WM8400_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */ +#define WM8400_GPIO3_PU_SHIFT 5 /* GPIO3_PU */ +#define WM8400_GPIO3_PU_WIDTH 1 /* GPIO3_PU */ +#define WM8400_GPIO3_PD 0x0010 /* GPIO3_PD */ +#define WM8400_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */ +#define WM8400_GPIO3_PD_SHIFT 4 /* GPIO3_PD */ +#define WM8400_GPIO3_PD_WIDTH 1 /* GPIO3_PD */ +#define WM8400_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */ +#define WM8400_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */ +#define WM8400_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */ + +/* + * R21 (0x15) - GPIO5 & GPIO6 + */ +#define WM8400_GPIO6_DEB_ENA 0x8000 /* GPIO6_DEB_ENA */ +#define WM8400_GPIO6_DEB_ENA_MASK 0x8000 /* GPIO6_DEB_ENA */ +#define WM8400_GPIO6_DEB_ENA_SHIFT 15 /* GPIO6_DEB_ENA */ +#define WM8400_GPIO6_DEB_ENA_WIDTH 1 /* GPIO6_DEB_ENA */ +#define WM8400_GPIO6_IRQ_ENA 0x4000 /* GPIO6_IRQ_ENA */ +#define WM8400_GPIO6_IRQ_ENA_MASK 0x4000 /* GPIO6_IRQ_ENA */ +#define WM8400_GPIO6_IRQ_ENA_SHIFT 14 /* GPIO6_IRQ_ENA */ +#define WM8400_GPIO6_IRQ_ENA_WIDTH 1 /* GPIO6_IRQ_ENA */ +#define WM8400_GPIO6_PU 0x2000 /* GPIO6_PU */ +#define WM8400_GPIO6_PU_MASK 0x2000 /* GPIO6_PU */ +#define WM8400_GPIO6_PU_SHIFT 13 /* GPIO6_PU */ +#define WM8400_GPIO6_PU_WIDTH 1 /* GPIO6_PU */ +#define WM8400_GPIO6_PD 0x1000 /* GPIO6_PD */ +#define WM8400_GPIO6_PD_MASK 0x1000 /* GPIO6_PD */ +#define WM8400_GPIO6_PD_SHIFT 12 /* GPIO6_PD */ +#define WM8400_GPIO6_PD_WIDTH 1 /* GPIO6_PD */ +#define WM8400_GPIO6_SEL_MASK 0x0F00 /* GPIO6_SEL - [11:8] */ +#define WM8400_GPIO6_SEL_SHIFT 8 /* GPIO6_SEL - [11:8] */ +#define WM8400_GPIO6_SEL_WIDTH 4 /* GPIO6_SEL - [11:8] */ +#define WM8400_GPIO5_DEB_ENA 0x0080 /* GPIO5_DEB_ENA */ +#define WM8400_GPIO5_DEB_ENA_MASK 0x0080 /* GPIO5_DEB_ENA */ +#define WM8400_GPIO5_DEB_ENA_SHIFT 7 /* GPIO5_DEB_ENA */ +#define WM8400_GPIO5_DEB_ENA_WIDTH 1 /* GPIO5_DEB_ENA */ +#define WM8400_GPIO5_IRQ_ENA 0x0040 /* GPIO5_IRQ_ENA */ +#define WM8400_GPIO5_IRQ_ENA_MASK 0x0040 /* GPIO5_IRQ_ENA */ +#define WM8400_GPIO5_IRQ_ENA_SHIFT 6 /* GPIO5_IRQ_ENA */ +#define WM8400_GPIO5_IRQ_ENA_WIDTH 1 /* GPIO5_IRQ_ENA */ +#define WM8400_GPIO5_PU 0x0020 /* GPIO5_PU */ +#define WM8400_GPIO5_PU_MASK 0x0020 /* GPIO5_PU */ +#define WM8400_GPIO5_PU_SHIFT 5 /* GPIO5_PU */ +#define WM8400_GPIO5_PU_WIDTH 1 /* GPIO5_PU */ +#define WM8400_GPIO5_PD 0x0010 /* GPIO5_PD */ +#define WM8400_GPIO5_PD_MASK 0x0010 /* GPIO5_PD */ +#define WM8400_GPIO5_PD_SHIFT 4 /* GPIO5_PD */ +#define WM8400_GPIO5_PD_WIDTH 1 /* GPIO5_PD */ +#define WM8400_GPIO5_SEL_MASK 0x000F /* GPIO5_SEL - [3:0] */ +#define WM8400_GPIO5_SEL_SHIFT 0 /* GPIO5_SEL - [3:0] */ +#define WM8400_GPIO5_SEL_WIDTH 4 /* GPIO5_SEL - [3:0] */ + +/* + * R22 (0x16) - GPIOCTRL 2 + */ +#define WM8400_TEMPOK_IRQ_ENA 0x0800 /* TEMPOK_IRQ_ENA */ +#define WM8400_TEMPOK_IRQ_ENA_MASK 0x0800 /* TEMPOK_IRQ_ENA */ +#define WM8400_TEMPOK_IRQ_ENA_SHIFT 11 /* TEMPOK_IRQ_ENA */ +#define WM8400_TEMPOK_IRQ_ENA_WIDTH 1 /* TEMPOK_IRQ_ENA */ +#define WM8400_MIC1SHRT_IRQ_ENA 0x0400 /* MIC1SHRT_IRQ_ENA */ +#define WM8400_MIC1SHRT_IRQ_ENA_MASK 0x0400 /* MIC1SHRT_IRQ_ENA */ +#define WM8400_MIC1SHRT_IRQ_ENA_SHIFT 10 /* MIC1SHRT_IRQ_ENA */ +#define WM8400_MIC1SHRT_IRQ_ENA_WIDTH 1 /* MIC1SHRT_IRQ_ENA */ +#define WM8400_MIC1DET_IRQ_ENA 0x0200 /* MIC1DET_IRQ_ENA */ +#define WM8400_MIC1DET_IRQ_ENA_MASK 0x0200 /* MIC1DET_IRQ_ENA */ +#define WM8400_MIC1DET_IRQ_ENA_SHIFT 9 /* MIC1DET_IRQ_ENA */ +#define WM8400_MIC1DET_IRQ_ENA_WIDTH 1 /* MIC1DET_IRQ_ENA */ +#define WM8400_FLL_LCK_IRQ_ENA 0x0100 /* FLL_LCK_IRQ_ENA */ +#define WM8400_FLL_LCK_IRQ_ENA_MASK 0x0100 /* FLL_LCK_IRQ_ENA */ +#define WM8400_FLL_LCK_IRQ_ENA_SHIFT 8 /* FLL_LCK_IRQ_ENA */ +#define WM8400_FLL_LCK_IRQ_ENA_WIDTH 1 /* FLL_LCK_IRQ_ENA */ +#define WM8400_GPI8_DEB_ENA 0x0080 /* GPI8_DEB_ENA */ +#define WM8400_GPI8_DEB_ENA_MASK 0x0080 /* GPI8_DEB_ENA */ +#define WM8400_GPI8_DEB_ENA_SHIFT 7 /* GPI8_DEB_ENA */ +#define WM8400_GPI8_DEB_ENA_WIDTH 1 /* GPI8_DEB_ENA */ +#define WM8400_GPI8_IRQ_ENA 0x0040 /* GPI8_IRQ_ENA */ +#define WM8400_GPI8_IRQ_ENA_MASK 0x0040 /* GPI8_IRQ_ENA */ +#define WM8400_GPI8_IRQ_ENA_SHIFT 6 /* GPI8_IRQ_ENA */ +#define WM8400_GPI8_IRQ_ENA_WIDTH 1 /* GPI8_IRQ_ENA */ +#define WM8400_GPI8_ENA 0x0010 /* GPI8_ENA */ +#define WM8400_GPI8_ENA_MASK 0x0010 /* GPI8_ENA */ +#define WM8400_GPI8_ENA_SHIFT 4 /* GPI8_ENA */ +#define WM8400_GPI8_ENA_WIDTH 1 /* GPI8_ENA */ +#define WM8400_GPI7_DEB_ENA 0x0008 /* GPI7_DEB_ENA */ +#define WM8400_GPI7_DEB_ENA_MASK 0x0008 /* GPI7_DEB_ENA */ +#define WM8400_GPI7_DEB_ENA_SHIFT 3 /* GPI7_DEB_ENA */ +#define WM8400_GPI7_DEB_ENA_WIDTH 1 /* GPI7_DEB_ENA */ +#define WM8400_GPI7_IRQ_ENA 0x0004 /* GPI7_IRQ_ENA */ +#define WM8400_GPI7_IRQ_ENA_MASK 0x0004 /* GPI7_IRQ_ENA */ +#define WM8400_GPI7_IRQ_ENA_SHIFT 2 /* GPI7_IRQ_ENA */ +#define WM8400_GPI7_IRQ_ENA_WIDTH 1 /* GPI7_IRQ_ENA */ +#define WM8400_GPI7_ENA 0x0001 /* GPI7_ENA */ +#define WM8400_GPI7_ENA_MASK 0x0001 /* GPI7_ENA */ +#define WM8400_GPI7_ENA_SHIFT 0 /* GPI7_ENA */ +#define WM8400_GPI7_ENA_WIDTH 1 /* GPI7_ENA */ + +/* + * R23 (0x17) - GPIO_POL + */ +#define WM8400_IRQ_INV 0x1000 /* IRQ_INV */ +#define WM8400_IRQ_INV_MASK 0x1000 /* IRQ_INV */ +#define WM8400_IRQ_INV_SHIFT 12 /* IRQ_INV */ +#define WM8400_IRQ_INV_WIDTH 1 /* IRQ_INV */ +#define WM8400_TEMPOK_POL 0x0800 /* TEMPOK_POL */ +#define WM8400_TEMPOK_POL_MASK 0x0800 /* TEMPOK_POL */ +#define WM8400_TEMPOK_POL_SHIFT 11 /* TEMPOK_POL */ +#define WM8400_TEMPOK_POL_WIDTH 1 /* TEMPOK_POL */ +#define WM8400_MIC1SHRT_POL 0x0400 /* MIC1SHRT_POL */ +#define WM8400_MIC1SHRT_POL_MASK 0x0400 /* MIC1SHRT_POL */ +#define WM8400_MIC1SHRT_POL_SHIFT 10 /* MIC1SHRT_POL */ +#define WM8400_MIC1SHRT_POL_WIDTH 1 /* MIC1SHRT_POL */ +#define WM8400_MIC1DET_POL 0x0200 /* MIC1DET_POL */ +#define WM8400_MIC1DET_POL_MASK 0x0200 /* MIC1DET_POL */ +#define WM8400_MIC1DET_POL_SHIFT 9 /* MIC1DET_POL */ +#define WM8400_MIC1DET_POL_WIDTH 1 /* MIC1DET_POL */ +#define WM8400_FLL_LCK_POL 0x0100 /* FLL_LCK_POL */ +#define WM8400_FLL_LCK_POL_MASK 0x0100 /* FLL_LCK_POL */ +#define WM8400_FLL_LCK_POL_SHIFT 8 /* FLL_LCK_POL */ +#define WM8400_FLL_LCK_POL_WIDTH 1 /* FLL_LCK_POL */ +#define WM8400_GPIO_POL_MASK 0x00FF /* GPIO_POL - [7:0] */ +#define WM8400_GPIO_POL_SHIFT 0 /* GPIO_POL - [7:0] */ +#define WM8400_GPIO_POL_WIDTH 8 /* GPIO_POL - [7:0] */ + +/* + * R65 (0x41) - LDO 1 Control + */ +#define WM8400_LDO1_ENA 0x8000 /* LDO1_ENA */ +#define WM8400_LDO1_ENA_MASK 0x8000 /* LDO1_ENA */ +#define WM8400_LDO1_ENA_SHIFT 15 /* LDO1_ENA */ +#define WM8400_LDO1_ENA_WIDTH 1 /* LDO1_ENA */ +#define WM8400_LDO1_SWI 0x4000 /* LDO1_SWI */ +#define WM8400_LDO1_SWI_MASK 0x4000 /* LDO1_SWI */ +#define WM8400_LDO1_SWI_SHIFT 14 /* LDO1_SWI */ +#define WM8400_LDO1_SWI_WIDTH 1 /* LDO1_SWI */ +#define WM8400_LDO1_OPFLT 0x1000 /* LDO1_OPFLT */ +#define WM8400_LDO1_OPFLT_MASK 0x1000 /* LDO1_OPFLT */ +#define WM8400_LDO1_OPFLT_SHIFT 12 /* LDO1_OPFLT */ +#define WM8400_LDO1_OPFLT_WIDTH 1 /* LDO1_OPFLT */ +#define WM8400_LDO1_ERRACT 0x0800 /* LDO1_ERRACT */ +#define WM8400_LDO1_ERRACT_MASK 0x0800 /* LDO1_ERRACT */ +#define WM8400_LDO1_ERRACT_SHIFT 11 /* LDO1_ERRACT */ +#define WM8400_LDO1_ERRACT_WIDTH 1 /* LDO1_ERRACT */ +#define WM8400_LDO1_HIB_MODE 0x0400 /* LDO1_HIB_MODE */ +#define WM8400_LDO1_HIB_MODE_MASK 0x0400 /* LDO1_HIB_MODE */ +#define WM8400_LDO1_HIB_MODE_SHIFT 10 /* LDO1_HIB_MODE */ +#define WM8400_LDO1_HIB_MODE_WIDTH 1 /* LDO1_HIB_MODE */ +#define WM8400_LDO1_VIMG_MASK 0x03E0 /* LDO1_VIMG - [9:5] */ +#define WM8400_LDO1_VIMG_SHIFT 5 /* LDO1_VIMG - [9:5] */ +#define WM8400_LDO1_VIMG_WIDTH 5 /* LDO1_VIMG - [9:5] */ +#define WM8400_LDO1_VSEL_MASK 0x001F /* LDO1_VSEL - [4:0] */ +#define WM8400_LDO1_VSEL_SHIFT 0 /* LDO1_VSEL - [4:0] */ +#define WM8400_LDO1_VSEL_WIDTH 5 /* LDO1_VSEL - [4:0] */ + +/* + * R66 (0x42) - LDO 2 Control + */ +#define WM8400_LDO2_ENA 0x8000 /* LDO2_ENA */ +#define WM8400_LDO2_ENA_MASK 0x8000 /* LDO2_ENA */ +#define WM8400_LDO2_ENA_SHIFT 15 /* LDO2_ENA */ +#define WM8400_LDO2_ENA_WIDTH 1 /* LDO2_ENA */ +#define WM8400_LDO2_SWI 0x4000 /* LDO2_SWI */ +#define WM8400_LDO2_SWI_MASK 0x4000 /* LDO2_SWI */ +#define WM8400_LDO2_SWI_SHIFT 14 /* LDO2_SWI */ +#define WM8400_LDO2_SWI_WIDTH 1 /* LDO2_SWI */ +#define WM8400_LDO2_OPFLT 0x1000 /* LDO2_OPFLT */ +#define WM8400_LDO2_OPFLT_MASK 0x1000 /* LDO2_OPFLT */ +#define WM8400_LDO2_OPFLT_SHIFT 12 /* LDO2_OPFLT */ +#define WM8400_LDO2_OPFLT_WIDTH 1 /* LDO2_OPFLT */ +#define WM8400_LDO2_ERRACT 0x0800 /* LDO2_ERRACT */ +#define WM8400_LDO2_ERRACT_MASK 0x0800 /* LDO2_ERRACT */ +#define WM8400_LDO2_ERRACT_SHIFT 11 /* LDO2_ERRACT */ +#define WM8400_LDO2_ERRACT_WIDTH 1 /* LDO2_ERRACT */ +#define WM8400_LDO2_HIB_MODE 0x0400 /* LDO2_HIB_MODE */ +#define WM8400_LDO2_HIB_MODE_MASK 0x0400 /* LDO2_HIB_MODE */ +#define WM8400_LDO2_HIB_MODE_SHIFT 10 /* LDO2_HIB_MODE */ +#define WM8400_LDO2_HIB_MODE_WIDTH 1 /* LDO2_HIB_MODE */ +#define WM8400_LDO2_VIMG_MASK 0x03E0 /* LDO2_VIMG - [9:5] */ +#define WM8400_LDO2_VIMG_SHIFT 5 /* LDO2_VIMG - [9:5] */ +#define WM8400_LDO2_VIMG_WIDTH 5 /* LDO2_VIMG - [9:5] */ +#define WM8400_LDO2_VSEL_MASK 0x001F /* LDO2_VSEL - [4:0] */ +#define WM8400_LDO2_VSEL_SHIFT 0 /* LDO2_VSEL - [4:0] */ +#define WM8400_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [4:0] */ + +/* + * R67 (0x43) - LDO 3 Control + */ +#define WM8400_LDO3_ENA 0x8000 /* LDO3_ENA */ +#define WM8400_LDO3_ENA_MASK 0x8000 /* LDO3_ENA */ +#define WM8400_LDO3_ENA_SHIFT 15 /* LDO3_ENA */ +#define WM8400_LDO3_ENA_WIDTH 1 /* LDO3_ENA */ +#define WM8400_LDO3_SWI 0x4000 /* LDO3_SWI */ +#define WM8400_LDO3_SWI_MASK 0x4000 /* LDO3_SWI */ +#define WM8400_LDO3_SWI_SHIFT 14 /* LDO3_SWI */ +#define WM8400_LDO3_SWI_WIDTH 1 /* LDO3_SWI */ +#define WM8400_LDO3_OPFLT 0x1000 /* LDO3_OPFLT */ +#define WM8400_LDO3_OPFLT_MASK 0x1000 /* LDO3_OPFLT */ +#define WM8400_LDO3_OPFLT_SHIFT 12 /* LDO3_OPFLT */ +#define WM8400_LDO3_OPFLT_WIDTH 1 /* LDO3_OPFLT */ +#define WM8400_LDO3_ERRACT 0x0800 /* LDO3_ERRACT */ +#define WM8400_LDO3_ERRACT_MASK 0x0800 /* LDO3_ERRACT */ +#define WM8400_LDO3_ERRACT_SHIFT 11 /* LDO3_ERRACT */ +#define WM8400_LDO3_ERRACT_WIDTH 1 /* LDO3_ERRACT */ +#define WM8400_LDO3_HIB_MODE 0x0400 /* LDO3_HIB_MODE */ +#define WM8400_LDO3_HIB_MODE_MASK 0x0400 /* LDO3_HIB_MODE */ +#define WM8400_LDO3_HIB_MODE_SHIFT 10 /* LDO3_HIB_MODE */ +#define WM8400_LDO3_HIB_MODE_WIDTH 1 /* LDO3_HIB_MODE */ +#define WM8400_LDO3_VIMG_MASK 0x03E0 /* LDO3_VIMG - [9:5] */ +#define WM8400_LDO3_VIMG_SHIFT 5 /* LDO3_VIMG - [9:5] */ +#define WM8400_LDO3_VIMG_WIDTH 5 /* LDO3_VIMG - [9:5] */ +#define WM8400_LDO3_VSEL_MASK 0x001F /* LDO3_VSEL - [4:0] */ +#define WM8400_LDO3_VSEL_SHIFT 0 /* LDO3_VSEL - [4:0] */ +#define WM8400_LDO3_VSEL_WIDTH 5 /* LDO3_VSEL - [4:0] */ + +/* + * R68 (0x44) - LDO 4 Control + */ +#define WM8400_LDO4_ENA 0x8000 /* LDO4_ENA */ +#define WM8400_LDO4_ENA_MASK 0x8000 /* LDO4_ENA */ +#define WM8400_LDO4_ENA_SHIFT 15 /* LDO4_ENA */ +#define WM8400_LDO4_ENA_WIDTH 1 /* LDO4_ENA */ +#define WM8400_LDO4_SWI 0x4000 /* LDO4_SWI */ +#define WM8400_LDO4_SWI_MASK 0x4000 /* LDO4_SWI */ +#define WM8400_LDO4_SWI_SHIFT 14 /* LDO4_SWI */ +#define WM8400_LDO4_SWI_WIDTH 1 /* LDO4_SWI */ +#define WM8400_LDO4_OPFLT 0x1000 /* LDO4_OPFLT */ +#define WM8400_LDO4_OPFLT_MASK 0x1000 /* LDO4_OPFLT */ +#define WM8400_LDO4_OPFLT_SHIFT 12 /* LDO4_OPFLT */ +#define WM8400_LDO4_OPFLT_WIDTH 1 /* LDO4_OPFLT */ +#define WM8400_LDO4_ERRACT 0x0800 /* LDO4_ERRACT */ +#define WM8400_LDO4_ERRACT_MASK 0x0800 /* LDO4_ERRACT */ +#define WM8400_LDO4_ERRACT_SHIFT 11 /* LDO4_ERRACT */ +#define WM8400_LDO4_ERRACT_WIDTH 1 /* LDO4_ERRACT */ +#define WM8400_LDO4_HIB_MODE 0x0400 /* LDO4_HIB_MODE */ +#define WM8400_LDO4_HIB_MODE_MASK 0x0400 /* LDO4_HIB_MODE */ +#define WM8400_LDO4_HIB_MODE_SHIFT 10 /* LDO4_HIB_MODE */ +#define WM8400_LDO4_HIB_MODE_WIDTH 1 /* LDO4_HIB_MODE */ +#define WM8400_LDO4_VIMG_MASK 0x03E0 /* LDO4_VIMG - [9:5] */ +#define WM8400_LDO4_VIMG_SHIFT 5 /* LDO4_VIMG - [9:5] */ +#define WM8400_LDO4_VIMG_WIDTH 5 /* LDO4_VIMG - [9:5] */ +#define WM8400_LDO4_VSEL_MASK 0x001F /* LDO4_VSEL - [4:0] */ +#define WM8400_LDO4_VSEL_SHIFT 0 /* LDO4_VSEL - [4:0] */ +#define WM8400_LDO4_VSEL_WIDTH 5 /* LDO4_VSEL - [4:0] */ + +/* + * R70 (0x46) - DCDC1 Control 1 + */ +#define WM8400_DC1_ENA 0x8000 /* DC1_ENA */ +#define WM8400_DC1_ENA_MASK 0x8000 /* DC1_ENA */ +#define WM8400_DC1_ENA_SHIFT 15 /* DC1_ENA */ +#define WM8400_DC1_ENA_WIDTH 1 /* DC1_ENA */ +#define WM8400_DC1_ACTIVE 0x4000 /* DC1_ACTIVE */ +#define WM8400_DC1_ACTIVE_MASK 0x4000 /* DC1_ACTIVE */ +#define WM8400_DC1_ACTIVE_SHIFT 14 /* DC1_ACTIVE */ +#define WM8400_DC1_ACTIVE_WIDTH 1 /* DC1_ACTIVE */ +#define WM8400_DC1_SLEEP 0x2000 /* DC1_SLEEP */ +#define WM8400_DC1_SLEEP_MASK 0x2000 /* DC1_SLEEP */ +#define WM8400_DC1_SLEEP_SHIFT 13 /* DC1_SLEEP */ +#define WM8400_DC1_SLEEP_WIDTH 1 /* DC1_SLEEP */ +#define WM8400_DC1_OPFLT 0x1000 /* DC1_OPFLT */ +#define WM8400_DC1_OPFLT_MASK 0x1000 /* DC1_OPFLT */ +#define WM8400_DC1_OPFLT_SHIFT 12 /* DC1_OPFLT */ +#define WM8400_DC1_OPFLT_WIDTH 1 /* DC1_OPFLT */ +#define WM8400_DC1_ERRACT 0x0800 /* DC1_ERRACT */ +#define WM8400_DC1_ERRACT_MASK 0x0800 /* DC1_ERRACT */ +#define WM8400_DC1_ERRACT_SHIFT 11 /* DC1_ERRACT */ +#define WM8400_DC1_ERRACT_WIDTH 1 /* DC1_ERRACT */ +#define WM8400_DC1_HIB_MODE 0x0400 /* DC1_HIB_MODE */ +#define WM8400_DC1_HIB_MODE_MASK 0x0400 /* DC1_HIB_MODE */ +#define WM8400_DC1_HIB_MODE_SHIFT 10 /* DC1_HIB_MODE */ +#define WM8400_DC1_HIB_MODE_WIDTH 1 /* DC1_HIB_MODE */ +#define WM8400_DC1_SOFTST_MASK 0x0300 /* DC1_SOFTST - [9:8] */ +#define WM8400_DC1_SOFTST_SHIFT 8 /* DC1_SOFTST - [9:8] */ +#define WM8400_DC1_SOFTST_WIDTH 2 /* DC1_SOFTST - [9:8] */ +#define WM8400_DC1_OV_PROT 0x0080 /* DC1_OV_PROT */ +#define WM8400_DC1_OV_PROT_MASK 0x0080 /* DC1_OV_PROT */ +#define WM8400_DC1_OV_PROT_SHIFT 7 /* DC1_OV_PROT */ +#define WM8400_DC1_OV_PROT_WIDTH 1 /* DC1_OV_PROT */ +#define WM8400_DC1_VSEL_MASK 0x007F /* DC1_VSEL - [6:0] */ +#define WM8400_DC1_VSEL_SHIFT 0 /* DC1_VSEL - [6:0] */ +#define WM8400_DC1_VSEL_WIDTH 7 /* DC1_VSEL - [6:0] */ + +/* + * R71 (0x47) - DCDC1 Control 2 + */ +#define WM8400_DC1_FRC_PWM 0x2000 /* DC1_FRC_PWM */ +#define WM8400_DC1_FRC_PWM_MASK 0x2000 /* DC1_FRC_PWM */ +#define WM8400_DC1_FRC_PWM_SHIFT 13 /* DC1_FRC_PWM */ +#define WM8400_DC1_FRC_PWM_WIDTH 1 /* DC1_FRC_PWM */ +#define WM8400_DC1_STBY_LIM_MASK 0x0300 /* DC1_STBY_LIM - [9:8] */ +#define WM8400_DC1_STBY_LIM_SHIFT 8 /* DC1_STBY_LIM - [9:8] */ +#define WM8400_DC1_STBY_LIM_WIDTH 2 /* DC1_STBY_LIM - [9:8] */ +#define WM8400_DC1_ACT_LIM 0x0080 /* DC1_ACT_LIM */ +#define WM8400_DC1_ACT_LIM_MASK 0x0080 /* DC1_ACT_LIM */ +#define WM8400_DC1_ACT_LIM_SHIFT 7 /* DC1_ACT_LIM */ +#define WM8400_DC1_ACT_LIM_WIDTH 1 /* DC1_ACT_LIM */ +#define WM8400_DC1_VIMG_MASK 0x007F /* DC1_VIMG - [6:0] */ +#define WM8400_DC1_VIMG_SHIFT 0 /* DC1_VIMG - [6:0] */ +#define WM8400_DC1_VIMG_WIDTH 7 /* DC1_VIMG - [6:0] */ + +/* + * R72 (0x48) - DCDC2 Control 1 + */ +#define WM8400_DC2_ENA 0x8000 /* DC2_ENA */ +#define WM8400_DC2_ENA_MASK 0x8000 /* DC2_ENA */ +#define WM8400_DC2_ENA_SHIFT 15 /* DC2_ENA */ +#define WM8400_DC2_ENA_WIDTH 1 /* DC2_ENA */ +#define WM8400_DC2_ACTIVE 0x4000 /* DC2_ACTIVE */ +#define WM8400_DC2_ACTIVE_MASK 0x4000 /* DC2_ACTIVE */ +#define WM8400_DC2_ACTIVE_SHIFT 14 /* DC2_ACTIVE */ +#define WM8400_DC2_ACTIVE_WIDTH 1 /* DC2_ACTIVE */ +#define WM8400_DC2_SLEEP 0x2000 /* DC2_SLEEP */ +#define WM8400_DC2_SLEEP_MASK 0x2000 /* DC2_SLEEP */ +#define WM8400_DC2_SLEEP_SHIFT 13 /* DC2_SLEEP */ +#define WM8400_DC2_SLEEP_WIDTH 1 /* DC2_SLEEP */ +#define WM8400_DC2_OPFLT 0x1000 /* DC2_OPFLT */ +#define WM8400_DC2_OPFLT_MASK 0x1000 /* DC2_OPFLT */ +#define WM8400_DC2_OPFLT_SHIFT 12 /* DC2_OPFLT */ +#define WM8400_DC2_OPFLT_WIDTH 1 /* DC2_OPFLT */ +#define WM8400_DC2_ERRACT 0x0800 /* DC2_ERRACT */ +#define WM8400_DC2_ERRACT_MASK 0x0800 /* DC2_ERRACT */ +#define WM8400_DC2_ERRACT_SHIFT 11 /* DC2_ERRACT */ +#define WM8400_DC2_ERRACT_WIDTH 1 /* DC2_ERRACT */ +#define WM8400_DC2_HIB_MODE 0x0400 /* DC2_HIB_MODE */ +#define WM8400_DC2_HIB_MODE_MASK 0x0400 /* DC2_HIB_MODE */ +#define WM8400_DC2_HIB_MODE_SHIFT 10 /* DC2_HIB_MODE */ +#define WM8400_DC2_HIB_MODE_WIDTH 1 /* DC2_HIB_MODE */ +#define WM8400_DC2_SOFTST_MASK 0x0300 /* DC2_SOFTST - [9:8] */ +#define WM8400_DC2_SOFTST_SHIFT 8 /* DC2_SOFTST - [9:8] */ +#define WM8400_DC2_SOFTST_WIDTH 2 /* DC2_SOFTST - [9:8] */ +#define WM8400_DC2_OV_PROT 0x0080 /* DC2_OV_PROT */ +#define WM8400_DC2_OV_PROT_MASK 0x0080 /* DC2_OV_PROT */ +#define WM8400_DC2_OV_PROT_SHIFT 7 /* DC2_OV_PROT */ +#define WM8400_DC2_OV_PROT_WIDTH 1 /* DC2_OV_PROT */ +#define WM8400_DC2_VSEL_MASK 0x007F /* DC2_VSEL - [6:0] */ +#define WM8400_DC2_VSEL_SHIFT 0 /* DC2_VSEL - [6:0] */ +#define WM8400_DC2_VSEL_WIDTH 7 /* DC2_VSEL - [6:0] */ + +/* + * R73 (0x49) - DCDC2 Control 2 + */ +#define WM8400_DC2_FRC_PWM 0x2000 /* DC2_FRC_PWM */ +#define WM8400_DC2_FRC_PWM_MASK 0x2000 /* DC2_FRC_PWM */ +#define WM8400_DC2_FRC_PWM_SHIFT 13 /* DC2_FRC_PWM */ +#define WM8400_DC2_FRC_PWM_WIDTH 1 /* DC2_FRC_PWM */ +#define WM8400_DC2_STBY_LIM_MASK 0x0300 /* DC2_STBY_LIM - [9:8] */ +#define WM8400_DC2_STBY_LIM_SHIFT 8 /* DC2_STBY_LIM - [9:8] */ +#define WM8400_DC2_STBY_LIM_WIDTH 2 /* DC2_STBY_LIM - [9:8] */ +#define WM8400_DC2_ACT_LIM 0x0080 /* DC2_ACT_LIM */ +#define WM8400_DC2_ACT_LIM_MASK 0x0080 /* DC2_ACT_LIM */ +#define WM8400_DC2_ACT_LIM_SHIFT 7 /* DC2_ACT_LIM */ +#define WM8400_DC2_ACT_LIM_WIDTH 1 /* DC2_ACT_LIM */ +#define WM8400_DC2_VIMG_MASK 0x007F /* DC2_VIMG - [6:0] */ +#define WM8400_DC2_VIMG_SHIFT 0 /* DC2_VIMG - [6:0] */ +#define WM8400_DC2_VIMG_WIDTH 7 /* DC2_VIMG - [6:0] */ + +/* + * R75 (0x4B) - Interface + */ +#define WM8400_AUTOINC 0x0008 /* AUTOINC */ +#define WM8400_AUTOINC_MASK 0x0008 /* AUTOINC */ +#define WM8400_AUTOINC_SHIFT 3 /* AUTOINC */ +#define WM8400_AUTOINC_WIDTH 1 /* AUTOINC */ +#define WM8400_ARA_ENA 0x0004 /* ARA_ENA */ +#define WM8400_ARA_ENA_MASK 0x0004 /* ARA_ENA */ +#define WM8400_ARA_ENA_SHIFT 2 /* ARA_ENA */ +#define WM8400_ARA_ENA_WIDTH 1 /* ARA_ENA */ +#define WM8400_SPI_CFG 0x0002 /* SPI_CFG */ +#define WM8400_SPI_CFG_MASK 0x0002 /* SPI_CFG */ +#define WM8400_SPI_CFG_SHIFT 1 /* SPI_CFG */ +#define WM8400_SPI_CFG_WIDTH 1 /* SPI_CFG */ + +/* + * R76 (0x4C) - PM GENERAL + */ +#define WM8400_CODEC_SOFTST 0x8000 /* CODEC_SOFTST */ +#define WM8400_CODEC_SOFTST_MASK 0x8000 /* CODEC_SOFTST */ +#define WM8400_CODEC_SOFTST_SHIFT 15 /* CODEC_SOFTST */ +#define WM8400_CODEC_SOFTST_WIDTH 1 /* CODEC_SOFTST */ +#define WM8400_CODEC_SOFTSD 0x4000 /* CODEC_SOFTSD */ +#define WM8400_CODEC_SOFTSD_MASK 0x4000 /* CODEC_SOFTSD */ +#define WM8400_CODEC_SOFTSD_SHIFT 14 /* CODEC_SOFTSD */ +#define WM8400_CODEC_SOFTSD_WIDTH 1 /* CODEC_SOFTSD */ +#define WM8400_CHIP_SOFTSD 0x2000 /* CHIP_SOFTSD */ +#define WM8400_CHIP_SOFTSD_MASK 0x2000 /* CHIP_SOFTSD */ +#define WM8400_CHIP_SOFTSD_SHIFT 13 /* CHIP_SOFTSD */ +#define WM8400_CHIP_SOFTSD_WIDTH 1 /* CHIP_SOFTSD */ +#define WM8400_DSLEEP1_POL 0x0008 /* DSLEEP1_POL */ +#define WM8400_DSLEEP1_POL_MASK 0x0008 /* DSLEEP1_POL */ +#define WM8400_DSLEEP1_POL_SHIFT 3 /* DSLEEP1_POL */ +#define WM8400_DSLEEP1_POL_WIDTH 1 /* DSLEEP1_POL */ +#define WM8400_DSLEEP2_POL 0x0004 /* DSLEEP2_POL */ +#define WM8400_DSLEEP2_POL_MASK 0x0004 /* DSLEEP2_POL */ +#define WM8400_DSLEEP2_POL_SHIFT 2 /* DSLEEP2_POL */ +#define WM8400_DSLEEP2_POL_WIDTH 1 /* DSLEEP2_POL */ +#define WM8400_PWR_STATE_MASK 0x0003 /* PWR_STATE - [1:0] */ +#define WM8400_PWR_STATE_SHIFT 0 /* PWR_STATE - [1:0] */ +#define WM8400_PWR_STATE_WIDTH 2 /* PWR_STATE - [1:0] */ + +/* + * R78 (0x4E) - PM Shutdown Control + */ +#define WM8400_CHIP_GT150_ERRACT 0x0200 /* CHIP_GT150_ERRACT */ +#define WM8400_CHIP_GT150_ERRACT_MASK 0x0200 /* CHIP_GT150_ERRACT */ +#define WM8400_CHIP_GT150_ERRACT_SHIFT 9 /* CHIP_GT150_ERRACT */ +#define WM8400_CHIP_GT150_ERRACT_WIDTH 1 /* CHIP_GT150_ERRACT */ +#define WM8400_CHIP_GT115_ERRACT 0x0100 /* CHIP_GT115_ERRACT */ +#define WM8400_CHIP_GT115_ERRACT_MASK 0x0100 /* CHIP_GT115_ERRACT */ +#define WM8400_CHIP_GT115_ERRACT_SHIFT 8 /* CHIP_GT115_ERRACT */ +#define WM8400_CHIP_GT115_ERRACT_WIDTH 1 /* CHIP_GT115_ERRACT */ +#define WM8400_LINE_CMP_ERRACT 0x0080 /* LINE_CMP_ERRACT */ +#define WM8400_LINE_CMP_ERRACT_MASK 0x0080 /* LINE_CMP_ERRACT */ +#define WM8400_LINE_CMP_ERRACT_SHIFT 7 /* LINE_CMP_ERRACT */ +#define WM8400_LINE_CMP_ERRACT_WIDTH 1 /* LINE_CMP_ERRACT */ +#define WM8400_UVLO_ERRACT 0x0040 /* UVLO_ERRACT */ +#define WM8400_UVLO_ERRACT_MASK 0x0040 /* UVLO_ERRACT */ +#define WM8400_UVLO_ERRACT_SHIFT 6 /* UVLO_ERRACT */ +#define WM8400_UVLO_ERRACT_WIDTH 1 /* UVLO_ERRACT */ + +/* + * R79 (0x4F) - Interrupt Status 1 + */ +#define WM8400_MICD_CINT 0x8000 /* MICD_CINT */ +#define WM8400_MICD_CINT_MASK 0x8000 /* MICD_CINT */ +#define WM8400_MICD_CINT_SHIFT 15 /* MICD_CINT */ +#define WM8400_MICD_CINT_WIDTH 1 /* MICD_CINT */ +#define WM8400_MICSCD_CINT 0x4000 /* MICSCD_CINT */ +#define WM8400_MICSCD_CINT_MASK 0x4000 /* MICSCD_CINT */ +#define WM8400_MICSCD_CINT_SHIFT 14 /* MICSCD_CINT */ +#define WM8400_MICSCD_CINT_WIDTH 1 /* MICSCD_CINT */ +#define WM8400_JDL_CINT 0x2000 /* JDL_CINT */ +#define WM8400_JDL_CINT_MASK 0x2000 /* JDL_CINT */ +#define WM8400_JDL_CINT_SHIFT 13 /* JDL_CINT */ +#define WM8400_JDL_CINT_WIDTH 1 /* JDL_CINT */ +#define WM8400_JDR_CINT 0x1000 /* JDR_CINT */ +#define WM8400_JDR_CINT_MASK 0x1000 /* JDR_CINT */ +#define WM8400_JDR_CINT_SHIFT 12 /* JDR_CINT */ +#define WM8400_JDR_CINT_WIDTH 1 /* JDR_CINT */ +#define WM8400_CODEC_SEQ_END_EINT 0x0800 /* CODEC_SEQ_END_EINT */ +#define WM8400_CODEC_SEQ_END_EINT_MASK 0x0800 /* CODEC_SEQ_END_EINT */ +#define WM8400_CODEC_SEQ_END_EINT_SHIFT 11 /* CODEC_SEQ_END_EINT */ +#define WM8400_CODEC_SEQ_END_EINT_WIDTH 1 /* CODEC_SEQ_END_EINT */ +#define WM8400_CDEL_TO_EINT 0x0400 /* CDEL_TO_EINT */ +#define WM8400_CDEL_TO_EINT_MASK 0x0400 /* CDEL_TO_EINT */ +#define WM8400_CDEL_TO_EINT_SHIFT 10 /* CDEL_TO_EINT */ +#define WM8400_CDEL_TO_EINT_WIDTH 1 /* CDEL_TO_EINT */ +#define WM8400_CHIP_GT150_EINT 0x0200 /* CHIP_GT150_EINT */ +#define WM8400_CHIP_GT150_EINT_MASK 0x0200 /* CHIP_GT150_EINT */ +#define WM8400_CHIP_GT150_EINT_SHIFT 9 /* CHIP_GT150_EINT */ +#define WM8400_CHIP_GT150_EINT_WIDTH 1 /* CHIP_GT150_EINT */ +#define WM8400_CHIP_GT115_EINT 0x0100 /* CHIP_GT115_EINT */ +#define WM8400_CHIP_GT115_EINT_MASK 0x0100 /* CHIP_GT115_EINT */ +#define WM8400_CHIP_GT115_EINT_SHIFT 8 /* CHIP_GT115_EINT */ +#define WM8400_CHIP_GT115_EINT_WIDTH 1 /* CHIP_GT115_EINT */ +#define WM8400_LINE_CMP_EINT 0x0080 /* LINE_CMP_EINT */ +#define WM8400_LINE_CMP_EINT_MASK 0x0080 /* LINE_CMP_EINT */ +#define WM8400_LINE_CMP_EINT_SHIFT 7 /* LINE_CMP_EINT */ +#define WM8400_LINE_CMP_EINT_WIDTH 1 /* LINE_CMP_EINT */ +#define WM8400_UVLO_EINT 0x0040 /* UVLO_EINT */ +#define WM8400_UVLO_EINT_MASK 0x0040 /* UVLO_EINT */ +#define WM8400_UVLO_EINT_SHIFT 6 /* UVLO_EINT */ +#define WM8400_UVLO_EINT_WIDTH 1 /* UVLO_EINT */ +#define WM8400_DC2_UV_EINT 0x0020 /* DC2_UV_EINT */ +#define WM8400_DC2_UV_EINT_MASK 0x0020 /* DC2_UV_EINT */ +#define WM8400_DC2_UV_EINT_SHIFT 5 /* DC2_UV_EINT */ +#define WM8400_DC2_UV_EINT_WIDTH 1 /* DC2_UV_EINT */ +#define WM8400_DC1_UV_EINT 0x0010 /* DC1_UV_EINT */ +#define WM8400_DC1_UV_EINT_MASK 0x0010 /* DC1_UV_EINT */ +#define WM8400_DC1_UV_EINT_SHIFT 4 /* DC1_UV_EINT */ +#define WM8400_DC1_UV_EINT_WIDTH 1 /* DC1_UV_EINT */ +#define WM8400_LDO4_UV_EINT 0x0008 /* LDO4_UV_EINT */ +#define WM8400_LDO4_UV_EINT_MASK 0x0008 /* LDO4_UV_EINT */ +#define WM8400_LDO4_UV_EINT_SHIFT 3 /* LDO4_UV_EINT */ +#define WM8400_LDO4_UV_EINT_WIDTH 1 /* LDO4_UV_EINT */ +#define WM8400_LDO3_UV_EINT 0x0004 /* LDO3_UV_EINT */ +#define WM8400_LDO3_UV_EINT_MASK 0x0004 /* LDO3_UV_EINT */ +#define WM8400_LDO3_UV_EINT_SHIFT 2 /* LDO3_UV_EINT */ +#define WM8400_LDO3_UV_EINT_WIDTH 1 /* LDO3_UV_EINT */ +#define WM8400_LDO2_UV_EINT 0x0002 /* LDO2_UV_EINT */ +#define WM8400_LDO2_UV_EINT_MASK 0x0002 /* LDO2_UV_EINT */ +#define WM8400_LDO2_UV_EINT_SHIFT 1 /* LDO2_UV_EINT */ +#define WM8400_LDO2_UV_EINT_WIDTH 1 /* LDO2_UV_EINT */ +#define WM8400_LDO1_UV_EINT 0x0001 /* LDO1_UV_EINT */ +#define WM8400_LDO1_UV_EINT_MASK 0x0001 /* LDO1_UV_EINT */ +#define WM8400_LDO1_UV_EINT_SHIFT 0 /* LDO1_UV_EINT */ +#define WM8400_LDO1_UV_EINT_WIDTH 1 /* LDO1_UV_EINT */ + +/* + * R80 (0x50) - Interrupt Status 1 Mask + */ +#define WM8400_IM_MICD_CINT 0x8000 /* IM_MICD_CINT */ +#define WM8400_IM_MICD_CINT_MASK 0x8000 /* IM_MICD_CINT */ +#define WM8400_IM_MICD_CINT_SHIFT 15 /* IM_MICD_CINT */ +#define WM8400_IM_MICD_CINT_WIDTH 1 /* IM_MICD_CINT */ +#define WM8400_IM_MICSCD_CINT 0x4000 /* IM_MICSCD_CINT */ +#define WM8400_IM_MICSCD_CINT_MASK 0x4000 /* IM_MICSCD_CINT */ +#define WM8400_IM_MICSCD_CINT_SHIFT 14 /* IM_MICSCD_CINT */ +#define WM8400_IM_MICSCD_CINT_WIDTH 1 /* IM_MICSCD_CINT */ +#define WM8400_IM_JDL_CINT 0x2000 /* IM_JDL_CINT */ +#define WM8400_IM_JDL_CINT_MASK 0x2000 /* IM_JDL_CINT */ +#define WM8400_IM_JDL_CINT_SHIFT 13 /* IM_JDL_CINT */ +#define WM8400_IM_JDL_CINT_WIDTH 1 /* IM_JDL_CINT */ +#define WM8400_IM_JDR_CINT 0x1000 /* IM_JDR_CINT */ +#define WM8400_IM_JDR_CINT_MASK 0x1000 /* IM_JDR_CINT */ +#define WM8400_IM_JDR_CINT_SHIFT 12 /* IM_JDR_CINT */ +#define WM8400_IM_JDR_CINT_WIDTH 1 /* IM_JDR_CINT */ +#define WM8400_IM_CODEC_SEQ_END_EINT 0x0800 /* IM_CODEC_SEQ_END_EINT */ +#define WM8400_IM_CODEC_SEQ_END_EINT_MASK 0x0800 /* IM_CODEC_SEQ_END_EINT */ +#define WM8400_IM_CODEC_SEQ_END_EINT_SHIFT 11 /* IM_CODEC_SEQ_END_EINT */ +#define WM8400_IM_CODEC_SEQ_END_EINT_WIDTH 1 /* IM_CODEC_SEQ_END_EINT */ +#define WM8400_IM_CDEL_TO_EINT 0x0400 /* IM_CDEL_TO_EINT */ +#define WM8400_IM_CDEL_TO_EINT_MASK 0x0400 /* IM_CDEL_TO_EINT */ +#define WM8400_IM_CDEL_TO_EINT_SHIFT 10 /* IM_CDEL_TO_EINT */ +#define WM8400_IM_CDEL_TO_EINT_WIDTH 1 /* IM_CDEL_TO_EINT */ +#define WM8400_IM_CHIP_GT150_EINT 0x0200 /* IM_CHIP_GT150_EINT */ +#define WM8400_IM_CHIP_GT150_EINT_MASK 0x0200 /* IM_CHIP_GT150_EINT */ +#define WM8400_IM_CHIP_GT150_EINT_SHIFT 9 /* IM_CHIP_GT150_EINT */ +#define WM8400_IM_CHIP_GT150_EINT_WIDTH 1 /* IM_CHIP_GT150_EINT */ +#define WM8400_IM_CHIP_GT115_EINT 0x0100 /* IM_CHIP_GT115_EINT */ +#define WM8400_IM_CHIP_GT115_EINT_MASK 0x0100 /* IM_CHIP_GT115_EINT */ +#define WM8400_IM_CHIP_GT115_EINT_SHIFT 8 /* IM_CHIP_GT115_EINT */ +#define WM8400_IM_CHIP_GT115_EINT_WIDTH 1 /* IM_CHIP_GT115_EINT */ +#define WM8400_IM_LINE_CMP_EINT 0x0080 /* IM_LINE_CMP_EINT */ +#define WM8400_IM_LINE_CMP_EINT_MASK 0x0080 /* IM_LINE_CMP_EINT */ +#define WM8400_IM_LINE_CMP_EINT_SHIFT 7 /* IM_LINE_CMP_EINT */ +#define WM8400_IM_LINE_CMP_EINT_WIDTH 1 /* IM_LINE_CMP_EINT */ +#define WM8400_IM_UVLO_EINT 0x0040 /* IM_UVLO_EINT */ +#define WM8400_IM_UVLO_EINT_MASK 0x0040 /* IM_UVLO_EINT */ +#define WM8400_IM_UVLO_EINT_SHIFT 6 /* IM_UVLO_EINT */ +#define WM8400_IM_UVLO_EINT_WIDTH 1 /* IM_UVLO_EINT */ +#define WM8400_IM_DC2_UV_EINT 0x0020 /* IM_DC2_UV_EINT */ +#define WM8400_IM_DC2_UV_EINT_MASK 0x0020 /* IM_DC2_UV_EINT */ +#define WM8400_IM_DC2_UV_EINT_SHIFT 5 /* IM_DC2_UV_EINT */ +#define WM8400_IM_DC2_UV_EINT_WIDTH 1 /* IM_DC2_UV_EINT */ +#define WM8400_IM_DC1_UV_EINT 0x0010 /* IM_DC1_UV_EINT */ +#define WM8400_IM_DC1_UV_EINT_MASK 0x0010 /* IM_DC1_UV_EINT */ +#define WM8400_IM_DC1_UV_EINT_SHIFT 4 /* IM_DC1_UV_EINT */ +#define WM8400_IM_DC1_UV_EINT_WIDTH 1 /* IM_DC1_UV_EINT */ +#define WM8400_IM_LDO4_UV_EINT 0x0008 /* IM_LDO4_UV_EINT */ +#define WM8400_IM_LDO4_UV_EINT_MASK 0x0008 /* IM_LDO4_UV_EINT */ +#define WM8400_IM_LDO4_UV_EINT_SHIFT 3 /* IM_LDO4_UV_EINT */ +#define WM8400_IM_LDO4_UV_EINT_WIDTH 1 /* IM_LDO4_UV_EINT */ +#define WM8400_IM_LDO3_UV_EINT 0x0004 /* IM_LDO3_UV_EINT */ +#define WM8400_IM_LDO3_UV_EINT_MASK 0x0004 /* IM_LDO3_UV_EINT */ +#define WM8400_IM_LDO3_UV_EINT_SHIFT 2 /* IM_LDO3_UV_EINT */ +#define WM8400_IM_LDO3_UV_EINT_WIDTH 1 /* IM_LDO3_UV_EINT */ +#define WM8400_IM_LDO2_UV_EINT 0x0002 /* IM_LDO2_UV_EINT */ +#define WM8400_IM_LDO2_UV_EINT_MASK 0x0002 /* IM_LDO2_UV_EINT */ +#define WM8400_IM_LDO2_UV_EINT_SHIFT 1 /* IM_LDO2_UV_EINT */ +#define WM8400_IM_LDO2_UV_EINT_WIDTH 1 /* IM_LDO2_UV_EINT */ +#define WM8400_IM_LDO1_UV_EINT 0x0001 /* IM_LDO1_UV_EINT */ +#define WM8400_IM_LDO1_UV_EINT_MASK 0x0001 /* IM_LDO1_UV_EINT */ +#define WM8400_IM_LDO1_UV_EINT_SHIFT 0 /* IM_LDO1_UV_EINT */ +#define WM8400_IM_LDO1_UV_EINT_WIDTH 1 /* IM_LDO1_UV_EINT */ + +/* + * R81 (0x51) - Interrupt Levels + */ +#define WM8400_MICD_LVL 0x8000 /* MICD_LVL */ +#define WM8400_MICD_LVL_MASK 0x8000 /* MICD_LVL */ +#define WM8400_MICD_LVL_SHIFT 15 /* MICD_LVL */ +#define WM8400_MICD_LVL_WIDTH 1 /* MICD_LVL */ +#define WM8400_MICSCD_LVL 0x4000 /* MICSCD_LVL */ +#define WM8400_MICSCD_LVL_MASK 0x4000 /* MICSCD_LVL */ +#define WM8400_MICSCD_LVL_SHIFT 14 /* MICSCD_LVL */ +#define WM8400_MICSCD_LVL_WIDTH 1 /* MICSCD_LVL */ +#define WM8400_JDL_LVL 0x2000 /* JDL_LVL */ +#define WM8400_JDL_LVL_MASK 0x2000 /* JDL_LVL */ +#define WM8400_JDL_LVL_SHIFT 13 /* JDL_LVL */ +#define WM8400_JDL_LVL_WIDTH 1 /* JDL_LVL */ +#define WM8400_JDR_LVL 0x1000 /* JDR_LVL */ +#define WM8400_JDR_LVL_MASK 0x1000 /* JDR_LVL */ +#define WM8400_JDR_LVL_SHIFT 12 /* JDR_LVL */ +#define WM8400_JDR_LVL_WIDTH 1 /* JDR_LVL */ +#define WM8400_CODEC_SEQ_END_LVL 0x0800 /* CODEC_SEQ_END_LVL */ +#define WM8400_CODEC_SEQ_END_LVL_MASK 0x0800 /* CODEC_SEQ_END_LVL */ +#define WM8400_CODEC_SEQ_END_LVL_SHIFT 11 /* CODEC_SEQ_END_LVL */ +#define WM8400_CODEC_SEQ_END_LVL_WIDTH 1 /* CODEC_SEQ_END_LVL */ +#define WM8400_CDEL_TO_LVL 0x0400 /* CDEL_TO_LVL */ +#define WM8400_CDEL_TO_LVL_MASK 0x0400 /* CDEL_TO_LVL */ +#define WM8400_CDEL_TO_LVL_SHIFT 10 /* CDEL_TO_LVL */ +#define WM8400_CDEL_TO_LVL_WIDTH 1 /* CDEL_TO_LVL */ +#define WM8400_CHIP_GT150_LVL 0x0200 /* CHIP_GT150_LVL */ +#define WM8400_CHIP_GT150_LVL_MASK 0x0200 /* CHIP_GT150_LVL */ +#define WM8400_CHIP_GT150_LVL_SHIFT 9 /* CHIP_GT150_LVL */ +#define WM8400_CHIP_GT150_LVL_WIDTH 1 /* CHIP_GT150_LVL */ +#define WM8400_CHIP_GT115_LVL 0x0100 /* CHIP_GT115_LVL */ +#define WM8400_CHIP_GT115_LVL_MASK 0x0100 /* CHIP_GT115_LVL */ +#define WM8400_CHIP_GT115_LVL_SHIFT 8 /* CHIP_GT115_LVL */ +#define WM8400_CHIP_GT115_LVL_WIDTH 1 /* CHIP_GT115_LVL */ +#define WM8400_LINE_CMP_LVL 0x0080 /* LINE_CMP_LVL */ +#define WM8400_LINE_CMP_LVL_MASK 0x0080 /* LINE_CMP_LVL */ +#define WM8400_LINE_CMP_LVL_SHIFT 7 /* LINE_CMP_LVL */ +#define WM8400_LINE_CMP_LVL_WIDTH 1 /* LINE_CMP_LVL */ +#define WM8400_UVLO_LVL 0x0040 /* UVLO_LVL */ +#define WM8400_UVLO_LVL_MASK 0x0040 /* UVLO_LVL */ +#define WM8400_UVLO_LVL_SHIFT 6 /* UVLO_LVL */ +#define WM8400_UVLO_LVL_WIDTH 1 /* UVLO_LVL */ +#define WM8400_DC2_UV_LVL 0x0020 /* DC2_UV_LVL */ +#define WM8400_DC2_UV_LVL_MASK 0x0020 /* DC2_UV_LVL */ +#define WM8400_DC2_UV_LVL_SHIFT 5 /* DC2_UV_LVL */ +#define WM8400_DC2_UV_LVL_WIDTH 1 /* DC2_UV_LVL */ +#define WM8400_DC1_UV_LVL 0x0010 /* DC1_UV_LVL */ +#define WM8400_DC1_UV_LVL_MASK 0x0010 /* DC1_UV_LVL */ +#define WM8400_DC1_UV_LVL_SHIFT 4 /* DC1_UV_LVL */ +#define WM8400_DC1_UV_LVL_WIDTH 1 /* DC1_UV_LVL */ +#define WM8400_LDO4_UV_LVL 0x0008 /* LDO4_UV_LVL */ +#define WM8400_LDO4_UV_LVL_MASK 0x0008 /* LDO4_UV_LVL */ +#define WM8400_LDO4_UV_LVL_SHIFT 3 /* LDO4_UV_LVL */ +#define WM8400_LDO4_UV_LVL_WIDTH 1 /* LDO4_UV_LVL */ +#define WM8400_LDO3_UV_LVL 0x0004 /* LDO3_UV_LVL */ +#define WM8400_LDO3_UV_LVL_MASK 0x0004 /* LDO3_UV_LVL */ +#define WM8400_LDO3_UV_LVL_SHIFT 2 /* LDO3_UV_LVL */ +#define WM8400_LDO3_UV_LVL_WIDTH 1 /* LDO3_UV_LVL */ +#define WM8400_LDO2_UV_LVL 0x0002 /* LDO2_UV_LVL */ +#define WM8400_LDO2_UV_LVL_MASK 0x0002 /* LDO2_UV_LVL */ +#define WM8400_LDO2_UV_LVL_SHIFT 1 /* LDO2_UV_LVL */ +#define WM8400_LDO2_UV_LVL_WIDTH 1 /* LDO2_UV_LVL */ +#define WM8400_LDO1_UV_LVL 0x0001 /* LDO1_UV_LVL */ +#define WM8400_LDO1_UV_LVL_MASK 0x0001 /* LDO1_UV_LVL */ +#define WM8400_LDO1_UV_LVL_SHIFT 0 /* LDO1_UV_LVL */ +#define WM8400_LDO1_UV_LVL_WIDTH 1 /* LDO1_UV_LVL */ + +/* + * R82 (0x52) - Shutdown Reason + */ +#define WM8400_SDR_CHIP_SOFTSD 0x2000 /* SDR_CHIP_SOFTSD */ +#define WM8400_SDR_CHIP_SOFTSD_MASK 0x2000 /* SDR_CHIP_SOFTSD */ +#define WM8400_SDR_CHIP_SOFTSD_SHIFT 13 /* SDR_CHIP_SOFTSD */ +#define WM8400_SDR_CHIP_SOFTSD_WIDTH 1 /* SDR_CHIP_SOFTSD */ +#define WM8400_SDR_NPDN 0x0800 /* SDR_NPDN */ +#define WM8400_SDR_NPDN_MASK 0x0800 /* SDR_NPDN */ +#define WM8400_SDR_NPDN_SHIFT 11 /* SDR_NPDN */ +#define WM8400_SDR_NPDN_WIDTH 1 /* SDR_NPDN */ +#define WM8400_SDR_CHIP_GT150 0x0200 /* SDR_CHIP_GT150 */ +#define WM8400_SDR_CHIP_GT150_MASK 0x0200 /* SDR_CHIP_GT150 */ +#define WM8400_SDR_CHIP_GT150_SHIFT 9 /* SDR_CHIP_GT150 */ +#define WM8400_SDR_CHIP_GT150_WIDTH 1 /* SDR_CHIP_GT150 */ +#define WM8400_SDR_CHIP_GT115 0x0100 /* SDR_CHIP_GT115 */ +#define WM8400_SDR_CHIP_GT115_MASK 0x0100 /* SDR_CHIP_GT115 */ +#define WM8400_SDR_CHIP_GT115_SHIFT 8 /* SDR_CHIP_GT115 */ +#define WM8400_SDR_CHIP_GT115_WIDTH 1 /* SDR_CHIP_GT115 */ +#define WM8400_SDR_LINE_CMP 0x0080 /* SDR_LINE_CMP */ +#define WM8400_SDR_LINE_CMP_MASK 0x0080 /* SDR_LINE_CMP */ +#define WM8400_SDR_LINE_CMP_SHIFT 7 /* SDR_LINE_CMP */ +#define WM8400_SDR_LINE_CMP_WIDTH 1 /* SDR_LINE_CMP */ +#define WM8400_SDR_UVLO 0x0040 /* SDR_UVLO */ +#define WM8400_SDR_UVLO_MASK 0x0040 /* SDR_UVLO */ +#define WM8400_SDR_UVLO_SHIFT 6 /* SDR_UVLO */ +#define WM8400_SDR_UVLO_WIDTH 1 /* SDR_UVLO */ +#define WM8400_SDR_DC2_UV 0x0020 /* SDR_DC2_UV */ +#define WM8400_SDR_DC2_UV_MASK 0x0020 /* SDR_DC2_UV */ +#define WM8400_SDR_DC2_UV_SHIFT 5 /* SDR_DC2_UV */ +#define WM8400_SDR_DC2_UV_WIDTH 1 /* SDR_DC2_UV */ +#define WM8400_SDR_DC1_UV 0x0010 /* SDR_DC1_UV */ +#define WM8400_SDR_DC1_UV_MASK 0x0010 /* SDR_DC1_UV */ +#define WM8400_SDR_DC1_UV_SHIFT 4 /* SDR_DC1_UV */ +#define WM8400_SDR_DC1_UV_WIDTH 1 /* SDR_DC1_UV */ +#define WM8400_SDR_LDO4_UV 0x0008 /* SDR_LDO4_UV */ +#define WM8400_SDR_LDO4_UV_MASK 0x0008 /* SDR_LDO4_UV */ +#define WM8400_SDR_LDO4_UV_SHIFT 3 /* SDR_LDO4_UV */ +#define WM8400_SDR_LDO4_UV_WIDTH 1 /* SDR_LDO4_UV */ +#define WM8400_SDR_LDO3_UV 0x0004 /* SDR_LDO3_UV */ +#define WM8400_SDR_LDO3_UV_MASK 0x0004 /* SDR_LDO3_UV */ +#define WM8400_SDR_LDO3_UV_SHIFT 2 /* SDR_LDO3_UV */ +#define WM8400_SDR_LDO3_UV_WIDTH 1 /* SDR_LDO3_UV */ +#define WM8400_SDR_LDO2_UV 0x0002 /* SDR_LDO2_UV */ +#define WM8400_SDR_LDO2_UV_MASK 0x0002 /* SDR_LDO2_UV */ +#define WM8400_SDR_LDO2_UV_SHIFT 1 /* SDR_LDO2_UV */ +#define WM8400_SDR_LDO2_UV_WIDTH 1 /* SDR_LDO2_UV */ +#define WM8400_SDR_LDO1_UV 0x0001 /* SDR_LDO1_UV */ +#define WM8400_SDR_LDO1_UV_MASK 0x0001 /* SDR_LDO1_UV */ +#define WM8400_SDR_LDO1_UV_SHIFT 0 /* SDR_LDO1_UV */ +#define WM8400_SDR_LDO1_UV_WIDTH 1 /* SDR_LDO1_UV */ + +/* + * R84 (0x54) - Line Circuits + */ +#define WM8400_BG_LINE_COMP 0x8000 /* BG_LINE_COMP */ +#define WM8400_BG_LINE_COMP_MASK 0x8000 /* BG_LINE_COMP */ +#define WM8400_BG_LINE_COMP_SHIFT 15 /* BG_LINE_COMP */ +#define WM8400_BG_LINE_COMP_WIDTH 1 /* BG_LINE_COMP */ +#define WM8400_LINE_CMP_VTHI_MASK 0x00F0 /* LINE_CMP_VTHI - [7:4] */ +#define WM8400_LINE_CMP_VTHI_SHIFT 4 /* LINE_CMP_VTHI - [7:4] */ +#define WM8400_LINE_CMP_VTHI_WIDTH 4 /* LINE_CMP_VTHI - [7:4] */ +#define WM8400_LINE_CMP_VTHD_MASK 0x000F /* LINE_CMP_VTHD - [3:0] */ +#define WM8400_LINE_CMP_VTHD_SHIFT 0 /* LINE_CMP_VTHD - [3:0] */ +#define WM8400_LINE_CMP_VTHD_WIDTH 4 /* LINE_CMP_VTHD - [3:0] */ + +u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg); +int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data); +int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val); + +#endif -- cgit v1.2.3 From 42fad570b666256a3fd009e23e74cbb365a29ca8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 11 Sep 2008 11:12:01 +0100 Subject: regulator: Add WM8400 regulator support The WM8400 provides two programmable DCDC step-down (buck) convertors and four low-dropout (LDO) regulators. This driver provides support for runtime managment of these in the standard regulator API. Support for configuration of the suspend and hibernate mode behaviour of the regulators is not yet included. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8400-private.h | 1 + include/linux/mfd/wm8400.h | 40 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 include/linux/mfd/wm8400.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8400-private.h b/include/linux/mfd/wm8400-private.h index 49042e990f0..2aab4e93a5c 100644 --- a/include/linux/mfd/wm8400-private.h +++ b/include/linux/mfd/wm8400-private.h @@ -21,6 +21,7 @@ #ifndef __LINUX_MFD_WM8400_PRIV_H #define __LINUX_MFD_WM8400_PRIV_H +#include #include #include diff --git a/include/linux/mfd/wm8400.h b/include/linux/mfd/wm8400.h new file mode 100644 index 00000000000..b46b566ac1a --- /dev/null +++ b/include/linux/mfd/wm8400.h @@ -0,0 +1,40 @@ +/* + * wm8400 client interface + * + * Copyright 2008 Wolfson Microelectronics plc + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LINUX_MFD_WM8400_H +#define __LINUX_MFD_WM8400_H + +#include + +#define WM8400_LDO1 0 +#define WM8400_LDO2 1 +#define WM8400_LDO3 2 +#define WM8400_LDO4 3 +#define WM8400_DCDC1 4 +#define WM8400_DCDC2 5 + +struct wm8400_platform_data { + int (*platform_init)(struct device *dev); +}; + +int wm8400_register_regulator(struct device *dev, int reg, + struct regulator_init_data *initdata); + +#endif -- cgit v1.2.3 From 06532c474718e330a7e3625ef91b94e22991128c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:03 +0100 Subject: mfd: Add WM8350 audio register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/audio.h | 592 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 592 insertions(+) create mode 100644 include/linux/mfd/wm8350/audio.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h new file mode 100644 index 00000000000..43342f76711 --- /dev/null +++ b/include/linux/mfd/wm8350/audio.h @@ -0,0 +1,592 @@ +/* + * audio.h -- Audio Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + * + */ + +#ifndef __LINUX_MFD_WM8350_AUDIO_H_ +#define __LINUX_MFD_WM8350_AUDIO_H_ + +#define WM8350_CLOCK_CONTROL_1 0x28 +#define WM8350_CLOCK_CONTROL_2 0x29 +#define WM8350_FLL_CONTROL_1 0x2A +#define WM8350_FLL_CONTROL_2 0x2B +#define WM8350_FLL_CONTROL_3 0x2C +#define WM8350_FLL_CONTROL_4 0x2D +#define WM8350_DAC_CONTROL 0x30 +#define WM8350_DAC_DIGITAL_VOLUME_L 0x32 +#define WM8350_DAC_DIGITAL_VOLUME_R 0x33 +#define WM8350_DAC_LR_RATE 0x35 +#define WM8350_DAC_CLOCK_CONTROL 0x36 +#define WM8350_DAC_MUTE 0x3A +#define WM8350_DAC_MUTE_VOLUME 0x3B +#define WM8350_DAC_SIDE 0x3C +#define WM8350_ADC_CONTROL 0x40 +#define WM8350_ADC_DIGITAL_VOLUME_L 0x42 +#define WM8350_ADC_DIGITAL_VOLUME_R 0x43 +#define WM8350_ADC_DIVIDER 0x44 +#define WM8350_ADC_LR_RATE 0x46 +#define WM8350_INPUT_CONTROL 0x48 +#define WM8350_IN3_INPUT_CONTROL 0x49 +#define WM8350_MIC_BIAS_CONTROL 0x4A +#define WM8350_OUTPUT_CONTROL 0x4C +#define WM8350_JACK_DETECT 0x4D +#define WM8350_ANTI_POP_CONTROL 0x4E +#define WM8350_LEFT_INPUT_VOLUME 0x50 +#define WM8350_RIGHT_INPUT_VOLUME 0x51 +#define WM8350_LEFT_MIXER_CONTROL 0x58 +#define WM8350_RIGHT_MIXER_CONTROL 0x59 +#define WM8350_OUT3_MIXER_CONTROL 0x5C +#define WM8350_OUT4_MIXER_CONTROL 0x5D +#define WM8350_OUTPUT_LEFT_MIXER_VOLUME 0x60 +#define WM8350_OUTPUT_RIGHT_MIXER_VOLUME 0x61 +#define WM8350_INPUT_MIXER_VOLUME_L 0x62 +#define WM8350_INPUT_MIXER_VOLUME_R 0x63 +#define WM8350_INPUT_MIXER_VOLUME 0x64 +#define WM8350_LOUT1_VOLUME 0x68 +#define WM8350_ROUT1_VOLUME 0x69 +#define WM8350_LOUT2_VOLUME 0x6A +#define WM8350_ROUT2_VOLUME 0x6B +#define WM8350_BEEP_VOLUME 0x6F +#define WM8350_AI_FORMATING 0x70 +#define WM8350_ADC_DAC_COMP 0x71 +#define WM8350_AI_ADC_CONTROL 0x72 +#define WM8350_AI_DAC_CONTROL 0x73 +#define WM8350_AIF_TEST 0x74 +#define WM8350_JACK_PIN_STATUS 0xE7 + +/* Bit values for R08 (0x08) */ +#define WM8350_CODEC_ISEL_1_5 0 /* x1.5 */ +#define WM8350_CODEC_ISEL_1_0 1 /* x1.0 */ +#define WM8350_CODEC_ISEL_0_75 2 /* x0.75 */ +#define WM8350_CODEC_ISEL_0_5 3 /* x0.5 */ + +#define WM8350_VMID_OFF 0 +#define WM8350_VMID_500K 1 +#define WM8350_VMID_100K 2 +#define WM8350_VMID_10K 3 + +/* + * R40 (0x28) - Clock Control 1 + */ +#define WM8350_TOCLK_RATE 0x4000 +#define WM8350_MCLK_SEL 0x0800 +#define WM8350_MCLK_DIV_MASK 0x0100 +#define WM8350_BCLK_DIV_MASK 0x00F0 +#define WM8350_OPCLK_DIV_MASK 0x0007 + +/* + * R41 (0x29) - Clock Control 2 + */ +#define WM8350_LRC_ADC_SEL 0x8000 +#define WM8350_MCLK_DIR 0x0001 + +/* + * R42 (0x2A) - FLL Control 1 + */ +#define WM8350_FLL_DITHER_WIDTH_MASK 0x3000 +#define WM8350_FLL_DITHER_HP 0x0800 +#define WM8350_FLL_OUTDIV_MASK 0x0700 +#define WM8350_FLL_RSP_RATE_MASK 0x00F0 +#define WM8350_FLL_RATE_MASK 0x0007 + +/* + * R43 (0x2B) - FLL Control 2 + */ +#define WM8350_FLL_RATIO_MASK 0xF800 +#define WM8350_FLL_N_MASK 0x03FF + +/* + * R44 (0x2C) - FLL Control 3 + */ +#define WM8350_FLL_K_MASK 0xFFFF + +/* + * R45 (0x2D) - FLL Control 4 + */ +#define WM8350_FLL_FRAC 0x0020 +#define WM8350_FLL_SLOW_LOCK_REF 0x0010 +#define WM8350_FLL_CLK_SRC_MASK 0x0003 + +/* + * R48 (0x30) - DAC Control + */ +#define WM8350_DAC_MONO 0x2000 +#define WM8350_AIF_LRCLKRATE 0x1000 +#define WM8350_DEEMP_MASK 0x0030 +#define WM8350_DACL_DATINV 0x0002 +#define WM8350_DACR_DATINV 0x0001 + +/* + * R50 (0x32) - DAC Digital Volume L + */ +#define WM8350_DAC_VU 0x0100 +#define WM8350_DACL_VOL_MASK 0x00FF + +/* + * R51 (0x33) - DAC Digital Volume R + */ +#define WM8350_DAC_VU 0x0100 +#define WM8350_DACR_VOL_MASK 0x00FF + +/* + * R53 (0x35) - DAC LR Rate + */ +#define WM8350_DACLRC_ENA 0x0800 +#define WM8350_DACLRC_RATE_MASK 0x07FF + +/* + * R54 (0x36) - DAC Clock Control + */ +#define WM8350_DACCLK_POL 0x0010 +#define WM8350_DAC_CLKDIV_MASK 0x0007 + +/* + * R58 (0x3A) - DAC Mute + */ +#define WM8350_DAC_MUTE_ENA 0x4000 + +/* + * R59 (0x3B) - DAC Mute Volume + */ +#define WM8350_DAC_MUTEMODE 0x4000 +#define WM8350_DAC_MUTERATE 0x2000 +#define WM8350_DAC_SB_FILT 0x1000 + +/* + * R60 (0x3C) - DAC Side + */ +#define WM8350_ADC_TO_DACL_MASK 0x3000 +#define WM8350_ADC_TO_DACR_MASK 0x0C00 + +/* + * R64 (0x40) - ADC Control + */ +#define WM8350_ADC_HPF_CUT_MASK 0x0300 +#define WM8350_ADCL_DATINV 0x0002 +#define WM8350_ADCR_DATINV 0x0001 + +/* + * R66 (0x42) - ADC Digital Volume L + */ +#define WM8350_ADC_VU 0x0100 +#define WM8350_ADCL_VOL_MASK 0x00FF + +/* + * R67 (0x43) - ADC Digital Volume R + */ +#define WM8350_ADC_VU 0x0100 +#define WM8350_ADCR_VOL_MASK 0x00FF + +/* + * R68 (0x44) - ADC Divider + */ +#define WM8350_ADCL_DAC_SVOL_MASK 0x0F00 +#define WM8350_ADCR_DAC_SVOL_MASK 0x00F0 +#define WM8350_ADCCLK_POL 0x0008 +#define WM8350_ADC_CLKDIV_MASK 0x0007 + +/* + * R70 (0x46) - ADC LR Rate + */ +#define WM8350_ADCLRC_ENA 0x0800 +#define WM8350_ADCLRC_RATE_MASK 0x07FF + +/* + * R72 (0x48) - Input Control + */ +#define WM8350_IN2R_ENA 0x0400 +#define WM8350_IN1RN_ENA 0x0200 +#define WM8350_IN1RP_ENA 0x0100 +#define WM8350_IN2L_ENA 0x0004 +#define WM8350_IN1LN_ENA 0x0002 +#define WM8350_IN1LP_ENA 0x0001 + +/* + * R73 (0x49) - IN3 Input Control + */ +#define WM8350_IN3R_SHORT 0x4000 +#define WM8350_IN3L_SHORT 0x0040 + +/* + * R74 (0x4A) - Mic Bias Control + */ +#define WM8350_MICBSEL 0x4000 +#define WM8350_MCDTHR_MASK 0x001C +#define WM8350_MCDSCTHR_MASK 0x0003 + +/* + * R76 (0x4C) - Output Control + */ +#define WM8350_OUT4_VROI 0x0800 +#define WM8350_OUT3_VROI 0x0400 +#define WM8350_OUT2_VROI 0x0200 +#define WM8350_OUT1_VROI 0x0100 +#define WM8350_OUT2_FB 0x0004 +#define WM8350_OUT1_FB 0x0001 + +/* + * R77 (0x4D) - Jack Detect + */ +#define WM8350_JDL_ENA 0x8000 +#define WM8350_JDR_ENA 0x4000 + +/* + * R78 (0x4E) - Anti Pop Control + */ +#define WM8350_ANTI_POP_MASK 0x0300 +#define WM8350_DIS_OP_LN4_MASK 0x00C0 +#define WM8350_DIS_OP_LN3_MASK 0x0030 +#define WM8350_DIS_OP_OUT2_MASK 0x000C +#define WM8350_DIS_OP_OUT1_MASK 0x0003 + +/* + * R80 (0x50) - Left Input Volume + */ +#define WM8350_INL_MUTE 0x4000 +#define WM8350_INL_ZC 0x2000 +#define WM8350_IN_VU 0x0100 +#define WM8350_INL_VOL_MASK 0x00FC + +/* + * R81 (0x51) - Right Input Volume + */ +#define WM8350_INR_MUTE 0x4000 +#define WM8350_INR_ZC 0x2000 +#define WM8350_IN_VU 0x0100 +#define WM8350_INR_VOL_MASK 0x00FC + +/* + * R88 (0x58) - Left Mixer Control + */ +#define WM8350_DACR_TO_MIXOUTL 0x1000 +#define WM8350_DACL_TO_MIXOUTL 0x0800 +#define WM8350_IN3L_TO_MIXOUTL 0x0004 +#define WM8350_INR_TO_MIXOUTL 0x0002 +#define WM8350_INL_TO_MIXOUTL 0x0001 + +/* + * R89 (0x59) - Right Mixer Control + */ +#define WM8350_DACR_TO_MIXOUTR 0x1000 +#define WM8350_DACL_TO_MIXOUTR 0x0800 +#define WM8350_IN3R_TO_MIXOUTR 0x0008 +#define WM8350_INR_TO_MIXOUTR 0x0002 +#define WM8350_INL_TO_MIXOUTR 0x0001 + +/* + * R92 (0x5C) - OUT3 Mixer Control + */ +#define WM8350_DACL_TO_OUT3 0x0800 +#define WM8350_MIXINL_TO_OUT3 0x0100 +#define WM8350_OUT4_TO_OUT3 0x0008 +#define WM8350_MIXOUTL_TO_OUT3 0x0001 + +/* + * R93 (0x5D) - OUT4 Mixer Control + */ +#define WM8350_DACR_TO_OUT4 0x1000 +#define WM8350_DACL_TO_OUT4 0x0800 +#define WM8350_OUT4_ATTN 0x0400 +#define WM8350_MIXINR_TO_OUT4 0x0200 +#define WM8350_OUT3_TO_OUT4 0x0004 +#define WM8350_MIXOUTR_TO_OUT4 0x0002 +#define WM8350_MIXOUTL_TO_OUT4 0x0001 + +/* + * R96 (0x60) - Output Left Mixer Volume + */ +#define WM8350_IN3L_MIXOUTL_VOL_MASK 0x0E00 +#define WM8350_IN3L_MIXOUTL_VOL_SHIFT 9 +#define WM8350_INR_MIXOUTL_VOL_MASK 0x00E0 +#define WM8350_INR_MIXOUTL_VOL_SHIFT 5 +#define WM8350_INL_MIXOUTL_VOL_MASK 0x000E +#define WM8350_INL_MIXOUTL_VOL_SHIFT 1 + +/* Bit values for R96 (0x60) */ +#define WM8350_IN3L_MIXOUTL_VOL_OFF 0 +#define WM8350_IN3L_MIXOUTL_VOL_M12DB 1 +#define WM8350_IN3L_MIXOUTL_VOL_M9DB 2 +#define WM8350_IN3L_MIXOUTL_VOL_M6DB 3 +#define WM8350_IN3L_MIXOUTL_VOL_M3DB 4 +#define WM8350_IN3L_MIXOUTL_VOL_0DB 5 +#define WM8350_IN3L_MIXOUTL_VOL_3DB 6 +#define WM8350_IN3L_MIXOUTL_VOL_6DB 7 + +#define WM8350_INR_MIXOUTL_VOL_OFF 0 +#define WM8350_INR_MIXOUTL_VOL_M12DB 1 +#define WM8350_INR_MIXOUTL_VOL_M9DB 2 +#define WM8350_INR_MIXOUTL_VOL_M6DB 3 +#define WM8350_INR_MIXOUTL_VOL_M3DB 4 +#define WM8350_INR_MIXOUTL_VOL_0DB 5 +#define WM8350_INR_MIXOUTL_VOL_3DB 6 +#define WM8350_INR_MIXOUTL_VOL_6DB 7 + +#define WM8350_INL_MIXOUTL_VOL_OFF 0 +#define WM8350_INL_MIXOUTL_VOL_M12DB 1 +#define WM8350_INL_MIXOUTL_VOL_M9DB 2 +#define WM8350_INL_MIXOUTL_VOL_M6DB 3 +#define WM8350_INL_MIXOUTL_VOL_M3DB 4 +#define WM8350_INL_MIXOUTL_VOL_0DB 5 +#define WM8350_INL_MIXOUTL_VOL_3DB 6 +#define WM8350_INL_MIXOUTL_VOL_6DB 7 + +/* + * R97 (0x61) - Output Right Mixer Volume + */ +#define WM8350_IN3R_MIXOUTR_VOL_MASK 0xE000 +#define WM8350_IN3R_MIXOUTR_VOL_SHIFT 13 +#define WM8350_INR_MIXOUTR_VOL_MASK 0x00E0 +#define WM8350_INR_MIXOUTR_VOL_SHIFT 5 +#define WM8350_INL_MIXOUTR_VOL_MASK 0x000E +#define WM8350_INL_MIXOUTR_VOL_SHIFT 1 + +/* Bit values for R96 (0x60) */ +#define WM8350_IN3R_MIXOUTR_VOL_OFF 0 +#define WM8350_IN3R_MIXOUTR_VOL_M12DB 1 +#define WM8350_IN3R_MIXOUTR_VOL_M9DB 2 +#define WM8350_IN3R_MIXOUTR_VOL_M6DB 3 +#define WM8350_IN3R_MIXOUTR_VOL_M3DB 4 +#define WM8350_IN3R_MIXOUTR_VOL_0DB 5 +#define WM8350_IN3R_MIXOUTR_VOL_3DB 6 +#define WM8350_IN3R_MIXOUTR_VOL_6DB 7 + +#define WM8350_INR_MIXOUTR_VOL_OFF 0 +#define WM8350_INR_MIXOUTR_VOL_M12DB 1 +#define WM8350_INR_MIXOUTR_VOL_M9DB 2 +#define WM8350_INR_MIXOUTR_VOL_M6DB 3 +#define WM8350_INR_MIXOUTR_VOL_M3DB 4 +#define WM8350_INR_MIXOUTR_VOL_0DB 5 +#define WM8350_INR_MIXOUTR_VOL_3DB 6 +#define WM8350_INR_MIXOUTR_VOL_6DB 7 + +#define WM8350_INL_MIXOUTR_VOL_OFF 0 +#define WM8350_INL_MIXOUTR_VOL_M12DB 1 +#define WM8350_INL_MIXOUTR_VOL_M9DB 2 +#define WM8350_INL_MIXOUTR_VOL_M6DB 3 +#define WM8350_INL_MIXOUTR_VOL_M3DB 4 +#define WM8350_INL_MIXOUTR_VOL_0DB 5 +#define WM8350_INL_MIXOUTR_VOL_3DB 6 +#define WM8350_INL_MIXOUTR_VOL_6DB 7 + +/* + * R98 (0x62) - Input Mixer Volume L + */ +#define WM8350_IN3L_MIXINL_VOL_MASK 0x0E00 +#define WM8350_IN2L_MIXINL_VOL_MASK 0x000E +#define WM8350_INL_MIXINL_VOL 0x0001 + +/* + * R99 (0x63) - Input Mixer Volume R + */ +#define WM8350_IN3R_MIXINR_VOL_MASK 0xE000 +#define WM8350_IN2R_MIXINR_VOL_MASK 0x00E0 +#define WM8350_INR_MIXINR_VOL 0x0001 + +/* + * R100 (0x64) - Input Mixer Volume + */ +#define WM8350_OUT4_MIXIN_DST 0x8000 +#define WM8350_OUT4_MIXIN_VOL_MASK 0x000E + +/* + * R104 (0x68) - LOUT1 Volume + */ +#define WM8350_OUT1L_MUTE 0x4000 +#define WM8350_OUT1L_ZC 0x2000 +#define WM8350_OUT1_VU 0x0100 +#define WM8350_OUT1L_VOL_MASK 0x00FC +#define WM8350_OUT1L_VOL_SHIFT 2 + +/* + * R105 (0x69) - ROUT1 Volume + */ +#define WM8350_OUT1R_MUTE 0x4000 +#define WM8350_OUT1R_ZC 0x2000 +#define WM8350_OUT1_VU 0x0100 +#define WM8350_OUT1R_VOL_MASK 0x00FC +#define WM8350_OUT1R_VOL_SHIFT 2 + +/* + * R106 (0x6A) - LOUT2 Volume + */ +#define WM8350_OUT2L_MUTE 0x4000 +#define WM8350_OUT2L_ZC 0x2000 +#define WM8350_OUT2_VU 0x0100 +#define WM8350_OUT2L_VOL_MASK 0x00FC + +/* + * R107 (0x6B) - ROUT2 Volume + */ +#define WM8350_OUT2R_MUTE 0x4000 +#define WM8350_OUT2R_ZC 0x2000 +#define WM8350_OUT2R_INV 0x0400 +#define WM8350_OUT2R_INV_MUTE 0x0200 +#define WM8350_OUT2_VU 0x0100 +#define WM8350_OUT2R_VOL_MASK 0x00FC + +/* + * R111 (0x6F) - BEEP Volume + */ +#define WM8350_IN3R_OUT2R_VOL_MASK 0x00E0 + +/* + * R112 (0x70) - AI Formating + */ +#define WM8350_AIF_BCLK_INV 0x8000 +#define WM8350_AIF_TRI 0x2000 +#define WM8350_AIF_LRCLK_INV 0x1000 +#define WM8350_AIF_WL_MASK 0x0C00 +#define WM8350_AIF_FMT_MASK 0x0300 + +/* + * R113 (0x71) - ADC DAC COMP + */ +#define WM8350_DAC_COMP 0x0080 +#define WM8350_DAC_COMPMODE 0x0040 +#define WM8350_ADC_COMP 0x0020 +#define WM8350_ADC_COMPMODE 0x0010 +#define WM8350_LOOPBACK 0x0001 + +/* + * R114 (0x72) - AI ADC Control + */ +#define WM8350_AIFADC_PD 0x0080 +#define WM8350_AIFADCL_SRC 0x0040 +#define WM8350_AIFADCR_SRC 0x0020 +#define WM8350_AIFADC_TDM_CHAN 0x0010 +#define WM8350_AIFADC_TDM 0x0008 + +/* + * R115 (0x73) - AI DAC Control + */ +#define WM8350_BCLK_MSTR 0x4000 +#define WM8350_AIFDAC_PD 0x0080 +#define WM8350_DACL_SRC 0x0040 +#define WM8350_DACR_SRC 0x0020 +#define WM8350_AIFDAC_TDM_CHAN 0x0010 +#define WM8350_AIFDAC_TDM 0x0008 +#define WM8350_DAC_BOOST_MASK 0x0003 + +/* + * R116 (0x74) - AIF Test + */ +#define WM8350_CODEC_BYP 0x4000 +#define WM8350_AIFADC_WR_TST 0x2000 +#define WM8350_AIFADC_RD_TST 0x1000 +#define WM8350_AIFDAC_WR_TST 0x0800 +#define WM8350_AIFDAC_RD_TST 0x0400 +#define WM8350_AIFADC_ASYN 0x0020 +#define WM8350_AIFDAC_ASYN 0x0010 + +/* + * R231 (0xE7) - Jack Status + */ +#define WM8350_JACK_R_LVL 0x0400 + +/* + * WM8350 Platform setup + */ +#define WM8350_S_CURVE_NONE 0x0 +#define WM8350_S_CURVE_FAST 0x1 +#define WM8350_S_CURVE_MEDIUM 0x2 +#define WM8350_S_CURVE_SLOW 0x3 + +#define WM8350_DISCHARGE_OFF 0x0 +#define WM8350_DISCHARGE_FAST 0x1 +#define WM8350_DISCHARGE_MEDIUM 0x2 +#define WM8350_DISCHARGE_SLOW 0x3 + +#define WM8350_TIE_OFF_500R 0x0 +#define WM8350_TIE_OFF_30K 0x1 + +/* + * Clock sources & directions + */ +#define WM8350_SYSCLK 0 + +#define WM8350_MCLK_SEL_PLL_MCLK 0 +#define WM8350_MCLK_SEL_PLL_DAC 1 +#define WM8350_MCLK_SEL_PLL_ADC 2 +#define WM8350_MCLK_SEL_PLL_32K 3 +#define WM8350_MCLK_SEL_MCLK 5 + +#define WM8350_MCLK_DIR_OUT 0 +#define WM8350_MCLK_DIR_IN 1 + +/* clock divider id's */ +#define WM8350_ADC_CLKDIV 0 +#define WM8350_DAC_CLKDIV 1 +#define WM8350_BCLK_CLKDIV 2 +#define WM8350_OPCLK_CLKDIV 3 +#define WM8350_TO_CLKDIV 4 +#define WM8350_SYS_CLKDIV 5 +#define WM8350_DACLR_CLKDIV 6 +#define WM8350_ADCLR_CLKDIV 7 + +/* ADC clock dividers */ +#define WM8350_ADCDIV_1 0x0 +#define WM8350_ADCDIV_1_5 0x1 +#define WM8350_ADCDIV_2 0x2 +#define WM8350_ADCDIV_3 0x3 +#define WM8350_ADCDIV_4 0x4 +#define WM8350_ADCDIV_5_5 0x5 +#define WM8350_ADCDIV_6 0x6 + +/* ADC clock dividers */ +#define WM8350_DACDIV_1 0x0 +#define WM8350_DACDIV_1_5 0x1 +#define WM8350_DACDIV_2 0x2 +#define WM8350_DACDIV_3 0x3 +#define WM8350_DACDIV_4 0x4 +#define WM8350_DACDIV_5_5 0x5 +#define WM8350_DACDIV_6 0x6 + +/* BCLK clock dividers */ +#define WM8350_BCLK_DIV_1 (0x0 << 4) +#define WM8350_BCLK_DIV_1_5 (0x1 << 4) +#define WM8350_BCLK_DIV_2 (0x2 << 4) +#define WM8350_BCLK_DIV_3 (0x3 << 4) +#define WM8350_BCLK_DIV_4 (0x4 << 4) +#define WM8350_BCLK_DIV_5_5 (0x5 << 4) +#define WM8350_BCLK_DIV_6 (0x6 << 4) +#define WM8350_BCLK_DIV_8 (0x7 << 4) +#define WM8350_BCLK_DIV_11 (0x8 << 4) +#define WM8350_BCLK_DIV_12 (0x9 << 4) +#define WM8350_BCLK_DIV_16 (0xa << 4) +#define WM8350_BCLK_DIV_22 (0xb << 4) +#define WM8350_BCLK_DIV_24 (0xc << 4) +#define WM8350_BCLK_DIV_32 (0xd << 4) +#define WM8350_BCLK_DIV_44 (0xe << 4) +#define WM8350_BCLK_DIV_48 (0xf << 4) + +/* Sys (MCLK) clock dividers */ +#define WM8350_MCLK_DIV_1 (0x0 << 8) +#define WM8350_MCLK_DIV_2 (0x1 << 8) + +/* OP clock dividers */ +#define WM8350_OPCLK_DIV_1 0x0 +#define WM8350_OPCLK_DIV_2 0x1 +#define WM8350_OPCLK_DIV_3 0x2 +#define WM8350_OPCLK_DIV_4 0x3 +#define WM8350_OPCLK_DIV_5_5 0x4 +#define WM8350_OPCLK_DIV_6 0x5 + +/* DAI ID */ +#define WM8350_HIFI_DAI 0 + +/* + * Audio interrupts. + */ +#define WM8350_IRQ_CODEC_JCK_DET_L 39 +#define WM8350_IRQ_CODEC_JCK_DET_R 40 +#define WM8350_IRQ_CODEC_MICSCD 41 +#define WM8350_IRQ_CODEC_MICD 42 + +#endif -- cgit v1.2.3 From 0c42e0b7631f1bfccc27eedac2a1e03f4c8c824c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:04 +0100 Subject: mfd: Add WM8350 GPIO register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/gpio.h | 326 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) create mode 100644 include/linux/mfd/wm8350/gpio.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h new file mode 100644 index 00000000000..928aa6e91e3 --- /dev/null +++ b/include/linux/mfd/wm8350/gpio.h @@ -0,0 +1,326 @@ +/* + * gpio.h -- GPIO Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + * + */ + +#ifndef __LINUX_MFD_WM8350_GPIO_H_ +#define __LINUX_MFD_WM8350_GPIO_H_ + +/* + * GPIO Registers. + */ +#define WM8350_GPIO_DEBOUNCE 0x80 +#define WM8350_GPIO_PIN_PULL_UP_CONTROL 0x81 +#define WM8350_GPIO_PULL_DOWN_CONTROL 0x82 +#define WM8350_GPIO_INT_MODE 0x83 +#define WM8350_GPIO_CONTROL 0x85 +#define WM8350_GPIO_CONFIGURATION_I_O 0x86 +#define WM8350_GPIO_PIN_POLARITY_TYPE 0x87 +#define WM8350_GPIO_FUNCTION_SELECT_1 0x8C +#define WM8350_GPIO_FUNCTION_SELECT_2 0x8D +#define WM8350_GPIO_FUNCTION_SELECT_3 0x8E +#define WM8350_GPIO_FUNCTION_SELECT_4 0x8F + +/* + * GPIO Functions + */ +#define WM8350_GPIO0_GPIO_IN 0x0 +#define WM8350_GPIO0_GPIO_OUT 0x0 +#define WM8350_GPIO0_PWR_ON_IN 0x1 +#define WM8350_GPIO0_PWR_ON_OUT 0x1 +#define WM8350_GPIO0_LDO_EN_IN 0x2 +#define WM8350_GPIO0_VRTC_OUT 0x2 +#define WM8350_GPIO0_LPWR1_IN 0x3 +#define WM8350_GPIO0_POR_B_OUT 0x3 + +#define WM8350_GPIO1_GPIO_IN 0x0 +#define WM8350_GPIO1_GPIO_OUT 0x0 +#define WM8350_GPIO1_PWR_ON_IN 0x1 +#define WM8350_GPIO1_DO_CONF_OUT 0x1 +#define WM8350_GPIO1_LDO_EN_IN 0x2 +#define WM8350_GPIO1_RESET_OUT 0x2 +#define WM8350_GPIO1_LPWR2_IN 0x3 +#define WM8350_GPIO1_MEMRST_OUT 0x3 + +#define WM8350_GPIO2_GPIO_IN 0x0 +#define WM8350_GPIO2_GPIO_OUT 0x0 +#define WM8350_GPIO2_PWR_ON_IN 0x1 +#define WM8350_GPIO2_PWR_ON_OUT 0x1 +#define WM8350_GPIO2_WAKE_UP_IN 0x2 +#define WM8350_GPIO2_VRTC_OUT 0x2 +#define WM8350_GPIO2_32KHZ_IN 0x3 +#define WM8350_GPIO2_32KHZ_OUT 0x3 + +#define WM8350_GPIO3_GPIO_IN 0x0 +#define WM8350_GPIO3_GPIO_OUT 0x0 +#define WM8350_GPIO3_PWR_ON_IN 0x1 +#define WM8350_GPIO3_P_CLK_OUT 0x1 +#define WM8350_GPIO3_LDO_EN_IN 0x2 +#define WM8350_GPIO3_VRTC_OUT 0x2 +#define WM8350_GPIO3_PWR_OFF_IN 0x3 +#define WM8350_GPIO3_32KHZ_OUT 0x3 + +#define WM8350_GPIO4_GPIO_IN 0x0 +#define WM8350_GPIO4_GPIO_OUT 0x0 +#define WM8350_GPIO4_MR_IN 0x1 +#define WM8350_GPIO4_MEM_RST_OUT 0x1 +#define WM8350_GPIO4_FLASH_IN 0x2 +#define WM8350_GPIO4_ADA_OUT 0x2 +#define WM8350_GPIO4_HIBERNATE_IN 0x3 +#define WM8350_GPIO4_FLASH_OUT 0x3 +#define WM8350_GPIO4_MICDET_OUT 0x4 +#define WM8350_GPIO4_MICSHT_OUT 0x5 + +#define WM8350_GPIO5_GPIO_IN 0x0 +#define WM8350_GPIO5_GPIO_OUT 0x0 +#define WM8350_GPIO5_LPWR1_IN 0x1 +#define WM8350_GPIO5_P_CLK_OUT 0x1 +#define WM8350_GPIO5_ADCLRCLK_IN 0x2 +#define WM8350_GPIO5_ADCLRCLK_OUT 0x2 +#define WM8350_GPIO5_HIBERNATE_IN 0x3 +#define WM8350_GPIO5_32KHZ_OUT 0x3 +#define WM8350_GPIO5_MICDET_OUT 0x4 +#define WM8350_GPIO5_MICSHT_OUT 0x5 +#define WM8350_GPIO5_ADA_OUT 0x6 +#define WM8350_GPIO5_OPCLK_OUT 0x7 + +#define WM8350_GPIO6_GPIO_IN 0x0 +#define WM8350_GPIO6_GPIO_OUT 0x0 +#define WM8350_GPIO6_LPWR2_IN 0x1 +#define WM8350_GPIO6_MEMRST_OUT 0x1 +#define WM8350_GPIO6_FLASH_IN 0x2 +#define WM8350_GPIO6_ADA_OUT 0x2 +#define WM8350_GPIO6_HIBERNATE_IN 0x3 +#define WM8350_GPIO6_RTC_OUT 0x3 +#define WM8350_GPIO6_MICDET_OUT 0x4 +#define WM8350_GPIO6_MICSHT_OUT 0x5 +#define WM8350_GPIO6_ADCLRCLKB_OUT 0x6 +#define WM8350_GPIO6_SDOUT_OUT 0x7 + +#define WM8350_GPIO7_GPIO_IN 0x0 +#define WM8350_GPIO7_GPIO_OUT 0x0 +#define WM8350_GPIO7_LPWR3_IN 0x1 +#define WM8350_GPIO7_P_CLK_OUT 0x1 +#define WM8350_GPIO7_MASK_IN 0x2 +#define WM8350_GPIO7_VCC_FAULT_OUT 0x2 +#define WM8350_GPIO7_HIBERNATE_IN 0x3 +#define WM8350_GPIO7_BATT_FAULT_OUT 0x3 +#define WM8350_GPIO7_MICDET_OUT 0x4 +#define WM8350_GPIO7_MICSHT_OUT 0x5 +#define WM8350_GPIO7_ADA_OUT 0x6 +#define WM8350_GPIO7_CSB_IN 0x7 + +#define WM8350_GPIO8_GPIO_IN 0x0 +#define WM8350_GPIO8_GPIO_OUT 0x0 +#define WM8350_GPIO8_MR_IN 0x1 +#define WM8350_GPIO8_VCC_FAULT_OUT 0x1 +#define WM8350_GPIO8_ADCBCLK_IN 0x2 +#define WM8350_GPIO8_ADCBCLK_OUT 0x2 +#define WM8350_GPIO8_PWR_OFF_IN 0x3 +#define WM8350_GPIO8_BATT_FAULT_OUT 0x3 +#define WM8350_GPIO8_ALTSCL_IN 0xf + +#define WM8350_GPIO9_GPIO_IN 0x0 +#define WM8350_GPIO9_GPIO_OUT 0x0 +#define WM8350_GPIO9_HEARTBEAT_IN 0x1 +#define WM8350_GPIO9_VCC_FAULT_OUT 0x1 +#define WM8350_GPIO9_MASK_IN 0x2 +#define WM8350_GPIO9_LINE_GT_BATT_OUT 0x2 +#define WM8350_GPIO9_PWR_OFF_IN 0x3 +#define WM8350_GPIO9_BATT_FAULT_OUT 0x3 +#define WM8350_GPIO9_ALTSDA_OUT 0xf + +#define WM8350_GPIO10_GPIO_IN 0x0 +#define WM8350_GPIO10_GPIO_OUT 0x0 +#define WM8350_GPIO10_ISINKC_OUT 0x1 +#define WM8350_GPIO10_PWR_OFF_IN 0x2 +#define WM8350_GPIO10_LINE_GT_BATT_OUT 0x2 +#define WM8350_GPIO10_CHD_IND_IN 0x3 + +#define WM8350_GPIO11_GPIO_IN 0x0 +#define WM8350_GPIO11_GPIO_OUT 0x0 +#define WM8350_GPIO11_ISINKD_OUT 0x1 +#define WM8350_GPIO11_WAKEUP_IN 0x2 +#define WM8350_GPIO11_LINE_GT_BATT_OUT 0x2 +#define WM8350_GPIO11_CHD_IND_IN 0x3 + +#define WM8350_GPIO12_GPIO_IN 0x0 +#define WM8350_GPIO12_GPIO_OUT 0x0 +#define WM8350_GPIO12_ISINKE_OUT 0x1 +#define WM8350_GPIO12_LINE_GT_BATT_OUT 0x2 +#define WM8350_GPIO12_LINE_EN_OUT 0x3 +#define WM8350_GPIO12_32KHZ_OUT 0x4 + +#define WM8350_GPIO_DIR_IN 0 +#define WM8350_GPIO_DIR_OUT 1 +#define WM8350_GPIO_ACTIVE_LOW 0 +#define WM8350_GPIO_ACTIVE_HIGH 1 +#define WM8350_GPIO_PULL_NONE 0 +#define WM8350_GPIO_PULL_UP 1 +#define WM8350_GPIO_PULL_DOWN 2 +#define WM8350_GPIO_INVERT_OFF 0 +#define WM8350_GPIO_INVERT_ON 1 +#define WM8350_GPIO_DEBOUNCE_OFF 0 +#define WM8350_GPIO_DEBOUNCE_ON 1 + +/* + * R128 (0x80) - GPIO Debounce + */ +#define WM8350_GP12_DB 0x1000 +#define WM8350_GP11_DB 0x0800 +#define WM8350_GP10_DB 0x0400 +#define WM8350_GP9_DB 0x0200 +#define WM8350_GP8_DB 0x0100 +#define WM8350_GP7_DB 0x0080 +#define WM8350_GP6_DB 0x0040 +#define WM8350_GP5_DB 0x0020 +#define WM8350_GP4_DB 0x0010 +#define WM8350_GP3_DB 0x0008 +#define WM8350_GP2_DB 0x0004 +#define WM8350_GP1_DB 0x0002 +#define WM8350_GP0_DB 0x0001 + +/* + * R129 (0x81) - GPIO Pin pull up Control + */ +#define WM8350_GP12_PU 0x1000 +#define WM8350_GP11_PU 0x0800 +#define WM8350_GP10_PU 0x0400 +#define WM8350_GP9_PU 0x0200 +#define WM8350_GP8_PU 0x0100 +#define WM8350_GP7_PU 0x0080 +#define WM8350_GP6_PU 0x0040 +#define WM8350_GP5_PU 0x0020 +#define WM8350_GP4_PU 0x0010 +#define WM8350_GP3_PU 0x0008 +#define WM8350_GP2_PU 0x0004 +#define WM8350_GP1_PU 0x0002 +#define WM8350_GP0_PU 0x0001 + +/* + * R130 (0x82) - GPIO Pull down Control + */ +#define WM8350_GP12_PD 0x1000 +#define WM8350_GP11_PD 0x0800 +#define WM8350_GP10_PD 0x0400 +#define WM8350_GP9_PD 0x0200 +#define WM8350_GP8_PD 0x0100 +#define WM8350_GP7_PD 0x0080 +#define WM8350_GP6_PD 0x0040 +#define WM8350_GP5_PD 0x0020 +#define WM8350_GP4_PD 0x0010 +#define WM8350_GP3_PD 0x0008 +#define WM8350_GP2_PD 0x0004 +#define WM8350_GP1_PD 0x0002 +#define WM8350_GP0_PD 0x0001 + +/* + * R131 (0x83) - GPIO Interrupt Mode + */ +#define WM8350_GP12_INTMODE 0x1000 +#define WM8350_GP11_INTMODE 0x0800 +#define WM8350_GP10_INTMODE 0x0400 +#define WM8350_GP9_INTMODE 0x0200 +#define WM8350_GP8_INTMODE 0x0100 +#define WM8350_GP7_INTMODE 0x0080 +#define WM8350_GP6_INTMODE 0x0040 +#define WM8350_GP5_INTMODE 0x0020 +#define WM8350_GP4_INTMODE 0x0010 +#define WM8350_GP3_INTMODE 0x0008 +#define WM8350_GP2_INTMODE 0x0004 +#define WM8350_GP1_INTMODE 0x0002 +#define WM8350_GP0_INTMODE 0x0001 + +/* + * R133 (0x85) - GPIO Control + */ +#define WM8350_GP_DBTIME_MASK 0x00C0 + +/* + * R134 (0x86) - GPIO Configuration (i/o) + */ +#define WM8350_GP12_DIR 0x1000 +#define WM8350_GP11_DIR 0x0800 +#define WM8350_GP10_DIR 0x0400 +#define WM8350_GP9_DIR 0x0200 +#define WM8350_GP8_DIR 0x0100 +#define WM8350_GP7_DIR 0x0080 +#define WM8350_GP6_DIR 0x0040 +#define WM8350_GP5_DIR 0x0020 +#define WM8350_GP4_DIR 0x0010 +#define WM8350_GP3_DIR 0x0008 +#define WM8350_GP2_DIR 0x0004 +#define WM8350_GP1_DIR 0x0002 +#define WM8350_GP0_DIR 0x0001 + +/* + * R135 (0x87) - GPIO Pin Polarity / Type + */ +#define WM8350_GP12_CFG 0x1000 +#define WM8350_GP11_CFG 0x0800 +#define WM8350_GP10_CFG 0x0400 +#define WM8350_GP9_CFG 0x0200 +#define WM8350_GP8_CFG 0x0100 +#define WM8350_GP7_CFG 0x0080 +#define WM8350_GP6_CFG 0x0040 +#define WM8350_GP5_CFG 0x0020 +#define WM8350_GP4_CFG 0x0010 +#define WM8350_GP3_CFG 0x0008 +#define WM8350_GP2_CFG 0x0004 +#define WM8350_GP1_CFG 0x0002 +#define WM8350_GP0_CFG 0x0001 + +/* + * R140 (0x8C) - GPIO Function Select 1 + */ +#define WM8350_GP3_FN_MASK 0xF000 +#define WM8350_GP2_FN_MASK 0x0F00 +#define WM8350_GP1_FN_MASK 0x00F0 +#define WM8350_GP0_FN_MASK 0x000F + +/* + * R141 (0x8D) - GPIO Function Select 2 + */ +#define WM8350_GP7_FN_MASK 0xF000 +#define WM8350_GP6_FN_MASK 0x0F00 +#define WM8350_GP5_FN_MASK 0x00F0 +#define WM8350_GP4_FN_MASK 0x000F + +/* + * R142 (0x8E) - GPIO Function Select 3 + */ +#define WM8350_GP11_FN_MASK 0xF000 +#define WM8350_GP10_FN_MASK 0x0F00 +#define WM8350_GP9_FN_MASK 0x00F0 +#define WM8350_GP8_FN_MASK 0x000F + +/* + * R143 (0x8F) - GPIO Function Select 4 + */ +#define WM8350_GP12_FN_MASK 0x000F + +/* + * R230 (0xE6) - GPIO Pin Status + */ +#define WM8350_GP12_LVL 0x1000 +#define WM8350_GP11_LVL 0x0800 +#define WM8350_GP10_LVL 0x0400 +#define WM8350_GP9_LVL 0x0200 +#define WM8350_GP8_LVL 0x0100 +#define WM8350_GP7_LVL 0x0080 +#define WM8350_GP6_LVL 0x0040 +#define WM8350_GP5_LVL 0x0020 +#define WM8350_GP4_LVL 0x0010 +#define WM8350_GP3_LVL 0x0008 +#define WM8350_GP2_LVL 0x0004 +#define WM8350_GP1_LVL 0x0002 +#define WM8350_GP0_LVL 0x0001 + +#endif -- cgit v1.2.3 From 03c127ee1e0c5f7a5285d1af3d5c1571ac2646a1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:05 +0100 Subject: mfd: Add WM8350 PMIC register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/pmic.h | 699 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 699 insertions(+) create mode 100644 include/linux/mfd/wm8350/pmic.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h new file mode 100644 index 00000000000..28d2fab2787 --- /dev/null +++ b/include/linux/mfd/wm8350/pmic.h @@ -0,0 +1,699 @@ +/* + * pmic.h -- Power Managment Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + * + */ + +#ifndef __LINUX_MFD_WM8350_PMIC_H +#define __LINUX_MFD_WM8350_PMIC_H + +/* + * Register values. + */ + +#define WM8350_CURRENT_SINK_DRIVER_A 0xAC +#define WM8350_CSA_FLASH_CONTROL 0xAD +#define WM8350_CURRENT_SINK_DRIVER_B 0xAE +#define WM8350_CSB_FLASH_CONTROL 0xAF +#define WM8350_DCDC_LDO_REQUESTED 0xB0 +#define WM8350_DCDC_ACTIVE_OPTIONS 0xB1 +#define WM8350_DCDC_SLEEP_OPTIONS 0xB2 +#define WM8350_POWER_CHECK_COMPARATOR 0xB3 +#define WM8350_DCDC1_CONTROL 0xB4 +#define WM8350_DCDC1_TIMEOUTS 0xB5 +#define WM8350_DCDC1_LOW_POWER 0xB6 +#define WM8350_DCDC2_CONTROL 0xB7 +#define WM8350_DCDC2_TIMEOUTS 0xB8 +#define WM8350_DCDC3_CONTROL 0xBA +#define WM8350_DCDC3_TIMEOUTS 0xBB +#define WM8350_DCDC3_LOW_POWER 0xBC +#define WM8350_DCDC4_CONTROL 0xBD +#define WM8350_DCDC4_TIMEOUTS 0xBE +#define WM8350_DCDC4_LOW_POWER 0xBF +#define WM8350_DCDC5_CONTROL 0xC0 +#define WM8350_DCDC5_TIMEOUTS 0xC1 +#define WM8350_DCDC6_CONTROL 0xC3 +#define WM8350_DCDC6_TIMEOUTS 0xC4 +#define WM8350_DCDC6_LOW_POWER 0xC5 +#define WM8350_LIMIT_SWITCH_CONTROL 0xC7 +#define WM8350_LDO1_CONTROL 0xC8 +#define WM8350_LDO1_TIMEOUTS 0xC9 +#define WM8350_LDO1_LOW_POWER 0xCA +#define WM8350_LDO2_CONTROL 0xCB +#define WM8350_LDO2_TIMEOUTS 0xCC +#define WM8350_LDO2_LOW_POWER 0xCD +#define WM8350_LDO3_CONTROL 0xCE +#define WM8350_LDO3_TIMEOUTS 0xCF +#define WM8350_LDO3_LOW_POWER 0xD0 +#define WM8350_LDO4_CONTROL 0xD1 +#define WM8350_LDO4_TIMEOUTS 0xD2 +#define WM8350_LDO4_LOW_POWER 0xD3 +#define WM8350_VCC_FAULT_MASKS 0xD7 +#define WM8350_MAIN_BANDGAP_CONTROL 0xD8 +#define WM8350_OSC_CONTROL 0xD9 +#define WM8350_RTC_TICK_CONTROL 0xDA +#define WM8350_SECURITY 0xDB +#define WM8350_RAM_BIST_1 0xDC +#define WM8350_DCDC_LDO_STATUS 0xE1 +#define WM8350_GPIO_PIN_STATUS 0xE6 + +#define WM8350_DCDC1_FORCE_PWM 0xF8 +#define WM8350_DCDC3_FORCE_PWM 0xFA +#define WM8350_DCDC4_FORCE_PWM 0xFB +#define WM8350_DCDC6_FORCE_PWM 0xFD + +/* + * R172 (0xAC) - Current Sink Driver A + */ +#define WM8350_CS1_HIB_MODE 0x1000 +#define WM8350_CS1_HIB_MODE_MASK 0x1000 +#define WM8350_CS1_HIB_MODE_SHIFT 12 +#define WM8350_CS1_ISEL_MASK 0x003F +#define WM8350_CS1_ISEL_SHIFT 0 + +/* Bit values for R172 (0xAC) */ +#define WM8350_CS1_HIB_MODE_DISABLE 0 +#define WM8350_CS1_HIB_MODE_LEAVE 1 + +#define WM8350_CS1_ISEL_220M 0x3F + +/* + * R173 (0xAD) - CSA Flash control + */ +#define WM8350_CS1_FLASH_MODE 0x8000 +#define WM8350_CS1_TRIGSRC 0x4000 +#define WM8350_CS1_DRIVE 0x2000 +#define WM8350_CS1_FLASH_DUR_MASK 0x0300 +#define WM8350_CS1_OFF_RAMP_MASK 0x0030 +#define WM8350_CS1_ON_RAMP_MASK 0x0003 + +/* + * R174 (0xAE) - Current Sink Driver B + */ +#define WM8350_CS2_HIB_MODE 0x1000 +#define WM8350_CS2_ISEL_MASK 0x003F + +/* + * R175 (0xAF) - CSB Flash control + */ +#define WM8350_CS2_FLASH_MODE 0x8000 +#define WM8350_CS2_TRIGSRC 0x4000 +#define WM8350_CS2_DRIVE 0x2000 +#define WM8350_CS2_FLASH_DUR_MASK 0x0300 +#define WM8350_CS2_OFF_RAMP_MASK 0x0030 +#define WM8350_CS2_ON_RAMP_MASK 0x0003 + +/* + * R176 (0xB0) - DCDC/LDO requested + */ +#define WM8350_LS_ENA 0x8000 +#define WM8350_LDO4_ENA 0x0800 +#define WM8350_LDO3_ENA 0x0400 +#define WM8350_LDO2_ENA 0x0200 +#define WM8350_LDO1_ENA 0x0100 +#define WM8350_DC6_ENA 0x0020 +#define WM8350_DC5_ENA 0x0010 +#define WM8350_DC4_ENA 0x0008 +#define WM8350_DC3_ENA 0x0004 +#define WM8350_DC2_ENA 0x0002 +#define WM8350_DC1_ENA 0x0001 + +/* + * R177 (0xB1) - DCDC Active options + */ +#define WM8350_PUTO_MASK 0x3000 +#define WM8350_PWRUP_DELAY_MASK 0x0300 +#define WM8350_DC6_ACTIVE 0x0020 +#define WM8350_DC4_ACTIVE 0x0008 +#define WM8350_DC3_ACTIVE 0x0004 +#define WM8350_DC1_ACTIVE 0x0001 + +/* + * R178 (0xB2) - DCDC Sleep options + */ +#define WM8350_DC6_SLEEP 0x0020 +#define WM8350_DC4_SLEEP 0x0008 +#define WM8350_DC3_SLEEP 0x0004 +#define WM8350_DC1_SLEEP 0x0001 + +/* + * R179 (0xB3) - Power-check comparator + */ +#define WM8350_PCCMP_ERRACT 0x4000 +#define WM8350_PCCMP_RAIL 0x0100 +#define WM8350_PCCMP_OFF_THR_MASK 0x0070 +#define WM8350_PCCMP_ON_THR_MASK 0x0007 + +/* + * R180 (0xB4) - DCDC1 Control + */ +#define WM8350_DC1_OPFLT 0x0400 +#define WM8350_DC1_VSEL_MASK 0x007F +#define WM8350_DC1_VSEL_SHIFT 0 + +/* + * R181 (0xB5) - DCDC1 Timeouts + */ +#define WM8350_DC1_ERRACT_MASK 0xC000 +#define WM8350_DC1_ERRACT_SHIFT 14 +#define WM8350_DC1_ENSLOT_MASK 0x3C00 +#define WM8350_DC1_ENSLOT_SHIFT 10 +#define WM8350_DC1_SDSLOT_MASK 0x03C0 +#define WM8350_DC1_UVTO_MASK 0x0030 +#define WM8350_DC1_SDSLOT_SHIFT 6 + +/* Bit values for R181 (0xB5) */ +#define WM8350_DC1_ERRACT_NONE 0 +#define WM8350_DC1_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC1_ERRACT_SHUTDOWN_SYS 2 + +/* + * R182 (0xB6) - DCDC1 Low Power + */ +#define WM8350_DC1_HIB_MODE_MASK 0x7000 +#define WM8350_DC1_HIB_TRIG_MASK 0x0300 +#define WM8350_DC1_VIMG_MASK 0x007F + +/* + * R183 (0xB7) - DCDC2 Control + */ +#define WM8350_DC2_MODE 0x4000 +#define WM8350_DC2_MODE_MASK 0x4000 +#define WM8350_DC2_MODE_SHIFT 14 +#define WM8350_DC2_HIB_MODE 0x1000 +#define WM8350_DC2_HIB_MODE_MASK 0x1000 +#define WM8350_DC2_HIB_MODE_SHIFT 12 +#define WM8350_DC2_HIB_TRIG_MASK 0x0300 +#define WM8350_DC2_HIB_TRIG_SHIFT 8 +#define WM8350_DC2_ILIM 0x0040 +#define WM8350_DC2_ILIM_MASK 0x0040 +#define WM8350_DC2_ILIM_SHIFT 6 +#define WM8350_DC2_RMP_MASK 0x0018 +#define WM8350_DC2_RMP_SHIFT 3 +#define WM8350_DC2_FBSRC_MASK 0x0003 +#define WM8350_DC2_FBSRC_SHIFT 0 + +/* Bit values for R183 (0xB7) */ +#define WM8350_DC2_MODE_BOOST 0 +#define WM8350_DC2_MODE_SWITCH 1 + +#define WM8350_DC2_HIB_MODE_ACTIVE 1 +#define WM8350_DC2_HIB_MODE_DISABLE 0 + +#define WM8350_DC2_HIB_TRIG_NONE 0 +#define WM8350_DC2_HIB_TRIG_LPWR1 1 +#define WM8350_DC2_HIB_TRIG_LPWR2 2 +#define WM8350_DC2_HIB_TRIG_LPWR3 3 + +#define WM8350_DC2_ILIM_HIGH 0 +#define WM8350_DC2_ILIM_LOW 1 + +#define WM8350_DC2_RMP_30V 0 +#define WM8350_DC2_RMP_20V 1 +#define WM8350_DC2_RMP_10V 2 +#define WM8350_DC2_RMP_5V 3 + +#define WM8350_DC2_FBSRC_FB2 0 +#define WM8350_DC2_FBSRC_ISINKA 1 +#define WM8350_DC2_FBSRC_ISINKB 2 +#define WM8350_DC2_FBSRC_USB 3 + +/* + * R184 (0xB8) - DCDC2 Timeouts + */ +#define WM8350_DC2_ERRACT_MASK 0xC000 +#define WM8350_DC2_ERRACT_SHIFT 14 +#define WM8350_DC2_ENSLOT_MASK 0x3C00 +#define WM8350_DC2_ENSLOT_SHIFT 10 +#define WM8350_DC2_SDSLOT_MASK 0x03C0 +#define WM8350_DC2_UVTO_MASK 0x0030 + +/* Bit values for R184 (0xB8) */ +#define WM8350_DC2_ERRACT_NONE 0 +#define WM8350_DC2_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC2_ERRACT_SHUTDOWN_SYS 2 + +/* + * R186 (0xBA) - DCDC3 Control + */ +#define WM8350_DC3_OPFLT 0x0400 +#define WM8350_DC3_VSEL_MASK 0x007F +#define WM8350_DC3_VSEL_SHIFT 0 + +/* + * R187 (0xBB) - DCDC3 Timeouts + */ +#define WM8350_DC3_ERRACT_MASK 0xC000 +#define WM8350_DC3_ERRACT_SHIFT 14 +#define WM8350_DC3_ENSLOT_MASK 0x3C00 +#define WM8350_DC3_ENSLOT_SHIFT 10 +#define WM8350_DC3_SDSLOT_MASK 0x03C0 +#define WM8350_DC3_UVTO_MASK 0x0030 +#define WM8350_DC3_SDSLOT_SHIFT 6 + +/* Bit values for R187 (0xBB) */ +#define WM8350_DC3_ERRACT_NONE 0 +#define WM8350_DC3_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC3_ERRACT_SHUTDOWN_SYS 2 +/* + * R188 (0xBC) - DCDC3 Low Power + */ +#define WM8350_DC3_HIB_MODE_MASK 0x7000 +#define WM8350_DC3_HIB_TRIG_MASK 0x0300 +#define WM8350_DC3_VIMG_MASK 0x007F + +/* + * R189 (0xBD) - DCDC4 Control + */ +#define WM8350_DC4_OPFLT 0x0400 +#define WM8350_DC4_VSEL_MASK 0x007F +#define WM8350_DC4_VSEL_SHIFT 0 + +/* + * R190 (0xBE) - DCDC4 Timeouts + */ +#define WM8350_DC4_ERRACT_MASK 0xC000 +#define WM8350_DC4_ERRACT_SHIFT 14 +#define WM8350_DC4_ENSLOT_MASK 0x3C00 +#define WM8350_DC4_ENSLOT_SHIFT 10 +#define WM8350_DC4_SDSLOT_MASK 0x03C0 +#define WM8350_DC4_UVTO_MASK 0x0030 +#define WM8350_DC4_SDSLOT_SHIFT 6 + +/* Bit values for R190 (0xBE) */ +#define WM8350_DC4_ERRACT_NONE 0 +#define WM8350_DC4_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC4_ERRACT_SHUTDOWN_SYS 2 + +/* + * R191 (0xBF) - DCDC4 Low Power + */ +#define WM8350_DC4_HIB_MODE_MASK 0x7000 +#define WM8350_DC4_HIB_TRIG_MASK 0x0300 +#define WM8350_DC4_VIMG_MASK 0x007F + +/* + * R192 (0xC0) - DCDC5 Control + */ +#define WM8350_DC5_MODE 0x4000 +#define WM8350_DC5_MODE_MASK 0x4000 +#define WM8350_DC5_MODE_SHIFT 14 +#define WM8350_DC5_HIB_MODE 0x1000 +#define WM8350_DC5_HIB_MODE_MASK 0x1000 +#define WM8350_DC5_HIB_MODE_SHIFT 12 +#define WM8350_DC5_HIB_TRIG_MASK 0x0300 +#define WM8350_DC5_HIB_TRIG_SHIFT 8 +#define WM8350_DC5_ILIM 0x0040 +#define WM8350_DC5_ILIM_MASK 0x0040 +#define WM8350_DC5_ILIM_SHIFT 6 +#define WM8350_DC5_RMP_MASK 0x0018 +#define WM8350_DC5_RMP_SHIFT 3 +#define WM8350_DC5_FBSRC_MASK 0x0003 +#define WM8350_DC5_FBSRC_SHIFT 0 + +/* Bit values for R192 (0xC0) */ +#define WM8350_DC5_MODE_BOOST 0 +#define WM8350_DC5_MODE_SWITCH 1 + +#define WM8350_DC5_HIB_MODE_ACTIVE 1 +#define WM8350_DC5_HIB_MODE_DISABLE 0 + +#define WM8350_DC5_HIB_TRIG_NONE 0 +#define WM8350_DC5_HIB_TRIG_LPWR1 1 +#define WM8350_DC5_HIB_TRIG_LPWR2 2 +#define WM8350_DC5_HIB_TRIG_LPWR3 3 + +#define WM8350_DC5_ILIM_HIGH 0 +#define WM8350_DC5_ILIM_LOW 1 + +#define WM8350_DC5_RMP_30V 0 +#define WM8350_DC5_RMP_20V 1 +#define WM8350_DC5_RMP_10V 2 +#define WM8350_DC5_RMP_5V 3 + +#define WM8350_DC5_FBSRC_FB2 0 +#define WM8350_DC5_FBSRC_ISINKA 1 +#define WM8350_DC5_FBSRC_ISINKB 2 +#define WM8350_DC5_FBSRC_USB 3 + +/* + * R193 (0xC1) - DCDC5 Timeouts + */ +#define WM8350_DC5_ERRACT_MASK 0xC000 +#define WM8350_DC5_ERRACT_SHIFT 14 +#define WM8350_DC5_ENSLOT_MASK 0x3C00 +#define WM8350_DC5_ENSLOT_SHIFT 10 +#define WM8350_DC5_SDSLOT_MASK 0x03C0 +#define WM8350_DC5_UVTO_MASK 0x0030 +#define WM8350_DC5_SDSLOT_SHIFT 6 + +/* Bit values for R193 (0xC1) */ +#define WM8350_DC5_ERRACT_NONE 0 +#define WM8350_DC5_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC5_ERRACT_SHUTDOWN_SYS 2 + +/* + * R195 (0xC3) - DCDC6 Control + */ +#define WM8350_DC6_OPFLT 0x0400 +#define WM8350_DC6_VSEL_MASK 0x007F +#define WM8350_DC6_VSEL_SHIFT 0 + +/* + * R196 (0xC4) - DCDC6 Timeouts + */ +#define WM8350_DC6_ERRACT_MASK 0xC000 +#define WM8350_DC6_ERRACT_SHIFT 14 +#define WM8350_DC6_ENSLOT_MASK 0x3C00 +#define WM8350_DC6_ENSLOT_SHIFT 10 +#define WM8350_DC6_SDSLOT_MASK 0x03C0 +#define WM8350_DC6_UVTO_MASK 0x0030 +#define WM8350_DC6_SDSLOT_SHIFT 6 + +/* Bit values for R196 (0xC4) */ +#define WM8350_DC6_ERRACT_NONE 0 +#define WM8350_DC6_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_DC6_ERRACT_SHUTDOWN_SYS 2 + +/* + * R197 (0xC5) - DCDC6 Low Power + */ +#define WM8350_DC6_HIB_MODE_MASK 0x7000 +#define WM8350_DC6_HIB_TRIG_MASK 0x0300 +#define WM8350_DC6_VIMG_MASK 0x007F + +/* + * R199 (0xC7) - Limit Switch Control + */ +#define WM8350_LS_ERRACT_MASK 0xC000 +#define WM8350_LS_ERRACT_SHIFT 14 +#define WM8350_LS_ENSLOT_MASK 0x3C00 +#define WM8350_LS_ENSLOT_SHIFT 10 +#define WM8350_LS_SDSLOT_MASK 0x03C0 +#define WM8350_LS_SDSLOT_SHIFT 6 +#define WM8350_LS_HIB_MODE 0x0010 +#define WM8350_LS_HIB_MODE_MASK 0x0010 +#define WM8350_LS_HIB_MODE_SHIFT 4 +#define WM8350_LS_HIB_PROT 0x0002 +#define WM8350_LS_HIB_PROT_MASK 0x0002 +#define WM8350_LS_HIB_PROT_SHIFT 1 +#define WM8350_LS_PROT 0x0001 +#define WM8350_LS_PROT_MASK 0x0001 +#define WM8350_LS_PROT_SHIFT 0 + +/* Bit values for R199 (0xC7) */ +#define WM8350_LS_ERRACT_NONE 0 +#define WM8350_LS_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_LS_ERRACT_SHUTDOWN_SYS 2 + +/* + * R200 (0xC8) - LDO1 Control + */ +#define WM8350_LDO1_SWI 0x4000 +#define WM8350_LDO1_OPFLT 0x0400 +#define WM8350_LDO1_VSEL_MASK 0x001F +#define WM8350_LDO1_VSEL_SHIFT 0 + +/* + * R201 (0xC9) - LDO1 Timeouts + */ +#define WM8350_LDO1_ERRACT_MASK 0xC000 +#define WM8350_LDO1_ERRACT_SHIFT 14 +#define WM8350_LDO1_ENSLOT_MASK 0x3C00 +#define WM8350_LDO1_ENSLOT_SHIFT 10 +#define WM8350_LDO1_SDSLOT_MASK 0x03C0 +#define WM8350_LDO1_UVTO_MASK 0x0030 +#define WM8350_LDO1_SDSLOT_SHIFT 6 + +/* Bit values for R201 (0xC9) */ +#define WM8350_LDO1_ERRACT_NONE 0 +#define WM8350_LDO1_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_LDO1_ERRACT_SHUTDOWN_SYS 2 + +/* + * R202 (0xCA) - LDO1 Low Power + */ +#define WM8350_LDO1_HIB_MODE_MASK 0x3000 +#define WM8350_LDO1_HIB_TRIG_MASK 0x0300 +#define WM8350_LDO1_VIMG_MASK 0x001F +#define WM8350_LDO1_HIB_MODE_DIS (0x1 << 12) + + +/* + * R203 (0xCB) - LDO2 Control + */ +#define WM8350_LDO2_SWI 0x4000 +#define WM8350_LDO2_OPFLT 0x0400 +#define WM8350_LDO2_VSEL_MASK 0x001F +#define WM8350_LDO2_VSEL_SHIFT 0 + +/* + * R204 (0xCC) - LDO2 Timeouts + */ +#define WM8350_LDO2_ERRACT_MASK 0xC000 +#define WM8350_LDO2_ERRACT_SHIFT 14 +#define WM8350_LDO2_ENSLOT_MASK 0x3C00 +#define WM8350_LDO2_ENSLOT_SHIFT 10 +#define WM8350_LDO2_SDSLOT_MASK 0x03C0 +#define WM8350_LDO2_SDSLOT_SHIFT 6 + +/* Bit values for R204 (0xCC) */ +#define WM8350_LDO2_ERRACT_NONE 0 +#define WM8350_LDO2_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_LDO2_ERRACT_SHUTDOWN_SYS 2 + +/* + * R205 (0xCD) - LDO2 Low Power + */ +#define WM8350_LDO2_HIB_MODE_MASK 0x3000 +#define WM8350_LDO2_HIB_TRIG_MASK 0x0300 +#define WM8350_LDO2_VIMG_MASK 0x001F + +/* + * R206 (0xCE) - LDO3 Control + */ +#define WM8350_LDO3_SWI 0x4000 +#define WM8350_LDO3_OPFLT 0x0400 +#define WM8350_LDO3_VSEL_MASK 0x001F +#define WM8350_LDO3_VSEL_SHIFT 0 + +/* + * R207 (0xCF) - LDO3 Timeouts + */ +#define WM8350_LDO3_ERRACT_MASK 0xC000 +#define WM8350_LDO3_ERRACT_SHIFT 14 +#define WM8350_LDO3_ENSLOT_MASK 0x3C00 +#define WM8350_LDO3_ENSLOT_SHIFT 10 +#define WM8350_LDO3_SDSLOT_MASK 0x03C0 +#define WM8350_LDO3_UVTO_MASK 0x0030 +#define WM8350_LDO3_SDSLOT_SHIFT 6 + +/* Bit values for R207 (0xCF) */ +#define WM8350_LDO3_ERRACT_NONE 0 +#define WM8350_LDO3_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_LDO3_ERRACT_SHUTDOWN_SYS 2 + +/* + * R208 (0xD0) - LDO3 Low Power + */ +#define WM8350_LDO3_HIB_MODE_MASK 0x3000 +#define WM8350_LDO3_HIB_TRIG_MASK 0x0300 +#define WM8350_LDO3_VIMG_MASK 0x001F + +/* + * R209 (0xD1) - LDO4 Control + */ +#define WM8350_LDO4_SWI 0x4000 +#define WM8350_LDO4_OPFLT 0x0400 +#define WM8350_LDO4_VSEL_MASK 0x001F +#define WM8350_LDO4_VSEL_SHIFT 0 + +/* + * R210 (0xD2) - LDO4 Timeouts + */ +#define WM8350_LDO4_ERRACT_MASK 0xC000 +#define WM8350_LDO4_ERRACT_SHIFT 14 +#define WM8350_LDO4_ENSLOT_MASK 0x3C00 +#define WM8350_LDO4_ENSLOT_SHIFT 10 +#define WM8350_LDO4_SDSLOT_MASK 0x03C0 +#define WM8350_LDO4_UVTO_MASK 0x0030 +#define WM8350_LDO4_SDSLOT_SHIFT 6 + +/* Bit values for R210 (0xD2) */ +#define WM8350_LDO4_ERRACT_NONE 0 +#define WM8350_LDO4_ERRACT_SHUTDOWN_CONV 1 +#define WM8350_LDO4_ERRACT_SHUTDOWN_SYS 2 + +/* + * R211 (0xD3) - LDO4 Low Power + */ +#define WM8350_LDO4_HIB_MODE_MASK 0x3000 +#define WM8350_LDO4_HIB_TRIG_MASK 0x0300 +#define WM8350_LDO4_VIMG_MASK 0x001F + +/* + * R215 (0xD7) - VCC_FAULT Masks + */ +#define WM8350_LS_FAULT 0x8000 +#define WM8350_LDO4_FAULT 0x0800 +#define WM8350_LDO3_FAULT 0x0400 +#define WM8350_LDO2_FAULT 0x0200 +#define WM8350_LDO1_FAULT 0x0100 +#define WM8350_DC6_FAULT 0x0020 +#define WM8350_DC5_FAULT 0x0010 +#define WM8350_DC4_FAULT 0x0008 +#define WM8350_DC3_FAULT 0x0004 +#define WM8350_DC2_FAULT 0x0002 +#define WM8350_DC1_FAULT 0x0001 + +/* + * R216 (0xD8) - Main Bandgap Control + */ +#define WM8350_MBG_LOAD_FUSES 0x8000 +#define WM8350_MBG_FUSE_WPREP 0x4000 +#define WM8350_MBG_FUSE_WRITE 0x2000 +#define WM8350_MBG_FUSE_TRIM_MASK 0x1F00 +#define WM8350_MBG_TRIM_SRC 0x0020 +#define WM8350_MBG_USER_TRIM_MASK 0x001F + +/* + * R217 (0xD9) - OSC Control + */ +#define WM8350_OSC_LOAD_FUSES 0x8000 +#define WM8350_OSC_FUSE_WPREP 0x4000 +#define WM8350_OSC_FUSE_WRITE 0x2000 +#define WM8350_OSC_FUSE_TRIM_MASK 0x0F00 +#define WM8350_OSC_TRIM_SRC 0x0020 +#define WM8350_OSC_USER_TRIM_MASK 0x000F + +/* + * R248 (0xF8) - DCDC1 Force PWM + */ +#define WM8350_DCDC1_FORCE_PWM_ENA 0x0010 + +/* + * R250 (0xFA) - DCDC3 Force PWM + */ +#define WM8350_DCDC3_FORCE_PWM_ENA 0x0010 + +/* + * R251 (0xFB) - DCDC4 Force PWM + */ +#define WM8350_DCDC4_FORCE_PWM_ENA 0x0010 + +/* + * R253 (0xFD) - DCDC1 Force PWM + */ +#define WM8350_DCDC6_FORCE_PWM_ENA 0x0010 + +/* + * DCDC's + */ +#define WM8350_DCDC_1 0 +#define WM8350_DCDC_2 1 +#define WM8350_DCDC_3 2 +#define WM8350_DCDC_4 3 +#define WM8350_DCDC_5 4 +#define WM8350_DCDC_6 5 + +/* DCDC modes */ +#define WM8350_DCDC_ACTIVE_STANDBY 0 +#define WM8350_DCDC_ACTIVE_PULSE 1 +#define WM8350_DCDC_SLEEP_NORMAL 0 +#define WM8350_DCDC_SLEEP_LOW 1 + +/* DCDC Low power (Hibernate) mode */ +#define WM8350_DCDC_HIB_MODE_CUR (0 << 12) +#define WM8350_DCDC_HIB_MODE_IMAGE (1 << 12) +#define WM8350_DCDC_HIB_MODE_STANDBY (2 << 12) +#define WM8350_DCDC_HIB_MODE_LDO (4 << 12) +#define WM8350_DCDC_HIB_MODE_LDO_IM (5 << 12) +#define WM8350_DCDC_HIB_MODE_DIS (7 << 12) +#define WM8350_DCDC_HIB_MODE_MASK (7 << 12) + +/* DCDC Low Power (Hibernate) signal */ +#define WM8350_DCDC_HIB_SIG_REG (0 << 8) +#define WM8350_DCDC_HIB_SIG_LPWR1 (1 << 8) +#define WM8350_DCDC_HIB_SIG_LPWR2 (2 << 8) +#define WM8350_DCDC_HIB_SIG_LPWR3 (3 << 8) + +/* LDO Low power (Hibernate) mode */ +#define WM8350_LDO_HIB_MODE_IMAGE (0 << 0) +#define WM8350_LDO_HIB_MODE_DIS (1 << 0) + +/* LDO Low Power (Hibernate) signal */ +#define WM8350_LDO_HIB_SIG_REG (0 << 8) +#define WM8350_LDO_HIB_SIG_LPWR1 (1 << 8) +#define WM8350_LDO_HIB_SIG_LPWR2 (2 << 8) +#define WM8350_LDO_HIB_SIG_LPWR3 (3 << 8) + +/* + * LDOs + */ +#define WM8350_LDO_1 6 +#define WM8350_LDO_2 7 +#define WM8350_LDO_3 8 +#define WM8350_LDO_4 9 + +/* + * ISINKs + */ +#define WM8350_ISINK_A 10 +#define WM8350_ISINK_B 11 + +#define WM8350_ISINK_MODE_BOOST 0 +#define WM8350_ISINK_MODE_SWITCH 1 +#define WM8350_ISINK_ILIM_NORMAL 0 +#define WM8350_ISINK_ILIM_LOW 1 + +#define WM8350_ISINK_FLASH_DISABLE 0 +#define WM8350_ISINK_FLASH_ENABLE 1 +#define WM8350_ISINK_FLASH_TRIG_BIT 0 +#define WM8350_ISINK_FLASH_TRIG_GPIO 1 +#define WM8350_ISINK_FLASH_MODE_EN (1 << 13) +#define WM8350_ISINK_FLASH_MODE_DIS (0 << 13) +#define WM8350_ISINK_FLASH_DUR_32MS (0 << 8) +#define WM8350_ISINK_FLASH_DUR_64MS (1 << 8) +#define WM8350_ISINK_FLASH_DUR_96MS (2 << 8) +#define WM8350_ISINK_FLASH_DUR_1024MS (3 << 8) +#define WM8350_ISINK_FLASH_ON_INSTANT (0 << 4) +#define WM8350_ISINK_FLASH_ON_0_25S (1 << 4) +#define WM8350_ISINK_FLASH_ON_0_50S (2 << 4) +#define WM8350_ISINK_FLASH_ON_1_00S (3 << 4) +#define WM8350_ISINK_FLASH_ON_1_95S (1 << 4) +#define WM8350_ISINK_FLASH_ON_3_91S (2 << 4) +#define WM8350_ISINK_FLASH_ON_7_80S (3 << 4) +#define WM8350_ISINK_FLASH_OFF_INSTANT (0 << 0) +#define WM8350_ISINK_FLASH_OFF_0_25S (1 << 0) +#define WM8350_ISINK_FLASH_OFF_0_50S (2 << 0) +#define WM8350_ISINK_FLASH_OFF_1_00S (3 << 0) +#define WM8350_ISINK_FLASH_OFF_1_95S (1 << 0) +#define WM8350_ISINK_FLASH_OFF_3_91S (2 << 0) +#define WM8350_ISINK_FLASH_OFF_7_80S (3 << 0) + +/* + * Regulator Interrupts. + */ +#define WM8350_IRQ_CS1 13 +#define WM8350_IRQ_CS2 14 +#define WM8350_IRQ_UV_LDO4 25 +#define WM8350_IRQ_UV_LDO3 26 +#define WM8350_IRQ_UV_LDO2 27 +#define WM8350_IRQ_UV_LDO1 28 +#define WM8350_IRQ_UV_DC6 29 +#define WM8350_IRQ_UV_DC5 30 +#define WM8350_IRQ_UV_DC4 31 +#define WM8350_IRQ_UV_DC3 32 +#define WM8350_IRQ_UV_DC2 33 +#define WM8350_IRQ_UV_DC1 34 +#define WM8350_IRQ_OC_LS 35 + +#define NUM_WM8350_REGULATORS 12 + +#endif -- cgit v1.2.3 From f8ea79c2ab39513e90054ed2828a85759d979bfa Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:06 +0100 Subject: mfd: Add WM8350 PMU register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/supply.h | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 include/linux/mfd/wm8350/supply.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/supply.h b/include/linux/mfd/wm8350/supply.h new file mode 100644 index 00000000000..f1d4317cf02 --- /dev/null +++ b/include/linux/mfd/wm8350/supply.h @@ -0,0 +1,105 @@ +/* + * supply.h -- Power Supply Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + * + */ + +#ifndef __LINUX_MFD_WM8350_SUPPLY_H_ +#define __LINUX_MFD_WM8350_SUPPLY_H_ + +/* + * Charger registers + */ +#define WM8350_BATTERY_CHARGER_CONTROL_1 0xA8 +#define WM8350_BATTERY_CHARGER_CONTROL_2 0xA9 +#define WM8350_BATTERY_CHARGER_CONTROL_3 0xAA + +/* + * R168 (0xA8) - Battery Charger Control 1 + */ +#define WM8350_CHG_ENA_R168 0x8000 +#define WM8350_CHG_THR 0x2000 +#define WM8350_CHG_EOC_SEL_MASK 0x1C00 +#define WM8350_CHG_TRICKLE_TEMP_CHOKE 0x0200 +#define WM8350_CHG_TRICKLE_USB_CHOKE 0x0100 +#define WM8350_CHG_RECOVER_T 0x0080 +#define WM8350_CHG_END_ACT 0x0040 +#define WM8350_CHG_FAST 0x0020 +#define WM8350_CHG_FAST_USB_THROTTLE 0x0010 +#define WM8350_CHG_NTC_MON 0x0008 +#define WM8350_CHG_BATT_HOT_MON 0x0004 +#define WM8350_CHG_BATT_COLD_MON 0x0002 +#define WM8350_CHG_CHIP_TEMP_MON 0x0001 + +/* + * R169 (0xA9) - Battery Charger Control 2 + */ +#define WM8350_CHG_ACTIVE 0x8000 +#define WM8350_CHG_PAUSE 0x4000 +#define WM8350_CHG_STS_MASK 0x3000 +#define WM8350_CHG_TIME_MASK 0x0F00 +#define WM8350_CHG_MASK_WALL_FB 0x0080 +#define WM8350_CHG_TRICKLE_SEL 0x0040 +#define WM8350_CHG_VSEL_MASK 0x0030 +#define WM8350_CHG_ISEL_MASK 0x000F +#define WM8350_CHG_STS_OFF 0x0000 +#define WM8350_CHG_STS_TRICKLE 0x1000 +#define WM8350_CHG_STS_FAST 0x2000 + +/* + * R170 (0xAA) - Battery Charger Control 3 + */ +#define WM8350_CHG_THROTTLE_T_MASK 0x0060 +#define WM8350_CHG_SMART 0x0010 +#define WM8350_CHG_TIMER_ADJT_MASK 0x000F + +/* + * Charger Interrupts + */ +#define WM8350_IRQ_CHG_BAT_HOT 0 +#define WM8350_IRQ_CHG_BAT_COLD 1 +#define WM8350_IRQ_CHG_BAT_FAIL 2 +#define WM8350_IRQ_CHG_TO 3 +#define WM8350_IRQ_CHG_END 4 +#define WM8350_IRQ_CHG_START 5 +#define WM8350_IRQ_CHG_FAST_RDY 6 +#define WM8350_IRQ_CHG_VBATT_LT_3P9 10 +#define WM8350_IRQ_CHG_VBATT_LT_3P1 11 +#define WM8350_IRQ_CHG_VBATT_LT_2P85 12 + +/* + * Charger Policy + */ +#define WM8350_CHG_TRICKLE_50mA (0 << 6) +#define WM8350_CHG_TRICKLE_100mA (1 << 6) +#define WM8350_CHG_4_05V (0 << 4) +#define WM8350_CHG_4_10V (1 << 4) +#define WM8350_CHG_4_15V (2 << 4) +#define WM8350_CHG_4_20V (3 << 4) +#define WM8350_CHG_FAST_LIMIT_mA(x) ((x / 50) & 0xf) +#define WM8350_CHG_EOC_mA(x) (((x - 10) & 0x7) << 10) +#define WM8350_CHG_TRICKLE_3_1V (0 << 13) +#define WM8350_CHG_TRICKLE_3_9V (1 << 13) + +/* + * Supply Registers. + */ +#define WM8350_USB_VOLTAGE_READBACK 0x9C +#define WM8350_LINE_VOLTAGE_READBACK 0x9D +#define WM8350_BATT_VOLTAGE_READBACK 0x9E + +/* + * Supply Interrupts. + */ +#define WM8350_IRQ_USB_LIMIT 15 +#define WM8350_IRQ_EXT_USB_FB 36 +#define WM8350_IRQ_EXT_WALL_FB 37 +#define WM8350_IRQ_EXT_BAT_FB 38 + +#endif -- cgit v1.2.3 From e7aabc346b111ae2ebcd390dcca7200a3361bb62 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:07 +0100 Subject: mfd: Add WM8350 comparator register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/comparator.h | 167 ++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 include/linux/mfd/wm8350/comparator.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/comparator.h b/include/linux/mfd/wm8350/comparator.h new file mode 100644 index 00000000000..05378864945 --- /dev/null +++ b/include/linux/mfd/wm8350/comparator.h @@ -0,0 +1,167 @@ +/* + * comparator.h -- Comparator Aux ADC for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + */ + +#ifndef __LINUX_MFD_WM8350_COMPARATOR_H_ +#define __LINUX_MFD_WM8350_COMPARATOR_H_ + +/* + * Registers + */ + +#define WM8350_DIGITISER_CONTROL_1 0x90 +#define WM8350_DIGITISER_CONTROL_2 0x91 +#define WM8350_AUX1_READBACK 0x98 +#define WM8350_AUX2_READBACK 0x99 +#define WM8350_AUX3_READBACK 0x9A +#define WM8350_AUX4_READBACK 0x9B +#define WM8350_CHIP_TEMP_READBACK 0x9F +#define WM8350_GENERIC_COMPARATOR_CONTROL 0xA3 +#define WM8350_GENERIC_COMPARATOR_1 0xA4 +#define WM8350_GENERIC_COMPARATOR_2 0xA5 +#define WM8350_GENERIC_COMPARATOR_3 0xA6 +#define WM8350_GENERIC_COMPARATOR_4 0xA7 + +/* + * R144 (0x90) - Digitiser Control (1) + */ +#define WM8350_AUXADC_CTC 0x4000 +#define WM8350_AUXADC_POLL 0x2000 +#define WM8350_AUXADC_HIB_MODE 0x1000 +#define WM8350_AUXADC_SEL8 0x0080 +#define WM8350_AUXADC_SEL7 0x0040 +#define WM8350_AUXADC_SEL6 0x0020 +#define WM8350_AUXADC_SEL5 0x0010 +#define WM8350_AUXADC_SEL4 0x0008 +#define WM8350_AUXADC_SEL3 0x0004 +#define WM8350_AUXADC_SEL2 0x0002 +#define WM8350_AUXADC_SEL1 0x0001 + +/* + * R145 (0x91) - Digitiser Control (2) + */ +#define WM8350_AUXADC_MASKMODE_MASK 0x3000 +#define WM8350_AUXADC_CRATE_MASK 0x0700 +#define WM8350_AUXADC_CAL 0x0004 +#define WM8350_AUX_RBMODE 0x0002 +#define WM8350_AUXADC_WAIT 0x0001 + +/* + * R152 (0x98) - AUX1 Readback + */ +#define WM8350_AUXADC_SCALE1_MASK 0x6000 +#define WM8350_AUXADC_REF1 0x1000 +#define WM8350_AUXADC_DATA1_MASK 0x0FFF + +/* + * R153 (0x99) - AUX2 Readback + */ +#define WM8350_AUXADC_SCALE2_MASK 0x6000 +#define WM8350_AUXADC_REF2 0x1000 +#define WM8350_AUXADC_DATA2_MASK 0x0FFF + +/* + * R154 (0x9A) - AUX3 Readback + */ +#define WM8350_AUXADC_SCALE3_MASK 0x6000 +#define WM8350_AUXADC_REF3 0x1000 +#define WM8350_AUXADC_DATA3_MASK 0x0FFF + +/* + * R155 (0x9B) - AUX4 Readback + */ +#define WM8350_AUXADC_SCALE4_MASK 0x6000 +#define WM8350_AUXADC_REF4 0x1000 +#define WM8350_AUXADC_DATA4_MASK 0x0FFF + +/* + * R156 (0x9C) - USB Voltage Readback + */ +#define WM8350_AUXADC_DATA_USB_MASK 0x0FFF + +/* + * R157 (0x9D) - LINE Voltage Readback + */ +#define WM8350_AUXADC_DATA_LINE_MASK 0x0FFF + +/* + * R158 (0x9E) - BATT Voltage Readback + */ +#define WM8350_AUXADC_DATA_BATT_MASK 0x0FFF + +/* + * R159 (0x9F) - Chip Temp Readback + */ +#define WM8350_AUXADC_DATA_CHIPTEMP_MASK 0x0FFF + +/* + * R163 (0xA3) - Generic Comparator Control + */ +#define WM8350_DCMP4_ENA 0x0008 +#define WM8350_DCMP3_ENA 0x0004 +#define WM8350_DCMP2_ENA 0x0002 +#define WM8350_DCMP1_ENA 0x0001 + +/* + * R164 (0xA4) - Generic comparator 1 + */ +#define WM8350_DCMP1_SRCSEL_MASK 0xE000 +#define WM8350_DCMP1_GT 0x1000 +#define WM8350_DCMP1_THR_MASK 0x0FFF + +/* + * R165 (0xA5) - Generic comparator 2 + */ +#define WM8350_DCMP2_SRCSEL_MASK 0xE000 +#define WM8350_DCMP2_GT 0x1000 +#define WM8350_DCMP2_THR_MASK 0x0FFF + +/* + * R166 (0xA6) - Generic comparator 3 + */ +#define WM8350_DCMP3_SRCSEL_MASK 0xE000 +#define WM8350_DCMP3_GT 0x1000 +#define WM8350_DCMP3_THR_MASK 0x0FFF + +/* + * R167 (0xA7) - Generic comparator 4 + */ +#define WM8350_DCMP4_SRCSEL_MASK 0xE000 +#define WM8350_DCMP4_GT 0x1000 +#define WM8350_DCMP4_THR_MASK 0x0FFF + +/* + * Interrupts. + */ +#define WM8350_IRQ_AUXADC_DATARDY 16 +#define WM8350_IRQ_AUXADC_DCOMP4 17 +#define WM8350_IRQ_AUXADC_DCOMP3 18 +#define WM8350_IRQ_AUXADC_DCOMP2 19 +#define WM8350_IRQ_AUXADC_DCOMP1 20 +#define WM8350_IRQ_SYS_HYST_COMP_FAIL 21 +#define WM8350_IRQ_SYS_CHIP_GT115 22 +#define WM8350_IRQ_SYS_CHIP_GT140 23 + +/* + * USB/2, LINE & BATT = ((VRTC * 2) / 4095)) * 10e6 uV + * Where VRTC = 2.7 V + */ +#define WM8350_AUX_COEFF 1319 + +#define WM8350_AUXADC_AUX1 0 +#define WM8350_AUXADC_AUX2 1 +#define WM8350_AUXADC_AUX3 2 +#define WM8350_AUXADC_AUX4 3 +#define WM8350_AUXADC_USB 4 +#define WM8350_AUXADC_LINE 5 +#define WM8350_AUXADC_BATT 6 +#define WM8350_AUXADC_TEMP 7 + +#endif -- cgit v1.2.3 From 64a91ce93499dad945c4725d39b52f734d31b742 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:08 +0100 Subject: mfd: Add WM8350 RTC register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/rtc.h | 260 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 include/linux/mfd/wm8350/rtc.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h new file mode 100644 index 00000000000..cb337ea8082 --- /dev/null +++ b/include/linux/mfd/wm8350/rtc.h @@ -0,0 +1,260 @@ +/* + * rtc.h -- RTC driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + */ + +#ifndef __LINUX_MFD_WM8350_RTC_H +#define __LINUX_MFD_WM8350_RTC_H + +/* + * Register values. + */ +#define WM8350_RTC_SECONDS_MINUTES 0x10 +#define WM8350_RTC_HOURS_DAY 0x11 +#define WM8350_RTC_DATE_MONTH 0x12 +#define WM8350_RTC_YEAR 0x13 +#define WM8350_ALARM_SECONDS_MINUTES 0x14 +#define WM8350_ALARM_HOURS_DAY 0x15 +#define WM8350_ALARM_DATE_MONTH 0x16 +#define WM8350_RTC_TIME_CONTROL 0x17 + +/* + * R16 (0x10) - RTC Seconds/Minutes + */ +#define WM8350_RTC_MINS_MASK 0x7F00 +#define WM8350_RTC_MINS_SHIFT 8 +#define WM8350_RTC_SECS_MASK 0x007F +#define WM8350_RTC_SECS_SHIFT 0 + +/* + * R17 (0x11) - RTC Hours/Day + */ +#define WM8350_RTC_DAY_MASK 0x0700 +#define WM8350_RTC_DAY_SHIFT 8 +#define WM8350_RTC_HPM_MASK 0x0020 +#define WM8350_RTC_HPM_SHIFT 5 +#define WM8350_RTC_HRS_MASK 0x001F +#define WM8350_RTC_HRS_SHIFT 0 + +/* Bit values for R21 (0x15) */ +#define WM8350_RTC_DAY_SUN 1 +#define WM8350_RTC_DAY_MON 2 +#define WM8350_RTC_DAY_TUE 3 +#define WM8350_RTC_DAY_WED 4 +#define WM8350_RTC_DAY_THU 5 +#define WM8350_RTC_DAY_FRI 6 +#define WM8350_RTC_DAY_SAT 7 + +#define WM8350_RTC_HPM_AM 0 +#define WM8350_RTC_HPM_PM 1 + +/* + * R18 (0x12) - RTC Date/Month + */ +#define WM8350_RTC_MTH_MASK 0x1F00 +#define WM8350_RTC_MTH_SHIFT 8 +#define WM8350_RTC_DATE_MASK 0x003F +#define WM8350_RTC_DATE_SHIFT 0 + +/* Bit values for R22 (0x16) */ +#define WM8350_RTC_MTH_JAN 1 +#define WM8350_RTC_MTH_FEB 2 +#define WM8350_RTC_MTH_MAR 3 +#define WM8350_RTC_MTH_APR 4 +#define WM8350_RTC_MTH_MAY 5 +#define WM8350_RTC_MTH_JUN 6 +#define WM8350_RTC_MTH_JUL 7 +#define WM8350_RTC_MTH_AUG 8 +#define WM8350_RTC_MTH_SEP 9 +#define WM8350_RTC_MTH_OCT 10 +#define WM8350_RTC_MTH_NOV 11 +#define WM8350_RTC_MTH_DEC 12 +#define WM8350_RTC_MTH_JAN_BCD 0x01 +#define WM8350_RTC_MTH_FEB_BCD 0x02 +#define WM8350_RTC_MTH_MAR_BCD 0x03 +#define WM8350_RTC_MTH_APR_BCD 0x04 +#define WM8350_RTC_MTH_MAY_BCD 0x05 +#define WM8350_RTC_MTH_JUN_BCD 0x06 +#define WM8350_RTC_MTH_JUL_BCD 0x07 +#define WM8350_RTC_MTH_AUG_BCD 0x08 +#define WM8350_RTC_MTH_SEP_BCD 0x09 +#define WM8350_RTC_MTH_OCT_BCD 0x10 +#define WM8350_RTC_MTH_NOV_BCD 0x11 +#define WM8350_RTC_MTH_DEC_BCD 0x12 + +/* + * R19 (0x13) - RTC Year + */ +#define WM8350_RTC_YHUNDREDS_MASK 0x3F00 +#define WM8350_RTC_YHUNDREDS_SHIFT 8 +#define WM8350_RTC_YUNITS_MASK 0x00FF +#define WM8350_RTC_YUNITS_SHIFT 0 + +/* + * R20 (0x14) - Alarm Seconds/Minutes + */ +#define WM8350_RTC_ALMMINS_MASK 0x7F00 +#define WM8350_RTC_ALMMINS_SHIFT 8 +#define WM8350_RTC_ALMSECS_MASK 0x007F +#define WM8350_RTC_ALMSECS_SHIFT 0 + +/* Bit values for R20 (0x14) */ +#define WM8350_RTC_ALMMINS_DONT_CARE -1 +#define WM8350_RTC_ALMSECS_DONT_CARE -1 + +/* + * R21 (0x15) - Alarm Hours/Day + */ +#define WM8350_RTC_ALMDAY_MASK 0x0F00 +#define WM8350_RTC_ALMDAY_SHIFT 8 +#define WM8350_RTC_ALMHPM_MASK 0x0020 +#define WM8350_RTC_ALMHPM_SHIFT 5 +#define WM8350_RTC_ALMHRS_MASK 0x001F +#define WM8350_RTC_ALMHRS_SHIFT 0 + +/* Bit values for R21 (0x15) */ +#define WM8350_RTC_ALMDAY_DONT_CARE -1 +#define WM8350_RTC_ALMDAY_SUN 1 +#define WM8350_RTC_ALMDAY_MON 2 +#define WM8350_RTC_ALMDAY_TUE 3 +#define WM8350_RTC_ALMDAY_WED 4 +#define WM8350_RTC_ALMDAY_THU 5 +#define WM8350_RTC_ALMDAY_FRI 6 +#define WM8350_RTC_ALMDAY_SAT 7 + +#define WM8350_RTC_ALMHPM_AM 0 +#define WM8350_RTC_ALMHPM_PM 1 + +#define WM8350_RTC_ALMHRS_DONT_CARE -1 + +/* + * R22 (0x16) - Alarm Date/Month + */ +#define WM8350_RTC_ALMMTH_MASK 0x1F00 +#define WM8350_RTC_ALMMTH_SHIFT 8 +#define WM8350_RTC_ALMDATE_MASK 0x003F +#define WM8350_RTC_ALMDATE_SHIFT 0 + +/* Bit values for R22 (0x16) */ +#define WM8350_RTC_ALMDATE_DONT_CARE -1 + +#define WM8350_RTC_ALMMTH_DONT_CARE -1 +#define WM8350_RTC_ALMMTH_JAN 1 +#define WM8350_RTC_ALMMTH_FEB 2 +#define WM8350_RTC_ALMMTH_MAR 3 +#define WM8350_RTC_ALMMTH_APR 4 +#define WM8350_RTC_ALMMTH_MAY 5 +#define WM8350_RTC_ALMMTH_JUN 6 +#define WM8350_RTC_ALMMTH_JUL 7 +#define WM8350_RTC_ALMMTH_AUG 8 +#define WM8350_RTC_ALMMTH_SEP 9 +#define WM8350_RTC_ALMMTH_OCT 10 +#define WM8350_RTC_ALMMTH_NOV 11 +#define WM8350_RTC_ALMMTH_DEC 12 +#define WM8350_RTC_ALMMTH_JAN_BCD 0x01 +#define WM8350_RTC_ALMMTH_FEB_BCD 0x02 +#define WM8350_RTC_ALMMTH_MAR_BCD 0x03 +#define WM8350_RTC_ALMMTH_APR_BCD 0x04 +#define WM8350_RTC_ALMMTH_MAY_BCD 0x05 +#define WM8350_RTC_ALMMTH_JUN_BCD 0x06 +#define WM8350_RTC_ALMMTH_JUL_BCD 0x07 +#define WM8350_RTC_ALMMTH_AUG_BCD 0x08 +#define WM8350_RTC_ALMMTH_SEP_BCD 0x09 +#define WM8350_RTC_ALMMTH_OCT_BCD 0x10 +#define WM8350_RTC_ALMMTH_NOV_BCD 0x11 +#define WM8350_RTC_ALMMTH_DEC_BCD 0x12 + +/* + * R23 (0x17) - RTC Time Control + */ +#define WM8350_RTC_BCD 0x8000 +#define WM8350_RTC_BCD_MASK 0x8000 +#define WM8350_RTC_BCD_SHIFT 15 +#define WM8350_RTC_12HR 0x4000 +#define WM8350_RTC_12HR_MASK 0x4000 +#define WM8350_RTC_12HR_SHIFT 14 +#define WM8350_RTC_DST 0x2000 +#define WM8350_RTC_DST_MASK 0x2000 +#define WM8350_RTC_DST_SHIFT 13 +#define WM8350_RTC_SET 0x0800 +#define WM8350_RTC_SET_MASK 0x0800 +#define WM8350_RTC_SET_SHIFT 11 +#define WM8350_RTC_STS 0x0400 +#define WM8350_RTC_STS_MASK 0x0400 +#define WM8350_RTC_STS_SHIFT 10 +#define WM8350_RTC_ALMSET 0x0200 +#define WM8350_RTC_ALMSET_MASK 0x0200 +#define WM8350_RTC_ALMSET_SHIFT 9 +#define WM8350_RTC_ALMSTS 0x0100 +#define WM8350_RTC_ALMSTS_MASK 0x0100 +#define WM8350_RTC_ALMSTS_SHIFT 8 +#define WM8350_RTC_PINT 0x0070 +#define WM8350_RTC_PINT_MASK 0x0070 +#define WM8350_RTC_PINT_SHIFT 4 +#define WM8350_RTC_DSW 0x000F +#define WM8350_RTC_DSW_MASK 0x000F +#define WM8350_RTC_DSW_SHIFT 0 + +/* Bit values for R23 (0x17) */ +#define WM8350_RTC_BCD_BINARY 0 +#define WM8350_RTC_BCD_BCD 1 + +#define WM8350_RTC_12HR_24HR 0 +#define WM8350_RTC_12HR_12HR 1 + +#define WM8350_RTC_DST_DISABLED 0 +#define WM8350_RTC_DST_ENABLED 1 + +#define WM8350_RTC_SET_RUN 0 +#define WM8350_RTC_SET_SET 1 + +#define WM8350_RTC_STS_RUNNING 0 +#define WM8350_RTC_STS_STOPPED 1 + +#define WM8350_RTC_ALMSET_RUN 0 +#define WM8350_RTC_ALMSET_SET 1 + +#define WM8350_RTC_ALMSTS_RUNNING 0 +#define WM8350_RTC_ALMSTS_STOPPED 1 + +#define WM8350_RTC_PINT_DISABLED 0 +#define WM8350_RTC_PINT_SECS 1 +#define WM8350_RTC_PINT_MINS 2 +#define WM8350_RTC_PINT_HRS 3 +#define WM8350_RTC_PINT_DAYS 4 +#define WM8350_RTC_PINT_MTHS 5 + +#define WM8350_RTC_DSW_DISABLED 0 +#define WM8350_RTC_DSW_1HZ 1 +#define WM8350_RTC_DSW_2HZ 2 +#define WM8350_RTC_DSW_4HZ 3 +#define WM8350_RTC_DSW_8HZ 4 +#define WM8350_RTC_DSW_16HZ 5 +#define WM8350_RTC_DSW_32HZ 6 +#define WM8350_RTC_DSW_64HZ 7 +#define WM8350_RTC_DSW_128HZ 8 +#define WM8350_RTC_DSW_256HZ 9 +#define WM8350_RTC_DSW_512HZ 10 +#define WM8350_RTC_DSW_1024HZ 11 + +/* + * R218 (0xDA) - RTC Tick Control + */ +#define WM8350_RTC_TICKSTS 0x4000 +#define WM8350_RTC_CLKSRC 0x2000 +#define WM8350_RTC_TRIM_MASK 0x03FF + +/* + * RTC Interrupts. + */ +#define WM8350_IRQ_RTC_PER 7 +#define WM8350_IRQ_RTC_SEC 8 +#define WM8350_IRQ_RTC_ALM 9 + +#endif -- cgit v1.2.3 From 213f326810b6852bc54f38fd8bb71793f70f2c7a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:09 +0100 Subject: mfd: Add WM8350 watchdog register definitions Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/wdt.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 include/linux/mfd/wm8350/wdt.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/wdt.h b/include/linux/mfd/wm8350/wdt.h new file mode 100644 index 00000000000..72fc9f55456 --- /dev/null +++ b/include/linux/mfd/wm8350/wdt.h @@ -0,0 +1,22 @@ +/* + * wdt.h -- Watchdog Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + */ + +#ifndef __LINUX_MFD_WM8350_WDT_H_ +#define __LINUX_MFD_WM8350_WDT_H_ + +#define WM8350_WDOG_HIB_MODE 0x0080 +#define WM8350_WDOG_DEBUG 0x0040 +#define WM8350_WDOG_MODE_MASK 0x0030 +#define WM8350_WDOG_TO_MASK 0x0007 + +#define WM8350_IRQ_SYS_WDOG_TO 24 + +#endif -- cgit v1.2.3 From 89b4012befb1abca5e86d232bc0e2a797b0d9825 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:10 +0100 Subject: mfd: Core support for the WM8350 AudioPlus PMIC The WM8350 is an integrated audio and power management subsystem intended for use as the primary PMIC in mobile multimedia applications. The WM8350 can be controlled via either I2C or SPI - the control interface is provided by a separate module in order to allow greatest flexibility in configuring the kernel. This driver was originally written by Liam Girdwood and has since been updated to current kernel APIs and split up for submission by me. All the heavy lifting here was done by Liam. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/core.h | 585 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 585 insertions(+) create mode 100644 include/linux/mfd/wm8350/core.h (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h new file mode 100644 index 00000000000..94778c1669d --- /dev/null +++ b/include/linux/mfd/wm8350/core.h @@ -0,0 +1,585 @@ +/* + * core.h -- Core Driver for Wolfson WM8350 PMIC + * + * Copyright 2007 Wolfson Microelectronics PLC + * + * 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. + * + */ + +#ifndef __LINUX_MFD_WM8350_CORE_H_ +#define __LINUX_MFD_WM8350_CORE_H_ + +#include +#include +#include + +/* + * Register values. + */ +#define WM8350_RESET_ID 0x00 +#define WM8350_ID 0x01 +#define WM8350_SYSTEM_CONTROL_1 0x03 +#define WM8350_SYSTEM_CONTROL_2 0x04 +#define WM8350_SYSTEM_HIBERNATE 0x05 +#define WM8350_INTERFACE_CONTROL 0x06 +#define WM8350_POWER_MGMT_1 0x08 +#define WM8350_POWER_MGMT_2 0x09 +#define WM8350_POWER_MGMT_3 0x0A +#define WM8350_POWER_MGMT_4 0x0B +#define WM8350_POWER_MGMT_5 0x0C +#define WM8350_POWER_MGMT_6 0x0D +#define WM8350_POWER_MGMT_7 0x0E + +#define WM8350_SYSTEM_INTERRUPTS 0x18 +#define WM8350_INT_STATUS_1 0x19 +#define WM8350_INT_STATUS_2 0x1A +#define WM8350_POWER_UP_INT_STATUS 0x1B +#define WM8350_UNDER_VOLTAGE_INT_STATUS 0x1C +#define WM8350_OVER_CURRENT_INT_STATUS 0x1D +#define WM8350_GPIO_INT_STATUS 0x1E +#define WM8350_COMPARATOR_INT_STATUS 0x1F +#define WM8350_SYSTEM_INTERRUPTS_MASK 0x20 +#define WM8350_INT_STATUS_1_MASK 0x21 +#define WM8350_INT_STATUS_2_MASK 0x22 +#define WM8350_POWER_UP_INT_STATUS_MASK 0x23 +#define WM8350_UNDER_VOLTAGE_INT_STATUS_MASK 0x24 +#define WM8350_OVER_CURRENT_INT_STATUS_MASK 0x25 +#define WM8350_GPIO_INT_STATUS_MASK 0x26 +#define WM8350_COMPARATOR_INT_STATUS_MASK 0x27 + +#define WM8350_MAX_REGISTER 0xFF + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Reset/ID + */ +#define WM8350_SW_RESET_CHIP_ID_MASK 0xFFFF + +/* + * R1 (0x01) - ID + */ +#define WM8350_CHIP_REV_MASK 0x7000 +#define WM8350_CONF_STS_MASK 0x0C00 +#define WM8350_CUST_ID_MASK 0x00FF + +/* + * R3 (0x03) - System Control 1 + */ +#define WM8350_CHIP_ON 0x8000 +#define WM8350_POWERCYCLE 0x2000 +#define WM8350_VCC_FAULT_OV 0x1000 +#define WM8350_REG_RSTB_TIME_MASK 0x0C00 +#define WM8350_BG_SLEEP 0x0200 +#define WM8350_MEM_VALID 0x0020 +#define WM8350_CHIP_SET_UP 0x0010 +#define WM8350_ON_DEB_T 0x0008 +#define WM8350_ON_POL 0x0002 +#define WM8350_IRQ_POL 0x0001 + +/* + * R4 (0x04) - System Control 2 + */ +#define WM8350_USB_SUSPEND_8MA 0x8000 +#define WM8350_USB_SUSPEND 0x4000 +#define WM8350_USB_MSTR 0x2000 +#define WM8350_USB_MSTR_SRC 0x1000 +#define WM8350_USB_500MA 0x0800 +#define WM8350_USB_NOLIM 0x0400 + +/* + * R5 (0x05) - System Hibernate + */ +#define WM8350_HIBERNATE 0x8000 +#define WM8350_WDOG_HIB_MODE 0x0080 +#define WM8350_REG_HIB_STARTUP_SEQ 0x0040 +#define WM8350_REG_RESET_HIB_MODE 0x0020 +#define WM8350_RST_HIB_MODE 0x0010 +#define WM8350_IRQ_HIB_MODE 0x0008 +#define WM8350_MEMRST_HIB_MODE 0x0004 +#define WM8350_PCCOMP_HIB_MODE 0x0002 +#define WM8350_TEMPMON_HIB_MODE 0x0001 + +/* + * R6 (0x06) - Interface Control + */ +#define WM8350_USE_DEV_PINS 0x8000 +#define WM8350_USE_DEV_PINS_MASK 0x8000 +#define WM8350_USE_DEV_PINS_SHIFT 15 +#define WM8350_DEV_ADDR_MASK 0x6000 +#define WM8350_DEV_ADDR_SHIFT 13 +#define WM8350_CONFIG_DONE 0x1000 +#define WM8350_CONFIG_DONE_MASK 0x1000 +#define WM8350_CONFIG_DONE_SHIFT 12 +#define WM8350_RECONFIG_AT_ON 0x0800 +#define WM8350_RECONFIG_AT_ON_MASK 0x0800 +#define WM8350_RECONFIG_AT_ON_SHIFT 11 +#define WM8350_AUTOINC 0x0200 +#define WM8350_AUTOINC_MASK 0x0200 +#define WM8350_AUTOINC_SHIFT 9 +#define WM8350_ARA 0x0100 +#define WM8350_ARA_MASK 0x0100 +#define WM8350_ARA_SHIFT 8 +#define WM8350_SPI_CFG 0x0008 +#define WM8350_SPI_CFG_MASK 0x0008 +#define WM8350_SPI_CFG_SHIFT 3 +#define WM8350_SPI_4WIRE 0x0004 +#define WM8350_SPI_4WIRE_MASK 0x0004 +#define WM8350_SPI_4WIRE_SHIFT 2 +#define WM8350_SPI_3WIRE 0x0002 +#define WM8350_SPI_3WIRE_MASK 0x0002 +#define WM8350_SPI_3WIRE_SHIFT 1 + +/* Bit values for R06 (0x06) */ +#define WM8350_USE_DEV_PINS_PRIMARY 0 +#define WM8350_USE_DEV_PINS_DEV 1 + +#define WM8350_DEV_ADDR_34 0 +#define WM8350_DEV_ADDR_36 1 +#define WM8350_DEV_ADDR_3C 2 +#define WM8350_DEV_ADDR_3E 3 + +#define WM8350_CONFIG_DONE_OFF 0 +#define WM8350_CONFIG_DONE_DONE 1 + +#define WM8350_RECONFIG_AT_ON_OFF 0 +#define WM8350_RECONFIG_AT_ON_ON 1 + +#define WM8350_AUTOINC_OFF 0 +#define WM8350_AUTOINC_ON 1 + +#define WM8350_ARA_OFF 0 +#define WM8350_ARA_ON 1 + +#define WM8350_SPI_CFG_CMOS 0 +#define WM8350_SPI_CFG_OD 1 + +#define WM8350_SPI_4WIRE_3WIRE 0 +#define WM8350_SPI_4WIRE_4WIRE 1 + +#define WM8350_SPI_3WIRE_I2C 0 +#define WM8350_SPI_3WIRE_SPI 1 + +/* + * R8 (0x08) - Power mgmt (1) + */ +#define WM8350_CODEC_ISEL_MASK 0xC000 +#define WM8350_VBUFEN 0x2000 +#define WM8350_OUTPUT_DRAIN_EN 0x0400 +#define WM8350_MIC_DET_ENA 0x0100 +#define WM8350_BIASEN 0x0020 +#define WM8350_MICBEN 0x0010 +#define WM8350_VMIDEN 0x0004 +#define WM8350_VMID_MASK 0x0003 +#define WM8350_VMID_SHIFT 0 + +/* + * R9 (0x09) - Power mgmt (2) + */ +#define WM8350_IN3R_ENA 0x0800 +#define WM8350_IN3L_ENA 0x0400 +#define WM8350_INR_ENA 0x0200 +#define WM8350_INL_ENA 0x0100 +#define WM8350_MIXINR_ENA 0x0080 +#define WM8350_MIXINL_ENA 0x0040 +#define WM8350_OUT4_ENA 0x0020 +#define WM8350_OUT3_ENA 0x0010 +#define WM8350_MIXOUTR_ENA 0x0002 +#define WM8350_MIXOUTL_ENA 0x0001 + +/* + * R10 (0x0A) - Power mgmt (3) + */ +#define WM8350_IN3R_TO_OUT2R 0x0080 +#define WM8350_OUT2R_ENA 0x0008 +#define WM8350_OUT2L_ENA 0x0004 +#define WM8350_OUT1R_ENA 0x0002 +#define WM8350_OUT1L_ENA 0x0001 + +/* + * R11 (0x0B) - Power mgmt (4) + */ +#define WM8350_SYSCLK_ENA 0x4000 +#define WM8350_ADC_HPF_ENA 0x2000 +#define WM8350_FLL_ENA 0x0800 +#define WM8350_FLL_OSC_ENA 0x0400 +#define WM8350_TOCLK_ENA 0x0100 +#define WM8350_DACR_ENA 0x0020 +#define WM8350_DACL_ENA 0x0010 +#define WM8350_ADCR_ENA 0x0008 +#define WM8350_ADCL_ENA 0x0004 + +/* + * R12 (0x0C) - Power mgmt (5) + */ +#define WM8350_CODEC_ENA 0x1000 +#define WM8350_RTC_TICK_ENA 0x0800 +#define WM8350_OSC32K_ENA 0x0400 +#define WM8350_CHG_ENA 0x0200 +#define WM8350_ACC_DET_ENA 0x0100 +#define WM8350_AUXADC_ENA 0x0080 +#define WM8350_DCMP4_ENA 0x0008 +#define WM8350_DCMP3_ENA 0x0004 +#define WM8350_DCMP2_ENA 0x0002 +#define WM8350_DCMP1_ENA 0x0001 + +/* + * R13 (0x0D) - Power mgmt (6) + */ +#define WM8350_LS_ENA 0x8000 +#define WM8350_LDO4_ENA 0x0800 +#define WM8350_LDO3_ENA 0x0400 +#define WM8350_LDO2_ENA 0x0200 +#define WM8350_LDO1_ENA 0x0100 +#define WM8350_DC6_ENA 0x0020 +#define WM8350_DC5_ENA 0x0010 +#define WM8350_DC4_ENA 0x0008 +#define WM8350_DC3_ENA 0x0004 +#define WM8350_DC2_ENA 0x0002 +#define WM8350_DC1_ENA 0x0001 + +/* + * R14 (0x0E) - Power mgmt (7) + */ +#define WM8350_CS2_ENA 0x0002 +#define WM8350_CS1_ENA 0x0001 + +/* + * R24 (0x18) - System Interrupts + */ +#define WM8350_OC_INT 0x2000 +#define WM8350_UV_INT 0x1000 +#define WM8350_PUTO_INT 0x0800 +#define WM8350_CS_INT 0x0200 +#define WM8350_EXT_INT 0x0100 +#define WM8350_CODEC_INT 0x0080 +#define WM8350_GP_INT 0x0040 +#define WM8350_AUXADC_INT 0x0020 +#define WM8350_RTC_INT 0x0010 +#define WM8350_SYS_INT 0x0008 +#define WM8350_CHG_INT 0x0004 +#define WM8350_USB_INT 0x0002 +#define WM8350_WKUP_INT 0x0001 + +/* + * R25 (0x19) - Interrupt Status 1 + */ +#define WM8350_CHG_BAT_HOT_EINT 0x8000 +#define WM8350_CHG_BAT_COLD_EINT 0x4000 +#define WM8350_CHG_BAT_FAIL_EINT 0x2000 +#define WM8350_CHG_TO_EINT 0x1000 +#define WM8350_CHG_END_EINT 0x0800 +#define WM8350_CHG_START_EINT 0x0400 +#define WM8350_CHG_FAST_RDY_EINT 0x0200 +#define WM8350_RTC_PER_EINT 0x0080 +#define WM8350_RTC_SEC_EINT 0x0040 +#define WM8350_RTC_ALM_EINT 0x0020 +#define WM8350_CHG_VBATT_LT_3P9_EINT 0x0004 +#define WM8350_CHG_VBATT_LT_3P1_EINT 0x0002 +#define WM8350_CHG_VBATT_LT_2P85_EINT 0x0001 + +/* + * R26 (0x1A) - Interrupt Status 2 + */ +#define WM8350_CS1_EINT 0x2000 +#define WM8350_CS2_EINT 0x1000 +#define WM8350_USB_LIMIT_EINT 0x0400 +#define WM8350_AUXADC_DATARDY_EINT 0x0100 +#define WM8350_AUXADC_DCOMP4_EINT 0x0080 +#define WM8350_AUXADC_DCOMP3_EINT 0x0040 +#define WM8350_AUXADC_DCOMP2_EINT 0x0020 +#define WM8350_AUXADC_DCOMP1_EINT 0x0010 +#define WM8350_SYS_HYST_COMP_FAIL_EINT 0x0008 +#define WM8350_SYS_CHIP_GT115_EINT 0x0004 +#define WM8350_SYS_CHIP_GT140_EINT 0x0002 +#define WM8350_SYS_WDOG_TO_EINT 0x0001 + +/* + * R27 (0x1B) - Power Up Interrupt Status + */ +#define WM8350_PUTO_LDO4_EINT 0x0800 +#define WM8350_PUTO_LDO3_EINT 0x0400 +#define WM8350_PUTO_LDO2_EINT 0x0200 +#define WM8350_PUTO_LDO1_EINT 0x0100 +#define WM8350_PUTO_DC6_EINT 0x0020 +#define WM8350_PUTO_DC5_EINT 0x0010 +#define WM8350_PUTO_DC4_EINT 0x0008 +#define WM8350_PUTO_DC3_EINT 0x0004 +#define WM8350_PUTO_DC2_EINT 0x0002 +#define WM8350_PUTO_DC1_EINT 0x0001 + +/* + * R28 (0x1C) - Under Voltage Interrupt status + */ +#define WM8350_UV_LDO4_EINT 0x0800 +#define WM8350_UV_LDO3_EINT 0x0400 +#define WM8350_UV_LDO2_EINT 0x0200 +#define WM8350_UV_LDO1_EINT 0x0100 +#define WM8350_UV_DC6_EINT 0x0020 +#define WM8350_UV_DC5_EINT 0x0010 +#define WM8350_UV_DC4_EINT 0x0008 +#define WM8350_UV_DC3_EINT 0x0004 +#define WM8350_UV_DC2_EINT 0x0002 +#define WM8350_UV_DC1_EINT 0x0001 + +/* + * R29 (0x1D) - Over Current Interrupt status + */ +#define WM8350_OC_LS_EINT 0x8000 + +/* + * R30 (0x1E) - GPIO Interrupt Status + */ +#define WM8350_GP12_EINT 0x1000 +#define WM8350_GP11_EINT 0x0800 +#define WM8350_GP10_EINT 0x0400 +#define WM8350_GP9_EINT 0x0200 +#define WM8350_GP8_EINT 0x0100 +#define WM8350_GP7_EINT 0x0080 +#define WM8350_GP6_EINT 0x0040 +#define WM8350_GP5_EINT 0x0020 +#define WM8350_GP4_EINT 0x0010 +#define WM8350_GP3_EINT 0x0008 +#define WM8350_GP2_EINT 0x0004 +#define WM8350_GP1_EINT 0x0002 +#define WM8350_GP0_EINT 0x0001 + +/* + * R31 (0x1F) - Comparator Interrupt Status + */ +#define WM8350_EXT_USB_FB_EINT 0x8000 +#define WM8350_EXT_WALL_FB_EINT 0x4000 +#define WM8350_EXT_BAT_FB_EINT 0x2000 +#define WM8350_CODEC_JCK_DET_L_EINT 0x0800 +#define WM8350_CODEC_JCK_DET_R_EINT 0x0400 +#define WM8350_CODEC_MICSCD_EINT 0x0200 +#define WM8350_CODEC_MICD_EINT 0x0100 +#define WM8350_WKUP_OFF_STATE_EINT 0x0040 +#define WM8350_WKUP_HIB_STATE_EINT 0x0020 +#define WM8350_WKUP_CONV_FAULT_EINT 0x0010 +#define WM8350_WKUP_WDOG_RST_EINT 0x0008 +#define WM8350_WKUP_GP_PWR_ON_EINT 0x0004 +#define WM8350_WKUP_ONKEY_EINT 0x0002 +#define WM8350_WKUP_GP_WAKEUP_EINT 0x0001 + +/* + * R32 (0x20) - System Interrupts Mask + */ +#define WM8350_IM_OC_INT 0x2000 +#define WM8350_IM_UV_INT 0x1000 +#define WM8350_IM_PUTO_INT 0x0800 +#define WM8350_IM_SPARE_INT 0x0400 +#define WM8350_IM_CS_INT 0x0200 +#define WM8350_IM_EXT_INT 0x0100 +#define WM8350_IM_CODEC_INT 0x0080 +#define WM8350_IM_GP_INT 0x0040 +#define WM8350_IM_AUXADC_INT 0x0020 +#define WM8350_IM_RTC_INT 0x0010 +#define WM8350_IM_SYS_INT 0x0008 +#define WM8350_IM_CHG_INT 0x0004 +#define WM8350_IM_USB_INT 0x0002 +#define WM8350_IM_WKUP_INT 0x0001 + +/* + * R33 (0x21) - Interrupt Status 1 Mask + */ +#define WM8350_IM_CHG_BAT_HOT_EINT 0x8000 +#define WM8350_IM_CHG_BAT_COLD_EINT 0x4000 +#define WM8350_IM_CHG_BAT_FAIL_EINT 0x2000 +#define WM8350_IM_CHG_TO_EINT 0x1000 +#define WM8350_IM_CHG_END_EINT 0x0800 +#define WM8350_IM_CHG_START_EINT 0x0400 +#define WM8350_IM_CHG_FAST_RDY_EINT 0x0200 +#define WM8350_IM_RTC_PER_EINT 0x0080 +#define WM8350_IM_RTC_SEC_EINT 0x0040 +#define WM8350_IM_RTC_ALM_EINT 0x0020 +#define WM8350_IM_CHG_VBATT_LT_3P9_EINT 0x0004 +#define WM8350_IM_CHG_VBATT_LT_3P1_EINT 0x0002 +#define WM8350_IM_CHG_VBATT_LT_2P85_EINT 0x0001 + +/* + * R34 (0x22) - Interrupt Status 2 Mask + */ +#define WM8350_IM_SPARE2_EINT 0x8000 +#define WM8350_IM_SPARE1_EINT 0x4000 +#define WM8350_IM_CS1_EINT 0x2000 +#define WM8350_IM_CS2_EINT 0x1000 +#define WM8350_IM_USB_LIMIT_EINT 0x0400 +#define WM8350_IM_AUXADC_DATARDY_EINT 0x0100 +#define WM8350_IM_AUXADC_DCOMP4_EINT 0x0080 +#define WM8350_IM_AUXADC_DCOMP3_EINT 0x0040 +#define WM8350_IM_AUXADC_DCOMP2_EINT 0x0020 +#define WM8350_IM_AUXADC_DCOMP1_EINT 0x0010 +#define WM8350_IM_SYS_HYST_COMP_FAIL_EINT 0x0008 +#define WM8350_IM_SYS_CHIP_GT115_EINT 0x0004 +#define WM8350_IM_SYS_CHIP_GT140_EINT 0x0002 +#define WM8350_IM_SYS_WDOG_TO_EINT 0x0001 + +/* + * R35 (0x23) - Power Up Interrupt Status Mask + */ +#define WM8350_IM_PUTO_LDO4_EINT 0x0800 +#define WM8350_IM_PUTO_LDO3_EINT 0x0400 +#define WM8350_IM_PUTO_LDO2_EINT 0x0200 +#define WM8350_IM_PUTO_LDO1_EINT 0x0100 +#define WM8350_IM_PUTO_DC6_EINT 0x0020 +#define WM8350_IM_PUTO_DC5_EINT 0x0010 +#define WM8350_IM_PUTO_DC4_EINT 0x0008 +#define WM8350_IM_PUTO_DC3_EINT 0x0004 +#define WM8350_IM_PUTO_DC2_EINT 0x0002 +#define WM8350_IM_PUTO_DC1_EINT 0x0001 + +/* + * R36 (0x24) - Under Voltage Interrupt status Mask + */ +#define WM8350_IM_UV_LDO4_EINT 0x0800 +#define WM8350_IM_UV_LDO3_EINT 0x0400 +#define WM8350_IM_UV_LDO2_EINT 0x0200 +#define WM8350_IM_UV_LDO1_EINT 0x0100 +#define WM8350_IM_UV_DC6_EINT 0x0020 +#define WM8350_IM_UV_DC5_EINT 0x0010 +#define WM8350_IM_UV_DC4_EINT 0x0008 +#define WM8350_IM_UV_DC3_EINT 0x0004 +#define WM8350_IM_UV_DC2_EINT 0x0002 +#define WM8350_IM_UV_DC1_EINT 0x0001 + +/* + * R37 (0x25) - Over Current Interrupt status Mask + */ +#define WM8350_IM_OC_LS_EINT 0x8000 + +/* + * R38 (0x26) - GPIO Interrupt Status Mask + */ +#define WM8350_IM_GP12_EINT 0x1000 +#define WM8350_IM_GP11_EINT 0x0800 +#define WM8350_IM_GP10_EINT 0x0400 +#define WM8350_IM_GP9_EINT 0x0200 +#define WM8350_IM_GP8_EINT 0x0100 +#define WM8350_IM_GP7_EINT 0x0080 +#define WM8350_IM_GP6_EINT 0x0040 +#define WM8350_IM_GP5_EINT 0x0020 +#define WM8350_IM_GP4_EINT 0x0010 +#define WM8350_IM_GP3_EINT 0x0008 +#define WM8350_IM_GP2_EINT 0x0004 +#define WM8350_IM_GP1_EINT 0x0002 +#define WM8350_IM_GP0_EINT 0x0001 + +/* + * R39 (0x27) - Comparator Interrupt Status Mask + */ +#define WM8350_IM_EXT_USB_FB_EINT 0x8000 +#define WM8350_IM_EXT_WALL_FB_EINT 0x4000 +#define WM8350_IM_EXT_BAT_FB_EINT 0x2000 +#define WM8350_IM_CODEC_JCK_DET_L_EINT 0x0800 +#define WM8350_IM_CODEC_JCK_DET_R_EINT 0x0400 +#define WM8350_IM_CODEC_MICSCD_EINT 0x0200 +#define WM8350_IM_CODEC_MICD_EINT 0x0100 +#define WM8350_IM_WKUP_OFF_STATE_EINT 0x0040 +#define WM8350_IM_WKUP_HIB_STATE_EINT 0x0020 +#define WM8350_IM_WKUP_CONV_FAULT_EINT 0x0010 +#define WM8350_IM_WKUP_WDOG_RST_EINT 0x0008 +#define WM8350_IM_WKUP_GP_PWR_ON_EINT 0x0004 +#define WM8350_IM_WKUP_ONKEY_EINT 0x0002 +#define WM8350_IM_WKUP_GP_WAKEUP_EINT 0x0001 + +/* + * R220 (0xDC) - RAM BIST 1 + */ +#define WM8350_READ_STATUS 0x0800 +#define WM8350_TSTRAM_CLK 0x0100 +#define WM8350_TSTRAM_CLK_ENA 0x0080 +#define WM8350_STARTSEQ 0x0040 +#define WM8350_READ_SRC 0x0020 +#define WM8350_COUNT_DIR 0x0010 +#define WM8350_TSTRAM_MODE_MASK 0x000E +#define WM8350_TSTRAM_ENA 0x0001 + +/* + * R225 (0xE1) - DCDC/LDO status + */ +#define WM8350_LS_STS 0x8000 +#define WM8350_LDO4_STS 0x0800 +#define WM8350_LDO3_STS 0x0400 +#define WM8350_LDO2_STS 0x0200 +#define WM8350_LDO1_STS 0x0100 +#define WM8350_DC6_STS 0x0020 +#define WM8350_DC5_STS 0x0010 +#define WM8350_DC4_STS 0x0008 +#define WM8350_DC3_STS 0x0004 +#define WM8350_DC2_STS 0x0002 +#define WM8350_DC1_STS 0x0001 + +/* WM8350 wake up conditions */ +#define WM8350_IRQ_WKUP_OFF_STATE 43 +#define WM8350_IRQ_WKUP_HIB_STATE 44 +#define WM8350_IRQ_WKUP_CONV_FAULT 45 +#define WM8350_IRQ_WKUP_WDOG_RST 46 +#define WM8350_IRQ_WKUP_GP_PWR_ON 47 +#define WM8350_IRQ_WKUP_ONKEY 48 +#define WM8350_IRQ_WKUP_GP_WAKEUP 49 + +/* wm8350 chip revisions */ +#define WM8350_REV_E 0x4 +#define WM8350_REV_F 0x5 +#define WM8350_REV_G 0x6 + +struct wm8350_reg_access { + u16 readable; /* Mask of readable bits */ + u16 writable; /* Mask of writable bits */ + u16 vol; /* Mask of volatile bits */ +}; +extern const struct wm8350_reg_access wm8350_reg_io_map[]; +extern const u16 wm8350_mode0_defaults[]; +extern const u16 wm8350_mode1_defaults[]; +extern const u16 wm8350_mode2_defaults[]; +extern const u16 wm8350_mode3_defaults[]; + +struct wm8350; + +struct wm8350_irq { + void (*handler) (struct wm8350 *, int, void *); + void *data; +}; + +struct wm8350 { + int rev; /* chip revision */ + + struct device *dev; + + /* device IO */ + union { + struct i2c_client *i2c_client; + struct spi_device *spi_device; + }; + int (*read_dev)(struct wm8350 *wm8350, char reg, int size, void *dest); + int (*write_dev)(struct wm8350 *wm8350, char reg, int size, + void *src); + u16 *reg_cache; +}; + +/* + * WM8350 device initialisation and exit. + */ +int wm8350_device_init(struct wm8350 *wm8350); +void wm8350_device_exit(struct wm8350 *wm8350); + +/* + * WM8350 device IO + */ +int wm8350_clear_bits(struct wm8350 *wm8350, u16 reg, u16 mask); +int wm8350_set_bits(struct wm8350 *wm8350, u16 reg, u16 mask); +u16 wm8350_reg_read(struct wm8350 *wm8350, int reg); +int wm8350_reg_write(struct wm8350 *wm8350, int reg, u16 val); +int wm8350_reg_lock(struct wm8350 *wm8350); +int wm8350_reg_unlock(struct wm8350 *wm8350); +int wm8350_block_read(struct wm8350 *wm8350, int reg, int size, u16 *dest); +int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src); + +#endif -- cgit v1.2.3 From 0e7203933224cbe09b5a9125f55b177b8dd5b1bd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:12 +0100 Subject: mfd: Add GPIO pin configuration support for WM8350 The WM8350 provides a number of user-configurable pins providing access to various signals generated by the functions on the chip. These are referred to as GPIO pins in the device documentation but in Linux terms they are more general than that, providing configuration of alternate functions. This patch implements support for selecting the alternate functions for these pins. They can also be used as GPIOs in the normal Linux sense - a subsequent patch will add support for doing so. This code was all written by Liam Girdwood and has had minor updates and rearrangements by Mark Brown. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/gpio.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h index 928aa6e91e3..c6cd2ca8854 100644 --- a/include/linux/mfd/wm8350/gpio.h +++ b/include/linux/mfd/wm8350/gpio.h @@ -323,4 +323,14 @@ #define WM8350_GP1_LVL 0x0002 #define WM8350_GP0_LVL 0x0001 +struct wm8350; + +int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func, + int pol, int pull, int invert, int debounce); + +/* + * GPIO Interrupts + */ +#define WM8350_IRQ_GPIO(x) (50 + x) + #endif -- cgit v1.2.3 From bcdd4efc1b6b8b98f30e127115f4bc7bbcd6f7ce Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:13 +0100 Subject: mfd: Add initialisation callback for WM8350 Some functions of the WM8350 require board-specific initialisation on startup. Provide a callback to the WM8350 driver in platform data for platforms to use to configure the chip. Use of a callback allows platforms to control the ordering of initialisation which can be important. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/core.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 94778c1669d..8f2beae6278 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -564,10 +564,22 @@ struct wm8350 { u16 *reg_cache; }; +/** + * Data to be supplied by the platform to initialise the WM8350. + * + * @init: Function called during driver initialisation. Should be + * used by the platform to configure GPIO functions and similar. + */ +struct wm8350_platform_data { + int (*init)(struct wm8350 *wm8350); +}; + + /* * WM8350 device initialisation and exit. */ -int wm8350_device_init(struct wm8350 *wm8350); +int wm8350_device_init(struct wm8350 *wm8350, + struct wm8350_platform_data *pdata); void wm8350_device_exit(struct wm8350 *wm8350); /* -- cgit v1.2.3 From ebccec0fa4e35dff0c18663a492a65f4dc6cad7a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:14 +0100 Subject: mfd: Add WM8350 interrupt support The WM8350 has an interrupt line to the CPU which is shared by the devices on the CPU. This patch adds support for the interrupt controller within the WM8350 which identifies which identifies the interrupt cause. In common with other similar chips this is done outside the standard interrupt framework due to the need to access the interrupt controller over an interrupt-driven bus. This code was all originally written by Liam Girdwood with updates for submission by me. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/core.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 8f2beae6278..d86d38260c6 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -530,6 +530,8 @@ #define WM8350_REV_F 0x5 #define WM8350_REV_G 0x6 +#define WM8350_NUM_IRQ 63 + struct wm8350_reg_access { u16 readable; /* Mask of readable bits */ u16 writable; /* Mask of writable bits */ @@ -562,6 +564,12 @@ struct wm8350 { int (*write_dev)(struct wm8350 *wm8350, char reg, int size, void *src); u16 *reg_cache; + + /* Interrupt handling */ + struct work_struct irq_work; + struct mutex irq_mutex; /* IRQ table mutex */ + struct wm8350_irq irq[WM8350_NUM_IRQ]; + int chip_irq; }; /** @@ -578,7 +586,7 @@ struct wm8350_platform_data { /* * WM8350 device initialisation and exit. */ -int wm8350_device_init(struct wm8350 *wm8350, +int wm8350_device_init(struct wm8350 *wm8350, int irq, struct wm8350_platform_data *pdata); void wm8350_device_exit(struct wm8350 *wm8350); @@ -594,4 +602,15 @@ int wm8350_reg_unlock(struct wm8350 *wm8350); int wm8350_block_read(struct wm8350 *wm8350, int reg, int size, u16 *dest); int wm8350_block_write(struct wm8350 *wm8350, int reg, int size, u16 *src); +/* + * WM8350 internal interrupts + */ +int wm8350_register_irq(struct wm8350 *wm8350, int irq, + void (*handler) (struct wm8350 *, int, void *), + void *data); +int wm8350_free_irq(struct wm8350 *wm8350, int irq); +int wm8350_mask_irq(struct wm8350 *wm8350, int irq); +int wm8350_unmask_irq(struct wm8350 *wm8350, int irq); + + #endif -- cgit v1.2.3 From da09155ac8d3f04c299b3d82a6ab0df8d03da632 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Oct 2008 15:58:15 +0100 Subject: regulator: Add WM8350 regulator support The WM8350 features six DCDC convertors (four buck and two boost), four LDO voltage regulators and two constant current sinks. This driver adds support for these through the regulator API. This driver was written by Liam Girdwood with updates for submission from Mark Brown. Signed-off-by: Mark Brown Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/core.h | 5 +++++ include/linux/mfd/wm8350/pmic.h | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index d86d38260c6..348101cb00d 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -17,6 +17,8 @@ #include #include +#include + /* * Register values. */ @@ -570,6 +572,9 @@ struct wm8350 { struct mutex irq_mutex; /* IRQ table mutex */ struct wm8350_irq irq[WM8350_NUM_IRQ]; int chip_irq; + + /* Client devices */ + struct wm8350_pmic pmic; }; /** diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h index 28d2fab2787..69b69e07f62 100644 --- a/include/linux/mfd/wm8350/pmic.h +++ b/include/linux/mfd/wm8350/pmic.h @@ -696,4 +696,46 @@ #define NUM_WM8350_REGULATORS 12 +struct wm8350; +struct platform_device; +struct regulator_init_data; + +struct wm8350_pmic { + /* ISINK to DCDC mapping */ + int isink_A_dcdc; + int isink_B_dcdc; + + /* hibernate configs */ + u16 dcdc1_hib_mode; + u16 dcdc3_hib_mode; + u16 dcdc4_hib_mode; + u16 dcdc6_hib_mode; + + /* regulator devices */ + struct platform_device *pdev[NUM_WM8350_REGULATORS]; +}; + +int wm8350_register_regulator(struct wm8350 *wm8350, int reg, + struct regulator_init_data *initdata); + +/* + * Additional DCDC control not supported via regulator API + */ +int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start, + u16 stop, u16 fault); +int wm8350_dcdc25_set_mode(struct wm8350 *wm8350, int dcdc, u16 mode, + u16 ilim, u16 ramp, u16 feedback); + +/* + * Additional LDO control not supported via regulator API + */ +int wm8350_ldo_set_slot(struct wm8350 *wm8350, int ldo, u16 start, u16 stop); + +/* + * Additional ISINK control not supported via regulator API + */ +int wm8350_isink_set_flash(struct wm8350 *wm8350, int isink, u16 mode, + u16 trigger, u16 duration, u16 on_ramp, + u16 off_ramp, u16 drive); + #endif -- cgit v1.2.3 From add41cb46175618fd42bc1ca07fe7f9dd38bf702 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Oct 2008 15:45:22 +0100 Subject: mfd: Add placeholders for WM8350 client devices In order to avoid merge problems further down the line add placeholders for several of the WM8350 client devices and register them, otherwise the patches adding the client devices will all try to update the same code. Also remove redundant checks for null regulator platform devices while we're at it. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Signed-off-by: Liam Girdwood --- include/linux/mfd/wm8350/audio.h | 6 ++++++ include/linux/mfd/wm8350/core.h | 10 ++++++++++ include/linux/mfd/wm8350/gpio.h | 6 ++++++ include/linux/mfd/wm8350/rtc.h | 6 ++++++ include/linux/mfd/wm8350/supply.h | 6 ++++++ include/linux/mfd/wm8350/wdt.h | 8 +++++++- 6 files changed, 41 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/audio.h b/include/linux/mfd/wm8350/audio.h index 43342f76711..217bb22ebb8 100644 --- a/include/linux/mfd/wm8350/audio.h +++ b/include/linux/mfd/wm8350/audio.h @@ -13,6 +13,8 @@ #ifndef __LINUX_MFD_WM8350_AUDIO_H_ #define __LINUX_MFD_WM8350_AUDIO_H_ +#include + #define WM8350_CLOCK_CONTROL_1 0x28 #define WM8350_CLOCK_CONTROL_2 0x29 #define WM8350_FLL_CONTROL_1 0x2A @@ -589,4 +591,8 @@ #define WM8350_IRQ_CODEC_MICSCD 41 #define WM8350_IRQ_CODEC_MICD 42 +struct wm8350_codec { + struct platform_device *pdev; +}; + #endif diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 348101cb00d..6ebf97f2a47 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h @@ -17,7 +17,12 @@ #include #include +#include +#include #include +#include +#include +#include /* * Register values. @@ -574,7 +579,12 @@ struct wm8350 { int chip_irq; /* Client devices */ + struct wm8350_codec codec; + struct wm8350_gpio gpio; struct wm8350_pmic pmic; + struct wm8350_power power; + struct wm8350_rtc rtc; + struct wm8350_wdt wdt; }; /** diff --git a/include/linux/mfd/wm8350/gpio.h b/include/linux/mfd/wm8350/gpio.h index c6cd2ca8854..ed91e8f5d29 100644 --- a/include/linux/mfd/wm8350/gpio.h +++ b/include/linux/mfd/wm8350/gpio.h @@ -13,6 +13,8 @@ #ifndef __LINUX_MFD_WM8350_GPIO_H_ #define __LINUX_MFD_WM8350_GPIO_H_ +#include + /* * GPIO Registers. */ @@ -328,6 +330,10 @@ struct wm8350; int wm8350_gpio_config(struct wm8350 *wm8350, int gpio, int dir, int func, int pol, int pull, int invert, int debounce); +struct wm8350_gpio { + struct platform_device *pdev; +}; + /* * GPIO Interrupts */ diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h index cb337ea8082..dfda69e9f44 100644 --- a/include/linux/mfd/wm8350/rtc.h +++ b/include/linux/mfd/wm8350/rtc.h @@ -12,6 +12,8 @@ #ifndef __LINUX_MFD_WM8350_RTC_H #define __LINUX_MFD_WM8350_RTC_H +#include + /* * Register values. */ @@ -257,4 +259,8 @@ #define WM8350_IRQ_RTC_SEC 8 #define WM8350_IRQ_RTC_ALM 9 +struct wm8350_rtc { + struct platform_device *pdev; +}; + #endif diff --git a/include/linux/mfd/wm8350/supply.h b/include/linux/mfd/wm8350/supply.h index f1d4317cf02..1c8f3cde79b 100644 --- a/include/linux/mfd/wm8350/supply.h +++ b/include/linux/mfd/wm8350/supply.h @@ -13,6 +13,8 @@ #ifndef __LINUX_MFD_WM8350_SUPPLY_H_ #define __LINUX_MFD_WM8350_SUPPLY_H_ +#include + /* * Charger registers */ @@ -102,4 +104,8 @@ #define WM8350_IRQ_EXT_WALL_FB 37 #define WM8350_IRQ_EXT_BAT_FB 38 +struct wm8350_power { + struct platform_device *pdev; +}; + #endif diff --git a/include/linux/mfd/wm8350/wdt.h b/include/linux/mfd/wm8350/wdt.h index 72fc9f55456..f6135b5e5ef 100644 --- a/include/linux/mfd/wm8350/wdt.h +++ b/include/linux/mfd/wm8350/wdt.h @@ -1,7 +1,7 @@ /* * wdt.h -- Watchdog Driver for Wolfson WM8350 PMIC * - * Copyright 2007 Wolfson Microelectronics PLC + * Copyright 2007, 2008 Wolfson Microelectronics PLC * * 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 @@ -12,6 +12,8 @@ #ifndef __LINUX_MFD_WM8350_WDT_H_ #define __LINUX_MFD_WM8350_WDT_H_ +#include + #define WM8350_WDOG_HIB_MODE 0x0080 #define WM8350_WDOG_DEBUG 0x0040 #define WM8350_WDOG_MODE_MASK 0x0030 @@ -19,4 +21,8 @@ #define WM8350_IRQ_SYS_WDOG_TO 24 +struct wm8350_wdt { + struct platform_device *pdev; +}; + #endif -- cgit v1.2.3 From 113aa838ec3a235d883f8357d31d90e16c47fc89 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 13 Oct 2008 19:01:08 -0700 Subject: net: Rationalise email address: Network Specific Parts Clean up the various different email addresses of mine listed in the code to a single current and valid address. As Dave says his network merges for 2.6.28 are now done this seems a good point to send them in where they won't risk disrupting real changes. Signed-off-by: Alan Cox Signed-off-by: David S. Miller --- include/linux/if_ether.h | 2 +- include/linux/if_fddi.h | 2 +- include/linux/if_hippi.h | 2 +- include/linux/igmp.h | 2 +- include/linux/netdevice.h | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h index bf1a53b2682..7f3c735f422 100644 --- a/include/linux/if_ether.h +++ b/include/linux/if_ether.h @@ -9,7 +9,7 @@ * * Author: Fred N. van Kempen, * Donald Becker, - * Alan Cox, + * Alan Cox, * Steve Whitehouse, * * This program is free software; you can redistribute it and/or diff --git a/include/linux/if_fddi.h b/include/linux/if_fddi.h index ae77daed6c2..45de1046dbb 100644 --- a/include/linux/if_fddi.h +++ b/include/linux/if_fddi.h @@ -12,7 +12,7 @@ * if_fddi.h is based on previous if_ether.h and if_tr.h work by * Fred N. van Kempen, * Donald Becker, - * Alan Cox, + * Alan Cox, * Steve Whitehouse, * Peter De Schrijver, * diff --git a/include/linux/if_hippi.h b/include/linux/if_hippi.h index 94d31ca7d71..f0f23516bb5 100644 --- a/include/linux/if_hippi.h +++ b/include/linux/if_hippi.h @@ -9,7 +9,7 @@ * * Author: Fred N. van Kempen, * Donald Becker, - * Alan Cox, + * Alan Cox, * Steve Whitehouse, * Jes Sorensen, * diff --git a/include/linux/igmp.h b/include/linux/igmp.h index 7bb3c095c15..f734a0ba069 100644 --- a/include/linux/igmp.h +++ b/include/linux/igmp.h @@ -2,7 +2,7 @@ * Linux NET3: Internet Group Management Protocol [IGMP] * * Authors: - * Alan Cox + * Alan Cox * * Extended to talk the BSD extended IGMP protocol of mrouted 3.6 * diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index d3ea3de70a8..64875859d65 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -11,7 +11,7 @@ * Fred N. van Kempen, * Corey Minyard * Donald J. Becker, - * Alan Cox, + * Alan Cox, * Bjorn Ekwall. * Pekka Riikonen * -- cgit v1.2.3 From 97e1c18e8d17bd87e1e383b2e9d9fc740332c8e2 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 18 Jul 2008 12:16:16 -0400 Subject: tracing: Kernel Tracepoints Implementation of kernel tracepoints. Inspired from the Linux Kernel Markers. Allows complete typing verification by declaring both tracing statement inline functions and probe registration/unregistration static inline functions within the same macro "DEFINE_TRACE". No format string is required. See the tracepoint Documentation and Samples patches for usage examples. Taken from the documentation patch : "A tracepoint placed in code provides a hook to call a function (probe) that you can provide at runtime. A tracepoint can be "on" (a probe is connected to it) or "off" (no probe is attached). When a tracepoint is "off" it has no effect, except for adding a tiny time penalty (checking a condition for a branch) and space penalty (adding a few bytes for the function call at the end of the instrumented function and adds a data structure in a separate section). When a tracepoint is "on", the function you provide is called each time the tracepoint is executed, in the execution context of the caller. When the function provided ends its execution, it returns to the caller (continuing from the tracepoint site). You can put tracepoints at important locations in the code. They are lightweight hooks that can pass an arbitrary number of parameters, which prototypes are described in a tracepoint declaration placed in a header file." Addition and removal of tracepoints is synchronized by RCU using the scheduler (and preempt_disable) as guarantees to find a quiescent state (this is really RCU "classic"). The update side uses rcu_barrier_sched() with call_rcu_sched() and the read/execute side uses "preempt_disable()/preempt_enable()". We make sure the previous array containing probes, which has been scheduled for deletion by the rcu callback, is indeed freed before we proceed to the next update. It therefore limits the rate of modification of a single tracepoint to one update per RCU period. The objective here is to permit fast batch add/removal of probes on _different_ tracepoints. Changelog : - Use #name ":" #proto as string to identify the tracepoint in the tracepoint table. This will make sure not type mismatch happens due to connexion of a probe with the wrong type to a tracepoint declared with the same name in a different header. - Add tracepoint_entry_free_old. - Change __TO_TRACE to get rid of the 'i' iterator. Masami Hiramatsu : Tested on x86-64. Performance impact of a tracepoint : same as markers, except that it adds about 70 bytes of instructions in an unlikely branch of each instrumented function (the for loop, the stack setup and the function call). It currently adds a memory read, a test and a conditional branch at the instrumentation site (in the hot path). Immediate values will eventually change this into a load immediate, test and branch, which removes the memory read which will make the i-cache impact smaller (changing the memory read for a load immediate removes 3-4 bytes per site on x86_32 (depending on mov prefixes), or 7-8 bytes on x86_64, it also saves the d-cache hit). About the performance impact of tracepoints (which is comparable to markers), even without immediate values optimizations, tests done by Hideo Aoki on ia64 show no regression. His test case was using hackbench on a kernel where scheduler instrumentation (about 5 events in code scheduler code) was added. Quoting Hideo Aoki about Markers : I evaluated overhead of kernel marker using linux-2.6-sched-fixes git tree, which includes several markers for LTTng, using an ia64 server. While the immediate trace mark feature isn't implemented on ia64, there is no major performance regression. So, I think that we don't have any issues to propose merging marker point patches into Linus's tree from the viewpoint of performance impact. I prepared two kernels to evaluate. The first one was compiled without CONFIG_MARKERS. The second one was enabled CONFIG_MARKERS. I downloaded the original hackbench from the following URL: http://devresources.linux-foundation.org/craiger/hackbench/src/hackbench.c I ran hackbench 5 times in each condition and calculated the average and difference between the kernels. The parameter of hackbench: every 50 from 50 to 800 The number of CPUs of the server: 2, 4, and 8 Below is the results. As you can see, major performance regression wasn't found in any case. Even if number of processes increases, differences between marker-enabled kernel and marker- disabled kernel doesn't increase. Moreover, if number of CPUs increases, the differences doesn't increase either. Curiously, marker-enabled kernel is better than marker-disabled kernel in more than half cases, although I guess it comes from the difference of memory access pattern. * 2 CPUs Number of | without | with | diff | diff | processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] | -------------------------------------------------------------- 50 | 4.811 | 4.872 | +0.061 | +1.27 | 100 | 9.854 | 10.309 | +0.454 | +4.61 | 150 | 15.602 | 15.040 | -0.562 | -3.6 | 200 | 20.489 | 20.380 | -0.109 | -0.53 | 250 | 25.798 | 25.652 | -0.146 | -0.56 | 300 | 31.260 | 30.797 | -0.463 | -1.48 | 350 | 36.121 | 35.770 | -0.351 | -0.97 | 400 | 42.288 | 42.102 | -0.186 | -0.44 | 450 | 47.778 | 47.253 | -0.526 | -1.1 | 500 | 51.953 | 52.278 | +0.325 | +0.63 | 550 | 58.401 | 57.700 | -0.701 | -1.2 | 600 | 63.334 | 63.222 | -0.112 | -0.18 | 650 | 68.816 | 68.511 | -0.306 | -0.44 | 700 | 74.667 | 74.088 | -0.579 | -0.78 | 750 | 78.612 | 79.582 | +0.970 | +1.23 | 800 | 85.431 | 85.263 | -0.168 | -0.2 | -------------------------------------------------------------- * 4 CPUs Number of | without | with | diff | diff | processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] | -------------------------------------------------------------- 50 | 2.586 | 2.584 | -0.003 | -0.1 | 100 | 5.254 | 5.283 | +0.030 | +0.56 | 150 | 8.012 | 8.074 | +0.061 | +0.76 | 200 | 11.172 | 11.000 | -0.172 | -1.54 | 250 | 13.917 | 14.036 | +0.119 | +0.86 | 300 | 16.905 | 16.543 | -0.362 | -2.14 | 350 | 19.901 | 20.036 | +0.135 | +0.68 | 400 | 22.908 | 23.094 | +0.186 | +0.81 | 450 | 26.273 | 26.101 | -0.172 | -0.66 | 500 | 29.554 | 29.092 | -0.461 | -1.56 | 550 | 32.377 | 32.274 | -0.103 | -0.32 | 600 | 35.855 | 35.322 | -0.533 | -1.49 | 650 | 39.192 | 38.388 | -0.804 | -2.05 | 700 | 41.744 | 41.719 | -0.025 | -0.06 | 750 | 45.016 | 44.496 | -0.520 | -1.16 | 800 | 48.212 | 47.603 | -0.609 | -1.26 | -------------------------------------------------------------- * 8 CPUs Number of | without | with | diff | diff | processes | Marker [Sec] | Marker [Sec] | [Sec] | [%] | -------------------------------------------------------------- 50 | 2.094 | 2.072 | -0.022 | -1.07 | 100 | 4.162 | 4.273 | +0.111 | +2.66 | 150 | 6.485 | 6.540 | +0.055 | +0.84 | 200 | 8.556 | 8.478 | -0.078 | -0.91 | 250 | 10.458 | 10.258 | -0.200 | -1.91 | 300 | 12.425 | 12.750 | +0.325 | +2.62 | 350 | 14.807 | 14.839 | +0.032 | +0.22 | 400 | 16.801 | 16.959 | +0.158 | +0.94 | 450 | 19.478 | 19.009 | -0.470 | -2.41 | 500 | 21.296 | 21.504 | +0.208 | +0.98 | 550 | 23.842 | 23.979 | +0.137 | +0.57 | 600 | 26.309 | 26.111 | -0.198 | -0.75 | 650 | 28.705 | 28.446 | -0.259 | -0.9 | 700 | 31.233 | 31.394 | +0.161 | +0.52 | 750 | 34.064 | 33.720 | -0.344 | -1.01 | 800 | 36.320 | 36.114 | -0.206 | -0.57 | -------------------------------------------------------------- Signed-off-by: Mathieu Desnoyers Acked-by: Masami Hiramatsu Acked-by: 'Peter Zijlstra' Signed-off-by: Ingo Molnar --- include/linux/module.h | 17 ++++++ include/linux/tracepoint.h | 127 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100644 include/linux/tracepoint.h (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 68e09557c95..8b611350386 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -331,6 +332,10 @@ struct module struct marker *markers; unsigned int num_markers; #endif +#ifdef CONFIG_TRACEPOINTS + struct tracepoint *tracepoints; + unsigned int num_tracepoints; +#endif #ifdef CONFIG_MODULE_UNLOAD /* What modules depend on me? */ @@ -454,6 +459,9 @@ extern void print_modules(void); extern void module_update_markers(void); +extern void module_update_tracepoints(void); +extern int module_get_iter_tracepoints(struct tracepoint_iter *iter); + #else /* !CONFIG_MODULES... */ #define EXPORT_SYMBOL(sym) #define EXPORT_SYMBOL_GPL(sym) @@ -558,6 +566,15 @@ static inline void module_update_markers(void) { } +static inline void module_update_tracepoints(void) +{ +} + +static inline int module_get_iter_tracepoints(struct tracepoint_iter *iter) +{ + return 0; +} + #endif /* CONFIG_MODULES */ struct device_driver; diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h new file mode 100644 index 00000000000..e623a6fca5c --- /dev/null +++ b/include/linux/tracepoint.h @@ -0,0 +1,127 @@ +#ifndef _LINUX_TRACEPOINT_H +#define _LINUX_TRACEPOINT_H + +/* + * Kernel Tracepoint API. + * + * See Documentation/tracepoint.txt. + * + * (C) Copyright 2008 Mathieu Desnoyers + * + * Heavily inspired from the Linux Kernel Markers. + * + * This file is released under the GPLv2. + * See the file COPYING for more details. + */ + +#include +#include + +struct module; +struct tracepoint; + +struct tracepoint { + const char *name; /* Tracepoint name */ + int state; /* State. */ + void **funcs; +} __attribute__((aligned(8))); + + +#define TPPROTO(args...) args +#define TPARGS(args...) args + +#ifdef CONFIG_TRACEPOINTS + +/* + * it_func[0] is never NULL because there is at least one element in the array + * when the array itself is non NULL. + */ +#define __DO_TRACE(tp, proto, args) \ + do { \ + void **it_func; \ + \ + rcu_read_lock_sched(); \ + it_func = rcu_dereference((tp)->funcs); \ + if (it_func) { \ + do { \ + ((void(*)(proto))(*it_func))(args); \ + } while (*(++it_func)); \ + } \ + rcu_read_unlock_sched(); \ + } while (0) + +/* + * Make sure the alignment of the structure in the __tracepoints section will + * not add unwanted padding between the beginning of the section and the + * structure. Force alignment to the same alignment as the section start. + */ +#define DEFINE_TRACE(name, proto, args) \ + static inline void trace_##name(proto) \ + { \ + static const char __tpstrtab_##name[] \ + __attribute__((section("__tracepoints_strings"))) \ + = #name ":" #proto; \ + static struct tracepoint __tracepoint_##name \ + __attribute__((section("__tracepoints"), aligned(8))) = \ + { __tpstrtab_##name, 0, NULL }; \ + if (unlikely(__tracepoint_##name.state)) \ + __DO_TRACE(&__tracepoint_##name, \ + TPPROTO(proto), TPARGS(args)); \ + } \ + static inline int register_trace_##name(void (*probe)(proto)) \ + { \ + return tracepoint_probe_register(#name ":" #proto, \ + (void *)probe); \ + } \ + static inline void unregister_trace_##name(void (*probe)(proto))\ + { \ + tracepoint_probe_unregister(#name ":" #proto, \ + (void *)probe); \ + } + +extern void tracepoint_update_probe_range(struct tracepoint *begin, + struct tracepoint *end); + +#else /* !CONFIG_TRACEPOINTS */ +#define DEFINE_TRACE(name, proto, args) \ + static inline void _do_trace_##name(struct tracepoint *tp, proto) \ + { } \ + static inline void trace_##name(proto) \ + { } \ + static inline int register_trace_##name(void (*probe)(proto)) \ + { \ + return -ENOSYS; \ + } \ + static inline void unregister_trace_##name(void (*probe)(proto))\ + { } + +static inline void tracepoint_update_probe_range(struct tracepoint *begin, + struct tracepoint *end) +{ } +#endif /* CONFIG_TRACEPOINTS */ + +/* + * Connect a probe to a tracepoint. + * Internal API, should not be used directly. + */ +extern int tracepoint_probe_register(const char *name, void *probe); + +/* + * Disconnect a probe from a tracepoint. + * Internal API, should not be used directly. + */ +extern int tracepoint_probe_unregister(const char *name, void *probe); + +struct tracepoint_iter { + struct module *module; + struct tracepoint *tracepoint; +}; + +extern void tracepoint_iter_start(struct tracepoint_iter *iter); +extern void tracepoint_iter_next(struct tracepoint_iter *iter); +extern void tracepoint_iter_stop(struct tracepoint_iter *iter); +extern void tracepoint_iter_reset(struct tracepoint_iter *iter); +extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, + struct tracepoint *begin, struct tracepoint *end); + +#endif -- cgit v1.2.3 From 36dcd67ae994fece615b7c700958d215e884b9ae Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 29 Jul 2008 12:00:59 +0200 Subject: ftrace: ignore functions that cannot be kprobe-ed kprobes already has an extensive list of annotations for functions that should not be instrumented. Add notrace annotations to these functions as well. This is particularly useful for functions called by the NMI path. Signed-off-by: Ingo Molnar --- include/linux/kprobes.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 0be7795655f..497b1d1f7a0 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -29,6 +29,7 @@ * and Prasanna S Panchamukhi * added function-return probes. */ +#include #include #include #include @@ -47,7 +48,7 @@ #define KPROBE_HIT_SSDONE 0x00000008 /* Attach to insert probes on any functions which should be ignored*/ -#define __kprobes __attribute__((__section__(".kprobes.text"))) +#define __kprobes __attribute__((__section__(".kprobes.text"))) notrace struct kprobe; struct pt_regs; @@ -256,7 +257,7 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head); #else /* CONFIG_KPROBES */ -#define __kprobes /**/ +#define __kprobes notrace struct jprobe; struct kretprobe; -- cgit v1.2.3 From 68bf21aa15c85d2e9b623dcda2b1ed8893275fa1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 15:45:08 -0400 Subject: ftrace: mcount call site on boot nops core This is the infrastructure to the converting the mcount call sites recorded by the __mcount_loc section into nops on boot. It also allows for using these sites to enable tracing as normal. When the __mcount_loc section is used, the "ftraced" kernel thread is disabled. This uses the current infrastructure to record the mcount call sites as well as convert them to nops. The mcount function is kept as a stub on boot up and not converted to the ftrace_record_ip function. We use the ftrace_record_ip to only record from the table. This patch does not handle modules. That comes with a later patch. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index bb384068272..d4d6ab453b7 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -162,4 +162,10 @@ static inline void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } #endif +#ifdef CONFIG_FTRACE_MCOUNT_RECORD +extern void ftrace_init(void); +#else +static inline void ftrace_init(void) { } +#endif + #endif /* _LINUX_FTRACE_H */ -- cgit v1.2.3 From 90d595fe5ca4b685465c068907e6e554760abea8 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 15:45:09 -0400 Subject: ftrace: enable mcount recording for modules This patch enables the loading of the __mcount_section of modules and changing all the callers of mcount into nops. The modification is done before the init_module function is called, so again, we do not need to use kstop_machine to make these changes. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index d4d6ab453b7..4936489f9ed 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -164,8 +164,11 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } #ifdef CONFIG_FTRACE_MCOUNT_RECORD extern void ftrace_init(void); +extern void ftrace_init_module(unsigned long *start, unsigned long *end); #else static inline void ftrace_init(void) { } +static inline void +ftrace_init_module(unsigned long *start, unsigned long *end) { } #endif #endif /* _LINUX_FTRACE_H */ -- cgit v1.2.3 From 29e71abf56cebc5c5a4e184a6eb4360cc58554ad Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 15:45:10 -0400 Subject: ftrace: rebuild everything on change to FTRACE_MCOUNT_RECORD When enabling or disabling CONFIG_FTRACE_MCOUNT_RECORD, we want a full kernel compile to handle the adding of the __mcount_loc sections. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/kernel.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 75d81f157d2..ecce4a4ccd5 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -486,4 +486,9 @@ struct sysinfo { #define NUMA_BUILD 0 #endif +/* Rebuild everything on CONFIG_FTRACE_MCOUNT_RECORD */ +#ifdef CONFIG_FTRACE_MCOUNT_RECORD +# define REBUILD_DUE_TO_FTRACE_MCOUNT_RECORD +#endif + #endif -- cgit v1.2.3 From 28614889bcb2558a47d02d52394b7fd9795a9547 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 22:47:18 -0400 Subject: ftrace: move notrace to compiler.h The notrace define belongs in compiler.h so that it can be used in init.h Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/compiler.h | 2 ++ include/linux/linkage.h | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 8322141ee48..98115d9d04d 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -44,6 +44,8 @@ extern void __chk_io_ptr(const volatile void __iomem *); # error Sorry, your compiler is too old/not recognized. #endif +#define notrace __attribute__((no_instrument_function)) + /* Intel compiler defines __GNUC__. So we will overwrite implementations * coming from above header files here */ diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 56ba3739465..9fd1f859021 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -4,8 +4,6 @@ #include #include -#define notrace __attribute__((no_instrument_function)) - #ifdef __cplusplus #define CPP_ASMLINKAGE extern "C" #else -- cgit v1.2.3 From fed1939c64d2288938fdc1c367d49082da65e195 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 14 Aug 2008 22:47:19 -0400 Subject: ftrace: remove old pointers to mcount When a mcount pointer is recorded into a table, it is used to add or remove calls to mcount (replacing them with nops). If the code is removed via removing a module, the pointers still exist. At modifying the code a check is always made to make sure the code being replaced is the code expected. In-other-words, the code being replaced is compared to what it is expected to be before being replaced. There is a very small chance that the code being replaced just happens to look like code that calls mcount (very small since the call to mcount is relative). To remove this chance, this patch adds ftrace_release to allow module unloading to remove the pointers to mcount within the module. Another change for init calls is made to not trace calls marked with __init. The tracing can not be started until after init is done anyway. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 2 ++ include/linux/init.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 4936489f9ed..6b232a2460c 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -165,10 +165,12 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } #ifdef CONFIG_FTRACE_MCOUNT_RECORD extern void ftrace_init(void); extern void ftrace_init_module(unsigned long *start, unsigned long *end); +extern void ftrace_release(void *start, unsigned long size); #else static inline void ftrace_init(void) { } static inline void ftrace_init_module(unsigned long *start, unsigned long *end) { } +static inline void ftrace_release(void *start, unsigned long size) { } #endif #endif /* _LINUX_FTRACE_H */ diff --git a/include/linux/init.h b/include/linux/init.h index 93538b696e3..27f61f6b3cb 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -40,7 +40,7 @@ /* These are for everybody (although not all archs will actually discard it in modules) */ -#define __init __section(.init.text) __cold +#define __init __section(.init.text) __cold notrace #define __initdata __section(.init.data) #define __initconst __section(.init.rodata) #define __exitdata __section(.exit.data) -- cgit v1.2.3 From dd0e545f061f90099a3dcc13aa77e29c6295cf23 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 1 Aug 2008 12:26:41 -0400 Subject: ftrace: printk formatting infrastructure This patch adds a feature that can help kernel developers debug their code using ftrace. int ftrace_printk(const char *fmt, ...); This records into the ftrace buffer using printf formatting. The entry size in the buffers are still a fixed length. A new type has been added that allows for more entries to be used for a single recording. The start of the print is still the same as the other entries. It returns the number of characters written to the ftrace buffer. For example: Having a module with the following code: static int __init ftrace_print_test(void) { ftrace_printk("jiffies are %ld\n", jiffies); return 0; } Gives me: insmod-5441 3...1 7569us : ftrace_print_test: jiffies are 4296626666 for the latency_trace file and: insmod-5441 [03] 1959.370498: ftrace_print_test jiffies are 4296626666 for the trace file. Note: Only the infrastructure should go into the kernel. It is to help facilitate debugging for other kernel developers. Calls to ftrace_printk is not intended to be left in the kernel, and should be frowned upon just like scattering printks around in the code. But having this easily at your fingertips helps the debugging go faster and bugs be solved quicker. Maybe later on, we can hook this with markers and have their printf format be sucked into ftrace output. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 6b232a2460c..f53b975e32f 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -157,9 +157,18 @@ static inline void __ftrace_enabled_restore(int enabled) #ifdef CONFIG_TRACING extern void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); +# define ftrace_printk(x...) __ftrace_printk(_THIS_IP_, x) +extern int +__ftrace_printk(unsigned long ip, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); #else static inline void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } +static inline int +ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))) +{ + return 0; +} #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD @@ -173,4 +182,5 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { } static inline void ftrace_release(void *start, unsigned long size) { } #endif + #endif /* _LINUX_FTRACE_H */ -- cgit v1.2.3 From 2f2c99dba2398ef7d9c21f7c793180a50e68b1f0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Fri, 1 Aug 2008 16:45:49 -0400 Subject: ftrace: ftrace_printk doc moved Based on Randy Dunlap's suggestion, the ftrace_printk kernel-doc belongs with the ftrace_printk macro that should be used. Not with the __ftrace_printk internal function. Signed-off-by: Steven Rostedt Acked-by: Randy Dunlap Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index f53b975e32f..018af16bce5 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -157,7 +157,24 @@ static inline void __ftrace_enabled_restore(int enabled) #ifdef CONFIG_TRACING extern void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); -# define ftrace_printk(x...) __ftrace_printk(_THIS_IP_, x) + +/** + * ftrace_printk - printf formatting in the ftrace buffer + * @fmt: the printf format for printing + * + * Note: __ftrace_printk is an internal function for ftrace_printk and + * the @ip is passed in via the ftrace_printk macro. + * + * This function allows a kernel developer to debug fast path sections + * that printk is not appropriate for. By scattering in various + * printk like tracing in the code, a developer can quickly see + * where problems are occurring. + * + * This is intended as a debugging tool for the developer only. + * Please refrain from leaving ftrace_printks scattered around in + * your code. + */ +# define ftrace_printk(fmt...) __ftrace_printk(_THIS_IP_, fmt) extern int __ftrace_printk(unsigned long ip, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -- cgit v1.2.3 From 3f5a54e371ca20b119b73704f6c01b71295c1714 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 30 Jul 2008 22:36:46 -0400 Subject: ftrace: dump out ftrace buffers to console on panic At OLS I had a lot of interest to be able to have the ftrace buffers dumped on panic. Usually one would expect to uses kexec and examine the buffers after a new kernel is loaded. But sometimes the resources do not permit kdump and kexec, so having an option to still see the sequence of events up to the crash is very advantageous. This patch adds the option to have the ftrace buffers dumped to the console in the latency_trace format on a panic. When the option is set, the default entries per CPU buffer are lowered to 16384, since the writing to the serial (if that is the console) may take an awful long time otherwise. [ Changes since -v1: Got alpine to send correctly (as well as spell check working). Removed config option. Moved the static variables into ftrace_dump itself. Gave printk a log level. ] Signed-off-by: Steven Rostedt Cc: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 018af16bce5..f7fb92045bf 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -178,6 +178,7 @@ ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3); extern int __ftrace_printk(unsigned long ip, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +extern void ftrace_dump(void); #else static inline void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } @@ -186,6 +187,7 @@ ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))) { return 0; } +static inline void ftrace_dump(void) { } #endif #ifdef CONFIG_FTRACE_MCOUNT_RECORD -- cgit v1.2.3 From 7b928c23fa3e9fa37d1d4ba52ba963f41ee5aae0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 15 Aug 2008 17:48:02 +0200 Subject: ftrace: build fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: In file included from init/main.c:65: include/linux/ftrace.h:166: error: expected ‘,' or ‘;' before ‘{' token make[1]: *** [init/main.o] Error 1 make: *** [init/main.o] Error 2 Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index f7fb92045bf..ce929cb5543 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -183,7 +183,10 @@ extern void ftrace_dump(void); static inline void ftrace_special(unsigned long arg1, unsigned long arg2, unsigned long arg3) { } static inline int -ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))) +ftrace_printk(const char *fmt, ...) __attribute__ ((format (printf, 1, 0))); + +static inline int +ftrace_printk(const char *fmt, ...) { return 0; } -- cgit v1.2.3 From c5131ad6c3cbe8f6674993e29a76cecf8deb4384 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 15 Aug 2008 18:22:09 +0200 Subject: ftrace: ftrace_kill_atomic() build fix fix: kernel/built-in.o: In function `ftrace_dump': (.text+0x2e2ea): undefined reference to `ftrace_kill_atomic' Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ce929cb5543..36c439927ff 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -36,6 +36,7 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1); # define register_ftrace_function(ops) do { } while (0) # define unregister_ftrace_function(ops) do { } while (0) # define clear_ftrace_function(ops) do { } while (0) +static inline void ftrace_kill_atomic(void) { } #endif /* CONFIG_FTRACE */ #ifdef CONFIG_DYNAMIC_FTRACE -- cgit v1.2.3 From 3700273586ee6a58b95dd07d9f8a02db4a9b476f Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Mon, 18 Aug 2008 16:24:56 +0800 Subject: ftrace: fix incorrect comment style of __ftrace_enabled_save() This patch fixes incorrect comment style of __ftrace_enabled_save(). Signed-off-by: Huang Ying Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 36c439927ff..8b4cf38c80d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -99,9 +99,11 @@ static inline void tracer_disable(void) #endif } -/* Ftrace disable/restore without lock. Some synchronization mechanism +/* + * Ftrace disable/restore without lock. Some synchronization mechanism * must be used to prevent ftrace_enabled to be changed between - * disable/restore. */ + * disable/restore. + */ static inline int __ftrace_enabled_save(void) { #ifdef CONFIG_FTRACE -- cgit v1.2.3 From c0719e5a4b1ccc04180b7a7b71095c9fb7131919 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Sat, 6 Sep 2008 01:06:03 -0400 Subject: ftrace: use ftrace_release for all dynamic ftrace functions ftrace_release is necessary for all uses of dynamic ftrace and not just the archs that have CONFIG_FTRACE_MCOUNT_RECORD defined. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 8b4cf38c80d..5de9903645d 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -77,8 +77,10 @@ extern void mcount_call(void); extern int skip_trace(unsigned long ip); -void ftrace_disable_daemon(void); -void ftrace_enable_daemon(void); +extern void ftrace_release(void *start, unsigned long size); + +extern void ftrace_disable_daemon(void); +extern void ftrace_enable_daemon(void); #else # define skip_trace(ip) ({ 0; }) @@ -86,6 +88,7 @@ void ftrace_enable_daemon(void); # define ftrace_set_filter(buf, len, reset) do { } while (0) # define ftrace_disable_daemon() do { } while (0) # define ftrace_enable_daemon() do { } while (0) +static inline void ftrace_release(void *start, unsigned long size) { } #endif /* CONFIG_DYNAMIC_FTRACE */ /* totally disable ftrace - can not re-enable after this */ @@ -199,12 +202,10 @@ static inline void ftrace_dump(void) { } #ifdef CONFIG_FTRACE_MCOUNT_RECORD extern void ftrace_init(void); extern void ftrace_init_module(unsigned long *start, unsigned long *end); -extern void ftrace_release(void *start, unsigned long size); #else static inline void ftrace_init(void) { } static inline void ftrace_init_module(unsigned long *start, unsigned long *end) { } -static inline void ftrace_release(void *start, unsigned long size) { } #endif -- cgit v1.2.3 From 9e57fb35d711331a9b1410c5c56ebeb3733428a0 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 16 Sep 2008 22:00:34 +0300 Subject: x86 mmiotrace: implement mmiotrace_printk() Offer mmiotrace users a function to inject markers from inside the kernel. This depends on the trace_vprintk() patch. Signed-off-by: Pekka Paalanen Acked-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/mmiotrace.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 61d19e1b7a0..60cc3bf5c53 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -34,11 +34,15 @@ extern void unregister_kmmio_probe(struct kmmio_probe *p); /* Called from page fault handler. */ extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); -/* Called from ioremap.c */ #ifdef CONFIG_MMIOTRACE +/* Called from ioremap.c */ extern void mmiotrace_ioremap(resource_size_t offset, unsigned long size, void __iomem *addr); extern void mmiotrace_iounmap(volatile void __iomem *addr); + +/* For anyone to insert markers. Remember trailing newline. */ +extern int mmiotrace_printk(const char *fmt, ...) + __attribute__ ((format (printf, 1, 2))); #else static inline void mmiotrace_ioremap(resource_size_t offset, unsigned long size, void __iomem *addr) @@ -48,7 +52,15 @@ static inline void mmiotrace_ioremap(resource_size_t offset, static inline void mmiotrace_iounmap(volatile void __iomem *addr) { } -#endif /* CONFIG_MMIOTRACE_HOOKS */ + +static inline int mmiotrace_printk(const char *fmt, ...) + __attribute__ ((format (printf, 1, 0))); + +static inline int mmiotrace_printk(const char *fmt, ...) +{ + return 0; +} +#endif /* CONFIG_MMIOTRACE */ enum mm_io_opcode { MMIO_READ = 0x1, /* struct mmiotrace_rw */ @@ -81,5 +93,6 @@ extern void enable_mmiotrace(void); extern void disable_mmiotrace(void); extern void mmio_trace_rw(struct mmiotrace_rw *rw); extern void mmio_trace_mapping(struct mmiotrace_map *map); +extern int mmio_trace_printk(const char *fmt, va_list args); #endif /* MMIOTRACE_H */ -- cgit v1.2.3 From 4427414170a63331a9cc36b9598502c5cdfe453b Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Tue, 16 Sep 2008 22:03:56 +0300 Subject: mmiotrace: remove left-over marker cruft Signed-off-by: Pekka Paalanen Acked-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/mmiotrace.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h index 60cc3bf5c53..139d7c88d9c 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -67,8 +67,7 @@ enum mm_io_opcode { MMIO_WRITE = 0x2, /* struct mmiotrace_rw */ MMIO_PROBE = 0x3, /* struct mmiotrace_map */ MMIO_UNPROBE = 0x4, /* struct mmiotrace_map */ - MMIO_MARKER = 0x5, /* raw char data */ - MMIO_UNKNOWN_OP = 0x6, /* struct mmiotrace_rw */ + MMIO_UNKNOWN_OP = 0x5, /* struct mmiotrace_rw */ }; struct mmiotrace_rw { -- cgit v1.2.3 From e98d0eabef2748d88fa58760d104e8e68517406b Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 29 Sep 2008 11:05:13 -0400 Subject: markers: marker_synchronize_unregister() Create marker_synchronize_unregister() which must be called before the end of exit() to make sure every probe callers have exited the non preemptible section and thus are not executing the probe code anymore. Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar --- include/linux/marker.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/marker.h b/include/linux/marker.h index 1290653f924..889196c7fbb 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -160,4 +160,11 @@ extern int marker_probe_unregister_private_data(marker_probe_func *probe, extern void *marker_get_private_data(const char *name, marker_probe_func *probe, int num); +/* + * marker_synchronize_unregister must be called between the last marker probe + * unregistration and the end of module exit to make sure there is no caller + * executing a probe when it is freed. + */ +#define marker_synchronize_unregister() synchronize_sched() + #endif -- cgit v1.2.3 From 53c8c8fdfd2d2d515bdcb3d0f2a11d1f3f42ece1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 3 Oct 2008 11:52:54 -0400 Subject: markers: turn marker_synchronize_unregister() into an inline Turn marker synchronize unregister into a static inline. There is no reason to keep it as a macro over a static inline. Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar --- include/linux/marker.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/marker.h b/include/linux/marker.h index 889196c7fbb..38e32e781ed 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -13,6 +13,7 @@ */ #include +#include struct module; struct marker; @@ -165,6 +166,9 @@ extern void *marker_get_private_data(const char *name, marker_probe_func *probe, * unregistration and the end of module exit to make sure there is no caller * executing a probe when it is freed. */ -#define marker_synchronize_unregister() synchronize_sched() +static inline void marker_synchronize_unregister(void) +{ + synchronize_sched(); +} #endif -- cgit v1.2.3 From d13744cd6e3fef373a3fe656ac349b4e7c49ff79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Weisbecker?= Date: Tue, 23 Sep 2008 11:32:08 +0100 Subject: tracing/ftrace: add the boot tracer Add the boot/initcall tracer. It's primary purpose is to be able to trace the initcalls. It is intended to be used with scripts/bootgraph.pl after some small improvements. Note that it is not active after its init. To avoid tracing (and so crashing) before the whole tracing engine init, you have to explicitly call start_boot_trace() after do_pre_smp_initcalls() to enable it. Signed-off-by: Frederic Weisbecker Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 5de9903645d..91954eb6460 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -5,6 +5,8 @@ #include #include +#include +#include extern int ftrace_enabled; extern int @@ -209,4 +211,21 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { } #endif +struct boot_trace { + pid_t caller; + initcall_t func; + int result; + unsigned long long duration; +}; + +#ifdef CONFIG_BOOT_TRACER +extern void trace_boot(struct boot_trace *it); +extern void start_boot_trace(void); +#else +static inline void trace_boot(struct boot_trace *it) { } +static inline void start_boot_trace(void) { } +#endif + + + #endif /* _LINUX_FTRACE_H */ -- cgit v1.2.3 From 7a8e76a3829f1067b70f715771ff88baf2fbf3c3 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 29 Sep 2008 23:02:38 -0400 Subject: tracing: unified trace buffer This is a unified tracing buffer that implements a ring buffer that hopefully everyone will eventually be able to use. The events recorded into the buffer have the following structure: struct ring_buffer_event { u32 type:2, len:3, time_delta:27; u32 array[]; }; The minimum size of an event is 8 bytes. All events are 4 byte aligned inside the buffer. There are 4 types (all internal use for the ring buffer, only the data type is exported to the interface users). RINGBUF_TYPE_PADDING: this type is used to note extra space at the end of a buffer page. RINGBUF_TYPE_TIME_EXTENT: This type is used when the time between events is greater than the 27 bit delta can hold. We add another 32 bits, and record that in its own event (8 byte size). RINGBUF_TYPE_TIME_STAMP: (Not implemented yet). This will hold data to help keep the buffer timestamps in sync. RINGBUF_TYPE_DATA: The event actually holds user data. The "len" field is only three bits. Since the data must be 4 byte aligned, this field is shifted left by 2, giving a max length of 28 bytes. If the data load is greater than 28 bytes, the first array field holds the full length of the data load and the len field is set to zero. Example, data size of 7 bytes: type = RINGBUF_TYPE_DATA len = 2 time_delta: - array[0..1]: <7 bytes of data> <1 byte empty> This event is saved in 12 bytes of the buffer. An event with 82 bytes of data: type = RINGBUF_TYPE_DATA len = 0 time_delta: - array[0]: 84 (Note the alignment) array[1..14]: <82 bytes of data> <2 bytes empty> The above event is saved in 92 bytes (if my math is correct). 82 bytes of data, 2 bytes empty, 4 byte header, 4 byte length. Do not reference the above event struct directly. Use the following functions to gain access to the event table, since the ring_buffer_event structure may change in the future. ring_buffer_event_length(event): get the length of the event. This is the size of the memory used to record this event, and not the size of the data pay load. ring_buffer_time_delta(event): get the time delta of the event This returns the delta time stamp since the last event. Note: Even though this is in the header, there should be no reason to access this directly, accept for debugging. ring_buffer_event_data(event): get the data from the event This is the function to use to get the actual data from the event. Note, it is only a pointer to the data inside the buffer. This data must be copied to another location otherwise you risk it being written over in the buffer. ring_buffer_lock: A way to lock the entire buffer. ring_buffer_unlock: unlock the buffer. ring_buffer_alloc: create a new ring buffer. Can choose between overwrite or consumer/producer mode. Overwrite will overwrite old data, where as consumer producer will throw away new data if the consumer catches up with the producer. The consumer/producer is the default. ring_buffer_free: free the ring buffer. ring_buffer_resize: resize the buffer. Changes the size of each cpu buffer. Note, it is up to the caller to provide that the buffer is not being used while this is happening. This requirement may go away but do not count on it. ring_buffer_lock_reserve: locks the ring buffer and allocates an entry on the buffer to write to. ring_buffer_unlock_commit: unlocks the ring buffer and commits it to the buffer. ring_buffer_write: writes some data into the ring buffer. ring_buffer_peek: Look at a next item in the cpu buffer. ring_buffer_consume: get the next item in the cpu buffer and consume it. That is, this function increments the head pointer. ring_buffer_read_start: Start an iterator of a cpu buffer. For now, this disables the cpu buffer, until you issue a finish. This is just because we do not want the iterator to be overwritten. This restriction may change in the future. But note, this is used for static reading of a buffer which is usually done "after" a trace. Live readings would want to use the ring_buffer_consume above, which will not disable the ring buffer. ring_buffer_read_finish: Finishes the read iterator and reenables the ring buffer. ring_buffer_iter_peek: Look at the next item in the cpu iterator. ring_buffer_read: Read the iterator and increment it. ring_buffer_iter_reset: Reset the iterator to point to the beginning of the cpu buffer. ring_buffer_iter_empty: Returns true if the iterator is at the end of the cpu buffer. ring_buffer_size: returns the size in bytes of each cpu buffer. Note, the real size is this times the number of CPUs. ring_buffer_reset_cpu: Sets the cpu buffer to empty ring_buffer_reset: sets all cpu buffers to empty ring_buffer_swap_cpu: swaps a cpu buffer from one buffer with a cpu buffer of another buffer. This is handy when you want to take a snap shot of a running trace on just one cpu. Having a backup buffer, to swap with facilitates this. Ftrace max latencies use this. ring_buffer_empty: Returns true if the ring buffer is empty. ring_buffer_empty_cpu: Returns true if the cpu buffer is empty. ring_buffer_record_disable: disable all cpu buffers (read only) ring_buffer_record_disable_cpu: disable a single cpu buffer (read only) ring_buffer_record_enable: enable all cpu buffers. ring_buffer_record_enabl_cpu: enable a single cpu buffer. ring_buffer_entries: The number of entries in a ring buffer. ring_buffer_overruns: The number of entries removed due to writing wrap. ring_buffer_time_stamp: Get the time stamp used by the ring buffer ring_buffer_normalize_time_stamp: normalize the ring buffer time stamp into nanosecs. I still need to implement the GTOD feature. But we need support from the cpu frequency infrastructure. But this can be done at a later time without affecting the ring buffer interface. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ring_buffer.h | 130 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 include/linux/ring_buffer.h (limited to 'include/linux') diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h new file mode 100644 index 00000000000..c52375b8330 --- /dev/null +++ b/include/linux/ring_buffer.h @@ -0,0 +1,130 @@ +#ifndef _LINUX_RING_BUFFER_H +#define _LINUX_RING_BUFFER_H + +#include +#include + +struct ring_buffer; +struct ring_buffer_iter; + +/* + * Don't reference this struct directly, use functions below. + */ +struct ring_buffer_event { + u32 type:2, len:3, time_delta:27; + u32 array[]; +}; + +/** + * enum ring_buffer_type - internal ring buffer types + * + * @RINGBUF_TYPE_PADDING: Left over page padding + * array is ignored + * size is variable depending on how much + * padding is needed + * + * @RINGBUF_TYPE_TIME_EXTEND: Extend the time delta + * array[0] = time delta (28 .. 59) + * size = 8 bytes + * + * @RINGBUF_TYPE_TIME_STAMP: Sync time stamp with external clock + * array[0] = tv_nsec + * array[1] = tv_sec + * size = 16 bytes + * + * @RINGBUF_TYPE_DATA: Data record + * If len is zero: + * array[0] holds the actual length + * array[1..(length+3)/4-1] holds data + * else + * length = len << 2 + * array[0..(length+3)/4] holds data + */ +enum ring_buffer_type { + RINGBUF_TYPE_PADDING, + RINGBUF_TYPE_TIME_EXTEND, + /* FIXME: RINGBUF_TYPE_TIME_STAMP not implemented */ + RINGBUF_TYPE_TIME_STAMP, + RINGBUF_TYPE_DATA, +}; + +unsigned ring_buffer_event_length(struct ring_buffer_event *event); +void *ring_buffer_event_data(struct ring_buffer_event *event); + +/** + * ring_buffer_event_time_delta - return the delta timestamp of the event + * @event: the event to get the delta timestamp of + * + * The delta timestamp is the 27 bit timestamp since the last event. + */ +static inline unsigned +ring_buffer_event_time_delta(struct ring_buffer_event *event) +{ + return event->time_delta; +} + +void ring_buffer_lock(struct ring_buffer *buffer, unsigned long *flags); +void ring_buffer_unlock(struct ring_buffer *buffer, unsigned long flags); + +/* + * size is in bytes for each per CPU buffer. + */ +struct ring_buffer * +ring_buffer_alloc(unsigned long size, unsigned flags); +void ring_buffer_free(struct ring_buffer *buffer); + +int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size); + +struct ring_buffer_event * +ring_buffer_lock_reserve(struct ring_buffer *buffer, + unsigned long length, + unsigned long *flags); +int ring_buffer_unlock_commit(struct ring_buffer *buffer, + struct ring_buffer_event *event, + unsigned long flags); +int ring_buffer_write(struct ring_buffer *buffer, + unsigned long length, void *data); + +struct ring_buffer_event * +ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts); +struct ring_buffer_event * +ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts); + +struct ring_buffer_iter * +ring_buffer_read_start(struct ring_buffer *buffer, int cpu); +void ring_buffer_read_finish(struct ring_buffer_iter *iter); + +struct ring_buffer_event * +ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts); +struct ring_buffer_event * +ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts); +void ring_buffer_iter_reset(struct ring_buffer_iter *iter); +int ring_buffer_iter_empty(struct ring_buffer_iter *iter); + +unsigned long ring_buffer_size(struct ring_buffer *buffer); + +void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu); +void ring_buffer_reset(struct ring_buffer *buffer); + +int ring_buffer_swap_cpu(struct ring_buffer *buffer_a, + struct ring_buffer *buffer_b, int cpu); + +int ring_buffer_empty(struct ring_buffer *buffer); +int ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu); + +void ring_buffer_record_disable(struct ring_buffer *buffer); +void ring_buffer_record_enable(struct ring_buffer *buffer); +void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu); +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); + +u64 ring_buffer_time_stamp(int cpu); +void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); + +enum ring_buffer_flags { + RB_FL_OVERWRITE = 1 << 0, +}; + +#endif /* _LINUX_RING_BUFFER_H */ -- cgit v1.2.3 From d769041f865330034131525ee6a7f72eb4af2a24 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 1 Oct 2008 00:29:53 -0400 Subject: ring_buffer: implement new locking The old "lock always" scheme had issues with lockdep, and was not very efficient anyways. This patch does a new design to be partially lockless on writes. Writes will add new entries to the per cpu pages by simply disabling interrupts. When a write needs to go to another page than it will grab the lock. A new "read page" has been added so that the reader can pull out a page from the ring buffer to read without worrying about the writer writing over it. This allows us to not take the lock for all reads. The lock is now only taken when a read needs to go to a new page. This is far from lockless, and interrupts still need to be disabled, but it is a step towards a more lockless solution, and it also solves a lot of the issues that were noticed by the first conversion of ftrace to the ring buffers. Note: the ring_buffer_{un}lock API has been removed. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ring_buffer.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index c52375b8330..536b0ca46a0 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -63,9 +63,6 @@ ring_buffer_event_time_delta(struct ring_buffer_event *event) return event->time_delta; } -void ring_buffer_lock(struct ring_buffer *buffer, unsigned long *flags); -void ring_buffer_unlock(struct ring_buffer *buffer, unsigned long flags); - /* * size is in bytes for each per CPU buffer. */ -- cgit v1.2.3 From cb5ab74204a6e2579d1119bf1348eb806526b12b Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 2 Oct 2008 12:59:20 +0200 Subject: tracing/fastboot: change the printing of boot tracer according to bootgraph.pl Change the boot tracer printing to make it parsable for the scripts/bootgraph.pl script. We have now to output two lines for each initcall, according to the printk in do_one_initcall() in init/main.c We need now the call's time and the return's time. Signed-off-by: Frederic Weisbecker Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 91954eb6460..4455490d91b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -216,6 +216,8 @@ struct boot_trace { initcall_t func; int result; unsigned long long duration; + ktime_t calltime; + ktime_t rettime; }; #ifdef CONFIG_BOOT_TRACER -- cgit v1.2.3 From 5601020feb0c3010e9e3e0131e9697ac6a06777b Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 2 Oct 2008 13:26:05 +0200 Subject: tracing/fastboot: get the initcall name before it disappears After some initcall traces, some initcall names may be inconsistent. That's because these functions will disappear from the .init section and also their name from the symbols table. So we have to copy the name of the function in a buffer large enough during the trace appending. It is not costly for the ring_buffer because the number of initcall entries is commonly not really large. Signed-off-by: Frederic Weisbecker Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 4455490d91b..e672e51c40a 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -7,6 +7,7 @@ #include #include #include +#include extern int ftrace_enabled; extern int @@ -213,7 +214,7 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { } struct boot_trace { pid_t caller; - initcall_t func; + char func[KSYM_NAME_LEN]; int result; unsigned long long duration; ktime_t calltime; @@ -221,10 +222,10 @@ struct boot_trace { }; #ifdef CONFIG_BOOT_TRACER -extern void trace_boot(struct boot_trace *it); +extern void trace_boot(struct boot_trace *it, initcall_t fn); extern void start_boot_trace(void); #else -static inline void trace_boot(struct boot_trace *it) { } +static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } static inline void start_boot_trace(void) { } #endif -- cgit v1.2.3 From 3e1932ad59726d794a865cc159c0593d54bf0cb6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 2 Oct 2008 17:45:47 +0200 Subject: tracing/fastboot: build fix fix: In file included from kernel/sysctl.c:52: include/linux/ftrace.h:217: error: 'KSYM_NAME_LEN' undeclared here (not in a function) Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index e672e51c40a..deded114dff 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -1,14 +1,14 @@ #ifndef _LINUX_FTRACE_H #define _LINUX_FTRACE_H -#ifdef CONFIG_FTRACE - #include #include #include #include #include +#ifdef CONFIG_FTRACE + extern int ftrace_enabled; extern int ftrace_enable_sysctl(struct ctl_table *table, int write, -- cgit v1.2.3 From eb7fa935274bb233686fdf7a53f40c5d9ee76ed6 Mon Sep 17 00:00:00 2001 From: Steven Noonan Date: Thu, 2 Oct 2008 12:00:07 -0700 Subject: ftrace: ktime.h not included in ftrace.h Including eliminates the following error: include/linux/ftrace.h:220: error: expected specifier-qualifier-list before 'ktime_t' Signed-off-by: Steven Noonan Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index deded114dff..ed53265d1f6 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3 From 097d036a2f25eecc42435c57e010aaf4a2eed2d9 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 3 Oct 2008 15:39:21 +0200 Subject: tracing/fastboot: only trace non-module initcalls At this time, only built-in initcalls interest us. We can't really produce a relevant graph if we include the modules initcall too. I had good results after this patch (see svg in attachment). Signed-off-by: Frederic Weisbecker Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ed53265d1f6..5812dba4ee2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -225,9 +225,11 @@ struct boot_trace { #ifdef CONFIG_BOOT_TRACER extern void trace_boot(struct boot_trace *it, initcall_t fn); extern void start_boot_trace(void); +extern void stop_boot_trace(void); #else static inline void trace_boot(struct boot_trace *it, initcall_t fn) { } static inline void start_boot_trace(void) { } +static inline void stop_boot_trace(void) { } #endif -- cgit v1.2.3 From ca538f6bbe583406f941f3041d40c41f9a13d1de Mon Sep 17 00:00:00 2001 From: Tim Bird Date: Thu, 9 Oct 2008 15:23:05 -0700 Subject: tracing/fastboot: add better resolution to initcall debug/tracing Change the time resolution for initcall_debug to microseconds, from milliseconds. This is handy to determine which initcalls you want to work on for faster booting. One one of my test machines, over 90% of the initcalls are less than a millisecond and (without this patch) these are all reported as 0 msecs. Working on the 900 us ones is more important than the 4 us ones. With 'quiet' on the kernel command line, this adds no significant overhead to kernel boot time. Signed-off-by: Tim Bird Signed-off-by: Andrew Morton Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 5812dba4ee2..a3d46151be1 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -215,9 +215,9 @@ ftrace_init_module(unsigned long *start, unsigned long *end) { } struct boot_trace { pid_t caller; - char func[KSYM_NAME_LEN]; + char func[KSYM_NAME_LEN]; int result; - unsigned long long duration; + unsigned long long duration; /* usecs */ ktime_t calltime; ktime_t rettime; }; -- cgit v1.2.3 From bfadadfccc19e36f7d600c5ce7b3e5ba5197fbf0 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 10 Oct 2008 03:48:25 -0400 Subject: markers: fix synchronize marker unregister static inline Use a #define for synchronize marker unregister to fix include dependencies. Fixes the slab circular inclusion which triggers when slab.git is combined with tracing.git, where rcupdate includes slab, which includes markers which includes rcupdate. Signed-off-by: Mathieu Desnoyers Acked-by: Pekka Enberg Signed-off-by: Ingo Molnar --- include/linux/marker.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/marker.h b/include/linux/marker.h index 38e32e781ed..889196c7fbb 100644 --- a/include/linux/marker.h +++ b/include/linux/marker.h @@ -13,7 +13,6 @@ */ #include -#include struct module; struct marker; @@ -166,9 +165,6 @@ extern void *marker_get_private_data(const char *name, marker_probe_func *probe, * unregistration and the end of module exit to make sure there is no caller * executing a probe when it is freed. */ -static inline void marker_synchronize_unregister(void) -{ - synchronize_sched(); -} +#define marker_synchronize_unregister() synchronize_sched() #endif -- cgit v1.2.3 From f2461fc82a083dd60062e05e704c5fcc1c658ba1 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 6 Oct 2008 10:33:00 -0400 Subject: tracepoints: tracepoint_synchronize_unregister() Create tracepoint_synchronize_unregister() which must be called before the end of exit() to make sure every probe callers have exited the non preemptible section and thus are not executing the probe code anymore. Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar --- include/linux/tracepoint.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index e623a6fca5c..199f4c207c1 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -124,4 +124,11 @@ extern void tracepoint_iter_reset(struct tracepoint_iter *iter); extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, struct tracepoint *begin, struct tracepoint *end); +/* + * tracepoint_synchronize_unregister must be called between the last tracepoint + * probe unregistration and the end of module exit to make sure there is no + * caller executing a probe when it is freed. + */ +#define tracepoint_synchronize_unregister() synchronize_sched() + #endif -- cgit v1.2.3 From 231375cc5cc3549bb413f94a164bdcbd5f9ce943 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Fri, 3 Oct 2008 15:01:33 -0400 Subject: tracepoints: synchronize unregister static inline Turn tracepoint synchronize unregister into a static inline. There is no reason to keep it as a macro over a static inline. Signed-off-by: Mathieu Desnoyers Signed-off-by: Ingo Molnar --- include/linux/tracepoint.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 199f4c207c1..c5bb39c7a77 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -129,6 +129,9 @@ extern int tracepoint_get_iter_range(struct tracepoint **tracepoint, * probe unregistration and the end of module exit to make sure there is no * caller executing a probe when it is freed. */ -#define tracepoint_synchronize_unregister() synchronize_sched() +static inline void tracepoint_synchronize_unregister(void) +{ + synchronize_sched(); +} #endif -- cgit v1.2.3 From 6028aa01f759a1dae11e5d0e495b3dc9d2b0a47b Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 14 Oct 2008 21:23:26 +0900 Subject: [MTD] [NAND] sh_flctl: add support for Renesas SuperH FLCTL Several Renesas SuperH CPU has FLCTL. The FLCTL support NAND Flash. This driver support SH7723. Signed-off-by: Yoshihiro Shimoda Acked-by: Paul Mundt Signed-off-by: David Woodhouse --- include/linux/mtd/sh_flctl.h | 125 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 include/linux/mtd/sh_flctl.h (limited to 'include/linux') diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h new file mode 100644 index 00000000000..e77c1cea404 --- /dev/null +++ b/include/linux/mtd/sh_flctl.h @@ -0,0 +1,125 @@ +/* + * SuperH FLCTL nand controller + * + * Copyright © 2008 Renesas Solutions Corp. + * + * 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; version 2 of the License. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __SH_FLCTL_H__ +#define __SH_FLCTL_H__ + +#include +#include +#include + +/* FLCTL registers */ +#define FLCMNCR(f) (f->reg + 0x0) +#define FLCMDCR(f) (f->reg + 0x4) +#define FLCMCDR(f) (f->reg + 0x8) +#define FLADR(f) (f->reg + 0xC) +#define FLADR2(f) (f->reg + 0x3C) +#define FLDATAR(f) (f->reg + 0x10) +#define FLDTCNTR(f) (f->reg + 0x14) +#define FLINTDMACR(f) (f->reg + 0x18) +#define FLBSYTMR(f) (f->reg + 0x1C) +#define FLBSYCNT(f) (f->reg + 0x20) +#define FLDTFIFO(f) (f->reg + 0x24) +#define FLECFIFO(f) (f->reg + 0x28) +#define FLTRCR(f) (f->reg + 0x2C) +#define FL4ECCRESULT0(f) (f->reg + 0x80) +#define FL4ECCRESULT1(f) (f->reg + 0x84) +#define FL4ECCRESULT2(f) (f->reg + 0x88) +#define FL4ECCRESULT3(f) (f->reg + 0x8C) +#define FL4ECCCR(f) (f->reg + 0x90) +#define FL4ECCCNT(f) (f->reg + 0x94) +#define FLERRADR(f) (f->reg + 0x98) + +/* FLCMNCR control bits */ +#define ECCPOS2 (0x1 << 25) +#define _4ECCCNTEN (0x1 << 24) +#define _4ECCEN (0x1 << 23) +#define _4ECCCORRECT (0x1 << 22) +#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/ +#define QTSEL_E (0x1 << 17) +#define ENDIAN (0x1 << 16) /* 1 = little endian */ +#define FCKSEL_E (0x1 << 15) +#define ECCPOS_00 (0x00 << 12) +#define ECCPOS_01 (0x01 << 12) +#define ECCPOS_02 (0x02 << 12) +#define ACM_SACCES_MODE (0x01 << 10) +#define NANWF_E (0x1 << 9) +#define SE_D (0x1 << 8) /* Spare area disable */ +#define CE1_ENABLE (0x1 << 4) /* Chip Enable 1 */ +#define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */ +#define TYPESEL_SET (0x1 << 0) + +/* FLCMDCR control bits */ +#define ADRCNT2_E (0x1 << 31) /* 5byte address enable */ +#define ADRMD_E (0x1 << 26) /* Sector address access */ +#define CDSRC_E (0x1 << 25) /* Data buffer selection */ +#define DOSR_E (0x1 << 24) /* Status read check */ +#define SELRW (0x1 << 21) /* 0:read 1:write */ +#define DOADR_E (0x1 << 20) /* Address stage execute */ +#define ADRCNT_1 (0x00 << 18) /* Address data bytes: 1byte */ +#define ADRCNT_2 (0x01 << 18) /* Address data bytes: 2byte */ +#define ADRCNT_3 (0x02 << 18) /* Address data bytes: 3byte */ +#define ADRCNT_4 (0x03 << 18) /* Address data bytes: 4byte */ +#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */ +#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */ + +/* FLTRCR control bits */ +#define TRSTRT (0x1 << 0) /* translation start */ +#define TREND (0x1 << 1) /* translation end */ + +/* FL4ECCCR control bits */ +#define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */ +#define _4ECCEND (0x1 << 1) /* 4 symbols end */ +#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */ + +#define INIT_FL4ECCRESULT_VAL 0x03FF03FF +#define LOOP_TIMEOUT_MAX 0x00010000 + +#define mtd_to_flctl(mtd) container_of(mtd, struct sh_flctl, mtd) + +struct sh_flctl { + struct mtd_info mtd; + struct nand_chip chip; + void __iomem *reg; + + uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ + int read_bytes; + int index; + int seqin_column; /* column in SEQIN cmd */ + int seqin_page_addr; /* page_addr in SEQIN cmd */ + uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ + int erase1_page_addr; /* page_addr in ERASE1 cmd */ + uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */ + uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */ + + int hwecc_cant_correct[4]; + + unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */ + unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ +}; + +struct sh_flctl_platform_data { + struct mtd_partition *parts; + int nr_parts; + unsigned long flcmncr_val; + + unsigned has_hwecc:1; +}; + +#endif /* __SH_FLCTL_H__ */ -- cgit v1.2.3 From 74baaaaec8b4f22e1ae279f5ecca4ff705b28912 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 14 Oct 2008 09:21:02 -0400 Subject: vfs: Remove the range_cont writeback mode. Ext4 was the only user of range_cont writeback mode and ext4 switched to a different method. So remove the range_cont mode which is not used in the kernel. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" CC: linux-fsdevel@vger.kernel.org --- include/linux/writeback.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 12b15c561a1..bd91987c065 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -63,7 +63,6 @@ struct writeback_control { unsigned for_writepages:1; /* This is a writepages() call */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned more_io:1; /* more io to be dispatched */ - unsigned range_cont:1; }; /* -- cgit v1.2.3 From e6a7d3c04f8fe49099521e6dc9a46b0272381f2f Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 14 Oct 2008 11:58:31 -0700 Subject: netfilter: ctnetlink: remove bogus module dependency between ctnetlink and nf_nat This patch removes the module dependency between ctnetlink and nf_nat by means of an indirect call that is initialized when nf_nat is loaded. Now, nf_conntrack_netlink only requires nf_conntrack and nfnetlink. This patch puts nfnetlink_parse_nat_setup_hook into the nf_conntrack_core to avoid dependencies between ctnetlink, nf_conntrack_ipv4 and nf_conntrack_ipv6. This patch also introduces the function ctnetlink_change_nat that is only invoked from the creation path. Actually, the nat handling cannot be invoked from the update path since this is not allowed. By introducing this function, we remove the useless nat handling in the update path and we avoid deadlock-prone code. This patch also adds the required EAGAIN logic for nfnetlink. Signed-off-by: Pablo Neira Ayuso Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netfilter/nfnetlink.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h index 0d8424f7689..7d8e0455cca 100644 --- a/include/linux/netfilter/nfnetlink.h +++ b/include/linux/netfilter/nfnetlink.h @@ -78,6 +78,9 @@ extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo); extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags); +extern void nfnl_lock(void); +extern void nfnl_unlock(void); + #define MODULE_ALIAS_NFNL_SUBSYS(subsys) \ MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys)) -- cgit v1.2.3 From 93f78da405685a756beeaeae4b5e41fcec39eab3 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 14 Oct 2008 12:12:02 -0700 Subject: Revert "vt: fix background color on line feed" This reverts commit c9e587abfdec2c2aaa55fab83bcb4972e2f84f9b, and the subsequent commits that fixed it up: - afa9b649 "fbcon: prevent cursor disappearance after switching to 512 character font" - d850a2fa "vt/fbcon: fix background color on line feed" - 7fe3915a "vt/fbcon: update scrl_erase_char after 256/512-glyph font switch" by request of Alan Cox. Quoth Alan: "Unfortunately it's wrong and its been causing breakages because various apps like ncurses expect our previous (and correct) behaviour." Alexander sent out a similar patch. Requested-by: Alan Cox Tested-by: Jan Engelhardt Cc: Alexander V. Lukyanov Signed-off-by: Linus Torvalds --- include/linux/console_struct.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index b03f80a078b..d71f7c0f931 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -53,7 +53,6 @@ struct vc_data { unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */ struct console_font vc_font; /* Current VC font set */ unsigned short vc_video_erase_char; /* Background erase character */ - unsigned short vc_scrl_erase_char; /* Erase character for scroll */ /* VT terminal data */ unsigned int vc_state; /* Escape sequence parser state */ unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */ -- cgit v1.2.3 From e8c84f9a5f06912c94c38961096c994da3890a2e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 19 May 2008 15:50:01 +0200 Subject: modpost: add support for hid Generate aliases for hid device modules to support autoloading. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 + include/linux/mod_devicetable.h | 10 ++++++++++ 2 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index ac4e678a04e..b7a17762a0b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -67,6 +67,7 @@ #include #include #include +#include /* hid_device_id */ #include #include #include diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 3481a7d5bc0..d6a3f47e95c 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -131,6 +131,16 @@ struct usb_device_id { #define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 +#define HID_ANY_ID (~0) + +struct hid_device_id { + __u16 bus; + __u32 vendor; + __u32 product; + kernel_ulong_t driver_data + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + /* s390 CCW devices */ struct ccw_device_id { __u16 match_flags; /* which fields to match against */ -- cgit v1.2.3 From 85cdaf524b7ddab627e7d15405693f2511ef7505 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:15 +0200 Subject: HID: make a bus from hid code Make a bus from hid core. This is the first step for converting all the quirks and separate almost-drivers into real drivers attached to this bus. It's implemented to change behaviour in very tiny manner, so that no driver needs to be changed this time. Also add generic drivers for both usb and bt into usbhid or hidp respectively which will bind all non-blacklisted device. Those blacklisted will be either grabbed by special drivers or by nobody if they are broken at the very rude base. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 104 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 96 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index b7a17762a0b..c4bea0eda85 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -418,6 +418,8 @@ struct hid_control_fifo { #define HID_CLAIMED_HIDDEV 2 #define HID_CLAIMED_HIDRAW 4 +#define HID_STAT_ADDED 1 + #define HID_CTRL_RUNNING 1 #define HID_OUT_RUNNING 2 #define HID_IN_RUNNING 3 @@ -432,22 +434,26 @@ struct hid_input { struct input_dev *input; }; +struct hid_driver; + struct hid_device { /* device report descriptor */ - __u8 *rdesc; + __u8 *rdesc; unsigned rsize; struct hid_collection *collection; /* List of HID collections */ unsigned collection_size; /* Number of allocated hid_collections */ unsigned maxcollection; /* Number of parsed collections */ unsigned maxapplication; /* Number of applications */ - unsigned short bus; /* BUS ID */ - unsigned short vendor; /* Vendor ID */ - unsigned short product; /* Product ID */ - unsigned version; /* HID version */ + __u16 bus; /* BUS ID */ + __u32 vendor; /* Vendor ID */ + __u32 product; /* Product ID */ + __u32 version; /* HID version */ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; - struct device *dev; /* device */ + struct device dev; /* device */ + struct hid_driver *driver; + unsigned int status; /* see STAT flags above */ unsigned claimed; /* Claimed by hidinput, hiddev? */ unsigned quirks; /* Various quirks the device can pull on us */ @@ -483,6 +489,16 @@ struct hid_device { /* device report descriptor */ #endif }; +static inline void *hid_get_drvdata(struct hid_device *hdev) +{ + return dev_get_drvdata(&hdev->dev); +} + +static inline void hid_set_drvdata(struct hid_device *hdev, void *data) +{ + dev_set_drvdata(&hdev->dev, data); +} + #define HID_GLOBAL_STACK_SIZE 4 #define HID_COLLECTION_STACK_SIZE 4 @@ -511,6 +527,61 @@ struct hid_descriptor { struct hid_class_descriptor desc[1]; } __attribute__ ((packed)); +#define HID_DEVICE(b, ven, prod) \ + .bus = (b), \ + .vendor = (ven), .product = (prod) + +#define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) +#define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) + +#define HID_REPORT_ID(rep) \ + .report_type = (rep) +#define HID_USAGE_ID(uhid, utype, ucode) \ + .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) +/* we don't want to catch types and codes equal to 0 */ +#define HID_TERMINATOR (HID_ANY_ID - 1) + +struct hid_report_id { + __u32 report_type; +}; +struct hid_usage_id { + __u32 usage_hid; + __u32 usage_type; + __u32 usage_code; +}; + +/** + * struct hid_driver + * @name: driver name (e.g. "Footech_bar-wheel") + * @id_table: which devices is this driver for (must be non-NULL for probe + * to be called) + * @probe: new device inserted + * @remove: device removed (NULL if not a hot-plug capable driver) + * @report_table: on which reports to call raw_event (NULL means all) + * @raw_event: if report in report_table, this hook is called (NULL means nop) + * @usage_table: on which events to call event (NULL means all) + * @event: if usage in usage_table, this hook is called (NULL means nop) + * + * raw_event and event should return 0 on no action performed, 1 when no + * further processing should be done and negative on error + */ +struct hid_driver { + char *name; + const struct hid_device_id *id_table; + + int (*probe)(struct hid_device *dev, const struct hid_device_id *id); + void (*remove)(struct hid_device *dev); + + const struct hid_report_id *report_table; + int (*raw_event)(struct hid_device *hdev, struct hid_report *report, + u8 *data, int size); + const struct hid_usage_id *usage_table; + int (*event)(struct hid_device *hdev, struct hid_field *field, + struct hid_usage *usage, __s32 value); +/* private: */ + struct device_driver driver; +}; + /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* We ignore a few input applications that are not widely used */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) @@ -521,6 +592,17 @@ struct hid_descriptor { extern int hid_debug; #endif +extern int hid_add_device(struct hid_device *); +extern void hid_destroy_device(struct hid_device *); + +extern int __must_check __hid_register_driver(struct hid_driver *, + struct module *, const char *mod_name); +static inline int __must_check hid_register_driver(struct hid_driver *driver) +{ + return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); +} +extern void hid_unregister_driver(struct hid_driver *); + extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); extern int hidinput_connect(struct hid_device *); @@ -533,8 +615,14 @@ int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned lon int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); void hid_output_report(struct hid_report *report, __u8 *data); -void hid_free_device(struct hid_device *device); -struct hid_device *hid_parse_report(__u8 *start, unsigned size); +struct hid_device *hid_allocate_device(void); +int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); + +void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, + int interrupt); + +extern int hid_generic_init(void); +extern void hid_generic_exit(void); /* HID quirks API */ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); -- cgit v1.2.3 From c500c9714011edab021591340042787722db9cf0 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:16 +0200 Subject: HID: hid, make parsing event driven Next step for complete hid bus, this patch includes: - call parser either from probe or from hid-core if there is no probe. - add ll_driver structure and centralize some stuff there (open, close...) - split and merge usb_hid_configure and hid_probe into several functions to allow hooks/fixes between them Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 104 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 99 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index c4bea0eda85..ac2584fe65c 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -419,6 +419,7 @@ struct hid_control_fifo { #define HID_CLAIMED_HIDRAW 4 #define HID_STAT_ADDED 1 +#define HID_STAT_PARSED 2 #define HID_CTRL_RUNNING 1 #define HID_OUT_RUNNING 2 @@ -435,6 +436,7 @@ struct hid_input { }; struct hid_driver; +struct hid_ll_driver; struct hid_device { /* device report descriptor */ __u8 *rdesc; @@ -452,6 +454,7 @@ struct hid_device { /* device report descriptor */ struct device dev; /* device */ struct hid_driver *driver; + struct hid_ll_driver *ll_driver; unsigned int status; /* see STAT flags above */ unsigned claimed; /* Claimed by hidinput, hiddev? */ @@ -471,11 +474,6 @@ struct hid_device { /* device report descriptor */ __s32 delayed_value; /* For A4 Tech mice hwheel quirk */ - /* device-specific function pointers */ - int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int); - int (*hid_open) (struct hid_device *); - void (*hid_close) (struct hid_device *); - /* hiddev event handler */ void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, struct hid_usage *, __s32); @@ -561,9 +559,22 @@ struct hid_usage_id { * @raw_event: if report in report_table, this hook is called (NULL means nop) * @usage_table: on which events to call event (NULL means all) * @event: if usage in usage_table, this hook is called (NULL means nop) + * @report_fixup: called before report descriptor parsing (NULL means nop) + * @input_mapping: invoked on input registering before mapping an usage + * @input_mapped: invoked on input registering after mapping an usage * * raw_event and event should return 0 on no action performed, 1 when no * further processing should be done and negative on error + * + * input_mapping shall return a negative value to completely ignore this usage + * (e.g. doubled or invalid usage), zero to continue with parsing of this + * usage by generic code (no special handling needed) or positive to skip + * generic parsing (needed special handling which was done in the hook already) + * input_mapped shall return negative to inform the layer that this usage + * should not be considered for further processing or zero to notify that + * no processing was performed and should be done in a generic manner + * Both these functions may be NULL which means the same behavior as returning + * zero from them. */ struct hid_driver { char *name; @@ -578,10 +589,43 @@ struct hid_driver { const struct hid_usage_id *usage_table; int (*event)(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value); + + void (*report_fixup)(struct hid_device *hdev, __u8 *buf, + unsigned int size); + + int (*input_mapping)(struct hid_device *hdev, + struct hid_input *hidinput, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max); + int (*input_mapped)(struct hid_device *hdev, + struct hid_input *hidinput, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max); /* private: */ struct device_driver driver; }; +/** + * hid_ll_driver - low level driver callbacks + * @start: called on probe to start the device + * @stop: called on remove + * @open: called by input layer on open + * @close: called by input layer on close + * @hidinput_input_event: event input event (e.g. ff or leds) + * @parse: this method is called only once to parse the device data, + * shouldn't allocate anything to not leak memory + */ +struct hid_ll_driver { + int (*start)(struct hid_device *hdev); + void (*stop)(struct hid_device *hdev); + + int (*open)(struct hid_device *hdev); + void (*close)(struct hid_device *hdev); + + int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, + unsigned int code, int value); + + int (*parse)(struct hid_device *hdev); +}; + /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ /* We ignore a few input applications that are not widely used */ #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) @@ -618,6 +662,56 @@ void hid_output_report(struct hid_report *report, __u8 *data); struct hid_device *hid_allocate_device(void); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); +/** + * hid_parse - parse HW reports + * + * @hdev: hid device + * + * Call this from probe after you set up the device (if needed). Your + * report_fixup will be called (if non-NULL) after reading raw report from + * device before passing it to hid layer for real parsing. + */ +static inline int __must_check hid_parse(struct hid_device *hdev) +{ + int ret; + + if (hdev->status & HID_STAT_PARSED) + return 0; + + ret = hdev->ll_driver->parse(hdev); + if (!ret) + hdev->status |= HID_STAT_PARSED; + + return ret; +} + +/** + * hid_hw_start - start underlaying HW + * + * @hdev: hid device + * + * Call this in probe function *after* hid_parse. This will setup HW buffers + * and start the device (if not deffered to device open). hid_hw_stop must be + * called if this was successfull. + */ +static inline int __must_check hid_hw_start(struct hid_device *hdev) +{ + return hdev->ll_driver->start(hdev); +} + +/** + * hid_hw_stop - stop underlaying HW + * + * @hdev: hid device + * + * This is usually called from remove function or from probe when something + * failed and hid_hw_start was called already. + */ +static inline void hid_hw_stop(struct hid_device *hdev) +{ + hdev->ll_driver->stop(hdev); +} + void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); -- cgit v1.2.3 From 022e8c4d08b3b06361594b60412db0242035c4b4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:18 +0200 Subject: HID: move usage input mapping to hid.h This mapping are currently used on 2 placces and will be needed by more quirk drivers, so move them to hid.h to allow them to use it. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index ac2584fe65c..986c0e7ea66 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -655,13 +655,67 @@ extern void hidinput_disconnect(struct hid_device *); int hid_set_field(struct hid_field *, unsigned, __s32); int hid_input_report(struct hid_device *, int type, u8 *, int, int); int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); -int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *); +int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *, + unsigned long **, int *); int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); void hid_output_report(struct hid_report *report, __u8 *data); struct hid_device *hid_allocate_device(void); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); +/** + * hid_map_usage - map usage input bits + * + * @hidinput: hidinput which we are interested in + * @usage: usage to fill in + * @bit: pointer to input->{}bit (out parameter) + * @max: maximal valid usage->code to consider later (out parameter) + * @type: input event type (EV_KEY, EV_REL, ...) + * @c: code which corresponds to this usage and type + */ +static inline void hid_map_usage(struct hid_input *hidinput, + struct hid_usage *usage, unsigned long **bit, int *max, + __u8 type, __u16 c) +{ + struct input_dev *input = hidinput->input; + + usage->type = type; + usage->code = c; + + switch (type) { + case EV_ABS: + *bit = input->absbit; + *max = ABS_MAX; + break; + case EV_REL: + *bit = input->relbit; + *max = REL_MAX; + break; + case EV_KEY: + *bit = input->keybit; + *max = KEY_MAX; + break; + case EV_LED: + *bit = input->ledbit; + *max = LED_MAX; + break; + } +} + +/** + * hid_map_usage_clear - map usage input bits and clear the input bit + * + * The same as hid_map_usage, except the @c bit is also cleared in supported + * bits (@bit). + */ +static inline void hid_map_usage_clear(struct hid_input *hidinput, + struct hid_usage *usage, unsigned long **bit, int *max, + __u8 type, __u16 c) +{ + hid_map_usage(hidinput, usage, bit, max, type, c); + clear_bit(c, *bit); +} + /** * hid_parse - parse HW reports * -- cgit v1.2.3 From 5f22a7992349c5ca3842190be52d5e9a1dd7adf4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:19 +0200 Subject: HID: move logitech quirks Move them from the core and input code to a separate driver. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 986c0e7ea66..e9c4154ba33 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -270,15 +270,11 @@ struct hid_item { #define HID_QUIRK_APPLE_FN_ON 0x00001000 #define HID_QUIRK_INVERT_HWHEEL 0x00002000 #define HID_QUIRK_APPLE_ISO_KEYBOARD 0x00004000 -#define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_IGNORE_MOUSE 0x00020000 #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 -#define HID_QUIRK_DUPLICATE_USAGES 0x00080000 #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 -#define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL 0x00400000 -#define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP 0x00800000 #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 #define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 @@ -291,7 +287,6 @@ struct hid_item { */ #define HID_QUIRK_RDESC_CYMOTION 0x00000001 -#define HID_QUIRK_RDESC_LOGITECH 0x00000002 #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 #define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 -- cgit v1.2.3 From d458a9dfc4de24870b8c747484b1988726534bee Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:20 +0200 Subject: HID: move ignore quirks Move ignore quirks from usbhid-quirks into hid-core code. Also don't output warning when ENODEV is error code in usbhid and try ordinal input in hidp when that error is returned. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index e9c4154ba33..0644fd33b98 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -257,7 +257,6 @@ struct hid_item { #define HID_QUIRK_INVERT 0x00000001 #define HID_QUIRK_NOTOUCH 0x00000002 -#define HID_QUIRK_IGNORE 0x00000004 #define HID_QUIRK_NOGET 0x00000008 #define HID_QUIRK_HIDDEV 0x00000010 #define HID_QUIRK_BADPAD 0x00000020 -- cgit v1.2.3 From 8c19a51591d06f5226499972567f528cf6066bb7 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 18 Jun 2008 23:36:49 +0200 Subject: HID: move apple quirks Move them from the core code to a separate driver. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 0644fd33b98..75cc1531dd8 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -264,13 +264,7 @@ struct hid_item { #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 -#define HID_QUIRK_MIGHTYMOUSE 0x00000400 -#define HID_QUIRK_APPLE_HAS_FN 0x00000800 -#define HID_QUIRK_APPLE_FN_ON 0x00001000 -#define HID_QUIRK_INVERT_HWHEEL 0x00002000 -#define HID_QUIRK_APPLE_ISO_KEYBOARD 0x00004000 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 -#define HID_QUIRK_IGNORE_MOUSE 0x00020000 #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 @@ -279,7 +273,6 @@ struct hid_item { #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 #define HID_QUIRK_MICROSOFT_KEYS 0x08000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 -#define HID_QUIRK_APPLE_NUMLOCK_EMULATION 0x20000000 /* * Separate quirks for runtime report descriptor fixup @@ -288,7 +281,6 @@ struct hid_item { #define HID_QUIRK_RDESC_CYMOTION 0x00000001 #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 #define HID_QUIRK_RDESC_PETALYNX 0x00000008 -#define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 #define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080 @@ -475,10 +467,6 @@ struct hid_device { /* device report descriptor */ /* handler for raw output data, used by hidraw */ int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); -#ifdef CONFIG_USB_HIDINPUT_POWERBOOK - unsigned long apple_pressed_fn[BITS_TO_LONGS(KEY_CNT)]; - unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)]; -#endif }; static inline void *hid_get_drvdata(struct hid_device *hdev) @@ -652,7 +640,6 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *, unsigned long **, int *); int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); -int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); void hid_output_report(struct hid_report *report, __u8 *data); struct hid_device *hid_allocate_device(void); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); -- cgit v1.2.3 From 02ae9a1a8bc1d08a8fd5f6a0b8bde400b0f891b9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 16 May 2008 11:49:22 +0200 Subject: HID: add compat support Add compat option to hid code to allow loading of all modules on systems which don't allow autoloading because of old userspace. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 75cc1531dd8..60e44e6b86e 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -790,10 +790,23 @@ dbg_hid(const char *fmt, ...) return 0; } #define dbg_hid_line dbg_hid -#endif +#endif /* HID_DEBUG */ #define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ __FILE__ , ## arg) -#endif +#endif /* HID_FF */ + +#ifdef CONFIG_HID_COMPAT +#define HID_COMPAT_LOAD_DRIVER(name) \ +void hid_compat_##name(void) { } \ +EXPORT_SYMBOL(hid_compat_##name) +#else +#define HID_COMPAT_LOAD_DRIVER(name) +#endif /* HID_COMPAT */ +#define HID_COMPAT_CALL_DRIVER(name) do { \ + extern void hid_compat_##name(void); \ + hid_compat_##name(); \ +} while (0) + #endif -- cgit v1.2.3 From 78a849a682a1d5ee7b7187b08abdc48656326a4e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 20 Jun 2008 21:26:11 +0200 Subject: HID: move microsoft quirks Move them from the core code to a separate driver. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 60e44e6b86e..1f1edd886ef 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -271,7 +271,6 @@ struct hid_item { #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 #define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 -#define HID_QUIRK_MICROSOFT_KEYS 0x08000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 /* @@ -283,7 +282,6 @@ struct hid_item { #define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 -#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080 #define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP 0x00000100 /* -- cgit v1.2.3 From 90231e7eaf752856a2c13f786f36ec7f641bad28 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 23 Jun 2008 21:56:07 +0200 Subject: HID: move sunplus quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 1f1edd886ef..a83d211021d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -282,7 +282,6 @@ struct hid_item { #define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 -#define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP 0x00000100 /* * This is the global environment of the parser. This information is -- cgit v1.2.3 From 0f2213208f8da51bcb665309e3468f000489c04f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 23 Jun 2008 22:54:08 +0200 Subject: HID: move cypress quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index a83d211021d..27bfbcc1ef8 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -262,7 +262,6 @@ struct hid_item { #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 @@ -278,7 +277,6 @@ struct hid_item { */ #define HID_QUIRK_RDESC_CYMOTION 0x00000001 -#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 #define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 -- cgit v1.2.3 From 14a21cd459f97e3b3cc4fcde48fc5bcdb81d097e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 23 Jun 2008 23:31:09 +0200 Subject: HID: move a4tech quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 27bfbcc1ef8..a7cc4af2e46 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -261,14 +261,11 @@ struct hid_item { #define HID_QUIRK_HIDDEV 0x00000010 #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 -#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 @@ -453,8 +450,6 @@ struct hid_device { /* device report descriptor */ void *driver_data; - __s32 delayed_value; /* For A4 Tech mice hwheel quirk */ - /* hiddev event handler */ void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, struct hid_usage *, __s32); -- cgit v1.2.3 From 3b239cd739a9499da08326356add3d9d992c7911 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 24 Jun 2008 20:42:25 +0200 Subject: HID: move cherry quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index a7cc4af2e46..d9ab4a3af43 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -273,7 +273,6 @@ struct hid_item { * Separate quirks for runtime report descriptor fixup */ -#define HID_QUIRK_RDESC_CYMOTION 0x00000001 #define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 -- cgit v1.2.3 From 1f243e302cea1561ac881eb5d27041c5342beba4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 24 Jun 2008 21:11:21 +0200 Subject: HID: move ezkey quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index d9ab4a3af43..298cbcce3a2 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -266,7 +266,6 @@ struct hid_item { #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 -#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 /* -- cgit v1.2.3 From 1e76253220dbe66e048e55680266dd1f4af0be85 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Tue, 24 Jun 2008 23:46:21 +0200 Subject: HID: move petalynx quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 298cbcce3a2..7f4c94ffa61 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -272,7 +272,6 @@ struct hid_item { * Separate quirks for runtime report descriptor fixup */ -#define HID_QUIRK_RDESC_PETALYNX 0x00000008 #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 -- cgit v1.2.3 From 3b8006e51038ef263a0404756d9e190c9a9f74d5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 25 Jun 2008 00:07:50 +0200 Subject: HID: move monterey quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 7f4c94ffa61..3a639bff4ab 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -272,7 +272,6 @@ struct hid_item { * Separate quirks for runtime report descriptor fixup */ -#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 /* -- cgit v1.2.3 From 980a3da6acdd577ee3ae192e868dc52fe4b7f2e5 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 25 Jun 2008 22:31:48 +0200 Subject: HID: move samsung quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 3a639bff4ab..5b47feecc10 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -268,12 +268,6 @@ struct hid_item { #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 -/* - * Separate quirks for runtime report descriptor fixup - */ - -#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 - /* * This is the global environment of the parser. This information is * persistent for main-items. The global environment can be saved and -- cgit v1.2.3 From 3715ade981d524f9bb3b851a1eb81d3604a873bc Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 31 Jul 2008 11:09:37 +0200 Subject: HID: remove hid-input-quirks Remove the file since these is no user now. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 5b47feecc10..0de5fe8894d 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -617,9 +617,6 @@ extern void hidinput_disconnect(struct hid_device *); int hid_set_field(struct hid_field *, unsigned, __s32); int hid_input_report(struct hid_device *, int type, u8 *, int, int); int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); -int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *, - unsigned long **, int *); -int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); void hid_output_report(struct hid_report *report, __u8 *data); struct hid_device *hid_allocate_device(void); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); -- cgit v1.2.3 From 2b88b803018dbc2e9c68cbcd1739186e0715911a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 25 Jun 2008 23:03:55 +0200 Subject: HID: remove rdesc quirk support Remove support for both dynamic and static report descriptor quirks. There is no longer rdesc code which it would support, so it's useless. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 0de5fe8894d..9eac330a1df 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -734,7 +734,6 @@ extern void hid_generic_exit(void); u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); int usbhid_quirks_init(char **quirks_param); void usbhid_quirks_exit(void); -void usbhid_fixup_report_descriptor(const u16, const u16, char *, unsigned, char **); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -- cgit v1.2.3 From bd28ce008bdc68ef5902f68d2d62cbb7fa78c415 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 25 Jun 2008 23:47:04 +0200 Subject: HID: move sony quirks Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 9eac330a1df..43aa51a7fa9 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -262,7 +262,6 @@ struct hid_item { #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 -#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 #define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_HIDINPUT 0x00200000 #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 -- cgit v1.2.3 From 93c10132a7ac160df3175b53f7ee857625412165 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 27 Jun 2008 00:04:24 +0200 Subject: HID: move connect quirks Move connecting from usbhid to the hid layer and fix also hidp in that manner. This removes all the ignore/force hidinput/hiddev connecting quirks. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 37 ++++++++++++++++++++++++++++++------- include/linux/hiddev.h | 6 ++++-- 2 files changed, 34 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 43aa51a7fa9..043209f7bfc 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -246,6 +246,19 @@ struct hid_item { #define HID_OUTPUT_REPORT 1 #define HID_FEATURE_REPORT 2 +/* + * HID connect requests + */ + +#define HID_CONNECT_HIDINPUT 0x01 +#define HID_CONNECT_HIDINPUT_FORCE 0x02 +#define HID_CONNECT_HIDRAW 0x04 +#define HID_CONNECT_HIDDEV 0x08 +#define HID_CONNECT_HIDDEV_FORCE 0x10 +#define HID_CONNECT_FF 0x20 +#define HID_CONNECT_DEFAULT (HID_CONNECT_HIDINPUT|HID_CONNECT_HIDRAW| \ + HID_CONNECT_HIDDEV|HID_CONNECT_FF) + /* * HID device quirks. */ @@ -258,13 +271,10 @@ struct hid_item { #define HID_QUIRK_INVERT 0x00000001 #define HID_QUIRK_NOTOUCH 0x00000002 #define HID_QUIRK_NOGET 0x00000008 -#define HID_QUIRK_HIDDEV 0x00000010 #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 #define HID_QUIRK_RESET_LEDS 0x00100000 -#define HID_QUIRK_HIDINPUT 0x00200000 -#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 /* @@ -439,7 +449,11 @@ struct hid_device { /* device report descriptor */ void *driver_data; + /* temporary hid_ff handling (until moved to the drivers) */ + int (*ff_init)(struct hid_device *); + /* hiddev event handler */ + int (*hiddev_connect)(struct hid_device *, unsigned int); void (*hiddev_hid_event) (struct hid_device *, struct hid_field *field, struct hid_usage *, __s32); void (*hiddev_report_event) (struct hid_device *, struct hid_report *); @@ -610,7 +624,7 @@ extern void hid_unregister_driver(struct hid_driver *); extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); -extern int hidinput_connect(struct hid_device *); +extern int hidinput_connect(struct hid_device *hid, unsigned int force); extern void hidinput_disconnect(struct hid_device *); int hid_set_field(struct hid_field *, unsigned, __s32); @@ -619,6 +633,7 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int void hid_output_report(struct hid_report *report, __u8 *data); struct hid_device *hid_allocate_device(void); int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); +int hid_connect(struct hid_device *hid, unsigned int connect_mask); /** * hid_map_usage - map usage input bits @@ -700,14 +715,22 @@ static inline int __must_check hid_parse(struct hid_device *hdev) * hid_hw_start - start underlaying HW * * @hdev: hid device + * @connect_mask: which outputs to connect, see HID_CONNECT_* * * Call this in probe function *after* hid_parse. This will setup HW buffers * and start the device (if not deffered to device open). hid_hw_stop must be * called if this was successfull. */ -static inline int __must_check hid_hw_start(struct hid_device *hdev) +static inline int __must_check hid_hw_start(struct hid_device *hdev, + unsigned int connect_mask) { - return hdev->ll_driver->start(hdev); + int ret = hdev->ll_driver->start(hdev); + if (ret || !connect_mask) + return ret; + ret = hid_connect(hdev, connect_mask); + if (ret) + hdev->ll_driver->stop(hdev); + return ret; } /** @@ -749,7 +772,7 @@ static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } #endif #else -static inline int hid_ff_init(struct hid_device *hid) { return -1; } +#define hid_ff_init NULL #endif #ifdef CONFIG_HID_DEBUG diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index a416b904ba9..6ae77b3468f 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h @@ -217,7 +217,7 @@ struct hid_field; struct hid_report; #ifdef CONFIG_USB_HIDDEV -int hiddev_connect(struct hid_device *); +int hiddev_connect(struct hid_device *hid, unsigned int force); void hiddev_disconnect(struct hid_device *); void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value); @@ -225,7 +225,9 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report); int __init hiddev_init(void); void hiddev_exit(void); #else -static inline int hiddev_connect(struct hid_device *hid) { return -1; } +static inline int hiddev_connect(struct hid_device *hid, + unsigned int force) +{ return -1; } static inline void hiddev_disconnect(struct hid_device *hid) { } static inline void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { } -- cgit v1.2.3 From 6edfa8dc33803a49ad936ead9840e453bee6ca3b Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 27 Jun 2008 20:41:02 +0200 Subject: HID: move reset leds quirk Move the handling of the leds resetting from the core to the dell and logitech drivers. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 043209f7bfc..b0f03fa2ed1 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -274,7 +274,6 @@ struct hid_item { #define HID_QUIRK_BADPAD 0x00000020 #define HID_QUIRK_MULTI_INPUT 0x00000040 #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 -#define HID_QUIRK_RESET_LEDS 0x00100000 #define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 /* @@ -756,6 +755,7 @@ extern void hid_generic_exit(void); u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); int usbhid_quirks_init(char **quirks_param); void usbhid_quirks_exit(void); +void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -- cgit v1.2.3 From 606bd0a8616a0e59021cb2997e942513f24f641d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 4 Jul 2008 23:06:45 +0200 Subject: HID: move logitech FF processing Merge the logitech force feedback processing directly into logitech driver from the usbhid core. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index b0f03fa2ed1..15ee33e0463 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -760,8 +760,6 @@ void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -int hid_lgff_init(struct hid_device *hid); -int hid_lg2ff_init(struct hid_device *hid); int hid_plff_init(struct hid_device *hid); int hid_tmff_init(struct hid_device *hid); int hid_zpff_init(struct hid_device *hid); -- cgit v1.2.3 From 5f022298aab58ddff9bccdb28b82a59109789da9 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Sep 2008 19:43:32 +0200 Subject: HID: move pantherlord FF processing Move the force feedback processing into a separate module. [jkosina@suse.cz: fix Kconfig texts a little bit] Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 15ee33e0463..63b80806720 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -int hid_plff_init(struct hid_device *hid); int hid_tmff_init(struct hid_device *hid); int hid_zpff_init(struct hid_device *hid); #ifdef CONFIG_HID_PID -- cgit v1.2.3 From 10e41a711e55f485709b4ca157e587cf36ef5a69 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Sep 2008 12:23:31 +0200 Subject: HID: move thrustmaster FF processing Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 63b80806720..8266e50637b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -int hid_tmff_init(struct hid_device *hid); int hid_zpff_init(struct hid_device *hid); #ifdef CONFIG_HID_PID int hid_pidff_init(struct hid_device *hid); -- cgit v1.2.3 From 987fbc1f7d446f4bf7063d3b756ae29db80be75e Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Sep 2008 12:23:32 +0200 Subject: HID: move zeroplus FF processing Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 8266e50637b..0773ba6a66f 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -760,7 +760,6 @@ void usbhid_set_leds(struct hid_device *hid); #ifdef CONFIG_HID_FF int hid_ff_init(struct hid_device *hid); -int hid_zpff_init(struct hid_device *hid); #ifdef CONFIG_HID_PID int hid_pidff_init(struct hid_device *hid); #else -- cgit v1.2.3 From 76483cf4d0efbc35eaf9905a437f2f1be0221360 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Thu, 18 Sep 2008 12:23:33 +0200 Subject: HID: remove hid-ff hid-ff.c now calls only pidff (generic driver), the special ones are now in separate drivers. Invoke pidff on all non-special directly. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 0773ba6a66f..dcdef0bb4bb 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -757,17 +757,10 @@ int usbhid_quirks_init(char **quirks_param); void usbhid_quirks_exit(void); void usbhid_set_leds(struct hid_device *hid); -#ifdef CONFIG_HID_FF -int hid_ff_init(struct hid_device *hid); - #ifdef CONFIG_HID_PID int hid_pidff_init(struct hid_device *hid); #else -static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } -#endif - -#else -#define hid_ff_init NULL +#define hid_pidff_init NULL #endif #ifdef CONFIG_HID_DEBUG -- cgit v1.2.3 From 34a5ceee5eafe8cfa650d333304ce84a573ff7f0 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Thu, 2 Oct 2008 22:14:54 +0200 Subject: HID: hiddev.h: Fix mixed space and tabs in example code. Fix mixed space and tabs in example code. Signed-off-by: Antonio Ospite Signed-off-by: Jiri Kosina --- include/linux/hiddev.h | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index 6ae77b3468f..7a9ba294412 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h @@ -182,26 +182,26 @@ struct hiddev_usage_ref_multi { /* To traverse the input report descriptor info for a HID device, perform the * following: * - * rinfo.report_type = HID_REPORT_TYPE_INPUT; - * rinfo.report_id = HID_REPORT_ID_FIRST; - * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); + * rinfo.report_type = HID_REPORT_TYPE_INPUT; + * rinfo.report_id = HID_REPORT_ID_FIRST; + * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); * - * while (ret >= 0) { - * for (i = 0; i < rinfo.num_fields; i++) { - * finfo.report_type = rinfo.report_type; - * finfo.report_id = rinfo.report_id; - * finfo.field_index = i; - * ioctl(fd, HIDIOCGFIELDINFO, &finfo); - * for (j = 0; j < finfo.maxusage; j++) { - * uref.field_index = i; - * uref.usage_index = j; - * ioctl(fd, HIDIOCGUCODE, &uref); - * ioctl(fd, HIDIOCGUSAGE, &uref); - * } - * } - * rinfo.report_id |= HID_REPORT_ID_NEXT; - * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); - * } + * while (ret >= 0) { + * for (i = 0; i < rinfo.num_fields; i++) { + * finfo.report_type = rinfo.report_type; + * finfo.report_id = rinfo.report_id; + * finfo.field_index = i; + * ioctl(fd, HIDIOCGFIELDINFO, &finfo); + * for (j = 0; j < finfo.maxusage; j++) { + * uref.field_index = i; + * uref.usage_index = j; + * ioctl(fd, HIDIOCGUCODE, &uref); + * ioctl(fd, HIDIOCGUSAGE, &uref); + * } + * } + * rinfo.report_id |= HID_REPORT_ID_NEXT; + * ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo); + * } */ -- cgit v1.2.3 From dded364bf4e1f0de67d7d7b9e77c06b23a9f081f Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Thu, 2 Oct 2008 22:15:02 +0200 Subject: HID: hiddev.h: Fix example code. Fix hiddev.h example code. To get the correct usage code, you need to set report_type and report_id. Signed-off-by: Antonio Ospite Signed-off-by: Jiri Kosina --- include/linux/hiddev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index 7a9ba294412..c760ae0eb6a 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h @@ -193,6 +193,8 @@ struct hiddev_usage_ref_multi { * finfo.field_index = i; * ioctl(fd, HIDIOCGFIELDINFO, &finfo); * for (j = 0; j < finfo.maxusage; j++) { + * uref.report_type = rinfo.report_type; + * uref.report_id = rinfo.report_id; * uref.field_index = i; * uref.usage_index = j; * ioctl(fd, HIDIOCGUCODE, &uref); -- cgit v1.2.3 From f129ea6d1efe0eddcbb1f0faaec5623788ad9e58 Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sat, 4 Oct 2008 14:44:06 +0200 Subject: HID: fix a lockup regression when using force feedback on a PID device Commit 8006479c9b75fb6594a7b746af3d7f1fbb68f18f introduced a spinlock in input_dev->event_lock, which is locked when handling input events. However, the hid-pidff driver sleeps when handling events as it waits for reports being sent to the device before changing the report contents again. This causes a system lockup when trying to use force feedback with a PID device, a regression introduced in 2.6.24 and 2.6.23.15. Fix it by extracting the raw report data from struct hid_report immediately when hid_submit_report() is called, therefore allowing drivers to change the contents of struct hid_report immediately without affecting the already-queued transfer. In hid-pidff, re-add the removed usbhid_wait_io() to pidff_erase_effect() instead, to prevent a full report queue from causing the submission to fail, thus not freeing up device memory. pidff_erase_effect() is not called while dev->event_lock is held. Signed-off-by: Anssi Hannula Signed-off-by: Jiri Kosina --- include/linux/hid.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index dcdef0bb4bb..f13bca2dd53 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -388,6 +388,12 @@ struct hid_report_enum { struct hid_control_fifo { unsigned char dir; struct hid_report *report; + char *raw_report; +}; + +struct hid_output_fifo { + struct hid_report *report; + char *raw_report; }; #define HID_CLAIMED_INPUT 1 -- cgit v1.2.3 From 4704f0e274829e3af00737d2d9adace2d71a9605 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 14 Oct 2008 19:16:07 -0400 Subject: NFS: Fix the resolution problem with nfs_inode_attrs_need_update() It appears that 'jiffies' timestamps do not have high enough resolution for nfs_inode_attrs_need_update(). One problem is that a GETATTR can be launched within < 1 jiffy of the last operation that updated the attribute. Another problem is that RPC calls can take < 1 jiffy to execute. We can fix this by switching the variables to use a simple global counter that gets incremented every time we start another GETATTR call. Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 10 +++------- include/linux/nfs_xdr.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index ca563ee13e3..ac8d0233b05 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -137,7 +137,7 @@ struct nfs_inode { unsigned long attrtimeo_timestamp; __u64 change_attr; /* v4 only */ - unsigned long last_updated; + unsigned long attr_gencount; /* "Generation counter" for the attribute cache. This is * bumped whenever we update the metadata on the * server. @@ -344,15 +344,11 @@ extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ct 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 u64 nfs_compat_user_ino64(u64 fileid); +extern void nfs_fattr_init(struct nfs_fattr *fattr); /* linux/net/ipv4/ipconfig.c: trims ip addr off front of name, too. */ extern __be32 root_nfs_parse_addr(char *name); /*__init*/ - -static inline void nfs_fattr_init(struct nfs_fattr *fattr) -{ - fattr->valid = 0; - fattr->time_start = jiffies; -} +extern unsigned long nfs_inc_attr_generation_counter(void); /* * linux/fs/nfs/file.c diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 6ee6ae3f095..c1c31acb8a2 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -56,6 +56,7 @@ struct nfs_fattr { __u64 change_attr; /* NFSv4 change attribute */ __u64 pre_change_attr;/* pre-op NFSv4 change attribute */ unsigned long time_start; + unsigned long gencount; }; #define NFS_ATTR_WCC 0x0001 /* pre-op WCC data */ -- cgit v1.2.3 From d98e6346350ac909f095768beb28b82368bd126f Mon Sep 17 00:00:00 2001 From: Hollis Blanchard Date: Tue, 1 Jul 2008 16:23:49 -0500 Subject: KVM: Move KVM TRACE DEFINITIONS to common header Move KVM trace definitions from x86 specific kvm headers to common kvm headers to create a cross-architecture numbering scheme for trace events. This means the kvmtrace_format userspace tool won't need to know which architecture produced the log file being processed. Signed-off-by: Jerone Young Signed-off-by: Hollis Blanchard Signed-off-by: Avi Kivity --- include/linux/kvm.h | 21 +++++++++++++++++++++ include/linux/kvm_host.h | 19 +++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 70a30651cd1..8a3ceadb136 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -440,4 +440,25 @@ struct kvm_trace_rec { #define KVM_GET_MP_STATE _IOR(KVMIO, 0x98, struct kvm_mp_state) #define KVM_SET_MP_STATE _IOW(KVMIO, 0x99, struct kvm_mp_state) +#define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) +#define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) +#define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) +#define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05) +#define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06) +#define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07) +#define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08) +#define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09) +#define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A) +#define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B) +#define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C) +#define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D) +#define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E) +#define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F) +#define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10) +#define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11) +#define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12) +#define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) +#define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) +#define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15) + #endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 8525afc5310..a18aaad2ab7 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -326,6 +326,25 @@ struct kvm_stats_debugfs_item { extern struct kvm_stats_debugfs_item debugfs_entries[]; extern struct dentry *kvm_debugfs_dir; +#define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 5, d1, d2, d3, d4, d5) +#define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 4, d1, d2, d3, d4, 0) +#define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 3, d1, d2, d3, 0, 0) +#define KVMTRACE_2D(evt, vcpu, d1, d2, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 2, d1, d2, 0, 0, 0) +#define KVMTRACE_1D(evt, vcpu, d1, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 1, d1, 0, 0, 0, 0) +#define KVMTRACE_0D(evt, vcpu, name) \ + trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ + vcpu, 0, 0, 0, 0, 0, 0) + #ifdef CONFIG_KVM_TRACE int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg); void kvm_trace_cleanup(void); -- cgit v1.2.3 From e32c8f2c0720fb21c6f4a5f6ccbebdadc878f707 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Mon, 14 Jul 2008 14:00:00 +0200 Subject: KVM: kvmtrace: Remove use of bit fields in kvm trace structure This patch fixes kvmtrace use on big endian systems. When using bit fields the compiler will lay data out in the wrong order expected when laid down into a file. This fixes it by using one variable instead of using bit fields. Signed-off-by: Jerone Young Signed-off-by: Christian Ehrhardt Signed-off-by: Avi Kivity --- include/linux/kvm.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 8a3ceadb136..8a16b083df2 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -311,9 +311,13 @@ struct kvm_s390_interrupt { /* This structure represents a single trace buffer record. */ struct kvm_trace_rec { - __u32 event:28; - __u32 extra_u32:3; - __u32 cycle_in:1; + /* variable rec_val + * is split into: + * bits 0 - 27 -> event id + * bits 28 -30 -> number of extra data args of size u32 + * bits 31 -> binary indicator for if tsc is in record + */ + __u32 rec_val; __u32 pid; __u32 vcpu_id; union { @@ -327,6 +331,13 @@ struct kvm_trace_rec { } u; }; +#define TRACE_REC_EVENT_ID(val) \ + (0x0fffffff & (val)) +#define TRACE_REC_NUM_DATA_ARGS(val) \ + (0x70000000 & ((val) << 28)) +#define TRACE_REC_TCS(val) \ + (0x80000000 & ((val) << 31)) + #define KVMIO 0xAE /* -- cgit v1.2.3 From 3f7f95c65ef6a89472a28da1b9436eaeee288831 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Mon, 14 Jul 2008 14:00:01 +0200 Subject: KVM: kvmtrace: replace get_cycles with ktime_get v3 The current kvmtrace code uses get_cycles() while the interpretation would be easier using using nanoseconds. ktime_get() should give at least the same accuracy as get_cycles on all architectures (even better on 32bit archs) but at a better unit (e.g. comparable between hosts with different frequencies. [avi: avoid ktime_t in public header] Signed-off-by: Christian Ehrhardt Acked-by: Christian Borntraeger Signed-off-by: Avi Kivity --- include/linux/kvm.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 8a16b083df2..5d08f11bb27 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -322,12 +322,12 @@ struct kvm_trace_rec { __u32 vcpu_id; union { struct { - __u64 cycle_u64; + __u64 timestamp; __u32 extra_u32[KVM_TRC_EXTRA_MAX]; - } __attribute__((packed)) cycle; + } __attribute__((packed)) timestamp; struct { __u32 extra_u32[KVM_TRC_EXTRA_MAX]; - } nocycle; + } notimestamp; } u; }; -- cgit v1.2.3 From 31711f2294b38d8334efaf7dbac6da4781fd151e Mon Sep 17 00:00:00 2001 From: Jerone Young Date: Mon, 14 Jul 2008 14:00:03 +0200 Subject: KVM: ppc: adds trace points for ppc tlb activity This patch adds trace points to track powerpc TLB activities using the KVM_TRACE infrastructure. Signed-off-by: Jerone Young Signed-off-by: Christian Ehrhardt Signed-off-by: Avi Kivity --- include/linux/kvm.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 5d08f11bb27..e21a5050d4d 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -471,5 +471,8 @@ struct kvm_trace_rec { #define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) #define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) #define KVM_TRC_TDP_FAULT (KVM_TRC_HANDLER + 0x15) +#define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16) +#define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17) +#define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18) #endif -- cgit v1.2.3 From 3b4bd7969f7b61a1ab455bff084ee4f0a2411055 Mon Sep 17 00:00:00 2001 From: Christian Ehrhardt Date: Mon, 14 Jul 2008 14:00:04 +0200 Subject: KVM: ppc: trace powerpc instruction emulation This patch adds a trace point for the instruction emulation on embedded powerpc utilizing the KVM_TRACE interface. Signed-off-by: Christian Ehrhardt Signed-off-by: Avi Kivity --- include/linux/kvm.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index e21a5050d4d..d29b6488144 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -474,5 +474,6 @@ struct kvm_trace_rec { #define KVM_TRC_GTLB_WRITE (KVM_TRC_HANDLER + 0x16) #define KVM_TRC_STLB_WRITE (KVM_TRC_HANDLER + 0x17) #define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18) +#define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19) #endif -- cgit v1.2.3 From 4d5c5d0fe89c921336b95f5e7e4f529a9df92f53 Mon Sep 17 00:00:00 2001 From: Ben-Ami Yassour Date: Mon, 28 Jul 2008 19:26:26 +0300 Subject: KVM: pci device assignment Based on a patch from: Amit Shah This patch adds support for handling PCI devices that are assigned to the guest. The device to be assigned to the guest is registered in the host kernel and interrupt delivery is handled. If a device is already assigned, or the device driver for it is still loaded on the host, the device assignment is failed by conveying a -EBUSY reply to the userspace. Devices that share their interrupt line are not supported at the moment. By itself, this patch will not make devices work within the guest. The VT-d extension is required to enable the device to perform DMA. Another alternative is PVDMA. Signed-off-by: Amit Shah Signed-off-by: Ben-Ami Yassour Signed-off-by: Weidong Han Signed-off-by: Avi Kivity --- include/linux/kvm.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index d29b6488144..ef4bc6f8977 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -383,6 +383,7 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ +#define KVM_CAP_DEVICE_ASSIGNMENT 17 /* * ioctls for VM fds @@ -412,6 +413,10 @@ struct kvm_trace_rec { _IOW(KVMIO, 0x67, struct kvm_coalesced_mmio_zone) #define KVM_UNREGISTER_COALESCED_MMIO \ _IOW(KVMIO, 0x68, struct kvm_coalesced_mmio_zone) +#define KVM_ASSIGN_PCI_DEVICE _IOR(KVMIO, 0x69, \ + struct kvm_assigned_pci_dev) +#define KVM_ASSIGN_IRQ _IOR(KVMIO, 0x70, \ + struct kvm_assigned_irq) /* * ioctls for vcpu fds @@ -476,4 +481,18 @@ struct kvm_trace_rec { #define KVM_TRC_STLB_INVAL (KVM_TRC_HANDLER + 0x18) #define KVM_TRC_PPC_INSTR (KVM_TRC_HANDLER + 0x19) +struct kvm_assigned_pci_dev { + __u32 assigned_dev_id; + __u32 busnr; + __u32 devfn; + __u32 flags; +}; + +struct kvm_assigned_irq { + __u32 assigned_dev_id; + __u32 host_irq; + __u32 guest_irq; + __u32 flags; +}; + #endif -- cgit v1.2.3 From d76901750ab9f71091d33ef3d2b5909d8a9a4ad4 Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Mon, 8 Sep 2008 15:23:48 -0300 Subject: KVM: x86: do not execute halted vcpus Offline or uninitialized vcpu's can be executed if requested to perform userspace work. Follow Avi's suggestion to handle halted vcpu's in the main loop, simplifying kvm_emulate_halt(). Introduce a new vcpu->requests bit to indicate events that promote state from halted to running. Also standardize vcpu wake sites. Signed-off-by: Marcelo Tosatti redhat.com> Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index a18aaad2ab7..4b036430ea2 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -34,6 +34,7 @@ #define KVM_REQ_MMU_RELOAD 3 #define KVM_REQ_TRIPLE_FAULT 4 #define KVM_REQ_PENDING_TIMER 5 +#define KVM_REQ_UNHALT 6 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -- cgit v1.2.3 From 7d81a5e03ddbb44d05a32cad4a46a23577216497 Mon Sep 17 00:00:00 2001 From: Thomas Bogendoerfer Date: Tue, 14 Oct 2008 17:16:55 +0200 Subject: MIPS: IP22/28: Switch over to RTC class driver This patchset removes some dead code and creates a platform device for the RTC class driver. Signed-off-by: Thomas Bogendoerfer Signed-off-by: Ralf Baechle --- include/linux/ds1286.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ds1286.h b/include/linux/ds1286.h index d8989860e4c..45ea0aa0aeb 100644 --- a/include/linux/ds1286.h +++ b/include/linux/ds1286.h @@ -8,8 +8,6 @@ #ifndef __LINUX_DS1286_H #define __LINUX_DS1286_H -#include - /********************************************************************** * register summary **********************************************************************/ -- cgit v1.2.3 From 387179464257921eb9aa3d15cc3ff194f6945a7c Mon Sep 17 00:00:00 2001 From: "Kay, Allen M" Date: Tue, 9 Sep 2008 18:37:29 +0300 Subject: VT-d: Changes to support KVM This patch extends the VT-d driver to support KVM [Ben: fixed memory pinning] [avi: move dma_remapping.h as well] Signed-off-by: Kay, Allen M Signed-off-by: Weidong Han Signed-off-by: Ben-Ami Yassour Signed-off-by: Amit Shah Acked-by: Mark Gross Signed-off-by: Avi Kivity --- include/linux/dma_remapping.h | 157 ++++++++++++++++++++ include/linux/intel-iommu.h | 327 ++++++++++++++++++++++++++++++++++++++++++ include/linux/iova.h | 52 +++++++ 3 files changed, 536 insertions(+) create mode 100644 include/linux/dma_remapping.h create mode 100644 include/linux/intel-iommu.h create mode 100644 include/linux/iova.h (limited to 'include/linux') diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h new file mode 100644 index 00000000000..bff5c65f81d --- /dev/null +++ b/include/linux/dma_remapping.h @@ -0,0 +1,157 @@ +#ifndef _DMA_REMAPPING_H +#define _DMA_REMAPPING_H + +/* + * We need a fixed PAGE_SIZE of 4K irrespective of + * arch PAGE_SIZE for IOMMU page tables. + */ +#define PAGE_SHIFT_4K (12) +#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) +#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) +#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) + +#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K) +#define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) +#define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) + + +/* + * 0: Present + * 1-11: Reserved + * 12-63: Context Ptr (12 - (haw-1)) + * 64-127: Reserved + */ +struct root_entry { + u64 val; + u64 rsvd1; +}; +#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry)) +static inline bool root_present(struct root_entry *root) +{ + return (root->val & 1); +} +static inline void set_root_present(struct root_entry *root) +{ + root->val |= 1; +} +static inline void set_root_value(struct root_entry *root, unsigned long value) +{ + root->val |= value & PAGE_MASK_4K; +} + +struct context_entry; +static inline struct context_entry * +get_context_addr_from_root(struct root_entry *root) +{ + return (struct context_entry *) + (root_present(root)?phys_to_virt( + root->val & PAGE_MASK_4K): + NULL); +} + +/* + * low 64 bits: + * 0: present + * 1: fault processing disable + * 2-3: translation type + * 12-63: address space root + * high 64 bits: + * 0-2: address width + * 3-6: aval + * 8-23: domain id + */ +struct context_entry { + u64 lo; + u64 hi; +}; +#define context_present(c) ((c).lo & 1) +#define context_fault_disable(c) (((c).lo >> 1) & 1) +#define context_translation_type(c) (((c).lo >> 2) & 3) +#define context_address_root(c) ((c).lo & PAGE_MASK_4K) +#define context_address_width(c) ((c).hi & 7) +#define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) + +#define context_set_present(c) do {(c).lo |= 1;} while (0) +#define context_set_fault_enable(c) \ + do {(c).lo &= (((u64)-1) << 2) | 1;} while (0) +#define context_set_translation_type(c, val) \ + do { \ + (c).lo &= (((u64)-1) << 4) | 3; \ + (c).lo |= ((val) & 3) << 2; \ + } while (0) +#define CONTEXT_TT_MULTI_LEVEL 0 +#define context_set_address_root(c, val) \ + do {(c).lo |= (val) & PAGE_MASK_4K;} while (0) +#define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0) +#define context_set_domain_id(c, val) \ + do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0) +#define context_clear_entry(c) do {(c).lo = 0; (c).hi = 0;} while (0) + +/* + * 0: readable + * 1: writable + * 2-6: reserved + * 7: super page + * 8-11: available + * 12-63: Host physcial address + */ +struct dma_pte { + u64 val; +}; +#define dma_clear_pte(p) do {(p).val = 0;} while (0) + +#define DMA_PTE_READ (1) +#define DMA_PTE_WRITE (2) + +#define dma_set_pte_readable(p) do {(p).val |= DMA_PTE_READ;} while (0) +#define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0) +#define dma_set_pte_prot(p, prot) \ + do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0) +#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K) +#define dma_set_pte_addr(p, addr) do {\ + (p).val |= ((addr) & PAGE_MASK_4K); } while (0) +#define dma_pte_present(p) (((p).val & 3) != 0) + +struct intel_iommu; + +struct dmar_domain { + int id; /* domain id */ + struct intel_iommu *iommu; /* back pointer to owning iommu */ + + struct list_head devices; /* all devices' list */ + struct iova_domain iovad; /* iova's that belong to this domain */ + + struct dma_pte *pgd; /* virtual address */ + spinlock_t mapping_lock; /* page table lock */ + int gaw; /* max guest address width */ + + /* adjusted guest address width, 0 is level 2 30-bit */ + int agaw; + +#define DOMAIN_FLAG_MULTIPLE_DEVICES 1 + int flags; +}; + +/* PCI domain-device relationship */ +struct device_domain_info { + struct list_head link; /* link to domain siblings */ + struct list_head global; /* link to global list */ + u8 bus; /* PCI bus numer */ + u8 devfn; /* PCI devfn number */ + struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */ + struct dmar_domain *domain; /* pointer to domain */ +}; + +extern int init_dmars(void); +extern void free_dmar_iommu(struct intel_iommu *iommu); + +extern int dmar_disabled; + +#ifndef CONFIG_DMAR_GFX_WA +static inline void iommu_prepare_gfx_mapping(void) +{ + return; +} +#endif /* !CONFIG_DMAR_GFX_WA */ + +#endif diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h new file mode 100644 index 00000000000..2e117f30a76 --- /dev/null +++ b/include/linux/intel-iommu.h @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * 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., 59 Temple + * Place - Suite 330, Boston, MA 02111-1307 USA. + * + * Copyright (C) 2006-2008 Intel Corporation + * Author: Ashok Raj + * Author: Anil S Keshavamurthy + */ + +#ifndef _INTEL_IOMMU_H_ +#define _INTEL_IOMMU_H_ + +#include +#include +#include +#include +#include +#include +#include + +/* + * Intel IOMMU register specification per version 1.0 public spec. + */ + +#define DMAR_VER_REG 0x0 /* Arch version supported by this IOMMU */ +#define DMAR_CAP_REG 0x8 /* Hardware supported capabilities */ +#define DMAR_ECAP_REG 0x10 /* Extended capabilities supported */ +#define DMAR_GCMD_REG 0x18 /* Global command register */ +#define DMAR_GSTS_REG 0x1c /* Global status register */ +#define DMAR_RTADDR_REG 0x20 /* Root entry table */ +#define DMAR_CCMD_REG 0x28 /* Context command reg */ +#define DMAR_FSTS_REG 0x34 /* Fault Status register */ +#define DMAR_FECTL_REG 0x38 /* Fault control register */ +#define DMAR_FEDATA_REG 0x3c /* Fault event interrupt data register */ +#define DMAR_FEADDR_REG 0x40 /* Fault event interrupt addr register */ +#define DMAR_FEUADDR_REG 0x44 /* Upper address register */ +#define DMAR_AFLOG_REG 0x58 /* Advanced Fault control */ +#define DMAR_PMEN_REG 0x64 /* Enable Protected Memory Region */ +#define DMAR_PLMBASE_REG 0x68 /* PMRR Low addr */ +#define DMAR_PLMLIMIT_REG 0x6c /* PMRR low limit */ +#define DMAR_PHMBASE_REG 0x70 /* pmrr high base addr */ +#define DMAR_PHMLIMIT_REG 0x78 /* pmrr high limit */ +#define DMAR_IQH_REG 0x80 /* Invalidation queue head register */ +#define DMAR_IQT_REG 0x88 /* Invalidation queue tail register */ +#define DMAR_IQA_REG 0x90 /* Invalidation queue addr register */ +#define DMAR_ICS_REG 0x98 /* Invalidation complete status register */ +#define DMAR_IRTA_REG 0xb8 /* Interrupt remapping table addr register */ + +#define OFFSET_STRIDE (9) +/* +#define dmar_readl(dmar, reg) readl(dmar + reg) +#define dmar_readq(dmar, reg) ({ \ + u32 lo, hi; \ + lo = readl(dmar + reg); \ + hi = readl(dmar + reg + 4); \ + (((u64) hi) << 32) + lo; }) +*/ +static inline u64 dmar_readq(void __iomem *addr) +{ + u32 lo, hi; + lo = readl(addr); + hi = readl(addr + 4); + return (((u64) hi) << 32) + lo; +} + +static inline void dmar_writeq(void __iomem *addr, u64 val) +{ + writel((u32)val, addr); + writel((u32)(val >> 32), addr + 4); +} + +#define DMAR_VER_MAJOR(v) (((v) & 0xf0) >> 4) +#define DMAR_VER_MINOR(v) ((v) & 0x0f) + +/* + * Decoding Capability Register + */ +#define cap_read_drain(c) (((c) >> 55) & 1) +#define cap_write_drain(c) (((c) >> 54) & 1) +#define cap_max_amask_val(c) (((c) >> 48) & 0x3f) +#define cap_num_fault_regs(c) ((((c) >> 40) & 0xff) + 1) +#define cap_pgsel_inv(c) (((c) >> 39) & 1) + +#define cap_super_page_val(c) (((c) >> 34) & 0xf) +#define cap_super_offset(c) (((find_first_bit(&cap_super_page_val(c), 4)) \ + * OFFSET_STRIDE) + 21) + +#define cap_fault_reg_offset(c) ((((c) >> 24) & 0x3ff) * 16) +#define cap_max_fault_reg_offset(c) \ + (cap_fault_reg_offset(c) + cap_num_fault_regs(c) * 16) + +#define cap_zlr(c) (((c) >> 22) & 1) +#define cap_isoch(c) (((c) >> 23) & 1) +#define cap_mgaw(c) ((((c) >> 16) & 0x3f) + 1) +#define cap_sagaw(c) (((c) >> 8) & 0x1f) +#define cap_caching_mode(c) (((c) >> 7) & 1) +#define cap_phmr(c) (((c) >> 6) & 1) +#define cap_plmr(c) (((c) >> 5) & 1) +#define cap_rwbf(c) (((c) >> 4) & 1) +#define cap_afl(c) (((c) >> 3) & 1) +#define cap_ndoms(c) (((unsigned long)1) << (4 + 2 * ((c) & 0x7))) +/* + * Extended Capability Register + */ + +#define ecap_niotlb_iunits(e) ((((e) >> 24) & 0xff) + 1) +#define ecap_iotlb_offset(e) ((((e) >> 8) & 0x3ff) * 16) +#define ecap_max_iotlb_offset(e) \ + (ecap_iotlb_offset(e) + ecap_niotlb_iunits(e) * 16) +#define ecap_coherent(e) ((e) & 0x1) +#define ecap_qis(e) ((e) & 0x2) +#define ecap_eim_support(e) ((e >> 4) & 0x1) +#define ecap_ir_support(e) ((e >> 3) & 0x1) +#define ecap_max_handle_mask(e) ((e >> 20) & 0xf) + + +/* IOTLB_REG */ +#define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) +#define DMA_TLB_DSI_FLUSH (((u64)2) << 60) +#define DMA_TLB_PSI_FLUSH (((u64)3) << 60) +#define DMA_TLB_IIRG(type) ((type >> 60) & 7) +#define DMA_TLB_IAIG(val) (((val) >> 57) & 7) +#define DMA_TLB_READ_DRAIN (((u64)1) << 49) +#define DMA_TLB_WRITE_DRAIN (((u64)1) << 48) +#define DMA_TLB_DID(id) (((u64)((id) & 0xffff)) << 32) +#define DMA_TLB_IVT (((u64)1) << 63) +#define DMA_TLB_IH_NONLEAF (((u64)1) << 6) +#define DMA_TLB_MAX_SIZE (0x3f) + +/* INVALID_DESC */ +#define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3) +#define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3) +#define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3) +#define DMA_ID_TLB_READ_DRAIN (((u64)1) << 7) +#define DMA_ID_TLB_WRITE_DRAIN (((u64)1) << 6) +#define DMA_ID_TLB_DID(id) (((u64)((id & 0xffff) << 16))) +#define DMA_ID_TLB_IH_NONLEAF (((u64)1) << 6) +#define DMA_ID_TLB_ADDR(addr) (addr) +#define DMA_ID_TLB_ADDR_MASK(mask) (mask) + +/* PMEN_REG */ +#define DMA_PMEN_EPM (((u32)1)<<31) +#define DMA_PMEN_PRS (((u32)1)<<0) + +/* GCMD_REG */ +#define DMA_GCMD_TE (((u32)1) << 31) +#define DMA_GCMD_SRTP (((u32)1) << 30) +#define DMA_GCMD_SFL (((u32)1) << 29) +#define DMA_GCMD_EAFL (((u32)1) << 28) +#define DMA_GCMD_WBF (((u32)1) << 27) +#define DMA_GCMD_QIE (((u32)1) << 26) +#define DMA_GCMD_SIRTP (((u32)1) << 24) +#define DMA_GCMD_IRE (((u32) 1) << 25) + +/* GSTS_REG */ +#define DMA_GSTS_TES (((u32)1) << 31) +#define DMA_GSTS_RTPS (((u32)1) << 30) +#define DMA_GSTS_FLS (((u32)1) << 29) +#define DMA_GSTS_AFLS (((u32)1) << 28) +#define DMA_GSTS_WBFS (((u32)1) << 27) +#define DMA_GSTS_QIES (((u32)1) << 26) +#define DMA_GSTS_IRTPS (((u32)1) << 24) +#define DMA_GSTS_IRES (((u32)1) << 25) + +/* CCMD_REG */ +#define DMA_CCMD_ICC (((u64)1) << 63) +#define DMA_CCMD_GLOBAL_INVL (((u64)1) << 61) +#define DMA_CCMD_DOMAIN_INVL (((u64)2) << 61) +#define DMA_CCMD_DEVICE_INVL (((u64)3) << 61) +#define DMA_CCMD_FM(m) (((u64)((m) & 0x3)) << 32) +#define DMA_CCMD_MASK_NOBIT 0 +#define DMA_CCMD_MASK_1BIT 1 +#define DMA_CCMD_MASK_2BIT 2 +#define DMA_CCMD_MASK_3BIT 3 +#define DMA_CCMD_SID(s) (((u64)((s) & 0xffff)) << 16) +#define DMA_CCMD_DID(d) ((u64)((d) & 0xffff)) + +/* FECTL_REG */ +#define DMA_FECTL_IM (((u32)1) << 31) + +/* FSTS_REG */ +#define DMA_FSTS_PPF ((u32)2) +#define DMA_FSTS_PFO ((u32)1) +#define dma_fsts_fault_record_index(s) (((s) >> 8) & 0xff) + +/* FRCD_REG, 32 bits access */ +#define DMA_FRCD_F (((u32)1) << 31) +#define dma_frcd_type(d) ((d >> 30) & 1) +#define dma_frcd_fault_reason(c) (c & 0xff) +#define dma_frcd_source_id(c) (c & 0xffff) +#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */ + +#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */ + +#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ +{\ + cycles_t start_time = get_cycles();\ + while (1) {\ + sts = op (iommu->reg + offset);\ + if (cond)\ + break;\ + if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\ + panic("DMAR hardware is malfunctioning\n");\ + cpu_relax();\ + }\ +} + +#define QI_LENGTH 256 /* queue length */ + +enum { + QI_FREE, + QI_IN_USE, + QI_DONE +}; + +#define QI_CC_TYPE 0x1 +#define QI_IOTLB_TYPE 0x2 +#define QI_DIOTLB_TYPE 0x3 +#define QI_IEC_TYPE 0x4 +#define QI_IWD_TYPE 0x5 + +#define QI_IEC_SELECTIVE (((u64)1) << 4) +#define QI_IEC_IIDEX(idx) (((u64)(idx & 0xffff) << 32)) +#define QI_IEC_IM(m) (((u64)(m & 0x1f) << 27)) + +#define QI_IWD_STATUS_DATA(d) (((u64)d) << 32) +#define QI_IWD_STATUS_WRITE (((u64)1) << 5) + +struct qi_desc { + u64 low, high; +}; + +struct q_inval { + spinlock_t q_lock; + struct qi_desc *desc; /* invalidation queue */ + int *desc_status; /* desc status */ + int free_head; /* first free entry */ + int free_tail; /* last free entry */ + int free_cnt; +}; + +#ifdef CONFIG_INTR_REMAP +/* 1MB - maximum possible interrupt remapping table size */ +#define INTR_REMAP_PAGE_ORDER 8 +#define INTR_REMAP_TABLE_REG_SIZE 0xf + +#define INTR_REMAP_TABLE_ENTRIES 65536 + +struct ir_table { + struct irte *base; +}; +#endif + +struct intel_iommu { + void __iomem *reg; /* Pointer to hardware regs, virtual addr */ + u64 cap; + u64 ecap; + int seg; + u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */ + spinlock_t register_lock; /* protect register handling */ + int seq_id; /* sequence id of the iommu */ + +#ifdef CONFIG_DMAR + unsigned long *domain_ids; /* bitmap of domains */ + struct dmar_domain **domains; /* ptr to domains */ + spinlock_t lock; /* protect context, domain ids */ + struct root_entry *root_entry; /* virtual address */ + + unsigned int irq; + unsigned char name[7]; /* Device Name */ + struct msi_msg saved_msg; + struct sys_device sysdev; +#endif + struct q_inval *qi; /* Queued invalidation info */ +#ifdef CONFIG_INTR_REMAP + struct ir_table *ir_table; /* Interrupt remapping info */ +#endif +}; + +static inline void __iommu_flush_cache( + struct intel_iommu *iommu, void *addr, int size) +{ + if (!ecap_coherent(iommu->ecap)) + clflush_cache_range(addr, size); +} + +extern struct dmar_drhd_unit * dmar_find_matched_drhd_unit(struct pci_dev *dev); + +extern int alloc_iommu(struct dmar_drhd_unit *drhd); +extern void free_iommu(struct intel_iommu *iommu); +extern int dmar_enable_qi(struct intel_iommu *iommu); +extern void qi_global_iec(struct intel_iommu *iommu); + +extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); + +void intel_iommu_domain_exit(struct dmar_domain *domain); +struct dmar_domain *intel_iommu_domain_alloc(struct pci_dev *pdev); +int intel_iommu_context_mapping(struct dmar_domain *domain, + struct pci_dev *pdev); +int intel_iommu_page_mapping(struct dmar_domain *domain, dma_addr_t iova, + u64 hpa, size_t size, int prot); +void intel_iommu_detach_dev(struct dmar_domain *domain, u8 bus, u8 devfn); +struct dmar_domain *intel_iommu_find_domain(struct pci_dev *pdev); +u64 intel_iommu_iova_to_pfn(struct dmar_domain *domain, u64 iova); + +#ifdef CONFIG_DMAR +int intel_iommu_found(void); +#else /* CONFIG_DMAR */ +static inline int intel_iommu_found(void) +{ + return 0; +} +#endif /* CONFIG_DMAR */ + +#endif diff --git a/include/linux/iova.h b/include/linux/iova.h new file mode 100644 index 00000000000..228f6c94b69 --- /dev/null +++ b/include/linux/iova.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006, Intel Corporation. + * + * This file is released under the GPLv2. + * + * Copyright (C) 2006-2008 Intel Corporation + * Author: Anil S Keshavamurthy + * + */ + +#ifndef _IOVA_H_ +#define _IOVA_H_ + +#include +#include +#include +#include + +/* IO virtual address start page frame number */ +#define IOVA_START_PFN (1) + +/* iova structure */ +struct iova { + struct rb_node node; + unsigned long pfn_hi; /* IOMMU dish out addr hi */ + unsigned long pfn_lo; /* IOMMU dish out addr lo */ +}; + +/* holds all the iova translations for a domain */ +struct iova_domain { + spinlock_t iova_alloc_lock;/* Lock to protect iova allocation */ + spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ + struct rb_root rbroot; /* iova domain rbtree root */ + struct rb_node *cached32_node; /* Save last alloced node */ + unsigned long dma_32bit_pfn; +}; + +struct iova *alloc_iova_mem(void); +void free_iova_mem(struct iova *iova); +void free_iova(struct iova_domain *iovad, unsigned long pfn); +void __free_iova(struct iova_domain *iovad, struct iova *iova); +struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size, + unsigned long limit_pfn, + bool size_aligned); +struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, + unsigned long pfn_hi); +void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); +void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); +struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); +void put_iova_domain(struct iova_domain *iovad); + +#endif -- cgit v1.2.3 From 62c476c7c7f25a5b245b9902a935636e6316e58c Mon Sep 17 00:00:00 2001 From: Ben-Ami Yassour Date: Sun, 14 Sep 2008 03:48:28 +0300 Subject: KVM: Device Assignment with VT-d Based on a patch by: Kay, Allen M This patch enables PCI device assignment based on VT-d support. When a device is assigned to the guest, the guest memory is pinned and the mapping is updated in the VT-d IOMMU. [Amit: Expose KVM_CAP_IOMMU so we can check if an IOMMU is present and also control enable/disable from userspace] Signed-off-by: Kay, Allen M Signed-off-by: Weidong Han Signed-off-by: Ben-Ami Yassour Signed-off-by: Amit Shah Acked-by: Mark Gross Signed-off-by: Avi Kivity --- include/linux/kvm.h | 3 +++ include/linux/kvm_host.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index ef4bc6f8977..4269be171fa 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -384,6 +384,7 @@ struct kvm_trace_rec { #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ #define KVM_CAP_DEVICE_ASSIGNMENT 17 +#define KVM_CAP_IOMMU 18 /* * ioctls for VM fds @@ -495,4 +496,6 @@ struct kvm_assigned_irq { __u32 flags; }; +#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) + #endif diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 4b036430ea2..6252802c3cc 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -286,6 +286,53 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); +struct kvm_irq_ack_notifier { + struct hlist_node link; + unsigned gsi; + void (*irq_acked)(struct kvm_irq_ack_notifier *kian); +}; + +struct kvm_assigned_dev_kernel { + struct kvm_irq_ack_notifier ack_notifier; + struct work_struct interrupt_work; + struct list_head list; + int assigned_dev_id; + int host_busnr; + int host_devfn; + int host_irq; + int guest_irq; + int irq_requested; + struct pci_dev *dev; + struct kvm *kvm; +}; + +#ifdef CONFIG_DMAR +int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, + unsigned long npages); +int kvm_iommu_map_guest(struct kvm *kvm, + struct kvm_assigned_dev_kernel *assigned_dev); +int kvm_iommu_unmap_guest(struct kvm *kvm); +#else /* CONFIG_DMAR */ +static inline int kvm_iommu_map_pages(struct kvm *kvm, + gfn_t base_gfn, + unsigned long npages) +{ + return 0; +} + +static inline int kvm_iommu_map_guest(struct kvm *kvm, + struct kvm_assigned_dev_kernel + *assigned_dev) +{ + return -ENODEV; +} + +static inline int kvm_iommu_unmap_guest(struct kvm *kvm) +{ + return 0; +} +#endif /* CONFIG_DMAR */ + static inline void kvm_guest_enter(void) { account_system_vtime(current); @@ -308,6 +355,11 @@ static inline gpa_t gfn_to_gpa(gfn_t gfn) return (gpa_t)gfn << PAGE_SHIFT; } +static inline hpa_t pfn_to_hpa(pfn_t pfn) +{ + return (hpa_t)pfn << PAGE_SHIFT; +} + static inline void kvm_migrate_timers(struct kvm_vcpu *vcpu) { set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests); -- cgit v1.2.3 From 4731d4c7a07769cf2926c327177b97bb8c68cafc Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Tue, 23 Sep 2008 13:18:39 -0300 Subject: KVM: MMU: out of sync shadow core Allow guest pagetables to go out of sync. Instead of emulating write accesses to guest pagetables, or unshadowing them, we un-write-protect the page table and allow the guest to modify it at will. We rely on invlpg executions to synchronize individual ptes, and will synchronize the entire pagetable on tlb flushes. Signed-off-by: Marcelo Tosatti Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 6252802c3cc..73b7c52b949 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -35,6 +35,7 @@ #define KVM_REQ_TRIPLE_FAULT 4 #define KVM_REQ_PENDING_TIMER 5 #define KVM_REQ_UNHALT 6 +#define KVM_REQ_MMU_SYNC 7 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -- cgit v1.2.3 From 8a98f6648a2b0756d8f26d6c13332f5526355fec Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Mon, 6 Oct 2008 13:47:38 +0800 Subject: KVM: Move device assignment logic to common code To share with other archs, this patch moves device assignment logic to common parts. Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/linux/kvm.h | 2 ++ include/linux/kvm_host.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 4269be171fa..9acf34a6dfb 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -383,7 +383,9 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ +#ifdef CONFIG_X86 #define KVM_CAP_DEVICE_ASSIGNMENT 17 +#endif #define KVM_CAP_IOMMU 18 /* diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 73b7c52b949..10c1146cd00 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -281,6 +281,7 @@ void kvm_free_physmem(struct kvm *kvm); struct kvm *kvm_arch_create_vm(void); void kvm_arch_destroy_vm(struct kvm *kvm); +void kvm_free_all_assigned_devices(struct kvm *kvm); int kvm_cpu_get_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_interrupt(struct kvm_vcpu *v); -- cgit v1.2.3 From c77fb9dc7a0383c86eabef30272a763a482403e1 Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Sat, 27 Sep 2008 10:55:40 +0800 Subject: KVM: Change is_mmio_pfn to kvm_is_mmio_pfn, and make it common for all archs Add a kvm_ prefix to avoid polluting kernel's name space. Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 10c1146cd00..b3b7598b4d9 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -288,6 +288,8 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v); int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu); void kvm_vcpu_kick(struct kvm_vcpu *vcpu); +int kvm_is_mmio_pfn(pfn_t pfn); + struct kvm_irq_ack_notifier { struct hlist_node link; unsigned gsi; -- cgit v1.2.3 From 3de42dc094ecd313dc7d551e007a134b52f8663d Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Mon, 6 Oct 2008 13:48:45 +0800 Subject: KVM: Separate irq ack notification out of arch/x86/kvm/irq.c Moving irq ack notification logic as common, and make it shared with ia64 side. Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b3b7598b4d9..3833c48fae3 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -309,6 +309,12 @@ struct kvm_assigned_dev_kernel { struct pci_dev *dev; struct kvm *kvm; }; +void kvm_set_irq(struct kvm *kvm, int irq, int level); +void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi); +void kvm_register_irq_ack_notifier(struct kvm *kvm, + struct kvm_irq_ack_notifier *kian); +void kvm_unregister_irq_ack_notifier(struct kvm *kvm, + struct kvm_irq_ack_notifier *kian); #ifdef CONFIG_DMAR int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, -- cgit v1.2.3 From 2381ad241d0bea1253a37f314b270848067640bb Mon Sep 17 00:00:00 2001 From: Xiantao Zhang Date: Wed, 8 Oct 2008 08:29:33 +0800 Subject: KVM: ia64: Add intel iommu support for guests. With intel iommu hardware, we can assign devices to kvm/ia64 guests. Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/linux/kvm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 9acf34a6dfb..797fcd78124 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -383,7 +383,7 @@ struct kvm_trace_rec { #define KVM_CAP_MP_STATE 14 #define KVM_CAP_COALESCED_MMIO 15 #define KVM_CAP_SYNC_MMU 16 /* Changes to host mmap are reflected in guest */ -#ifdef CONFIG_X86 +#if defined(CONFIG_X86)||defined(CONFIG_IA64) #define KVM_CAP_DEVICE_ASSIGNMENT 17 #endif #define KVM_CAP_IOMMU 18 -- cgit v1.2.3 From 40b8606253552109815786e5d4b0de98782d31f5 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 15 Oct 2008 14:20:28 +1100 Subject: DECLARE_PER_CPU needs linux/percpu.h Signed-off-by: Stephen Rothwell --- include/linux/hrtimer.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 508ce20b8f9..1e6f731381d 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -20,6 +20,8 @@ #include #include #include +#include + struct hrtimer_clock_base; struct hrtimer_cpu_base; -- cgit v1.2.3 From be585c07dd577faac26014db4246e6d7c7a131e7 Mon Sep 17 00:00:00 2001 From: Jay Fenlason Date: Wed, 1 Oct 2008 18:13:20 -0400 Subject: firewire: Add more documentation to firewire-cdev.h Signed-off-by: Jay Fenlason Signed-off-by: Stefan Richter --- include/linux/firewire-cdev.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 0f0e271f97f..4d078e99c01 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -154,8 +154,13 @@ struct fw_cdev_event_iso_interrupt { * @request: Valid if @common.type == %FW_CDEV_EVENT_REQUEST * @iso_interrupt: Valid if @common.type == %FW_CDEV_EVENT_ISO_INTERRUPT * - * Convenience union for userspace use. Events could be read(2) into a char - * buffer and then cast to this union for further processing. + * Convenience union for userspace use. Events could be read(2) into an + * appropriately aligned char buffer and then cast to this union for further + * processing. Note that for a request, response or iso_interrupt event, + * the data[] or header[] may make the size of the full event larger than + * sizeof(union fw_cdev_event). Also note that if you attempt to read(2) + * an event into a buffer that is not large enough for it, the data that does + * not fit will be discarded so that the next read(2) will return a new event. */ union fw_cdev_event { struct fw_cdev_event_common common; -- cgit v1.2.3 From 22441cfa0c70dcd457f3c081fcf285c3bd155824 Mon Sep 17 00:00:00 2001 From: Pedro Ribeiro Date: Wed, 15 Oct 2008 15:47:49 -0700 Subject: IPV6: Fix default gateway criteria wrt. HIGH/LOW preference radv option Problem observed: In IPv6, in the presence of multiple routers candidates to default gateway in one segment, each sending a different value of preference, the Linux hosts connected to the segment weren't selecting the right one in all the combinations possible of LOW/MEDIUM/HIGH preference. This patch changes two files: include/linux/icmpv6.h Get the "router_pref" bitfield in the right place (as RFC4191 says), named the bit left with this fix as "home_agent" (RFC3775 say that's his function) net/ipv6/ndisc.c Corrects the binary logic behind the updating of the router preference in the flags of the routing table Result: With this two fixes applied, the default route used by the system was to consistent with the rules mentioned in RFC4191 in case of changes in the value of preference in router advertisements Signed-off-by: Pedro Ribeiro Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/icmpv6.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/icmpv6.h b/include/linux/icmpv6.h index 03067443198..a93a8dd3311 100644 --- a/include/linux/icmpv6.h +++ b/include/linux/icmpv6.h @@ -40,16 +40,18 @@ struct icmp6hdr { struct icmpv6_nd_ra { __u8 hop_limit; #if defined(__LITTLE_ENDIAN_BITFIELD) - __u8 reserved:4, + __u8 reserved:3, router_pref:2, + home_agent:1, other:1, managed:1; #elif defined(__BIG_ENDIAN_BITFIELD) __u8 managed:1, other:1, + home_agent:1, router_pref:2, - reserved:4; + reserved:3; #else #error "Please fix " #endif -- cgit v1.2.3 From 29d434b39c807320fbe4bcdce0ab98a0b9fcb285 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Oct 2008 16:08:57 +0200 Subject: fuse: add include protectors Add include protectors to include/linux/fuse.h and fs/fuse/fuse_i.h. Signed-off-by: Tejun Heo Signed-off-by: Miklos Szeredi --- include/linux/fuse.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 265635dc990..8bc1101e9b3 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -19,6 +19,9 @@ * - add file flags field to fuse_read_in and fuse_write_in */ +#ifndef _LINUX_FUSE_H +#define _LINUX_FUSE_H + #include #include @@ -409,3 +412,5 @@ struct fuse_dirent { #define FUSE_DIRENT_ALIGN(x) (((x) + sizeof(__u64) - 1) & ~(sizeof(__u64) - 1)) #define FUSE_DIRENT_SIZE(d) \ FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen) + +#endif /* _LINUX_FUSE_H */ -- cgit v1.2.3 From a7c1b990f71574e077b94ce4582e2cf11cb891fe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Oct 2008 16:08:57 +0200 Subject: fuse: implement nonseekable open Let the client request nonseekable open using FOPEN_NONSEEKABLE and call nonseekable_open() on the file if requested. Signed-off-by: Tejun Heo Signed-off-by: Miklos Szeredi --- include/linux/fuse.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 8bc1101e9b3..350fe9767bb 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -17,6 +17,9 @@ * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in * - add blksize field to fuse_attr * - add file flags field to fuse_read_in and fuse_write_in + * + * 7.10 + * - add nonseekable open flag */ #ifndef _LINUX_FUSE_H @@ -29,7 +32,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 9 +#define FUSE_KERNEL_MINOR_VERSION 10 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -101,9 +104,11 @@ struct fuse_file_lock { * * FOPEN_DIRECT_IO: bypass page cache for this open file * FOPEN_KEEP_CACHE: don't invalidate the data cache on open + * FOPEN_NONSEEKABLE: the file is not seekable */ #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) +#define FOPEN_NONSEEKABLE (1 << 2) /** * INIT request/reply flags -- cgit v1.2.3 From 17bc6c30cf6bfffd816bdc53682dd46fc34a2cf4 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Thu, 16 Oct 2008 10:09:17 -0400 Subject: vfs: Add no_nrwrite_index_update writeback control flag If no_nrwrite_index_update is set we don't update nr_to_write and address space writeback_index in write_cache_pages. This change enables a file system to skip these updates in write_cache_pages and do them in the writepages() callback. This patch will be followed by an ext4 patch that make use of these new flags. Signed-off-by: Aneesh Kumar K.V Signed-off-by: "Theodore Ts'o" CC: linux-fsdevel@vger.kernel.org --- include/linux/writeback.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/writeback.h b/include/linux/writeback.h index bd91987c065..e585657e983 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -63,6 +63,15 @@ struct writeback_control { unsigned for_writepages:1; /* This is a writepages() call */ unsigned range_cyclic:1; /* range_start is cyclic */ unsigned more_io:1; /* more io to be dispatched */ + /* + * write_cache_pages() won't update wbc->nr_to_write and + * mapping->writeback_index if no_nrwrite_index_update + * is set. write_cache_pages() may write more than we + * requested and we want to make sure nr_to_write and + * writeback_index are updated in a consistent manner + * so we use a single control to update them + */ + unsigned no_nrwrite_index_update:1; }; /* -- cgit v1.2.3 From 3ddfda11861d305b02ed810b522dcf48b74ca808 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:49:43 -0700 Subject: generic: add dyn_array support Allow crazy big arrays via bootmem at init stage. Architectures use CONFIG_HAVE_DYN_ARRAY to enable it. usage: | static struct irq_desc irq_desc_init __initdata = { | .status = IRQ_DISABLED, | .chip = &no_irq_chip, | .handle_irq = handle_bad_irq, | .depth = 1, | .lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock), | #ifdef CONFIG_SMP | .affinity = CPU_MASK_ALL | #endif | }; | | static void __init init_work(void *data) | { | struct dyn_array *da = data; | struct irq_desc *desc; | int i; | | desc = *da->name; | | for (i = 0; i < *da->nr; i++) | memcpy(&desc[i], &irq_desc_init, sizeof(struct irq_desc)); | } | | struct irq_desc *irq_desc; | DEFINE_DYN_ARRAY(irq_desc, sizeof(struct irq_desc), nr_irqs, PAGE_SIZE, init_work); after pre_alloc_dyn_array() after setup_arch(), the array is ready to be used. Via this facility we can replace irq_desc[NR_IRQS] array with dyn_array irq_desc[nr_irqs]. v2: remove _nopanic in pre_alloc_dyn_array() Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/init.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 93538b696e3..cf9fa7f174a 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -246,6 +246,29 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); + +struct dyn_array { + void **name; + unsigned long size; + unsigned int *nr; + unsigned long align; + void (*init_work)(void *); +}; +extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; + +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __dyn_array_##nameX __initdata = \ + { .name = (void **)&nameX,\ + .size = sizeX,\ + .nr = &nrX,\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".dyn_array.init"))) = \ + &__dyn_array_##nameX + +extern void pre_alloc_dyn_array(void); #endif /* __ASSEMBLY__ */ /** -- cgit v1.2.3 From 1f3fcd4b1adc972d5c6a34cfed98931c46575b49 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:49:44 -0700 Subject: add per_cpu_dyn_array support allow dyn-array in per_cpu area, allocated dynamically. usage: | /* in .h */ | struct kernel_stat { | struct cpu_usage_stat cpustat; | unsigned int *irqs; | }; | | /* in .c */ | DEFINE_PER_CPU(struct kernel_stat, kstat); | | DEFINE_PER_CPU_DYN_ARRAY_ADDR(per_cpu__kstat_irqs, per_cpu__kstat.irqs, sizeof(unsigned int), nr_irqs, sizeof(unsigned long), NULL); after setup_percpu()/per_cpu_alloc_dyn_array(), the dyn_array in per_cpu area is ready to use. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/init.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index cf9fa7f174a..332806826b8 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -255,12 +255,13 @@ struct dyn_array { void (*init_work)(void *); }; extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; +extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[]; -#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ +#define DEFINE_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ static struct dyn_array __dyn_array_##nameX __initdata = \ - { .name = (void **)&nameX,\ + { .name = (void **)&(nameX),\ .size = sizeX,\ - .nr = &nrX,\ + .nr = &(nrX),\ .align = alignX,\ .init_work = init_workX,\ }; \ @@ -268,7 +269,27 @@ extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; __attribute__((__section__(".dyn_array.init"))) = \ &__dyn_array_##nameX +#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + DEFINE_DYN_ARRAY_ADDR(nameX, nameX, sizeX, nrX, alignX, init_workX) + +#define DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ + static struct dyn_array __per_cpu_dyn_array_##nameX __initdata = \ + { .name = (void **)&(addrX),\ + .size = sizeX,\ + .nr = &(nrX),\ + .align = alignX,\ + .init_work = init_workX,\ + }; \ + static struct dyn_array *__per_cpu_dyn_array_ptr_##nameX __used \ + __attribute__((__section__(".per_cpu_dyn_array.init"))) = \ + &__per_cpu_dyn_array_##nameX + +#define DEFINE_PER_CPU_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ + DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX) + extern void pre_alloc_dyn_array(void); +extern unsigned long per_cpu_dyn_array_size(void); +extern void per_cpu_alloc_dyn_array(int cpu, char *ptr); #endif /* __ASSEMBLY__ */ /** -- cgit v1.2.3 From 1f8ff037a871690c762d267d8a052529d3102fc9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:49:45 -0700 Subject: x86: alloc dyn_array all together so could spare some memory with small alignment in bootmem also tighten the alignment checking, and make print out less debug info. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/init.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 332806826b8..59fbb4aaba6 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -288,7 +288,7 @@ extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[] DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX) extern void pre_alloc_dyn_array(void); -extern unsigned long per_cpu_dyn_array_size(void); +extern unsigned long per_cpu_dyn_array_size(unsigned long *align); extern void per_cpu_alloc_dyn_array(int cpu, char *ptr); #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 85c0f90978bf50596dbd23854648020f1f9b5bfd Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:49:47 -0700 Subject: irq: introduce nr_irqs at this point nr_irqs is equal NR_IRQS convert a few easy users from NR_IRQS to dynamic nr_irqs. v2: according to Eric, we need to take care of arch without generic_hardirqs Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 58ff4e74b2f..511803853a5 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -15,6 +15,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 -- cgit v1.2.3 From d60458b224d6b997a582a05cb8c4b9bed9e17a1d Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:00 -0700 Subject: irq: make irq_desc to use dyn_array Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 1d73d1abb83..5f4b013624d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -179,7 +179,11 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; +#ifdef CONFIG_HAVE_DYN_ARRAY +extern struct irq_desc *irq_desc; +#else extern struct irq_desc irq_desc[NR_IRQS]; +#endif /* * Migration helpers for obsolete names, they will go away: -- cgit v1.2.3 From d17a55ded3393ad3878010bb3a8243a15a8d8df5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:01 -0700 Subject: irq: make irqs in kernel stat use per_cpu_dyn_array Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/kernel_stat.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index cf9f40a91c9..fe1f7fe534b 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,7 +28,11 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned int *irqs; +#else unsigned int irqs[NR_IRQS]; +#endif }; DECLARE_PER_CPU(struct kernel_stat, kstat); -- cgit v1.2.3 From 08678b0841267c1d00d771fe01548d86043d065e Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:05 -0700 Subject: generic: sparse irqs: use irq_desc() together with dyn_array, instead of irq_desc[] add CONFIG_HAVE_SPARSE_IRQ to for use condensed array. Get rid of irq_desc[] array assumptions. Preallocate 32 irq_desc, and irq_desc() will try to get more. ( No change in functionality is expected anywhere, except the odd build failure where we missed a code site or where a crossing commit itroduces new irq_desc[] usage. ) v2: according to Eric, change get_irq_desc() to irq_desc() Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 5f4b013624d..80b8200f2ad 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -152,6 +152,10 @@ struct irq_chip { * @name: flow handler name for /proc/interrupts output */ struct irq_desc { + unsigned int irq; +#ifdef CONFIG_HAVE_SPARSE_IRQ + struct irq_desc *next; +#endif irq_flow_handler_t handle_irq; struct irq_chip *chip; struct msi_desc *msi_desc; @@ -179,9 +183,9 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; -#ifdef CONFIG_HAVE_DYN_ARRAY -extern struct irq_desc *irq_desc; -#else +extern struct irq_desc *irq_to_desc(unsigned int irq); +#ifndef CONFIG_HAVE_DYN_ARRAY +/* could be removed if we get rid of all irq_desc reference */ extern struct irq_desc irq_desc[NR_IRQS]; #endif @@ -249,7 +253,10 @@ extern int no_irq_affinity; static inline int irq_balancing_disabled(unsigned int irq) { - return irq_desc[irq].status & IRQ_NO_BALANCING_MASK; + struct irq_desc *desc; + + desc = irq_to_desc(irq); + return desc->status & IRQ_NO_BALANCING_MASK; } /* Handle irq action chains: */ @@ -281,7 +288,7 @@ extern unsigned int __do_IRQ(unsigned int irq); */ static inline void generic_handle_irq(unsigned int irq) { - struct irq_desc *desc = irq_desc + irq; + struct irq_desc *desc = irq_to_desc(irq); #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ desc->handle_irq(irq, desc); @@ -325,7 +332,10 @@ __set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained, static inline void __set_irq_handler_unlocked(int irq, irq_flow_handler_t handler) { - irq_desc[irq].handle_irq = handler; + struct irq_desc *desc; + + desc = irq_to_desc(irq); + desc->handle_irq = handler; } /* @@ -359,7 +369,7 @@ extern void destroy_irq(unsigned int irq); /* Test to see if a driver has successfully requested an irq */ static inline int irq_has_action(unsigned int irq) { - struct irq_desc *desc = irq_desc + irq; + struct irq_desc *desc = irq_to_desc(irq); return desc->action != NULL; } @@ -374,10 +384,10 @@ extern int set_irq_chip_data(unsigned int irq, void *data); extern int set_irq_type(unsigned int irq, unsigned int type); extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); -#define get_irq_chip(irq) (irq_desc[irq].chip) -#define get_irq_chip_data(irq) (irq_desc[irq].chip_data) -#define get_irq_data(irq) (irq_desc[irq].handler_data) -#define get_irq_msi(irq) (irq_desc[irq].msi_desc) +#define get_irq_chip(irq) (irq_to_desc(irq)->chip) +#define get_irq_chip_data(irq) (irq_to_desc(irq)->chip_data) +#define get_irq_data(irq) (irq_to_desc(irq)->handler_data) +#define get_irq_msi(irq) (irq_to_desc(irq)->msi_desc) #endif /* CONFIG_GENERIC_HARDIRQS */ -- cgit v1.2.3 From 3060d6fe28570640c2d7d66d38b9eaa848c3b9e3 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:08 -0700 Subject: x86: put timer_rand_state pointer into irq_desc irq_timer_state[] is a NR_IRQS sized array that is a side-by array to the real irq_desc[] array. Integrate that field into the (now dynamic) irq_desc dynamic array and save some RAM. v2: keep the old way to support arch not support irq_desc Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 80b8200f2ad..60c856aaac0 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -127,6 +127,7 @@ struct irq_chip { const char *typename; }; +struct timer_rand_state; /** * struct irq_desc - interrupt descriptor * @@ -155,6 +156,7 @@ struct irq_desc { unsigned int irq; #ifdef CONFIG_HAVE_SPARSE_IRQ struct irq_desc *next; + struct timer_rand_state *timer_rand_state; #endif irq_flow_handler_t handle_irq; struct irq_chip *chip; -- cgit v1.2.3 From 7f95ec9e4c12fd067febfd57532da1166d75d858 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:09 -0700 Subject: x86: move kstat_irqs from kstat to irq_desc based on Eric's patch ... together mold it with dyn_array for irq_desc, will allcate kstat_irqs for nr_irq_desc alltogether if needed. -- at that point nr_cpus is known already. v2: make sure system without generic_hardirqs works they don't have irq_desc v3: fix merging v4: [mingo@elte.hu] fix typo [ mingo@elte.hu ] irq: build fix fix: arch/x86/xen/spinlock.c: In function 'xen_spin_lock_slow': arch/x86/xen/spinlock.c:90: error: 'struct kernel_stat' has no member named 'irqs' Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 7 +++++++ include/linux/kernel_stat.h | 22 +++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 60c856aaac0..cbf471aee1c 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -157,6 +157,11 @@ struct irq_desc { #ifdef CONFIG_HAVE_SPARSE_IRQ struct irq_desc *next; struct timer_rand_state *timer_rand_state; +#endif +#ifdef CONFIG_HAVE_DYN_ARRAY + unsigned int *kstat_irqs; +#else + unsigned int kstat_irqs[NR_CPUS]; #endif irq_flow_handler_t handle_irq; struct irq_chip *chip; @@ -190,6 +195,8 @@ extern struct irq_desc *irq_to_desc(unsigned int irq); /* could be removed if we get rid of all irq_desc reference */ extern struct irq_desc irq_desc[NR_IRQS]; #endif +#define kstat_irqs_this_cpu(DESC) \ + ((DESC)->kstat_irqs[smp_processor_id()]) /* * Migration helpers for obsolete names, they will go away: diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index fe1f7fe534b..f10616712de 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,10 +28,8 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; -#ifdef CONFIG_HAVE_DYN_ARRAY - unsigned int *irqs; -#else - unsigned int irqs[NR_IRQS]; +#ifndef CONFIG_GENERIC_HARDIRQS + unsigned int irqs[NR_IRQS]; #endif }; @@ -43,15 +41,25 @@ DECLARE_PER_CPU(struct kernel_stat, kstat); extern unsigned long long nr_context_switches(void); +#ifndef CONFIG_GENERIC_HARDIRQS +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 */ -static inline int kstat_irqs(int irq) +static inline unsigned int kstat_irqs(unsigned int irq) { - int cpu, sum = 0; + unsigned int sum = 0; + int cpu; for_each_possible_cpu(cpu) - sum += kstat_cpu(cpu).irqs[irq]; + sum += kstat_irqs_cpu(irq, cpu); return sum; } -- cgit v1.2.3 From 9059d8fa4a3a9153da53da890039f7f956cc9d19 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:10 -0700 Subject: irq: add irq_desc_without_new add an irq_desc accessor that will not allocate any sparse entry but returns failure if there's no entry present. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index cbf471aee1c..c9ffef7c3b4 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -191,10 +191,23 @@ struct irq_desc { } ____cacheline_internodealigned_in_smp; extern struct irq_desc *irq_to_desc(unsigned int irq); +extern struct irq_desc *__irq_to_desc(unsigned int irq); + +#ifndef CONFIG_HAVE_SPARSE_IRQ + #ifndef CONFIG_HAVE_DYN_ARRAY /* could be removed if we get rid of all irq_desc reference */ extern struct irq_desc irq_desc[NR_IRQS]; +#else +extern struct irq_desc *irq_desc; #endif + +#else + +extern struct irq_desc *sparse_irqs; + +#endif + #define kstat_irqs_this_cpu(DESC) \ ((DESC)->kstat_irqs[smp_processor_id()]) -- cgit v1.2.3 From 2c6927a38f65b53b62f86158fba29a068c4e8b6a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:11 -0700 Subject: irq: replace loop with nr_irqs with for_each_irq_desc There are a handful of loops that go from 0 to nr_irqs and use get_irq_desc() on them. These would allocate all the irq_desc entries, regardless of the need for them. Use the smarter for_each_irq_desc() iterator that will only iterate over the present ones. v2: make sure arch without GENERIC_HARDIRQS work too Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index c9ffef7c3b4..9de16ca8b8e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -202,9 +202,16 @@ extern struct irq_desc irq_desc[NR_IRQS]; extern struct irq_desc *irq_desc; #endif +#ifdef CONFIG_GENERIC_HARDIRQS +#define for_each_irq_desc(irq, desc) \ + for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc = &irq_desc[irq]) +#endif + #else extern struct irq_desc *sparse_irqs; +#define for_each_irq_desc(irqX, desc) \ + for (desc = sparse_irqs, irqX = desc->irq; desc && irqX != -1U; desc = desc->next, irqX = desc ? desc->irq : -1U) #endif -- cgit v1.2.3 From c7fb03a475bd80c642c1345d85c7c550f63514b8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:12 -0700 Subject: irq, fs/proc: replace loop with nr_irqs for proc/stat Replace another nr_irqs loop to avoid the allocation of all sparse irq entries - use for_each_irq_desc instead. v2: make sure arch without GENERIC_HARDIRQS works too Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 511803853a5..d4039a0b23f 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -17,6 +17,11 @@ extern int nr_irqs; +#ifndef CONFIG_GENERIC_HARDIRQS +#define for_each_irq_desc(irq, desc) \ + for (irq = 0; irq < nr_irqs; irq++) +#endif + /* * These correspond to the IORESOURCE_IRQ_* defines in * linux/ioport.h to select the interrupt line behaviour. When -- cgit v1.2.3 From 46926b67fc663d357a1a8174328998a9e49da0b8 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:15 -0700 Subject: generic: add irq_desc in function in parameter So we could remove some duplicated calling to irq_desc v2: make sure irq_desc in init/main.c is not used without generic_hardirqs Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 9de16ca8b8e..7b59e193a11 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -315,10 +315,8 @@ extern unsigned int __do_IRQ(unsigned int irq); * irqchip-style controller then we call the ->handle_irq() handler, * and it calls __do_IRQ() if it's attached to an irqtype-style controller. */ -static inline void generic_handle_irq(unsigned int irq) +static inline void generic_handle_irq_desc(unsigned int irq, struct irq_desc *desc) { - struct irq_desc *desc = irq_to_desc(irq); - #ifdef CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ desc->handle_irq(irq, desc); #else @@ -329,6 +327,11 @@ static inline void generic_handle_irq(unsigned int irq) #endif } +static inline void generic_handle_irq(unsigned int irq) +{ + generic_handle_irq_desc(irq, irq_to_desc(irq)); +} + /* Handling of unhandled and spurious interrupts: */ extern void note_interrupt(unsigned int irq, struct irq_desc *desc, int action_ret); -- cgit v1.2.3 From cb5bc83225a86ca53bbb889ed8439e4fd6cf44ac Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:17 -0700 Subject: x86_64: rename irq_desc/irq_desc_alloc change names: irq_desc() ==> irq_desc_alloc __irq_desc() ==> irq_desc Also split a few of the uses in lowlevel x86 code. v2: need to check if desc is null in smp_irq_move_cleanup Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 7b59e193a11..5fe1b01c11f 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -191,7 +191,7 @@ struct irq_desc { } ____cacheline_internodealigned_in_smp; extern struct irq_desc *irq_to_desc(unsigned int irq); -extern struct irq_desc *__irq_to_desc(unsigned int irq); +extern struct irq_desc *irq_to_desc_alloc(unsigned int irq); #ifndef CONFIG_HAVE_SPARSE_IRQ -- cgit v1.2.3 From 67fb283e148e9bd761f73691d3173b6eab9ba8db Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:18 -0700 Subject: irq: separate sparse_irqs from sparse_irqs_free so later don't need compare with -1U Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 5fe1b01c11f..d5749852ee6 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -211,7 +211,7 @@ extern struct irq_desc *irq_desc; extern struct irq_desc *sparse_irqs; #define for_each_irq_desc(irqX, desc) \ - for (desc = sparse_irqs, irqX = desc->irq; desc && irqX != -1U; desc = desc->next, irqX = desc ? desc->irq : -1U) + for (desc = sparse_irqs, irqX = desc->irq; desc; desc = desc->next, irqX = desc ? desc->irq : -1U) #endif -- cgit v1.2.3 From e420dfb40c453a9760b86c7f338052bdb4dfa755 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:21 -0700 Subject: x86: put irq_2_iommu pointer into irq_desc when CONFIG_HAVE_SPARSE_IRQ preallocate some irq_2_iommu entries, and use get_one_free_irq_2_iomm to get new one and link to irq_desc if needed. else will use dyn_array or static array. v2: <= nr_irqs fix Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index d5749852ee6..788d5a35a58 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -128,6 +128,7 @@ struct irq_chip { }; struct timer_rand_state; +struct irq_2_iommu; /** * struct irq_desc - interrupt descriptor * @@ -162,6 +163,9 @@ struct irq_desc { unsigned int *kstat_irqs; #else unsigned int kstat_irqs[NR_CPUS]; +#endif +#if defined(CONFIG_INTR_REMAP) && defined(CONFIG_HAVE_SPARSE_IRQ) + struct irq_2_iommu *irq_2_iommu; #endif irq_flow_handler_t handle_irq; struct irq_chip *chip; -- cgit v1.2.3 From 6d50bc26836e16a9589e0b128d527c29e30d722a Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:22 -0700 Subject: x86: use 28 bits irq NR for pci msi/msix and ht also print out irq no in /proc/interrups and /proc/stat in hex, so could tell bus/dev/func. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 788d5a35a58..704136138dc 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -399,6 +399,7 @@ extern void set_irq_noprobe(unsigned int irq); extern void set_irq_probe(unsigned int irq); /* Handle dynamic irq creation and destruction */ +extern unsigned int create_irq_nr(unsigned int irq_want); extern int create_irq(void); extern void destroy_irq(unsigned int irq); -- cgit v1.2.3 From 8b8e8c1bf7275eca859fe551dfa484134eaf013b Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:23 -0700 Subject: x86: remove irqbalance in kernel for 32 bit This has been deprecated for years, the user space irqbalanced utility works better with numa, has configurable policies, etc... Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 704136138dc..2445d2b3d5d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -185,7 +185,7 @@ struct irq_desc { cpumask_t affinity; unsigned int cpu; #endif -#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) +#ifdef CONFIG_GENERIC_PENDING_IRQ cpumask_t pending_mask; #endif #ifdef CONFIG_PROC_FS @@ -241,13 +241,13 @@ extern int setup_irq(unsigned int irq, struct irqaction *new); #ifdef CONFIG_SMP -#if defined(CONFIG_GENERIC_PENDING_IRQ) || defined(CONFIG_IRQBALANCE) +#ifdef CONFIG_GENERIC_PENDING_IRQ void set_pending_irq(unsigned int irq, cpumask_t mask); void move_native_irq(int irq); void move_masked_irq(int irq); -#else /* CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE */ +#else /* CONFIG_GENERIC_PENDING_IRQ */ static inline void move_irq(int irq) { @@ -274,14 +274,6 @@ static inline void set_pending_irq(unsigned int irq, cpumask_t mask) #endif /* CONFIG_SMP */ -#ifdef CONFIG_IRQBALANCE -extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); -#else -static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) -{ -} -#endif - extern int no_irq_affinity; static inline int irq_balancing_disabled(unsigned int irq) -- cgit v1.2.3 From 42379b1122bab7f9aefdbd4b7004a6fa89dfbae5 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Tue, 19 Aug 2008 20:50:45 -0700 Subject: pci: change msi-x vector to 32bit we are using 28bit pci (bus/dev/fn + 12 bits) as irq number, so the cache for irq number should be 32 bit too. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 98dc6243a70..1f8db240ca4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -723,7 +723,7 @@ enum pci_dma_burst_strategy { }; struct msix_entry { - u16 vector; /* kernel uses to write allocated vector */ + u32 vector; /* kernel uses to write allocated vector */ u16 entry; /* driver uses to specify entry, OS writes */ }; -- cgit v1.2.3 From 8c464a4b23ca283b414022ebc77787f3c7040fa7 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 25 Aug 2008 12:41:19 -0700 Subject: sparseirq: move kstat_irqs from kstat to irq_desc - fix fix non-sparseirq architectures. Signed-off-by: Yinghai Lu Signed-off-by: Ingo Molnar --- include/linux/irq.h | 4 ++-- include/linux/kernel_stat.h | 10 ++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 2445d2b3d5d..93fe9a943e7 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -161,8 +161,6 @@ struct irq_desc { #endif #ifdef CONFIG_HAVE_DYN_ARRAY unsigned int *kstat_irqs; -#else - unsigned int kstat_irqs[NR_CPUS]; #endif #if defined(CONFIG_INTR_REMAP) && defined(CONFIG_HAVE_SPARSE_IRQ) struct irq_2_iommu *irq_2_iommu; @@ -219,8 +217,10 @@ extern struct irq_desc *sparse_irqs; #endif +#ifdef CONFIG_HAVE_DYN_ARRAY #define kstat_irqs_this_cpu(DESC) \ ((DESC)->kstat_irqs[smp_processor_id()]) +#endif /* * Migration helpers for obsolete names, they will go away: diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index f10616712de..21249d8c129 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,7 +28,7 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; -#ifndef CONFIG_GENERIC_HARDIRQS +#ifndef CONFIG_HAVE_DYN_ARRAY unsigned int irqs[NR_IRQS]; #endif }; @@ -41,7 +41,13 @@ DECLARE_PER_CPU(struct kernel_stat, kstat); extern unsigned long long nr_context_switches(void); -#ifndef CONFIG_GENERIC_HARDIRQS +#ifndef CONFIG_HAVE_DYN_ARRAY +#define kstat_irqs_this_cpu(irq) \ + (kstat_this_cpu.irqs[irq]) +#endif + + +#ifndef CONFIG_HAVE_DYN_ARRAY static inline unsigned int kstat_irqs_cpu(unsigned int irq, int cpu) { return kstat_cpu(cpu).irqs[irq]; -- cgit v1.2.3 From f6dd5c3106fb283e37d915eeb33019ef40510f85 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 3 Sep 2008 16:58:32 -0700 Subject: dmar: fix using early fixmap mapping for DMAR table parsing Very early detection of the DMAR tables will setup fixmap mapping. For parsing these tables later (while enabling dma and/or interrupt remapping), early fixmap mapping shouldn't be used. Fix it by calling table detection routines again, which will call generic apci_get_table() for setting up the correct mapping. Signed-off-by: Yinghai Lu Signed-off-by: Suresh Siddha Signed-off-by: Ingo Molnar --- include/linux/dmar.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dmar.h b/include/linux/dmar.h index c360c558e59..f1984fc3e06 100644 --- a/include/linux/dmar.h +++ b/include/linux/dmar.h @@ -45,7 +45,6 @@ extern struct list_head dmar_drhd_units; list_for_each_entry(drhd, &dmar_drhd_units, list) extern int dmar_table_init(void); -extern int early_dmar_detect(void); extern int dmar_dev_scope_init(void); /* Intel IOMMU detection */ -- cgit v1.2.3 From a50f70b17541c0060967c6df61133e968bad3652 Mon Sep 17 00:00:00 2001 From: Russ Anderson Date: Fri, 3 Oct 2008 11:58:54 -0500 Subject: x86: Add UV EFI table entry v4 Look for a UV entry in the EFI tables. Signed-off-by: Russ Anderson Signed-off-by: Paul Jackson Acked-by: Huang Ying Signed-off-by: H. Peter Anvin Signed-off-by: Ingo Molnar --- include/linux/efi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/efi.h b/include/linux/efi.h index 807373d467f..bb66feb164b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -208,6 +208,9 @@ typedef efi_status_t efi_set_virtual_address_map_t (unsigned long memory_map_siz #define EFI_GLOBAL_VARIABLE_GUID \ EFI_GUID( 0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c ) +#define UV_SYSTEM_TABLE_GUID \ + EFI_GUID( 0x3b13a7d4, 0x633e, 0x11dd, 0x93, 0xec, 0xda, 0x25, 0x56, 0xd8, 0x95, 0x93 ) + typedef struct { efi_guid_t guid; unsigned long table; @@ -255,6 +258,7 @@ extern struct efi { unsigned long boot_info; /* boot info table */ unsigned long hcdp; /* HCDP table */ unsigned long uga; /* UGA table */ + unsigned long uv_systab; /* UV system table */ efi_get_time_t *get_time; efi_set_time_t *set_time; efi_get_wakeup_time_t *get_wakeup_time; -- cgit v1.2.3 From 7ef0c30dbf96a8d9a234e90c248eb19df3c031be Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 13:07:35 +0200 Subject: genirq: define nr_irqs for architectures with GENERIC_HARDIRQS=n Revert the sparse irq changes in m68k/s390/sparc and just define nr_irqs as NR_IRQS for those architectures. Signed-off-by: Thomas Gleixner --- include/linux/interrupt.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index d4039a0b23f..5a57df2ee92 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -15,11 +15,13 @@ #include #include -extern int nr_irqs; - #ifndef CONFIG_GENERIC_HARDIRQS -#define for_each_irq_desc(irq, desc) \ +# define for_each_irq_desc(irq, desc) \ for (irq = 0; irq < nr_irqs; irq++) + +# define nr_irqs NR_IRQS +#else +extern int nr_irqs; #endif /* -- cgit v1.2.3 From 70dd4d992ab324a59cdcd6bedc3f4e729863d514 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 15:39:27 +0200 Subject: genirq: consolidate nr_irqs and for_each_irq_desc() Move all of those to linux/irq.h where they belong. Signed-off-by: Thomas Gleixner --- include/linux/interrupt.h | 9 --------- include/linux/irq.h | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 5a57df2ee92..58ff4e74b2f 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -15,15 +15,6 @@ #include #include -#ifndef CONFIG_GENERIC_HARDIRQS -# define for_each_irq_desc(irq, desc) \ - for (irq = 0; irq < nr_irqs; irq++) - -# define nr_irqs NR_IRQS -#else -extern int nr_irqs; -#endif - /* * 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 93fe9a943e7..dbe8734ae86 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -11,6 +11,18 @@ #include +#ifndef CONFIG_GENERIC_HARDIRQS +# define nr_irqs NR_IRQS + +# 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++) +#endif + #ifndef CONFIG_S390 #include @@ -204,11 +216,6 @@ extern struct irq_desc irq_desc[NR_IRQS]; extern struct irq_desc *irq_desc; #endif -#ifdef CONFIG_GENERIC_HARDIRQS -#define for_each_irq_desc(irq, desc) \ - for (irq = 0, desc = irq_desc; irq < nr_irqs; irq++, desc = &irq_desc[irq]) -#endif - #else extern struct irq_desc *sparse_irqs; -- cgit v1.2.3 From c6b7674f323622d86316bf7951ad9cae1ce24642 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 14:31:29 +0200 Subject: genirq: use inline function for irq_to_desc For the non sparse irq case an inline function is perfectly fine. Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index dbe8734ae86..7d1adacaadb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -204,8 +204,6 @@ struct irq_desc { const char *name; } ____cacheline_internodealigned_in_smp; -extern struct irq_desc *irq_to_desc(unsigned int irq); -extern struct irq_desc *irq_to_desc_alloc(unsigned int irq); #ifndef CONFIG_HAVE_SPARSE_IRQ @@ -216,8 +214,21 @@ extern struct irq_desc irq_desc[NR_IRQS]; extern struct irq_desc *irq_desc; #endif +static inline struct irq_desc *irq_to_desc(unsigned int irq) +{ + return (irq < nr_irqs) ? irq_desc + irq : NULL; +} + +static inline struct irq_desc *irq_to_desc_alloc(unsigned int irq) +{ + return irq_to_desc(irq); +} + #else +extern struct irq_desc *irq_to_desc(unsigned int irq); +extern struct irq_desc *irq_to_desc_alloc(unsigned int irq); + extern struct irq_desc *sparse_irqs; #define for_each_irq_desc(irqX, desc) \ for (desc = sparse_irqs, irqX = desc->irq; desc; desc = desc->next, irqX = desc ? desc->irq : -1U) -- cgit v1.2.3 From 2cc21ef843d4fb7da122239b644a1f6f0aca60a6 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 14:16:55 +0200 Subject: genirq: remove sparse irq code This code is not ready, but we need to rip it out instead of rebasing as we would lose the APIC/IO_APIC unification otherwise. Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 7d1adacaadb..68e0f3f9df3 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -167,15 +167,8 @@ struct irq_2_iommu; */ struct irq_desc { unsigned int irq; -#ifdef CONFIG_HAVE_SPARSE_IRQ - struct irq_desc *next; - struct timer_rand_state *timer_rand_state; -#endif #ifdef CONFIG_HAVE_DYN_ARRAY unsigned int *kstat_irqs; -#endif -#if defined(CONFIG_INTR_REMAP) && defined(CONFIG_HAVE_SPARSE_IRQ) - struct irq_2_iommu *irq_2_iommu; #endif irq_flow_handler_t handle_irq; struct irq_chip *chip; @@ -205,8 +198,6 @@ struct irq_desc { } ____cacheline_internodealigned_in_smp; -#ifndef CONFIG_HAVE_SPARSE_IRQ - #ifndef CONFIG_HAVE_DYN_ARRAY /* could be removed if we get rid of all irq_desc reference */ extern struct irq_desc irq_desc[NR_IRQS]; @@ -224,17 +215,6 @@ static inline struct irq_desc *irq_to_desc_alloc(unsigned int irq) return irq_to_desc(irq); } -#else - -extern struct irq_desc *irq_to_desc(unsigned int irq); -extern struct irq_desc *irq_to_desc_alloc(unsigned int irq); - -extern struct irq_desc *sparse_irqs; -#define for_each_irq_desc(irqX, desc) \ - for (desc = sparse_irqs, irqX = desc->irq; desc; desc = desc->next, irqX = desc ? desc->irq : -1U) - -#endif - #ifdef CONFIG_HAVE_DYN_ARRAY #define kstat_irqs_this_cpu(DESC) \ ((DESC)->kstat_irqs[smp_processor_id()]) -- cgit v1.2.3 From ee32c9732244bde4b9b59eeac2814c23e2b71f8d Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 14:34:09 +0200 Subject: genirq: remove irq_to_desc_alloc Remove the leftover of sparseirqs. Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 68e0f3f9df3..3f33c779030 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -210,11 +210,6 @@ static inline struct irq_desc *irq_to_desc(unsigned int irq) return (irq < nr_irqs) ? irq_desc + irq : NULL; } -static inline struct irq_desc *irq_to_desc_alloc(unsigned int irq) -{ - return irq_to_desc(irq); -} - #ifdef CONFIG_HAVE_DYN_ARRAY #define kstat_irqs_this_cpu(DESC) \ ((DESC)->kstat_irqs[smp_processor_id()]) -- cgit v1.2.3 From d6c88a507ef0b6afdb013cba4e7804ba7324d99a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 15 Oct 2008 15:27:23 +0200 Subject: genirq: revert dynarray Revert the dynarray changes. They need more thought and polishing. Signed-off-by: Thomas Gleixner --- include/linux/init.h | 43 ------------------------------------------- include/linux/irq.h | 15 --------------- include/linux/kernel_stat.h | 16 ++++++---------- 3 files changed, 6 insertions(+), 68 deletions(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 59fbb4aaba6..70ad53e1eab 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -247,49 +247,6 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); -struct dyn_array { - void **name; - unsigned long size; - unsigned int *nr; - unsigned long align; - void (*init_work)(void *); -}; -extern struct dyn_array *__dyn_array_start[], *__dyn_array_end[]; -extern struct dyn_array *__per_cpu_dyn_array_start[], *__per_cpu_dyn_array_end[]; - -#define DEFINE_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ - static struct dyn_array __dyn_array_##nameX __initdata = \ - { .name = (void **)&(nameX),\ - .size = sizeX,\ - .nr = &(nrX),\ - .align = alignX,\ - .init_work = init_workX,\ - }; \ - static struct dyn_array *__dyn_array_ptr_##nameX __used \ - __attribute__((__section__(".dyn_array.init"))) = \ - &__dyn_array_##nameX - -#define DEFINE_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ - DEFINE_DYN_ARRAY_ADDR(nameX, nameX, sizeX, nrX, alignX, init_workX) - -#define DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, addrX, sizeX, nrX, alignX, init_workX) \ - static struct dyn_array __per_cpu_dyn_array_##nameX __initdata = \ - { .name = (void **)&(addrX),\ - .size = sizeX,\ - .nr = &(nrX),\ - .align = alignX,\ - .init_work = init_workX,\ - }; \ - static struct dyn_array *__per_cpu_dyn_array_ptr_##nameX __used \ - __attribute__((__section__(".per_cpu_dyn_array.init"))) = \ - &__per_cpu_dyn_array_##nameX - -#define DEFINE_PER_CPU_DYN_ARRAY(nameX, sizeX, nrX, alignX, init_workX) \ - DEFINE_PER_CPU_DYN_ARRAY_ADDR(nameX, nameX, nrX, alignX, init_workX) - -extern void pre_alloc_dyn_array(void); -extern unsigned long per_cpu_dyn_array_size(unsigned long *align); -extern void per_cpu_alloc_dyn_array(int cpu, char *ptr); #endif /* __ASSEMBLY__ */ /** diff --git a/include/linux/irq.h b/include/linux/irq.h index 3f33c779030..38bf89f2ade 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -139,8 +139,6 @@ struct irq_chip { const char *typename; }; -struct timer_rand_state; -struct irq_2_iommu; /** * struct irq_desc - interrupt descriptor * @@ -167,9 +165,6 @@ struct irq_2_iommu; */ struct irq_desc { unsigned int irq; -#ifdef CONFIG_HAVE_DYN_ARRAY - unsigned int *kstat_irqs; -#endif irq_flow_handler_t handle_irq; struct irq_chip *chip; struct msi_desc *msi_desc; @@ -198,23 +193,13 @@ struct irq_desc { } ____cacheline_internodealigned_in_smp; -#ifndef CONFIG_HAVE_DYN_ARRAY -/* could be removed if we get rid of all irq_desc reference */ extern struct irq_desc irq_desc[NR_IRQS]; -#else -extern struct irq_desc *irq_desc; -#endif static inline struct irq_desc *irq_to_desc(unsigned int irq) { return (irq < nr_irqs) ? irq_desc + irq : NULL; } -#ifdef CONFIG_HAVE_DYN_ARRAY -#define kstat_irqs_this_cpu(DESC) \ - ((DESC)->kstat_irqs[smp_processor_id()]) -#endif - /* * Migration helpers for obsolete names, they will go away: */ diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index 21249d8c129..a9d0d360b77 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,9 +28,7 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; -#ifndef CONFIG_HAVE_DYN_ARRAY unsigned int irqs[NR_IRQS]; -#endif }; DECLARE_PER_CPU(struct kernel_stat, kstat); @@ -41,20 +39,18 @@ DECLARE_PER_CPU(struct kernel_stat, kstat); extern unsigned long long nr_context_switches(void); -#ifndef CONFIG_HAVE_DYN_ARRAY -#define kstat_irqs_this_cpu(irq) \ - (kstat_this_cpu.irqs[irq]) -#endif +struct irq_desc; +static inline void kstat_incr_irqs_this_cpu(unsigned int irq, + struct irq_desc *desc) +{ + kstat_this_cpu.irqs[irq]++; +} -#ifndef CONFIG_HAVE_DYN_ARRAY 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 -- cgit v1.2.3 From a1aca5de08a0cb840a90fb3f729a5940f8d21185 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 15 Oct 2008 19:29:15 +0200 Subject: genirq: remove artifacts from sparseirq removal Signed-off-by: Ingo Molnar --- include/linux/init.h | 1 - include/linux/kernel_stat.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 70ad53e1eab..93538b696e3 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -246,7 +246,6 @@ struct obs_kernel_param { /* Relies on boot_command_line being set */ void __init parse_early_param(void); - #endif /* __ASSEMBLY__ */ /** diff --git a/include/linux/kernel_stat.h b/include/linux/kernel_stat.h index a9d0d360b77..89b6ecd4147 100644 --- a/include/linux/kernel_stat.h +++ b/include/linux/kernel_stat.h @@ -28,7 +28,7 @@ struct cpu_usage_stat { struct kernel_stat { struct cpu_usage_stat cpustat; - unsigned int irqs[NR_IRQS]; + unsigned int irqs[NR_IRQS]; }; DECLARE_PER_CPU(struct kernel_stat, kstat); -- cgit v1.2.3 From 811410fdb6b9d82a518542289efe9b2a51e3cbfb Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 16 Oct 2008 14:16:11 +0200 Subject: genirq: add reverse iterator for irq_desc Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 38bf89f2ade..31632aa65d1 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -21,6 +21,10 @@ 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 #ifndef CONFIG_S390 -- cgit v1.2.3 From 2be3b52a5785a6a5c5349fbd315f57595f7074be Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 16 Oct 2008 14:50:27 +0200 Subject: proc: fixup irq iterator There is no need for irq_desc here. Even for sparse_irq we can handle this clever in for_each_irq_nr(). Signed-off-by: Thomas Gleixner --- include/linux/irq.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 31632aa65d1..0618fb362cb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -27,6 +27,9 @@ extern int nr_irqs; irq > 0; irq--, desc--) #endif +#define for_each_irq_nr(irq) \ + for (irq = 0; irq < nr_irqs; irq++) + #ifndef CONFIG_S390 #include -- cgit v1.2.3 From ae87221d3ce49d9de1e43756da834fd0bf05a2ad Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 24 Aug 2007 16:11:54 -0700 Subject: sysfs: crash debugging Print the name of the last-accessed sysfs file when we oops, to help track down oopses which occur in sysfs store/read handlers. Because these oopses tend to not leave any trace of the offending code in the stack traces. Cc: Kay Sievers Cc: Mathieu Desnoyers Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 37fa24152bd..8ec406afb3e 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -119,6 +119,8 @@ void sysfs_remove_file_from_group(struct kobject *kobj, void sysfs_notify(struct kobject *kobj, char *dir, char *attr); +void sysfs_printk_last_file(void); + extern int __must_check sysfs_init(void); #else /* CONFIG_SYSFS */ @@ -231,6 +233,10 @@ static inline int __must_check sysfs_init(void) return 0; } +static inline void sysfs_printk_last_file(void) +{ +} + #endif /* CONFIG_SYSFS */ #endif /* _SYSFS_H_ */ -- cgit v1.2.3 From 7fb6b5d51daf3613045258ee8add07022d8c39d3 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 21 Jul 2008 20:03:34 -0700 Subject: device create: remove device_create_drvdata Now that the tree is cleaned up, device_create_drvdata can be safely removed. Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index 246937c9cbc..60f6456691a 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -502,7 +502,6 @@ extern struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) __attribute__((format(printf, 5, 6))); -#define device_create_drvdata device_create extern void device_destroy(struct class *cls, dev_t devt); /* -- cgit v1.2.3 From 346e15beb5343c2eb8216d820f2ed8f150822b08 Mon Sep 17 00:00:00 2001 From: Jason Baron Date: Tue, 12 Aug 2008 16:46:19 -0400 Subject: driver core: basic infrastructure for per-module dynamic debug messages Base infrastructure to enable per-module debug messages. I've introduced CONFIG_DYNAMIC_PRINTK_DEBUG, which when enabled centralizes control of debugging statements on a per-module basis in one /proc file, currently, /dynamic_printk/modules. When, CONFIG_DYNAMIC_PRINTK_DEBUG, is not set, debugging statements can still be enabled as before, often by defining 'DEBUG' for the proper compilation unit. Thus, this patch set has no affect when CONFIG_DYNAMIC_PRINTK_DEBUG is not set. The infrastructure currently ties into all pr_debug() and dev_dbg() calls. That is, if CONFIG_DYNAMIC_PRINTK_DEBUG is set, all pr_debug() and dev_dbg() calls can be dynamically enabled/disabled on a per-module basis. Future plans include extending this functionality to subsystems, that define their own debug levels and flags. Usage: Dynamic debugging is controlled by the debugfs file, /dynamic_printk/modules. This file contains a list of the modules that can be enabled. The format of the file is as follows: . . . : Name of the module in which the debug call resides : whether the messages are enabled or not For example: snd_hda_intel enabled=0 fixup enabled=1 driver enabled=0 Enable a module: $echo "set enabled=1 " > dynamic_printk/modules Disable a module: $echo "set enabled=0 " > dynamic_printk/modules Enable all modules: $echo "set enabled=1 all" > dynamic_printk/modules Disable all modules: $echo "set enabled=0 all" > dynamic_printk/modules Finally, passing "dynamic_printk" at the command line enables debugging for all modules. This mode can be turned off via the above disable command. [gkh: minor cleanups and tweaks to make the build work quietly] Signed-off-by: Jason Baron Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 6 ++- include/linux/dynamic_printk.h | 93 ++++++++++++++++++++++++++++++++++++++++++ include/linux/kernel.h | 7 +++- include/linux/module.h | 1 - 4 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 include/linux/dynamic_printk.h (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index 60f6456691a..fb034461b39 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -550,7 +550,11 @@ extern const char *dev_driver_string(const struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg) -#ifdef DEBUG +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +#define dev_dbg(dev, format, ...) do { \ + dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ + } while (0) +#elif defined(DEBUG) #define dev_dbg(dev, format, arg...) \ dev_printk(KERN_DEBUG , dev , format , ## arg) #else diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h new file mode 100644 index 00000000000..2d528d00907 --- /dev/null +++ b/include/linux/dynamic_printk.h @@ -0,0 +1,93 @@ +#ifndef _DYNAMIC_PRINTK_H +#define _DYNAMIC_PRINTK_H + +#define DYNAMIC_DEBUG_HASH_BITS 6 +#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS) + +#define TYPE_BOOLEAN 1 + +#define DYNAMIC_ENABLED_ALL 0 +#define DYNAMIC_ENABLED_NONE 1 +#define DYNAMIC_ENABLED_SOME 2 + +extern int dynamic_enabled; + +/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which + * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They + * use independent hash functions, to reduce the chance of false positives. + */ +extern long long dynamic_printk_enabled; +extern long long dynamic_printk_enabled2; + +struct mod_debug { + char *modname; + char *logical_modname; + char *flag_names; + int type; + int hash; + int hash2; +} __attribute__((aligned(8))); + +int register_dynamic_debug_module(char *mod_name, int type, char *share_name, + char *flags, int hash, int hash2); + +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +extern int unregister_dynamic_debug_module(char *mod_name); +extern int __dynamic_dbg_enabled_helper(char *modname, int type, + int value, int hash); + +#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \ + int __ret = 0; \ + if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \ + (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \ + __ret = __dynamic_dbg_enabled_helper(module, type, \ + value, hash);\ + __ret; }) + +#define dynamic_pr_debug(fmt, ...) do { \ + static char mod_name[] \ + __attribute__((section("__verbose_strings"))) \ + = KBUILD_MODNAME; \ + static struct mod_debug descriptor \ + __used \ + __attribute__((section("__verbose"), aligned(8))) = \ + { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\ + if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \ + 0, 0, DEBUG_HASH)) \ + printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \ + ##__VA_ARGS__); \ + } while (0) + +#define dynamic_dev_dbg(dev, format, ...) do { \ + static char mod_name[] \ + __attribute__((section("__verbose_strings"))) \ + = KBUILD_MODNAME; \ + static struct mod_debug descriptor \ + __used \ + __attribute__((section("__verbose"), aligned(8))) = \ + { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\ + if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \ + 0, 0, DEBUG_HASH)) \ + dev_printk(KERN_DEBUG, dev, \ + KBUILD_MODNAME ": " format, \ + ##__VA_ARGS__); \ + } while (0) + +#else + +static inline int unregister_dynamic_debug_module(const char *mod_name) +{ + return 0; +} +static inline int __dynamic_dbg_enabled_helper(char *modname, int type, + int value, int hash) +{ + return 0; +} + +#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; }) +#define dynamic_pr_debug(fmt, ...) do { } while (0) +#define dynamic_dev_dbg(dev, format, ...) do { } while (0) +#endif + +#endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 75d81f157d2..ededb6e83b4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -303,8 +304,12 @@ static inline char *pack_hex_byte(char *buf, u8 byte) #define pr_info(fmt, arg...) \ printk(KERN_INFO fmt, ##arg) -#ifdef DEBUG /* If you are writing a driver, please use dev_dbg instead */ +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +#define pr_debug(fmt, ...) do { \ + dynamic_pr_debug(fmt, ##__VA_ARGS__); \ + } while (0) +#elif defined(DEBUG) #define pr_debug(fmt, arg...) \ printk(KERN_DEBUG fmt, ##arg) #else diff --git a/include/linux/module.h b/include/linux/module.h index 68e09557c95..a41555cbe00 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -345,7 +345,6 @@ struct module /* Reference counts */ struct module_ref ref[NR_CPUS]; #endif - }; #ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {} -- cgit v1.2.3 From f1282c844e86db5a041afa41335b5f9eea6cec0c Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Wed, 16 Jul 2008 08:58:04 +1000 Subject: sysfs: Support sysfs_notify from atomic context with new sysfs_notify_dirent Support sysfs_notify from atomic context with new sysfs_notify_dirent sysfs_notify currently takes sysfs_mutex. This means that it cannot be called in atomic context. sysfs_mutex is sometimes held over a malloc (sysfs_rename_dir) so it can block on low memory. In md I want to be able to notify on a sysfs attribute from atomic context, and I don't want to block on low memory because I could be in the writeout path for freeing memory. So: - export the "sysfs_dirent" structure along with sysfs_get, sysfs_put and sysfs_get_dirent so I can get the sysfs_dirent that I want to notify on and hold it in an md structure. - split sysfs_notify_dirent out of sysfs_notify so the sysfs_dirent can be notified on with no blocking (just a spinlock). Signed-off-by: Neil Brown Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 8ec406afb3e..d8e0230f1e6 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -78,6 +78,8 @@ struct sysfs_ops { ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); }; +struct sysfs_dirent; + #ifdef CONFIG_SYSFS int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), @@ -118,10 +120,13 @@ void sysfs_remove_file_from_group(struct kobject *kobj, const struct attribute *attr, const char *group); void sysfs_notify(struct kobject *kobj, char *dir, char *attr); - +void sysfs_notify_dirent(struct sysfs_dirent *sd); +struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, + const unsigned char *name); +struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd); +void sysfs_put(struct sysfs_dirent *sd); void sysfs_printk_last_file(void); - -extern int __must_check sysfs_init(void); +int __must_check sysfs_init(void); #else /* CONFIG_SYSFS */ @@ -227,6 +232,22 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj, static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr) { } +static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) +{ +} +static inline +struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, + const unsigned char *name) +{ + return NULL; +} +static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd) +{ + return NULL; +} +static inline void sysfs_put(struct sysfs_dirent *sd) +{ +} static inline int __must_check sysfs_init(void) { -- cgit v1.2.3 From e61396627f91abb855ddd8925be9172fb5871944 Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sat, 20 Sep 2008 19:08:39 -0700 Subject: debug: Introduce a dev_WARN() function in the line of dev_printk(), this patch introduces a dev_WARN() function, that takes a struct device and then a printk format/args set of arguments. Unlike dev_printk(), the effect is that of WARN() in that a full warning message (including filename/line, module list, versions and a backtrace) is printed in addition to the device name and the arguments. Signed-off-by: Arjan van de Ven Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index fb034461b39..ec90e79f6a0 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -570,6 +570,14 @@ extern const char *dev_driver_string(const struct device *dev); ({ if (0) dev_printk(KERN_DEBUG, dev, format, ##arg); 0; }) #endif +/* + * dev_WARN() acts like dev_printk(), but with the key difference + * of using a WARN/WARN_ON to get the message out, including the + * file/line information and a backtrace. + */ +#define dev_WARN(dev, format, arg...) \ + WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg); + /* Create alias, so I can be autoloaded. */ #define MODULE_ALIAS_CHARDEV(major,minor) \ MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) -- cgit v1.2.3 From d8bf254089a6c31d7d01a4d1d2f1861662900855 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Mon, 22 Sep 2008 14:41:40 -0700 Subject: platform: add new device registration helper Add a helper that registers simple platform_device w/o resources but with parent and device data. This is usefull to cleanup platform code from code that registers such simple devices as leds-gpio, generic-bl, etc. Signed-off-by: Dmitry Baryshkov Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/platform_device.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 95ac21ab3a0..4b8cc6a3247 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -37,6 +37,8 @@ extern int platform_add_devices(struct platform_device **, int); extern struct platform_device *platform_device_register_simple(const char *, int id, struct resource *, unsigned int); +extern struct platform_device *platform_device_register_data(struct device *, + const char *, int, const void *, size_t); extern struct platform_device *platform_device_alloc(const char *name, int id); extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num); -- cgit v1.2.3 From 8c0e3998f5b71e68fe6b6e489a92e052715e563c Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 25 Sep 2008 16:45:13 -0700 Subject: sysfs: Make dir and name args to sysfs_notify() const Because they can be, and because code like this produces a warning if they're not: struct device_attribute dev_attr; sysfs_notify(&kobj, NULL, dev_attr.attr.name); Signed-off-by: Trent Piepho CC: Neil Brown Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index d8e0230f1e6..b330e289d71 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -119,7 +119,7 @@ int sysfs_add_file_to_group(struct kobject *kobj, void sysfs_remove_file_from_group(struct kobject *kobj, const struct attribute *attr, const char *group); -void sysfs_notify(struct kobject *kobj, char *dir, char *attr); +void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr); void sysfs_notify_dirent(struct sysfs_dirent *sd); struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd, const unsigned char *name); @@ -229,7 +229,8 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj, { } -static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr) +static inline void sysfs_notify(struct kobject *kobj, const char *dir, + const char *attr) { } static inline void sysfs_notify_dirent(struct sysfs_dirent *sd) -- cgit v1.2.3 From 030c1d2bfcc2187650fb975456ca0b61a5bb77f4 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 8 May 2008 14:41:00 -0700 Subject: kobject: Fix kobject_rename and !CONFIG_SYSFS When looking at kobject_rename I found two bugs with that exist when sysfs support is disabled in the kernel. kobject_rename does not change the name on the kobject when sysfs support is not compiled in. kobject_rename without locking attempts to check the validity of a rename operation, which the kobject layer simply does not have the infrastructure to do. This patch documents the previously unstated requirement of kobject_rename that is the responsibility of the caller to provide mutual exclusion and to be certain that the new_name for the kobject is valid. This patch modifies sysfs_rename_dir in !CONFIG_SYSFS case to call kobject_set_name to actually change the kobject_name. This patch removes the bogus and misleading check in kobject_rename that attempts to see if a rename is valid. The check is bogus because we do not have the proper locking. The check is misleading because it looks like we can and do perform checking at the kobject level that we don't. Signed-off-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b330e289d71..39924a96220 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -20,6 +20,8 @@ struct kobject; struct module; +extern int kobject_set_name(struct kobject *kobj, const char *name, ...) + __attribute__((format(printf, 2, 3))); /* FIXME * The *owner field is no longer used, but leave around * until the tree gets cleaned up fully. @@ -147,7 +149,7 @@ static inline void sysfs_remove_dir(struct kobject *kobj) static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name) { - return 0; + return kobject_set_name(kobj, "%s", new_name); } static inline int sysfs_move_dir(struct kobject *kobj, -- cgit v1.2.3 From 0b4a4fea253e1296222603ccc55430ed7cd9413a Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 3 Jul 2008 18:05:28 -0700 Subject: kobject: Cleanup kobject_rename and !CONFIG_SYSFS It finally dawned on me what the clean fix to sysfs_rename_dir calling kobject_set_name is. Move the work into kobject_rename where it belongs. The callers serialize us anyway so this is safe. Signed-off-by: Eric W. Biederman Acked-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman --- include/linux/sysfs.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 39924a96220..b330e289d71 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -20,8 +20,6 @@ struct kobject; struct module; -extern int kobject_set_name(struct kobject *kobj, const char *name, ...) - __attribute__((format(printf, 2, 3))); /* FIXME * The *owner field is no longer used, but leave around * until the tree gets cleaned up fully. @@ -149,7 +147,7 @@ static inline void sysfs_remove_dir(struct kobject *kobj) static inline int sysfs_rename_dir(struct kobject *kobj, const char *new_name) { - return kobject_set_name(kobj, "%s", new_name); + return 0; } static inline int sysfs_move_dir(struct kobject *kobj, -- cgit v1.2.3 From 99178b036c97293a65004ff5ec5cff9f833aaecd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Aug 2008 11:00:57 -0500 Subject: Driver core: add bus_sort_breadthfirst() function The PCI core wants to reorder the devices in the bus list. So move this functionality out of the pci core and into the driver core so that anyone else can also do this if needed. This also lets us change how struct device is attached to drivers in the future without messing with the PCI core. Acked-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index ec90e79f6a0..987f5912720 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -90,6 +90,9 @@ int __must_check bus_for_each_drv(struct bus_type *bus, struct device_driver *start, void *data, int (*fn)(struct device_driver *, void *)); +void bus_sort_breadthfirst(struct bus_type *bus, + int (*compare)(const struct device *a, + const struct device *b)); /* * Bus notifiers: Get notified of addition/removal of devices * and binding/unbinding of drivers to devices. -- cgit v1.2.3 From 1648993fb05c487947c1cec6307aca29d8002abe Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 15 Oct 2008 22:01:03 -0700 Subject: introduce generic header file for the software IO/TLB A series of patches introduce a generic header file for the software IO/TLB implementation in lib/swiotlb.c. Currently each architecture using this code defines the prototypes itself. The prototypes are moved to include/linux/swiotlb.h and this file is included in architecture specific code for X86 and IA64. This patch: Create include/linux/swiotlb.h file which contains all function prototypes for the lib/swiotlb.c file. (akpm: the dependent patches will be trickled through arch trees) Signed-off-by: Joerg Roedel Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swiotlb.h | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 include/linux/swiotlb.h (limited to 'include/linux') diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h new file mode 100644 index 00000000000..b18ec5533e8 --- /dev/null +++ b/include/linux/swiotlb.h @@ -0,0 +1,83 @@ +#ifndef __LINUX_SWIOTLB_H +#define __LINUX_SWIOTLB_H + +#include + +struct device; +struct dma_attrs; +struct scatterlist; + +extern void +swiotlb_init(void); + +extern void +*swiotlb_alloc_coherent(struct device *hwdev, size_t size, + dma_addr_t *dma_handle, gfp_t flags); + +extern void +swiotlb_free_coherent(struct device *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle); + +extern dma_addr_t +swiotlb_map_single(struct device *hwdev, void *ptr, size_t size, int dir); + +extern void +swiotlb_unmap_single(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); + +extern dma_addr_t +swiotlb_map_single_attrs(struct device *hwdev, void *ptr, size_t size, + int dir, struct dma_attrs *attrs); + +extern void +swiotlb_unmap_single_attrs(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir, struct dma_attrs *attrs); + +extern int +swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, + int direction); + +extern void +swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents, + int direction); + +extern int +swiotlb_map_sg_attrs(struct device *hwdev, struct scatterlist *sgl, int nelems, + int dir, struct dma_attrs *attrs); + +extern void +swiotlb_unmap_sg_attrs(struct device *hwdev, struct scatterlist *sgl, + int nelems, int dir, struct dma_attrs *attrs); + +extern void +swiotlb_sync_single_for_cpu(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); + +extern void +swiotlb_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg, + int nelems, int dir); + +extern void +swiotlb_sync_single_for_device(struct device *hwdev, dma_addr_t dev_addr, + size_t size, int dir); + +extern void +swiotlb_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg, + int nelems, int dir); + +extern void +swiotlb_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dev_addr, + unsigned long offset, size_t size, int dir); + +extern void +swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr, + unsigned long offset, size_t size, + int dir); + +extern int +swiotlb_dma_mapping_error(struct device *hwdev, dma_addr_t dma_addr); + +extern int +swiotlb_dma_supported(struct device *hwdev, u64 mask); + +#endif /* __LINUX_SWIOTLB_H */ -- cgit v1.2.3 From 9363b9f23c9cc36cc8ef6c05fdf879ee4a96ae92 Mon Sep 17 00:00:00 2001 From: Balbir Singh Date: Wed, 15 Oct 2008 22:01:05 -0700 Subject: memrlimit: cgroup mm owner callback changes to add task info This patch adds an additional field to the mm_owner callbacks. This field is required to get to the mm that changed. Hold mmap_sem in write mode before calling the mm_owner_changed callback [hugh@veritas.com: fix mmap_sem deadlock] Signed-off-by: Balbir Singh Cc: Sudhir Kumar Cc: YAMAMOTO Takashi Cc: Paul Menage Cc: Li Zefan Cc: Pavel Emelianov Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Cc: David Rientjes Cc: Vivek Goyal Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index c98dd7cb707..30934e4bfaa 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -326,7 +326,8 @@ struct cgroup_subsys { */ void (*mm_owner_changed)(struct cgroup_subsys *ss, struct cgroup *old, - struct cgroup *new); + struct cgroup *new, + struct task_struct *p); int subsys_id; int active; int disabled; -- cgit v1.2.3 From 1bfcf1304ea79c46efc3724e548b13b4b442b418 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Oct 2008 22:01:21 -0700 Subject: pm: rework disabling of user mode helpers during suspend/hibernation We currently use a PM notifier to disable user mode helpers before suspend and hibernation and to re-enable them during resume. However, this is not an ideal solution, because if any drivers want to upload firmware into memory before suspend, they have to use a PM notifier for this purpose and there is no guarantee that the ordering of PM notifiers will be as expected (ie. the notifier that disables user mode helpers has to be run after the driver's notifier used for uploading the firmware). For this reason, it seems better to move the disabling and enabling of user mode helpers to separate functions that will be called by the PM core as necessary. [akpm@linux-foundation.org: remove unneeded ifdefs] Signed-off-by: Rafael J. Wysocki Cc: Alan Stern Acked-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kmod.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kmod.h b/include/linux/kmod.h index a1a91577813..92213a9194e 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -99,4 +99,7 @@ struct file; extern int call_usermodehelper_pipe(char *path, char *argv[], char *envp[], struct file **filp); +extern int usermodehelper_disable(void); +extern void usermodehelper_enable(void); + #endif /* __LINUX_KMOD_H__ */ -- cgit v1.2.3 From d5c003b4d1690e666dbab02bc8e705947baa848c Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Wed, 15 Oct 2008 22:01:24 -0700 Subject: include: replace __FUNCTION__ with __func__ __FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ext2_fs.h | 2 +- include/linux/ext3_fs.h | 4 ++-- include/linux/ext3_jbd.h | 14 +++++++------- include/linux/jbd.h | 4 ++-- include/linux/jbd2.h | 4 ++-- include/linux/pm.h | 2 +- include/linux/reiserfs_fs.h | 2 +- include/linux/rtmutex.h | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h index 2efe7b863cf..78c775a83f7 100644 --- a/include/linux/ext2_fs.h +++ b/include/linux/ext2_fs.h @@ -47,7 +47,7 @@ #ifdef EXT2FS_DEBUG # define ext2_debug(f, a...) { \ printk ("EXT2-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ printk (f, ## a); \ } #else diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 8120fa1bc23..159d9b476cd 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -43,7 +43,7 @@ #define ext3_debug(f, a...) \ do { \ printk (KERN_DEBUG "EXT3-fs DEBUG (%s, %d): %s:", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ printk (KERN_DEBUG f, ## a); \ } while (0) #else @@ -871,7 +871,7 @@ extern void ext3_update_dynamic_rev (struct super_block *sb); #define ext3_std_error(sb, errno) \ do { \ if ((errno)) \ - __ext3_std_error((sb), __FUNCTION__, (errno)); \ + __ext3_std_error((sb), __func__, (errno)); \ } while (0) /* diff --git a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h index 8c43b13a02f..cf82d519be4 100644 --- a/include/linux/ext3_jbd.h +++ b/include/linux/ext3_jbd.h @@ -137,17 +137,17 @@ int __ext3_journal_dirty_metadata(const char *where, handle_t *handle, struct buffer_head *bh); #define ext3_journal_get_undo_access(handle, bh) \ - __ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh)) + __ext3_journal_get_undo_access(__func__, (handle), (bh)) #define ext3_journal_get_write_access(handle, bh) \ - __ext3_journal_get_write_access(__FUNCTION__, (handle), (bh)) + __ext3_journal_get_write_access(__func__, (handle), (bh)) #define ext3_journal_revoke(handle, blocknr, bh) \ - __ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh)) + __ext3_journal_revoke(__func__, (handle), (blocknr), (bh)) #define ext3_journal_get_create_access(handle, bh) \ - __ext3_journal_get_create_access(__FUNCTION__, (handle), (bh)) + __ext3_journal_get_create_access(__func__, (handle), (bh)) #define ext3_journal_dirty_metadata(handle, bh) \ - __ext3_journal_dirty_metadata(__FUNCTION__, (handle), (bh)) + __ext3_journal_dirty_metadata(__func__, (handle), (bh)) #define ext3_journal_forget(handle, bh) \ - __ext3_journal_forget(__FUNCTION__, (handle), (bh)) + __ext3_journal_forget(__func__, (handle), (bh)) int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh); @@ -160,7 +160,7 @@ static inline handle_t *ext3_journal_start(struct inode *inode, int nblocks) } #define ext3_journal_stop(handle) \ - __ext3_journal_stop(__FUNCTION__, (handle)) + __ext3_journal_stop(__func__, (handle)) static inline handle_t *ext3_journal_current_handle(void) { diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 07a9b52a265..7ebbcb1c9ba 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -61,7 +61,7 @@ extern u8 journal_enable_debug; do { \ if ((n) <= journal_enable_debug) { \ printk (KERN_DEBUG "(%s, %d): %s: ", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ printk (f, ## a); \ } \ } while (0) @@ -984,7 +984,7 @@ extern int cleanup_journal_tail(journal_t *); #define jbd_ENOSYS() \ do { \ - printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \ + printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \ current->state = TASK_UNINTERRUPTIBLE; \ schedule(); \ } while (1) diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index d2e91ea998f..463d6f10b64 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -61,7 +61,7 @@ extern u8 jbd2_journal_enable_debug; do { \ if ((n) <= jbd2_journal_enable_debug) { \ printk (KERN_DEBUG "(%s, %d): %s: ", \ - __FILE__, __LINE__, __FUNCTION__); \ + __FILE__, __LINE__, __func__); \ printk (f, ## a); \ } \ } while (0) @@ -1143,7 +1143,7 @@ extern int jbd2_cleanup_journal_tail(journal_t *); #define jbd_ENOSYS() \ do { \ - printk (KERN_ERR "JBD unimplemented function %s\n", __FUNCTION__); \ + printk (KERN_ERR "JBD unimplemented function %s\n", __func__); \ current->state = TASK_UNINTERRUPTIBLE; \ schedule(); \ } while (1) diff --git a/include/linux/pm.h b/include/linux/pm.h index 4dcce54b6d7..42de4003c4e 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -419,7 +419,7 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); #define suspend_report_result(fn, ret) \ do { \ - __suspend_report_result(__FUNCTION__, fn, ret); \ + __suspend_report_result(__func__, fn, ret); \ } while (0) #else /* !CONFIG_PM_SLEEP */ diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index e9963af16cd..bc5114d35e9 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -87,7 +87,7 @@ void reiserfs_warning(struct super_block *s, const char *fmt, ...); if( !( cond ) ) \ reiserfs_panic( NULL, "reiserfs[%i]: assertion " scond " failed at " \ __FILE__ ":%i:%s: " format "\n", \ - in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __FUNCTION__ , ##args ) + in_interrupt() ? -1 : task_pid_nr(current), __LINE__ , __func__ , ##args ) #define RASSERT(cond, format, args...) __RASSERT(cond, #cond, format, ##args) diff --git a/include/linux/rtmutex.h b/include/linux/rtmutex.h index 382bb795116..f19b00b7d53 100644 --- a/include/linux/rtmutex.h +++ b/include/linux/rtmutex.h @@ -54,7 +54,7 @@ struct hrtimer_sleeper; #ifdef CONFIG_DEBUG_RT_MUTEXES # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) \ , .name = #mutexname, .file = __FILE__, .line = __LINE__ -# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __FUNCTION__) +# define rt_mutex_init(mutex) __rt_mutex_init(mutex, __func__) extern void rt_mutex_debug_task_free(struct task_struct *tsk); #else # define __DEBUG_RT_MUTEX_INITIALIZER(mutexname) -- cgit v1.2.3 From 693ac389326a87d608baa2902c45a6e78ed46681 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 15 Oct 2008 22:01:25 -0700 Subject: include/linux/mount.h: remove CVS keyword Remove a CVS keyword that wasn't updated for a long time from a comment. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mount.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mount.h b/include/linux/mount.h index 30a1d63b6fb..cab2a85e2ee 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -5,8 +5,6 @@ * * Author: Marco van Wieringen * - * Version: $Id: mount.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $ - * */ #ifndef _LINUX_MOUNT_H #define _LINUX_MOUNT_H -- cgit v1.2.3 From 1ecfea06386c6b1344e83c8f909c87c88262ba1d Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Wed, 15 Oct 2008 22:01:27 -0700 Subject: init.h: remove long-dead __setup_null_param() macro This macro appears to have been unused for ages, and there are no invocations of it anywhere in the source tree. Signed-off-by: Robert P. J. Day Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/init.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 93538b696e3..ad63824460e 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -233,9 +233,6 @@ struct obs_kernel_param { __attribute__((aligned((sizeof(long))))) \ = { __setup_str_##unique_id, fn, early } -#define __setup_null_param(str, unique_id) \ - __setup_param(str, unique_id, NULL, 0) - #define __setup(str, fn) \ __setup_param(str, fn, fn, 0) @@ -296,7 +293,6 @@ void __init parse_early_param(void); void cleanup_module(void) __attribute__((alias(#exitfn))); #define __setup_param(str, unique_id, fn) /* nothing */ -#define __setup_null_param(str, unique_id) /* nothing */ #define __setup(str, func) /* nothing */ #endif -- cgit v1.2.3 From c80cfb0406c01bb5da91bfe30f5cb1fd96831138 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Oct 2008 22:01:35 -0700 Subject: vsprintf: use new vsprintf symbolic function pointer format Use the '%pF' format to get rid of an "#ifdef DEBUG" and make some printks atomic. This removes the last in-tree uses of print_fn_descriptor_symbol(). I marked print_fn_descriptor_symbol() deprecated and scheduled it for removal next year to give time for out-of-tree modules to be updated. parisc's print_fn_descriptor_symbol() is currently broken there (it needs to dereference the function pointer similar to ia64 and power). This patch shouldn't make anything worse, but it means we need to fix dereference_function_descriptor() instead of print_fn_descriptor_symbol() to get meaningful initcall_debug output. Signed-off-by: Bjorn Helgaas Cc: Jesse Barnes Cc: Kyle McMartin Cc: "Rafael J. Wysocki" Cc: Kay Sievers Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kallsyms.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kallsyms.h b/include/linux/kallsyms.h index b9614488744..f3fe34391d8 100644 --- a/include/linux/kallsyms.h +++ b/include/linux/kallsyms.h @@ -93,12 +93,10 @@ static inline void print_symbol(const char *fmt, unsigned long addr) } /* - * Pretty-print a function pointer. - * - * ia64 and ppc64 function pointers are really function descriptors, - * which contain a pointer the real address. + * Pretty-print a function pointer. This function is deprecated. + * Please use the "%pF" vsprintf format instead. */ -static inline void print_fn_descriptor_symbol(const char *fmt, void *addr) +static inline void __deprecated print_fn_descriptor_symbol(const char *fmt, void *addr) { #if defined(CONFIG_IA64) || defined(CONFIG_PPC64) addr = *(void **)addr; -- cgit v1.2.3 From a25d644fc0e232f242d1f3baa63c149c42536ff0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 15 Oct 2008 22:01:38 -0700 Subject: wait: kill is_sync_wait() is_sync_wait() is used to distinguish between sync and async waits. Basically sync waits are the ones initialized with init_waitqueue_entry() and async ones with init_waitqueue_func_entry(). The sync/async distinction is used only in prepare_to_wait[_exclusive]() and its only function is to skip setting the current task state if the wait is async. This has a few problems. * No one uses it. None of func_entry users use prepare_to_wait() functions, so the code path never gets executed. * The distinction is bogus. Maybe back when func_entry is used only by aio but it's now also used by epoll and in future possibly by 9p and poll/select. * Taking @state as argument and ignoring it silenly depending on how @wait is initialized is just a bad error-prone API. * It prevents func_entry waits from using wait->private for no good reason. This patch kills is_sync_wait() and the associated code paths from prepare_to_wait[_exclusive](). As there was no user of these code paths, this patch doesn't cause any behavior difference. Signed-off-by: Tejun Heo Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/wait.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/wait.h b/include/linux/wait.h index 0081147a9fe..ef609f842fa 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -108,15 +108,6 @@ static inline int waitqueue_active(wait_queue_head_t *q) return !list_empty(&q->task_list); } -/* - * Used to distinguish between sync and async io wait context: - * sync i/o typically specifies a NULL wait queue entry or a wait - * queue entry bound to a task (current task) to wake up. - * aio specifies a wait queue entry with an async notification - * callback routine, not associated with any task. - */ -#define is_sync_wait(wait) (!(wait) || ((wait)->private)) - extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); extern void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait); extern void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait); -- cgit v1.2.3 From 25ddbb18aae33ad255eb9f35aacebe3af01e1e9c Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Wed, 15 Oct 2008 22:01:41 -0700 Subject: Make the taint flags reliable It's somewhat unlikely that it happens, but right now a race window between interrupts or machine checks or oopses could corrupt the tainted bitmap because it is modified in a non atomic fashion. Convert the taint variable to an unsigned long and use only atomic bit operations on it. Unfortunately this means the intvec sysctl functions cannot be used on it anymore. It turned out the taint sysctl handler could actually be simplified a bit (since it only increases capabilities) so this patch actually removes code. [akpm@linux-foundation.org: remove unneeded include] Signed-off-by: Andi Kleen Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 75d81f157d2..e971c55f45a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -235,9 +235,10 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in extern int panic_timeout; extern int panic_on_oops; extern int panic_on_unrecovered_nmi; -extern int tainted; extern const char *print_tainted(void); -extern void add_taint(unsigned); +extern void add_taint(unsigned flag); +extern int test_taint(unsigned flag); +extern unsigned long get_taint(void); extern int root_mountflags; /* Values used for system_state */ @@ -250,16 +251,16 @@ extern enum system_states { SYSTEM_SUSPEND_DISK, } system_state; -#define TAINT_PROPRIETARY_MODULE (1<<0) -#define TAINT_FORCED_MODULE (1<<1) -#define TAINT_UNSAFE_SMP (1<<2) -#define TAINT_FORCED_RMMOD (1<<3) -#define TAINT_MACHINE_CHECK (1<<4) -#define TAINT_BAD_PAGE (1<<5) -#define TAINT_USER (1<<6) -#define TAINT_DIE (1<<7) -#define TAINT_OVERRIDDEN_ACPI_TABLE (1<<8) -#define TAINT_WARN (1<<9) +#define TAINT_PROPRIETARY_MODULE 0 +#define TAINT_FORCED_MODULE 1 +#define TAINT_UNSAFE_SMP 2 +#define TAINT_FORCED_RMMOD 3 +#define TAINT_MACHINE_CHECK 4 +#define TAINT_BAD_PAGE 5 +#define TAINT_USER 6 +#define TAINT_DIE 7 +#define TAINT_OVERRIDDEN_ACPI_TABLE 8 +#define TAINT_WARN 9 extern void dump_stack(void) __cold; -- cgit v1.2.3 From 22b8ce94708f7cdf0b04965c6f7443dfd374c35c Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Wed, 15 Oct 2008 22:01:46 -0700 Subject: profiling: dynamically enable readprofile at runtime Way too often, I have a machine that exhibits some kind of crappy behavior. The CPU looks wedged in the kernel or it is spending way too much system time and I wonder what is responsible. I try to run readprofile. But, of course, Ubuntu doesn't enable it by default. Dang! The reason we boot-time enable it is that it takes a big bufffer that we generally can only bootmem alloc. But, does it hurt to at least try and runtime-alloc it? To use: echo 2 > /sys/kernel/profile Then run readprofile like normal. This should fix the compile issue with allmodconfig. I've compile-tested on a bunch more configs now including a few more architectures. Signed-off-by: Dave Hansen Acked-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/profile.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/profile.h b/include/linux/profile.h index 7e7087239af..570045053ce 100644 --- a/include/linux/profile.h +++ b/include/linux/profile.h @@ -35,7 +35,9 @@ enum profile_type { extern int prof_on __read_mostly; /* init basic kernel profiler */ -void __init profile_init(void); +int profile_init(void); +int profile_setup(char *str); +int create_proc_profile(void); void profile_tick(int type); /* @@ -84,9 +86,9 @@ struct pt_regs; #define prof_on 0 -static inline void profile_init(void) +static inline int profile_init(void) { - return; + return 0; } static inline void profile_tick(int type) -- cgit v1.2.3 From e1f8e87449147ffe5ea3de64a46af7de450ce279 Mon Sep 17 00:00:00 2001 From: Francois Cami Date: Wed, 15 Oct 2008 22:01:59 -0700 Subject: Remove Andrew Morton's old email accounts People can use the real name an an index into MAINTAINERS to find the current email address. Signed-off-by: Francois Cami Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/journal-head.h | 2 +- include/linux/task_io_accounting.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/journal-head.h b/include/linux/journal-head.h index 8a62d1e84b9..bb70ebb6a2d 100644 --- a/include/linux/journal-head.h +++ b/include/linux/journal-head.h @@ -3,7 +3,7 @@ * * buffer_head fields for JBD * - * 27 May 2001 Andrew Morton + * 27 May 2001 Andrew Morton * Created - pulled out of fs.h */ diff --git a/include/linux/task_io_accounting.h b/include/linux/task_io_accounting.h index 5e88afc9a2f..bdf855c2856 100644 --- a/include/linux/task_io_accounting.h +++ b/include/linux/task_io_accounting.h @@ -5,7 +5,7 @@ * Don't include this header file directly - it is designed to be dragged in via * sched.h. * - * Blame akpm@osdl.org for all this. + * Blame Andrew Morton for all this. */ struct task_io_accounting { -- cgit v1.2.3 From f7ad160b49c49dc9cd383b9184c6fa4a9b4f7ebb Mon Sep 17 00:00:00 2001 From: Alex Raimondi Date: Wed, 15 Oct 2008 22:02:03 -0700 Subject: include/linux/clk.h: fix comment clk_get and clk_put may not be used from within interrupt context. Change comment to this function. Signed-off-by: Alex Raimondi Signed-off-by: Haavard Skinnemoen Acked-by: Russell King Cc: john stultz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/clk.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/clk.h b/include/linux/clk.h index 5ca8c6fddb5..778777316ea 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -35,6 +35,8 @@ struct clk; * clk_get may return different clock producers depending on @dev.) * * Drivers must assume that the clock source is not enabled. + * + * clk_get should not be called from within interrupt context. */ struct clk *clk_get(struct device *dev, const char *id); @@ -76,6 +78,8 @@ unsigned long clk_get_rate(struct clk *clk); * Note: drivers must ensure that all clk_enable calls made on this * clock source are balanced by clk_disable calls prior to calling * this function. + * + * clk_put should not be called from within interrupt context. */ void clk_put(struct clk *clk); -- cgit v1.2.3 From f7a5000f7a8924e9c5fad1801616601d6dc65a17 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 15 Oct 2008 22:02:05 -0700 Subject: compat: move cp_compat_stat to common code struct stat / compat_stat is the same on all architectures, so cp_compat_stat should be, too. Turns out it is, except that various architectures have slightly and some high2lowuid/high2lowgid or the direct assignment instead of the SET_UID/SET_GID that expands to the correct one anyway. This patch replaces the arch-specific cp_compat_stat implementations with a common one based on the x86-64 one. Signed-off-by: Christoph Hellwig Acked-by: David S. Miller [ sparc bits ] Acked-by: Kyle McMartin [ parisc bits ] Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/compat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index cf8d11cad5a..999dddd8d93 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -78,7 +78,6 @@ typedef struct { compat_sigset_word sig[_COMPAT_NSIG_WORDS]; } compat_sigset_t; -extern int cp_compat_stat(struct kstat *, struct compat_stat __user *); extern int get_compat_timespec(struct timespec *, const struct compat_timespec __user *); extern int put_compat_timespec(const struct timespec *, struct compat_timespec __user *); -- cgit v1.2.3 From b418da16dd44810e5d5a22bba377cca80512a524 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 15 Oct 2008 22:02:06 -0700 Subject: compat: generic compat get/settimeofday Nothing arch specific in get/settimeofday. The details of the timeval conversion varied a little from arch to arch, but all with the same results. Also add an extern declaration for sys_tz to linux/time.h because externs in .c files are fowned upon. I'll kill the externs in various other files in a sparate patch. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Christoph Hellwig Acked-by: David S. Miller [ sparc bits ] Cc: "Luck, Tony" Cc: Ralf Baechle Acked-by: Kyle McMartin Cc: Matthew Wilcox Cc: Grant Grundler Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Ingo Molnar Cc: Thomas Gleixner Cc: "H. Peter Anvin" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/compat.h | 5 +++++ include/linux/time.h | 2 ++ 2 files changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/compat.h b/include/linux/compat.h index 999dddd8d93..f061a1ea1b7 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -234,6 +234,11 @@ extern int get_compat_itimerspec(struct itimerspec *dst, extern int put_compat_itimerspec(struct compat_itimerspec __user *dst, const struct itimerspec *src); +asmlinkage long compat_sys_gettimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); +asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, + struct timezone __user *tz); + asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); extern int compat_printk(const char *fmt, ...); diff --git a/include/linux/time.h b/include/linux/time.h index e15206a7e82..51e883df0fa 100644 --- a/include/linux/time.h +++ b/include/linux/time.h @@ -29,6 +29,8 @@ struct timezone { #ifdef __KERNEL__ +extern struct timezone sys_tz; + /* Parameters used to convert the timespec values: */ #define MSEC_PER_SEC 1000L #define USEC_PER_MSEC 1000L -- cgit v1.2.3 From 56d936607408d71c4141b2ed501410b072f1e211 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Wed, 15 Oct 2008 22:02:10 -0700 Subject: introduce generic iommu_num_pages function This patch introduces the generic iommu_num_pages function. It can be used by a given memory area. Signed-off-by: Joerg Roedel Cc: "David S. Miller" Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Ingo Molnar Cc: Thomas Gleixner Cc: FUJITA Tomonori Cc: Muli Ben-Yehuda Cc: Dave Airlie Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/iommu-helper.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/iommu-helper.h b/include/linux/iommu-helper.h index a6d0586e2bf..3b068e5b567 100644 --- a/include/linux/iommu-helper.h +++ b/include/linux/iommu-helper.h @@ -23,4 +23,7 @@ extern unsigned long iommu_area_alloc(unsigned long *map, unsigned long size, extern void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr); +extern unsigned long iommu_num_pages(unsigned long addr, unsigned long len, + unsigned long io_page_size); + #endif -- cgit v1.2.3 From 53112488bebe25c0f5f8a002470046c0fe9a6c61 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Wed, 15 Oct 2008 22:02:37 -0700 Subject: alpha: introduce field 'taso' into struct linux_binprm This change is Alpha-specific. It adds field 'taso' into struct linux_binprm to remember if the application is TASO. Previously, field sh_bang was used for this purpose. Signed-off-by: Kirill A. Shutemov Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Pavel Emelyanov Cc: Alexander Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/binfmts.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 826f6235080..54980a3c760 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -36,6 +36,9 @@ struct linux_binprm{ unsigned long p; /* current top of mem */ unsigned int sh_bang:1, misc_bang:1; +#ifdef __alpha__ + unsigned int taso:1; +#endif struct file * file; int e_uid, e_gid; kernel_cap_t cap_post_exec_permitted; -- cgit v1.2.3 From bf2a9a39639b8b51377905397a5005f444e9a892 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Wed, 15 Oct 2008 22:02:39 -0700 Subject: Allow recursion in binfmt_script and binfmt_misc binfmt_script and binfmt_misc disallow recursion to avoid stack overflow using sh_bang and misc_bang. It causes problem in some cases: $ echo '#!/bin/ls' > /tmp/t0 $ echo '#!/tmp/t0' > /tmp/t1 $ echo '#!/tmp/t1' > /tmp/t2 $ chmod +x /tmp/t* $ /tmp/t2 zsh: exec format error: /tmp/t2 Similar problem with binfmt_misc. This patch introduces field 'recursion_depth' into struct linux_binprm to track recursion level in binfmt_misc and binfmt_script. If recursion level more then BINPRM_MAX_RECURSION it generates -ENOEXEC. [akpm@linux-foundation.org: make linux_binprm.recursion_depth a uint] Signed-off-by: Kirill A. Shutemov Cc: Pavel Emelyanov Cc: Alexander Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/binfmts.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 54980a3c760..7394b5b349f 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h @@ -39,6 +39,7 @@ struct linux_binprm{ #ifdef __alpha__ unsigned int taso:1; #endif + unsigned int recursion_depth; struct file * file; int e_uid, e_gid; kernel_cap_t cap_post_exec_permitted; @@ -61,6 +62,7 @@ struct linux_binprm{ #define BINPRM_FLAGS_EXECFD_BIT 1 #define BINPRM_FLAGS_EXECFD (1 << BINPRM_FLAGS_EXECFD_BIT) +#define BINPRM_MAX_RECURSION 4 /* * This structure defines the functions that are used to load the binary formats that -- cgit v1.2.3 From 2bec19feabd53cba75e9dab0e79afbe868a37113 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Wed, 15 Oct 2008 22:02:44 -0700 Subject: orion_spi: handle 88F6183 erratum Add support to orion_spi for the 88F6183 ARM SoC by adding code to work around a 6183-specific erratum. Signed-off-by: Lennert Buytenhek Signed-off-by: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/spi/orion_spi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/spi/orion_spi.h b/include/linux/spi/orion_spi.h index b4d9fa6f797..decf6d8c77b 100644 --- a/include/linux/spi/orion_spi.h +++ b/include/linux/spi/orion_spi.h @@ -11,6 +11,7 @@ struct orion_spi_info { u32 tclk; /* no support yet */ + u32 enable_clock_fix; }; -- cgit v1.2.3 From 9d793b0bcbbbc37d80241862dfa5257963d5415e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 15 Oct 2008 22:02:47 -0700 Subject: i2o: Fix 32/64bit DMA locking The I2O ioctls assume 32bits. In itself that is fine as they are old cards and nobody uses 64bit. However on LKML it was noted this assumption is also made for allocated memory and is unsafe on 64bit systems. Fixing this is a mess. It turns out there is tons of crap buried in a header file that does racy 32/64bit filtering on the masks. So we: - Verify all callers of the racy code can sleep (i2o_dma_[re]alloc) - Move the code into a new i2o/memory.c file - Remove the gfp_mask argument so nobody can try and misuse the function - Wrap a mutex around the problem area (a single mutex is easy to do and none of this is performance relevant) - Switch the remaining problem kmalloc holdout to use i2o_dma_alloc Cc: Markus Lidel Cc: Vasily Averin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/i2o.h | 292 +++------------------------------------------------- 1 file changed, 12 insertions(+), 280 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 75ae6d8aba4..4c4e57d1f19 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -570,7 +570,6 @@ struct i2o_controller { #endif spinlock_t lock; /* lock for controller configuration */ - void *driver_data[I2O_MAX_DRIVERS]; /* storage for drivers */ }; @@ -691,289 +690,22 @@ static inline u32 i2o_dma_high(dma_addr_t dma_addr) }; #endif -/** - * i2o_sg_tablesize - Calculate the maximum number of elements in a SGL - * @c: I2O controller for which the calculation should be done - * @body_size: maximum body size used for message in 32-bit words. - * - * Return the maximum number of SG elements in a SG list. - */ -static inline u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size) -{ - i2o_status_block *sb = c->status_block.virt; - u16 sg_count = - (sb->inbound_frame_size - sizeof(struct i2o_message) / 4) - - body_size; - - if (c->pae_support) { - /* - * for 64-bit a SG attribute element must be added and each - * SG element needs 12 bytes instead of 8. - */ - sg_count -= 2; - sg_count /= 3; - } else - sg_count /= 2; - - if (c->short_req && (sg_count > 8)) - sg_count = 8; - - return sg_count; -}; - -/** - * i2o_dma_map_single - Map pointer to controller and fill in I2O message. - * @c: I2O controller - * @ptr: pointer to the data which should be mapped - * @size: size of data in bytes - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_single(). The pointer sg_ptr will only be set to the end of the - * SG list if the allocation was successful. - * - * Returns DMA address which must be checked for failures using - * dma_mapping_error(). - */ -static inline dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, +extern u16 i2o_sg_tablesize(struct i2o_controller *c, u16 body_size); +extern dma_addr_t i2o_dma_map_single(struct i2o_controller *c, void *ptr, size_t size, enum dma_data_direction direction, - u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - dma_addr_t dma_addr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0xd4000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0xd0000000; - break; - default: - return 0; - } - - dma_addr = dma_map_single(&c->pdev->dev, ptr, size, direction); - if (!dma_mapping_error(&c->pdev->dev, dma_addr)) { -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - *mptr++ = cpu_to_le32(sg_flags | size); - *mptr++ = cpu_to_le32(i2o_dma_low(dma_addr)); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(dma_addr)); -#endif - *sg_ptr = mptr; - } - return dma_addr; -}; - -/** - * i2o_dma_map_sg - Map a SG List to controller and fill in I2O message. - * @c: I2O controller - * @sg: SG list to be mapped - * @sg_count: number of elements in the SG list - * @direction: DMA_TO_DEVICE / DMA_FROM_DEVICE - * @sg_ptr: pointer to the SG list inside the I2O message - * - * This function does all necessary DMA handling and also writes the I2O - * SGL elements into the I2O message. For details on DMA handling see also - * dma_map_sg(). The pointer sg_ptr will only be set to the end of the SG - * list if the allocation was successful. - * - * Returns 0 on failure or 1 on success. - */ -static inline int i2o_dma_map_sg(struct i2o_controller *c, + u32 ** sg_ptr); +extern int i2o_dma_map_sg(struct i2o_controller *c, struct scatterlist *sg, int sg_count, enum dma_data_direction direction, - u32 ** sg_ptr) -{ - u32 sg_flags; - u32 *mptr = *sg_ptr; - - switch (direction) { - case DMA_TO_DEVICE: - sg_flags = 0x14000000; - break; - case DMA_FROM_DEVICE: - sg_flags = 0x10000000; - break; - default: - return 0; - } - - sg_count = dma_map_sg(&c->pdev->dev, sg, sg_count, direction); - if (!sg_count) - return 0; - -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) { - *mptr++ = cpu_to_le32(0x7C020002); - *mptr++ = cpu_to_le32(PAGE_SIZE); - } -#endif - - while (sg_count-- > 0) { - if (!sg_count) - sg_flags |= 0xC0000000; - *mptr++ = cpu_to_le32(sg_flags | sg_dma_len(sg)); - *mptr++ = cpu_to_le32(i2o_dma_low(sg_dma_address(sg))); -#ifdef CONFIG_I2O_EXT_ADAPTEC_DMA64 - if ((sizeof(dma_addr_t) > 4) && c->pae_support) - *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg))); -#endif - sg = sg_next(sg); - } - *sg_ptr = mptr; - - return 1; -}; - -/** - * i2o_dma_alloc - Allocate DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which should get the DMA buffer - * @len: length of the new DMA memory - * @gfp_mask: GFP mask - * - * Allocate a coherent DMA memory and write the pointers into addr. - * - * Returns 0 on success or -ENOMEM on failure. - */ -static inline int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, - size_t len, gfp_t gfp_mask) -{ - struct pci_dev *pdev = to_pci_dev(dev); - int dma_64 = 0; - - if ((sizeof(dma_addr_t) > 4) && (pdev->dma_mask == DMA_64BIT_MASK)) { - dma_64 = 1; - if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) - return -ENOMEM; - } - - addr->virt = dma_alloc_coherent(dev, len, &addr->phys, gfp_mask); - - if ((sizeof(dma_addr_t) > 4) && dma_64) - if (pci_set_dma_mask(pdev, DMA_64BIT_MASK)) - printk(KERN_WARNING "i2o: unable to set 64-bit DMA"); - - if (!addr->virt) - return -ENOMEM; - - memset(addr->virt, 0, len); - addr->len = len; - - return 0; -}; - -/** - * i2o_dma_free - Free DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: i2o_dma struct which contains the DMA buffer - * - * Free a coherent DMA memory and set virtual address of addr to NULL. - */ -static inline void i2o_dma_free(struct device *dev, struct i2o_dma *addr) -{ - if (addr->virt) { - if (addr->phys) - dma_free_coherent(dev, addr->len, addr->virt, - addr->phys); - else - kfree(addr->virt); - addr->virt = NULL; - } -}; - -/** - * i2o_dma_realloc - Realloc DMA memory - * @dev: struct device pointer to the PCI device of the I2O controller - * @addr: pointer to a i2o_dma struct DMA buffer - * @len: new length of memory - * @gfp_mask: GFP mask - * - * If there was something allocated in the addr, free it first. If len > 0 - * than try to allocate it and write the addresses back to the addr - * structure. If len == 0 set the virtual address to NULL. - * - * Returns the 0 on success or negative error code on failure. - */ -static inline int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, - size_t len, gfp_t gfp_mask) -{ - i2o_dma_free(dev, addr); - - if (len) - return i2o_dma_alloc(dev, addr, len, gfp_mask); - - return 0; -}; - -/* - * i2o_pool_alloc - Allocate an slab cache and mempool - * @mempool: pointer to struct i2o_pool to write data into. - * @name: name which is used to identify cache - * @size: size of each object - * @min_nr: minimum number of objects - * - * First allocates a slab cache with name and size. Then allocates a - * mempool which uses the slab cache for allocation and freeing. - * - * Returns 0 on success or negative error code on failure. - */ -static inline int i2o_pool_alloc(struct i2o_pool *pool, const char *name, - size_t size, int min_nr) -{ - pool->name = kmalloc(strlen(name) + 1, GFP_KERNEL); - if (!pool->name) - goto exit; - strcpy(pool->name, name); - - pool->slab = - kmem_cache_create(pool->name, size, 0, SLAB_HWCACHE_ALIGN, NULL); - if (!pool->slab) - goto free_name; - - pool->mempool = mempool_create_slab_pool(min_nr, pool->slab); - if (!pool->mempool) - goto free_slab; - - return 0; - - free_slab: - kmem_cache_destroy(pool->slab); - - free_name: - kfree(pool->name); - - exit: - return -ENOMEM; -}; - -/* - * i2o_pool_free - Free slab cache and mempool again - * @mempool: pointer to struct i2o_pool which should be freed - * - * Note that you have to return all objects to the mempool again before - * calling i2o_pool_free(). - */ -static inline void i2o_pool_free(struct i2o_pool *pool) -{ - mempool_destroy(pool->mempool); - kmem_cache_destroy(pool->slab); - kfree(pool->name); -}; - + u32 ** sg_ptr); +extern int i2o_dma_alloc(struct device *dev, struct i2o_dma *addr, size_t len); +extern void i2o_dma_free(struct device *dev, struct i2o_dma *addr); +extern int i2o_dma_realloc(struct device *dev, struct i2o_dma *addr, + size_t len); +extern int i2o_pool_alloc(struct i2o_pool *pool, const char *name, + size_t size, int min_nr); +extern void i2o_pool_free(struct i2o_pool *pool); /* I2O driver (OSM) functions */ extern int i2o_driver_register(struct i2o_driver *); extern void i2o_driver_unregister(struct i2o_driver *); -- cgit v1.2.3 From bb979d7fc360bc37cbaff43a6fafceb897cb5e47 Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Wed, 15 Oct 2008 22:02:52 -0700 Subject: autofs4: cleanup autofs mount type usage Usage of the AUTOFS_TYPE_* defines is a little confusing and appears inconsistent. Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/auto_fs4.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index b785c6f8644..aa96a04ae02 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h @@ -29,6 +29,11 @@ #define AUTOFS_EXP_IMMEDIATE 1 #define AUTOFS_EXP_LEAVES 2 +#define AUTOFS_TYPE_ANY 0x0000 +#define AUTOFS_TYPE_INDIRECT 0x0001 +#define AUTOFS_TYPE_DIRECT 0x0002 +#define AUTOFS_TYPE_OFFSET 0x0004 + /* Daemon notification packet types */ enum autofs_notify { NFY_NONE, -- cgit v1.2.3 From 8d7b48e0bc5fa01a818eac713d4cb0763090cd0e Mon Sep 17 00:00:00 2001 From: Ian Kent Date: Wed, 15 Oct 2008 22:02:54 -0700 Subject: autofs4: add miscellaneous device for ioctls Add a miscellaneous device to the autofs4 module for routing ioctls. This provides the ability to obtain an ioctl file handle for an autofs mount point that is possibly covered by another mount. The actual problem with autofs is that it can't reconnect to existing mounts. Immediately one things of just adding the ability to remount autofs file systems would solve it, but alas, that can't work. This is because autofs direct mounts and the implementation of "on demand mount and expire" of nested mount trees have the file system mounted on top of the mount trigger dentry. To resolve this a miscellaneous device node for routing ioctl commands to these mount points has been implemented in the autofs4 kernel module and a library added to autofs. This provides the ability to open a file descriptor for these over mounted autofs mount points. Please refer to Documentation/filesystems/autofs4-mount-control.txt for a discussion of the problem, implementation alternatives considered and a description of the interface. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: build fix] Signed-off-by: Ian Kent Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/auto_dev-ioctl.h | 157 +++++++++++++++++++++++++++++++++++++++++ include/linux/auto_fs4.h | 2 +- 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 include/linux/auto_dev-ioctl.h (limited to 'include/linux') diff --git a/include/linux/auto_dev-ioctl.h b/include/linux/auto_dev-ioctl.h new file mode 100644 index 00000000000..f4d05ccd731 --- /dev/null +++ b/include/linux/auto_dev-ioctl.h @@ -0,0 +1,157 @@ +/* + * Copyright 2008 Red Hat, Inc. All rights reserved. + * Copyright 2008 Ian Kent + * + * This file is part of the Linux kernel and is made available under + * the terms of the GNU General Public License, version 2, or at your + * option, any later version, incorporated herein by reference. + */ + +#ifndef _LINUX_AUTO_DEV_IOCTL_H +#define _LINUX_AUTO_DEV_IOCTL_H + +#include + +#define AUTOFS_DEVICE_NAME "autofs" + +#define AUTOFS_DEV_IOCTL_VERSION_MAJOR 1 +#define AUTOFS_DEV_IOCTL_VERSION_MINOR 0 + +#define AUTOFS_DEVID_LEN 16 + +#define AUTOFS_DEV_IOCTL_SIZE sizeof(struct autofs_dev_ioctl) + +/* + * An ioctl interface for autofs mount point control. + */ + +/* + * All the ioctls use this structure. + * When sending a path size must account for the total length + * of the chunk of memory otherwise is is the size of the + * structure. + */ + +struct autofs_dev_ioctl { + __u32 ver_major; + __u32 ver_minor; + __u32 size; /* total size of data passed in + * including this struct */ + __s32 ioctlfd; /* automount command fd */ + + __u32 arg1; /* Command parameters */ + __u32 arg2; + + char path[0]; +}; + +static inline void init_autofs_dev_ioctl(struct autofs_dev_ioctl *in) +{ + in->ver_major = AUTOFS_DEV_IOCTL_VERSION_MAJOR; + in->ver_minor = AUTOFS_DEV_IOCTL_VERSION_MINOR; + in->size = sizeof(struct autofs_dev_ioctl); + in->ioctlfd = -1; + in->arg1 = 0; + in->arg2 = 0; + return; +} + +/* + * If you change this make sure you make the corresponding change + * to autofs-dev-ioctl.c:lookup_ioctl() + */ +enum { + /* Get various version info */ + AUTOFS_DEV_IOCTL_VERSION_CMD = 0x71, + AUTOFS_DEV_IOCTL_PROTOVER_CMD, + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, + + /* Open mount ioctl fd */ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, + + /* Close mount ioctl fd */ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, + + /* Mount/expire status returns */ + AUTOFS_DEV_IOCTL_READY_CMD, + AUTOFS_DEV_IOCTL_FAIL_CMD, + + /* Activate/deactivate autofs mount */ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, + AUTOFS_DEV_IOCTL_CATATONIC_CMD, + + /* Expiry timeout */ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, + + /* Get mount last requesting uid and gid */ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, + + /* Check for eligible expire candidates */ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, + + /* Request busy status */ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, + + /* Check if path is a mountpoint */ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, +}; + +#define AUTOFS_IOCTL 0x93 + +#define AUTOFS_DEV_IOCTL_VERSION \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_VERSION_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_PROTOSUBVER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_PROTOSUBVER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_OPENMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_OPENMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CLOSEMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CLOSEMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_READY \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_READY_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_FAIL \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_FAIL_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_SETPIPEFD \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_SETPIPEFD_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_CATATONIC \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_CATATONIC_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_TIMEOUT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_TIMEOUT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_REQUESTER \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_REQUESTER_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_EXPIRE \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_EXPIRE_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ASKUMOUNT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ASKUMOUNT_CMD, struct autofs_dev_ioctl) + +#define AUTOFS_DEV_IOCTL_ISMOUNTPOINT \ + _IOWR(AUTOFS_IOCTL, \ + AUTOFS_DEV_IOCTL_ISMOUNTPOINT_CMD, struct autofs_dev_ioctl) + +#endif /* _LINUX_AUTO_DEV_IOCTL_H */ diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h index aa96a04ae02..2253716d4b9 100644 --- a/include/linux/auto_fs4.h +++ b/include/linux/auto_fs4.h @@ -23,7 +23,7 @@ #define AUTOFS_MIN_PROTO_VERSION 3 #define AUTOFS_MAX_PROTO_VERSION 5 -#define AUTOFS_PROTO_SUBVERSION 0 +#define AUTOFS_PROTO_SUBVERSION 1 /* Mask for expire behaviour */ #define AUTOFS_EXP_IMMEDIATE 1 -- cgit v1.2.3 From 3d599d1ca57f443e5c4ff5af1e69d90350082f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Wed, 15 Oct 2008 22:03:12 -0700 Subject: gpio_free might sleep, generic part MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to the documentation gpio_free should only be called from task context only. To make this more explicit add a might sleep to all implementations. This is the generic part which changes gpiolib and the fallback implementation only. Signed-off-by: Uwe Kleine-König Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/gpio.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/gpio.h b/include/linux/gpio.h index 730a20b8357..e10c49a5b96 100644 --- a/include/linux/gpio.h +++ b/include/linux/gpio.h @@ -8,6 +8,7 @@ #else +#include #include #include @@ -32,6 +33,8 @@ static inline int gpio_request(unsigned gpio, const char *label) static inline void gpio_free(unsigned gpio) { + might_sleep(); + /* GPIO can never have been requested */ WARN_ON(1); } -- cgit v1.2.3 From e3a1938805d2e81b27d3d348788644f3bad004f2 Mon Sep 17 00:00:00 2001 From: "Darrick J. Wong" Date: Wed, 15 Oct 2008 22:03:52 -0700 Subject: matroxfb: support G200eV chip Support the Matrox G200eV chip, based on timings that I found in the X.org matrox driver. Signed-off-by: Darrick J. Wong Acked-by: Krzysztof Helt Cc: Petr Vandrovec Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 1176f1f177e..8edddc240e4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -587,6 +587,7 @@ #define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 #define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 #define PCI_DEVICE_ID_MATROX_G400 0x0525 +#define PCI_DEVICE_ID_MATROX_G200EV_PCI 0x0530 #define PCI_DEVICE_ID_MATROX_G550 0x2527 #define PCI_DEVICE_ID_MATROX_VIA 0x4536 -- cgit v1.2.3 From b53cde3557b8f97e6a635782875d442551a89bf1 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 15 Oct 2008 22:03:55 -0700 Subject: fbdev: add new TMIO framebuffer driver Add driver for TMIO framebuffer cells as found e.g. in Toshiba TC6393XB chips. Signed-off-by: Dmitry Baryshkov Cc: Ian Molton Acked-by: Samuel Ortiz Acked-by: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mfd/tmio.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/tmio.h b/include/linux/mfd/tmio.h index ec612e66391..516d955ab8a 100644 --- a/include/linux/mfd/tmio.h +++ b/include/linux/mfd/tmio.h @@ -1,6 +1,8 @@ #ifndef MFD_TMIO_H #define MFD_TMIO_H +#include + #define tmio_ioread8(addr) readb(addr) #define tmio_ioread16(addr) readw(addr) #define tmio_ioread16_rep(r, b, l) readsw(r, b, l) @@ -25,4 +27,21 @@ struct tmio_nand_data { unsigned int num_partitions; }; +#define FBIO_TMIO_ACC_WRITE 0x7C639300 +#define FBIO_TMIO_ACC_SYNC 0x7C639301 + +struct tmio_fb_data { + int (*lcd_set_power)(struct platform_device *fb_dev, + bool on); + int (*lcd_mode)(struct platform_device *fb_dev, + const struct fb_videomode *mode); + int num_modes; + struct fb_videomode *modes; + + /* in mm: size of screen */ + int height; + int width; +}; + + #endif -- cgit v1.2.3 From b563cf59c4d67da7d671788a9848416bfa4180ab Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Wed, 15 Oct 2008 22:03:58 -0700 Subject: pnp: make the resource type an unsigned long PnP encodes the resource type directly as its struct resource->flags value which is an unsigned long. Make it so... Signed-off-by: Rene Herman Cc: "H. Peter Anvin" Acked-by: Bjorn Helgaas Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pnp.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pnp.h b/include/linux/pnp.h index be764e514e3..53b70fd1d9a 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -22,9 +22,11 @@ struct pnp_dev; * Resource Management */ #ifdef CONFIG_PNP -struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int); +struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned long type, + unsigned int num); #else -static inline struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num) +static inline struct resource *pnp_get_resource(struct pnp_dev *dev, + unsigned long type, unsigned int num) { return NULL; } -- cgit v1.2.3 From 60836eb63b941f407dc2a609f3f0f34fd74ef6c3 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 15 Oct 2008 22:04:00 -0700 Subject: telephony: remove CVS keywords Remove CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/telephony.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/telephony.h b/include/linux/telephony.h index 0d0cf2a1e7b..5b2b6261f19 100644 --- a/include/linux/telephony.h +++ b/include/linux/telephony.h @@ -28,10 +28,6 @@ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * - * Version: $Revision: 4.2 $ - * - * $Id: telephony.h,v 4.2 2001/08/06 07:09:43 craigs Exp $ - * *****************************************************************************/ #ifndef TELEPHONY_H -- cgit v1.2.3 From b73c29f6b0ddbcf07b43c5c5e6354e5839b5e68d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 15 Oct 2008 22:04:13 -0700 Subject: quota: remove CVS keywords Remove CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Acked-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/quota.h | 2 -- include/linux/quotaops.h | 3 --- 2 files changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/quota.h b/include/linux/quota.h index 376a05048bc..40401b55448 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -28,8 +28,6 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * Version: $Id: quota.h,v 2.0 1996/11/17 16:48:14 mvw Exp mvw $ */ #ifndef _LINUX_QUOTA_ diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index ca6b9b5c8d5..a558a4c1d35 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -3,9 +3,6 @@ * macros expand to the right source-code. * * Author: Marco van Wieringen - * - * Version: $Id: quotaops.h,v 1.2 1998/01/15 16:22:26 ecd Exp $ - * */ #ifndef _LINUX_QUOTAOPS_ #define _LINUX_QUOTAOPS_ -- cgit v1.2.3 From f221e726bf4e082a05dcd573379ac859bfba7126 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 15 Oct 2008 22:04:23 -0700 Subject: sysctl: simplify ->strategy name and nlen parameters passed to ->strategy hook are unused, remove them. In general ->strategy hook should know what it's doing, and don't do something tricky for which, say, pointer to original userspace array may be needed (name). Signed-off-by: Alexey Dobriyan Acked-by: David S. Miller [ networking bits ] Cc: Ralf Baechle Cc: David Howells Cc: Matt Mackall Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sysctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index d0437f36921..39d471d1163 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -972,7 +972,7 @@ extern int sysctl_perm(struct ctl_table_root *root, typedef struct ctl_table ctl_table; -typedef int ctl_handler (struct ctl_table *table, int __user *name, int nlen, +typedef int ctl_handler (struct ctl_table *table, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); -- cgit v1.2.3 From 25cbe53ef1cb828ae012f3955a5aa18117114439 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 15 Oct 2008 22:04:25 -0700 Subject: pid_ns: kill the now unused task_child_reaper() task_child_reaper() has no callers anymore, kill it. Signed-off-by: Oleg Nesterov Acked-by: Serge Hallyn Acked-by: Pavel Emelyanov Acked-by: Sukadev Bhattiprolu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pid_namespace.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pid_namespace.h b/include/linux/pid_namespace.h index 1af82c4e17d..d82fe825d62 100644 --- a/include/linux/pid_namespace.h +++ b/include/linux/pid_namespace.h @@ -84,12 +84,6 @@ static inline struct pid_namespace *task_active_pid_ns(struct task_struct *tsk) return tsk->nsproxy->pid_ns; } -static inline struct task_struct *task_child_reaper(struct task_struct *tsk) -{ - BUG_ON(tsk != current); - return tsk->nsproxy->pid_ns->child_reaper; -} - void pidhash_init(void); void pidmap_init(void); -- cgit v1.2.3 From 612de10db06c0704a66bbe7fd13990cb1c2cb958 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 15 Oct 2008 22:04:33 -0700 Subject: parport: remove CVS keywords Remove CVS keywords that weren't updated for a long time from comments. Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/parport.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/parport.h b/include/linux/parport.h index 6a0d7cdb577..e1f83c5065c 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h @@ -1,5 +1,3 @@ -/* $Id: parport.h,v 1.1 1998/05/17 10:57:52 andrea Exp andrea $ */ - /* * Any part of this program may be used in documents licensed under * the GNU Free Documentation License, Version 1.1 or any later version -- cgit v1.2.3 From ebf3f09c634906d371f2bfd71b41c7e0c52efe7e Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 15 Oct 2008 22:05:12 -0700 Subject: Configure out AIO support This patchs adds the CONFIG_AIO option which allows to remove support for asynchronous I/O operations, that are not necessarly used by applications, particularly on embedded devices. As this is a size-reduction option, it depends on CONFIG_EMBEDDED. It allows to save ~7 kilobytes of kernel code/data: text data bss dec hex filename 1115067 119180 217088 1451335 162547 vmlinux 1108025 119048 217088 1444161 160941 vmlinux.new -7042 -132 0 -7174 -1C06 +/- This patch has been originally written by Matt Mackall , and is part of the Linux Tiny project. [randy.dunlap@oracle.com: build fix] Signed-off-by: Thomas Petazzoni Cc: Benjamin LaHaise Cc: Zach Brown Signed-off-by: Matt Mackall Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/aio.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/aio.h b/include/linux/aio.h index 09b276c3522..f6b8cf99b59 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h @@ -204,12 +204,21 @@ struct kioctx { /* prototypes */ extern unsigned aio_max_size; +#ifdef CONFIG_AIO extern ssize_t wait_on_sync_kiocb(struct kiocb *iocb); extern int aio_put_req(struct kiocb *iocb); extern void kick_iocb(struct kiocb *iocb); extern int aio_complete(struct kiocb *iocb, long res, long res2); struct mm_struct; extern void exit_aio(struct mm_struct *mm); +#else +static inline ssize_t wait_on_sync_kiocb(struct kiocb *iocb) { return 0; } +static inline int aio_put_req(struct kiocb *iocb) { return 0; } +static inline void kick_iocb(struct kiocb *iocb) { } +static inline int aio_complete(struct kiocb *iocb, long res, long res2) { return 0; } +struct mm_struct; +static inline void exit_aio(struct mm_struct *mm) { } +#endif /* CONFIG_AIO */ #define io_wait_to_kiocb(wait) container_of(wait, struct kiocb, ki_wait) -- cgit v1.2.3 From c9f66169f1c696f9489503d7de92daff135c1efd Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 15 Oct 2008 22:05:15 -0700 Subject: resource: add resource_type() and IORESOURCE_TYPE_BITS Add resource_type() and IORESOURCE_TYPE_BITS. They make it easier to add more resource types without having to rewrite tons of code. Signed-off-by: Magnus Damm Cc: Ben Dooks Cc: Jean Delvare Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ioport.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ioport.h b/include/linux/ioport.h index ee9bcc6f32b..0dde77272d7 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h @@ -34,7 +34,8 @@ struct resource_list { */ #define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ -#define IORESOURCE_IO 0x00000100 /* Resource type */ +#define IORESOURCE_TYPE_BITS 0x00000f00 /* Resource type */ +#define IORESOURCE_IO 0x00000100 #define IORESOURCE_MEM 0x00000200 #define IORESOURCE_IRQ 0x00000400 #define IORESOURCE_DMA 0x00000800 @@ -126,6 +127,10 @@ static inline resource_size_t resource_size(struct resource *res) { return res->end - res->start + 1; } +static inline unsigned long resource_type(struct resource *res) +{ + return res->flags & IORESOURCE_TYPE_BITS; +} /* Convenience shorthand with allocation */ #define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) -- cgit v1.2.3 From 3e624fc72fba09b6f999a9fbb87b64efccd38036 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 16 Oct 2008 20:00:24 -0400 Subject: ext4: Replace hackish ext4_mb_poll_new_transaction with commit callback The multiblock allocator needs to be able to release blocks (and issue a blkdev discard request) when the transaction which freed those blocks is committed. Previously this was done via a polling mechanism when blocks are allocated or freed. A much better way of doing things is to create a jbd2 callback function and attaching the list of blocks to be freed directly to the transaction structure. Signed-off-by: "Theodore Ts'o" --- include/linux/jbd2.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index 463d6f10b64..c7d106ef22e 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h @@ -641,6 +641,11 @@ struct transaction_s */ int t_handle_count; + /* + * For use by the filesystem to store fs-specific data + * structures associated with the transaction + */ + struct list_head t_private_list; }; struct transaction_run_stats_s { @@ -935,6 +940,10 @@ struct journal_s pid_t j_last_sync_writer; + /* This function is called when a transaction is closed */ + void (*j_commit_callback)(journal_t *, + transaction_t *); + /* * Journal statistics */ -- cgit v1.2.3 From 54514a70adefe356afe854e2d3912d46668068e6 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 23 Sep 2008 22:15:57 -0700 Subject: softirq: Add support for triggering softirq work on softirqs. This is basically a genericization of Jens Axboe's block layer remote softirq changes. Signed-off-by: David S. Miller Signed-off-by: Jens Axboe --- include/linux/interrupt.h | 21 +++++++++++++++++++++ include/linux/smp.h | 4 +++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 54b3623434e..35a61dc60d5 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #include #include @@ -273,6 +275,25 @@ extern void softirq_init(void); extern void raise_softirq_irqoff(unsigned int nr); extern void raise_softirq(unsigned int nr); +/* This is the worklist that queues up per-cpu softirq work. + * + * send_remote_sendirq() adds work to these lists, and + * the softirq handler itself dequeues from them. The queues + * are protected by disabling local cpu interrupts and they must + * only be accessed by the local cpu that they are for. + */ +DECLARE_PER_CPU(struct list_head [NR_SOFTIRQS], softirq_work_list); + +/* Try to send a softirq to a remote cpu. If this cannot be done, the + * work will be queued to the local cpu. + */ +extern void send_remote_softirq(struct call_single_data *cp, int cpu, int softirq); + +/* Like send_remote_softirq(), but the caller must disable local cpu interrupts + * and compute the current cpu, passed in as 'this_cpu'. + */ +extern void __send_remote_softirq(struct call_single_data *cp, int cpu, + int this_cpu, int softirq); /* Tasklets --- multithreaded analogue of BHs. diff --git a/include/linux/smp.h b/include/linux/smp.h index 66484d4a845..2e4d58b26c0 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -16,7 +17,8 @@ struct call_single_data { struct list_head list; void (*func) (void *info); void *info; - unsigned int flags; + u16 flags; + u16 priv; }; #ifdef CONFIG_SMP -- cgit v1.2.3 From 8677142710516d986d932d6f1fba7be8382c1fec Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Mon, 13 Oct 2008 14:19:05 +0200 Subject: block: fix nr_phys_segments miscalculation bug This fixes the bug reported by Nikanth Karthikesan : http://lkml.org/lkml/2008/10/2/203 The root cause of the bug is that blk_phys_contig_segment miscalculates q->max_segment_size. blk_phys_contig_segment checks: req->biotail->bi_size + next_req->bio->bi_size > q->max_segment_size But blk_recalc_rq_segments might expect that req->biotail and the previous bio in the req are supposed be merged into one segment. blk_recalc_rq_segments might also expect that next_req->bio and the next bio in the next_req are supposed be merged into one segment. In such case, we merge two requests that can't be merged here. Later, blk_rq_map_sg gives more segments than it should. We need to keep track of segment size in blk_recalc_rq_segments and use it to see if two requests can be merged. This patch implements it in the similar way that we used to do for hw merging (virtual merging). Signed-off-by: FUJITA Tomonori Signed-off-by: Jens Axboe --- include/linux/bio.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index ff5b4cf9e2d..dc3cec386a9 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -79,6 +79,13 @@ struct bio { unsigned int bi_size; /* residual I/O count */ + /* + * To keep track of the max segment size, we account for the + * sizes of the first and last mergeable segments in this bio. + */ + unsigned int bi_seg_front_size; + unsigned int bi_seg_back_size; + unsigned int bi_max_vecs; /* max bvl_vecs we can hold */ unsigned int bi_comp_cpu; /* completion CPU */ -- cgit v1.2.3 From 756f8243188e013bd067811cdc0cc60760abfdf9 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Thu, 16 Oct 2008 08:23:21 +0200 Subject: blktrace: add support for driver data This patch adds the new api call blk_add_driver_data() to blktrace. It allows to trace device driver-specific binary data. Signed-off-by: Stefan Raspl Signed-off-by: Martin Peschke Signed-off-by: Jens Axboe --- include/linux/blktrace_api.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index 3a31eb50616..bdf505d33e7 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -24,6 +24,7 @@ enum blktrace_cat { BLK_TC_AHEAD = 1 << 11, /* readahead */ BLK_TC_META = 1 << 12, /* metadata */ BLK_TC_DISCARD = 1 << 13, /* discard requests */ + BLK_TC_DRV_DATA = 1 << 14, /* binary per-driver data */ BLK_TC_END = 1 << 15, /* only 16-bits, reminder */ }; @@ -51,6 +52,7 @@ enum blktrace_act { __BLK_TA_BOUNCE, /* bio was bounced */ __BLK_TA_REMAP, /* bio was remapped */ __BLK_TA_ABORT, /* request aborted */ + __BLK_TA_DRV_DATA, /* driver-specific binary data */ }; /* @@ -82,6 +84,7 @@ enum blktrace_notify { #define BLK_TA_BOUNCE (__BLK_TA_BOUNCE) #define BLK_TA_REMAP (__BLK_TA_REMAP | BLK_TC_ACT(BLK_TC_QUEUE)) #define BLK_TA_ABORT (__BLK_TA_ABORT | BLK_TC_ACT(BLK_TC_QUEUE)) +#define BLK_TA_DRV_DATA (__BLK_TA_DRV_DATA | BLK_TC_ACT(BLK_TC_DRV_DATA)) #define BLK_TN_PROCESS (__BLK_TN_PROCESS | BLK_TC_ACT(BLK_TC_NOTIFY)) #define BLK_TN_TIMESTAMP (__BLK_TN_TIMESTAMP | BLK_TC_ACT(BLK_TC_NOTIFY)) @@ -317,6 +320,34 @@ static inline void blk_add_trace_remap(struct request_queue *q, struct bio *bio, __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); } +/** + * blk_add_driver_data - Add binary message with driver-specific data + * @q: queue the io is for + * @rq: io request + * @data: driver-specific data + * @len: length of driver-specific data + * + * Description: + * Some drivers might want to write driver-specific data per request. + * + **/ +static inline void blk_add_driver_data(struct request_queue *q, + struct request *rq, + void *data, size_t len) +{ + struct blk_trace *bt = q->blk_trace; + + if (likely(!bt)) + return; + + if (blk_pc_request(rq)) + __blk_add_trace(bt, 0, rq->data_len, 0, BLK_TA_DRV_DATA, + rq->errors, len, data); + else + __blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9, + 0, BLK_TA_DRV_DATA, rq->errors, len, data); +} + extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, char __user *arg); extern int blk_trace_startstop(struct request_queue *q, int start); @@ -330,6 +361,7 @@ extern int blk_trace_remove(struct request_queue *q); #define blk_add_trace_generic(q, rq, rw, what) do { } while (0) #define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0) #define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0) +#define blk_add_driver_data(q, rq, data, len) do {} while (0) #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) #define blk_trace_startstop(q, start) (-ENOTTY) -- cgit v1.2.3 From 3481f21097cb560392c411377893b5109fbde557 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Thu, 16 Oct 2008 16:31:55 -0700 Subject: dmar: context cache and IOTLB invalidation using queued invalidation Implement context cache invalidate and IOTLB invalidation using queued invalidation interface. This interface will be used by DMA remapping, when queued invalidation is supported. Signed-off-by: Youquan Song Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse --- include/linux/intel-iommu.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 2e117f30a76..0c5f5e49107 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -127,6 +127,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) /* IOTLB_REG */ +#define DMA_TLB_FLUSH_GRANU_OFFSET 60 #define DMA_TLB_GLOBAL_FLUSH (((u64)1) << 60) #define DMA_TLB_DSI_FLUSH (((u64)2) << 60) #define DMA_TLB_PSI_FLUSH (((u64)3) << 60) @@ -140,6 +141,7 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) #define DMA_TLB_MAX_SIZE (0x3f) /* INVALID_DESC */ +#define DMA_CCMD_INVL_GRANU_OFFSET 61 #define DMA_ID_TLB_GLOBAL_FLUSH (((u64)1) << 3) #define DMA_ID_TLB_DSI_FLUSH (((u64)2) << 3) #define DMA_ID_TLB_PSI_FLUSH (((u64)3) << 3) @@ -238,6 +240,19 @@ enum { #define QI_IWD_STATUS_DATA(d) (((u64)d) << 32) #define QI_IWD_STATUS_WRITE (((u64)1) << 5) +#define QI_IOTLB_DID(did) (((u64)did) << 16) +#define QI_IOTLB_DR(dr) (((u64)dr) << 7) +#define QI_IOTLB_DW(dw) (((u64)dw) << 6) +#define QI_IOTLB_GRAN(gran) (((u64)gran) >> (DMA_TLB_FLUSH_GRANU_OFFSET-4)) +#define QI_IOTLB_ADDR(addr) (((u64)addr) & PAGE_MASK_4K) +#define QI_IOTLB_IH(ih) (((u64)ih) << 6) +#define QI_IOTLB_AM(am) (((u8)am)) + +#define QI_CC_FM(fm) (((u64)fm) << 48) +#define QI_CC_SID(sid) (((u64)sid) << 32) +#define QI_CC_DID(did) (((u64)did) << 16) +#define QI_CC_GRAN(gran) (((u64)gran) >> (DMA_CCMD_INVL_GRANU_OFFSET-4)) + struct qi_desc { u64 low, high; }; @@ -303,6 +318,12 @@ extern void free_iommu(struct intel_iommu *iommu); extern int dmar_enable_qi(struct intel_iommu *iommu); extern void qi_global_iec(struct intel_iommu *iommu); +extern int qi_flush_context(struct intel_iommu *iommu, u16 did, u16 sid, + u8 fm, u64 type, int non_present_entry_flush); +extern int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, + unsigned int size_order, u64 type, + int non_present_entry_flush); + extern void qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu); void intel_iommu_domain_exit(struct dmar_domain *domain); -- cgit v1.2.3 From a77b67d4023770805141014b8fa9eb5467457817 Mon Sep 17 00:00:00 2001 From: Youquan Song Date: Thu, 16 Oct 2008 16:31:56 -0700 Subject: dmar: Use queued invalidation interface for IOTLB and context invalidation If queued invalidation interface is available and enabled, queued invalidation interface will be used instead of the register based interface. According to Vt-d2 specification, when queued invalidation is enabled, invalidation command submit works only through invalidation queue and not through the command registers interface. Signed-off-by: Youquan Song Signed-off-by: Suresh Siddha Signed-off-by: David Woodhouse --- include/linux/intel-iommu.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index 0c5f5e49107..afb0d2a5b7c 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -278,6 +278,13 @@ struct ir_table { }; #endif +struct iommu_flush { + int (*flush_context)(struct intel_iommu *iommu, u16 did, u16 sid, u8 fm, + u64 type, int non_present_entry_flush); + int (*flush_iotlb)(struct intel_iommu *iommu, u16 did, u64 addr, + unsigned int size_order, u64 type, int non_present_entry_flush); +}; + struct intel_iommu { void __iomem *reg; /* Pointer to hardware regs, virtual addr */ u64 cap; @@ -297,6 +304,7 @@ struct intel_iommu { unsigned char name[7]; /* Device Name */ struct msi_msg saved_msg; struct sys_device sysdev; + struct iommu_flush flush; #endif struct q_inval *qi; /* Queued invalidation info */ #ifdef CONFIG_INTR_REMAP -- cgit v1.2.3 From e62b4853983d032dcb3cde9fb20407dc556f47bc Mon Sep 17 00:00:00 2001 From: David Miller Date: Thu, 16 Oct 2008 21:14:11 -0700 Subject: sched: kill unused scheduler decl. I noticed this while making investigations into the tbench regressions. Please apply. sched: Remove hrtick_resched() extern decl. This function was removed by 31656519e132f6612584815f128c83976a9aaaef ("sched, x86: clean up hrtick implementation"). Signed-off-by: David S. Miller Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index c226c7b8294..6eda6ad735d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -287,7 +287,6 @@ extern void trap_init(void); extern void account_process_tick(struct task_struct *task, int user); extern void update_process_times(int user); extern void scheduler_tick(void); -extern void hrtick_resched(void); extern void sched_show_task(struct task_struct *p); -- cgit v1.2.3 From f73e2d13a16cc88c4faa4729967f92bfeec8a142 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 17 Oct 2008 14:03:08 +0200 Subject: block: remove __generic_unplug_device() from exports The only out-of-core user is IDE, and that should be using blk_start_queueing() instead. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a92d9e4ea96..8eed8b15f99 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -856,7 +856,6 @@ extern void 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 *); extern void generic_unplug_device(struct request_queue *); -extern void __generic_unplug_device(struct request_queue *); extern long nr_blockdev_pages(void); int blk_get_queue(struct request_queue *); -- cgit v1.2.3 From fe11edfaabf1787c05d782a7b33e6497d1118b1d Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:11 +0200 Subject: ide: IDE_AFLAG_MEDIA_CHANGED -> IDE_DFLAG_MEDIA_CHANGED There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index c47e371554c..155a57f55c6 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -464,7 +464,6 @@ struct ide_acpi_hwif_link; /* ATAPI device flags */ enum { IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), - IDE_AFLAG_MEDIA_CHANGED = (1 << 1), /* Drive cannot lock the door. */ IDE_AFLAG_NO_DOORLOCK = (1 << 2), @@ -578,7 +577,8 @@ enum { /* don't unload heads */ IDE_DFLAG_NO_UNLOAD = (1 << 27), /* heads unloaded, please don't reset port */ - IDE_DFLAG_PARKED = (1 << 28) + IDE_DFLAG_PARKED = (1 << 28), + IDE_DFLAG_MEDIA_CHANGED = (1 << 29), }; struct ide_drive_s { -- cgit v1.2.3 From da167876bd0f71f1c646e5dd98997544d8d90e8e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:11 +0200 Subject: ide: IDE_AFLAG_WP -> IDE_DFLAG_WP There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 155a57f55c6..bd0a4d36b6d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -503,8 +503,6 @@ enum { IDE_AFLAG_CLIK_DRIVE = (1 << 19), /* Requires BH algorithm for packets */ IDE_AFLAG_ZIP_DRIVE = (1 << 20), - /* Write protect */ - IDE_AFLAG_WP = (1 << 21), /* Supports format progress report */ IDE_AFLAG_SRFP = (1 << 22), @@ -579,6 +577,8 @@ enum { /* heads unloaded, please don't reset port */ IDE_DFLAG_PARKED = (1 << 28), IDE_DFLAG_MEDIA_CHANGED = (1 << 29), + /* write protect */ + IDE_DFLAG_WP = (1 << 30), }; struct ide_drive_s { -- cgit v1.2.3 From e01286282eef85e4783b06fb2e0ed84fc111eb32 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:11 +0200 Subject: ide: IDE_AFLAG_FORMAT_IN_PROGRESS -> IDE_DFLAG_FORMAT_IN_PROGRESS There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index bd0a4d36b6d..d111c3ebbba 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -497,8 +497,6 @@ enum { IDE_AFLAG_LE_SPEED_FIELDS = (1 << 17), /* ide-floppy */ - /* Format in progress */ - IDE_AFLAG_FORMAT_IN_PROGRESS = (1 << 18), /* Avoid commands not supported in Clik drive */ IDE_AFLAG_CLIK_DRIVE = (1 << 19), /* Requires BH algorithm for packets */ @@ -579,6 +577,7 @@ enum { IDE_DFLAG_MEDIA_CHANGED = (1 << 29), /* write protect */ IDE_DFLAG_WP = (1 << 30), + IDE_DFLAG_FORMAT_IN_PROGRESS = (1 << 31), }; struct ide_drive_s { -- cgit v1.2.3 From 42619d35c7af2f88cad56425fe3981f1f65ff0bd Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:11 +0200 Subject: ide: remove IDE_AFLAG_NO_DOORLOCKING Just use IDE_DFLAG_DOORLOCKING instead. There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index d111c3ebbba..ba51a93fa54 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -464,8 +464,6 @@ struct ide_acpi_hwif_link; /* ATAPI device flags */ enum { IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), - /* Drive cannot lock the door. */ - IDE_AFLAG_NO_DOORLOCK = (1 << 2), /* ide-cd */ /* Drive cannot eject the disc. */ -- cgit v1.2.3 From 79cb380397c834a35952d8497651d93b543ef968 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:13 +0200 Subject: ide: allow device drivers to specify per-device type /proc settings Turn ide_driver_t's 'proc' field into ->proc_entries method (and also 'settings' field into ->proc_devsets method). Then update all device drivers accordingly. There should be no functional changes caused by this patch. Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index ba51a93fa54..488808891ac 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1120,8 +1120,8 @@ struct ide_driver_s { void (*resume)(ide_drive_t *); void (*shutdown)(ide_drive_t *); #ifdef CONFIG_IDE_PROC_FS - ide_proc_entry_t *proc; - const struct ide_proc_devset *settings; + ide_proc_entry_t * (*proc_entries)(ide_drive_t *); + const struct ide_proc_devset * (*proc_devsets)(ide_drive_t *); #endif }; -- cgit v1.2.3 From 806f80a6fc203ad0bde84e5a9e94572617d2ae45 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Fri, 17 Oct 2008 18:09:14 +0200 Subject: ide: add generic ATA/ATAPI disk driver * Add struct ide_disk_ops containing protocol specific methods. * Add 'struct ide_disk_ops *' to ide_drive_t. * Convert ide-{disk,floppy} drivers to use struct ide_disk_ops. * Merge ide-{disk,floppy} drivers into generic ide-gd driver. While at it: - ide_disk_init_capacity() -> ide_disk_get_capacity() Acked-by: Borislav Petkov Signed-off-by: Bartlomiej Zolnierkiewicz --- include/linux/ide.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 488808891ac..89e53cfbc78 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -461,6 +461,23 @@ struct ide_acpi_drive_link; struct ide_acpi_hwif_link; #endif +struct ide_drive_s; + +struct ide_disk_ops { + int (*check)(struct ide_drive_s *, const char *); + int (*get_capacity)(struct ide_drive_s *); + void (*setup)(struct ide_drive_s *); + void (*flush)(struct ide_drive_s *); + int (*init_media)(struct ide_drive_s *, struct gendisk *); + int (*set_doorlock)(struct ide_drive_s *, struct gendisk *, + int); + ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *, + sector_t); + int (*end_request)(struct ide_drive_s *, int, int); + int (*ioctl)(struct ide_drive_s *, struct inode *, + struct file *, unsigned int, unsigned long); +}; + /* ATAPI device flags */ enum { IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), @@ -594,6 +611,8 @@ struct ide_drive_s { #endif struct hwif_s *hwif; /* actually (ide_hwif_t *) */ + const struct ide_disk_ops *disk_ops; + unsigned long dev_flags; unsigned long sleep; /* sleep until this time */ -- cgit v1.2.3 From 719254faa17ffedc87ba0fadb9b34e535c9758d5 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Fri, 17 Oct 2008 09:59:47 +0200 Subject: NOHZ: unify the nohz function calls in irq_enter() We have two separate nohz function calls in irq_enter() for no good reason. Just call a single NOHZ function from irq_enter() and call the bits in the tick code. Signed-off-by: Thomas Gleixner --- include/linux/tick.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/tick.h b/include/linux/tick.h index 98921a3e1aa..b6ec8189ac0 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -96,9 +96,11 @@ extern cpumask_t *tick_get_broadcast_oneshot_mask(void); extern void tick_clock_notify(void); extern int tick_check_oneshot_change(int allow_nohz); extern struct tick_sched *tick_get_tick_sched(int cpu); +extern void tick_check_idle(int cpu); # else static inline void tick_clock_notify(void) { } static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } +static inline void tick_check_idle(int cpu) { } # endif #else /* CONFIG_GENERIC_CLOCKEVENTS */ @@ -106,26 +108,23 @@ static inline void tick_init(void) { } static inline void tick_cancel_sched_timer(int cpu) { } static inline void tick_clock_notify(void) { } static inline int tick_check_oneshot_change(int allow_nohz) { return 0; } +static inline void tick_check_idle(int cpu) { } #endif /* !CONFIG_GENERIC_CLOCKEVENTS */ # ifdef CONFIG_NO_HZ extern void tick_nohz_stop_sched_tick(int inidle); extern void tick_nohz_restart_sched_tick(void); -extern void tick_nohz_update_jiffies(void); extern ktime_t tick_nohz_get_sleep_length(void); -extern void tick_nohz_stop_idle(int cpu); extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time); # else static inline void tick_nohz_stop_sched_tick(int inidle) { } static inline void tick_nohz_restart_sched_tick(void) { } -static inline void tick_nohz_update_jiffies(void) { } static inline ktime_t tick_nohz_get_sleep_length(void) { ktime_t len = { .tv64 = NSEC_PER_SEC/HZ }; return len; } -static inline void tick_nohz_stop_idle(int cpu) { } static inline u64 get_cpu_idle_time_us(int cpu, u64 *unused) { return -1; } # endif /* !NO_HZ */ -- cgit v1.2.3 From 504e518953a330c8d44a95bdd65a5c9f50f1012e Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Thu, 16 Oct 2008 14:15:16 +1100 Subject: Make nfs_file_cred more robust. As not all files have an associated open_context (e.g. device special files), it is safest to test for the existence of the open context before de-referencing it. Signed-off-by: NeilBrown Signed-off-by: Trond Myklebust --- include/linux/nfs_fs.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index ac8d0233b05..4eaa8347a0d 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -367,8 +367,12 @@ static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) static inline struct rpc_cred *nfs_file_cred(struct file *file) { - if (file != NULL) - return nfs_file_open_context(file)->cred; + if (file != NULL) { + struct nfs_open_context *ctx = + nfs_file_open_context(file); + if (ctx) + return ctx->cred; + } return NULL; } -- cgit v1.2.3 From 97854829b97093ae172144a2597fc49ea203dcf3 Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 14 Oct 2008 19:48:07 -0300 Subject: V4L/DVB (9195): Frontend API Fix: 32APSK is a valid modulation for the DVB-S2 delivery Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 6e4ace27027..38942f731b9 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -166,6 +166,7 @@ typedef enum fe_modulation { VSB_16, PSK_8, APSK_16, + APSK_32, DQPSK, } fe_modulation_t; -- cgit v1.2.3 From 5ba4ecc8b0166de4363cc31aa68d52abe0dff8de Mon Sep 17 00:00:00 2001 From: Manu Abraham Date: Tue, 14 Oct 2008 19:50:03 -0300 Subject: V4L/DVB (9196): Add support for DSS delivery Signed-off-by: Manu Abraham Signed-off-by: Mauro Carvalho Chehab --- include/linux/dvb/frontend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h index 38942f731b9..79a8ed8e6a7 100644 --- a/include/linux/dvb/frontend.h +++ b/include/linux/dvb/frontend.h @@ -296,6 +296,7 @@ typedef enum fe_delivery_system { SYS_DVBC_ANNEX_AC, SYS_DVBC_ANNEX_B, SYS_DVBT, + SYS_DSS, SYS_DVBS, SYS_DVBS2, SYS_DVBH, -- cgit v1.2.3 From 2a1d245b70f3f966f96767aaea1a2db6823e2f6e Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 15 Oct 2008 14:47:36 -0300 Subject: V4L/DVB (9240): saa7127: Fix two typos Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- include/linux/i2c-id.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/i2c-id.h b/include/linux/i2c-id.h index 493435bcdbe..01d67ba9e98 100644 --- a/include/linux/i2c-id.h +++ b/include/linux/i2c-id.h @@ -60,7 +60,7 @@ #define I2C_DRIVERID_WM8775 69 /* wm8775 audio processor */ #define I2C_DRIVERID_CS53L32A 70 /* cs53l32a audio processor */ #define I2C_DRIVERID_CX25840 71 /* cx2584x video encoder */ -#define I2C_DRIVERID_SAA7127 72 /* saa7124 video encoder */ +#define I2C_DRIVERID_SAA7127 72 /* saa7127 video encoder */ #define I2C_DRIVERID_SAA711X 73 /* saa711x video encoders */ #define I2C_DRIVERID_AKITAIOEXP 74 /* IO Expander on Sharp SL-C1000 */ #define I2C_DRIVERID_INFRARED 75 /* I2C InfraRed on Video boards */ -- cgit v1.2.3 From 5b775f672cc993ba9dba5626811ab1f2ac42883b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 26 Aug 2008 16:22:06 -0700 Subject: USB: add USB test and measurement class driver This driver was originaly written by Stefan Kopp, but massively reworked by Greg for submission. Thanks to Felipe Balbi for lots of work in cleaning up this driver. Thanks to Oliver Neukum for reviewing previous versions and pointing out problems. Cc: Stefan Kopp Cc: Marcel Janssen Cc: Felipe Balbi Cc: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/Kbuild | 2 +- include/linux/usb/tmc.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 include/linux/usb/tmc.h (limited to 'include/linux') diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 42e84fc315e..29fd73b0bff 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild @@ -4,4 +4,4 @@ header-y += ch9.h header-y += gadgetfs.h header-y += midi.h header-y += g_printer.h - +header-y += tmc.h diff --git a/include/linux/usb/tmc.h b/include/linux/usb/tmc.h new file mode 100644 index 00000000000..c045ae12556 --- /dev/null +++ b/include/linux/usb/tmc.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2007 Stefan Kopp, Gechingen, Germany + * Copyright (C) 2008 Novell, Inc. + * Copyright (C) 2008 Greg Kroah-Hartman + * + * This file holds USB constants defined by the USB Device Class + * Definition for Test and Measurement devices published by the USB-IF. + * + * It also has the ioctl definitions for the usbtmc kernel driver that + * userspace needs to know about. + */ + +#ifndef __LINUX_USB_TMC_H +#define __LINUX_USB_TMC_H + +/* USB TMC status values */ +#define USBTMC_STATUS_SUCCESS 0x01 +#define USBTMC_STATUS_PENDING 0x02 +#define USBTMC_STATUS_FAILED 0x80 +#define USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS 0x81 +#define USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS 0x82 +#define USBTMC_STATUS_SPLIT_IN_PROGRESS 0x83 + +/* USB TMC requests values */ +#define USBTMC_REQUEST_INITIATE_ABORT_BULK_OUT 1 +#define USBTMC_REQUEST_CHECK_ABORT_BULK_OUT_STATUS 2 +#define USBTMC_REQUEST_INITIATE_ABORT_BULK_IN 3 +#define USBTMC_REQUEST_CHECK_ABORT_BULK_IN_STATUS 4 +#define USBTMC_REQUEST_INITIATE_CLEAR 5 +#define USBTMC_REQUEST_CHECK_CLEAR_STATUS 6 +#define USBTMC_REQUEST_GET_CAPABILITIES 7 +#define USBTMC_REQUEST_INDICATOR_PULSE 64 + +/* Request values for USBTMC driver's ioctl entry point */ +#define USBTMC_IOC_NR 91 +#define USBTMC_IOCTL_INDICATOR_PULSE _IO(USBTMC_IOC_NR, 1) +#define USBTMC_IOCTL_CLEAR _IO(USBTMC_IOC_NR, 2) +#define USBTMC_IOCTL_ABORT_BULK_OUT _IO(USBTMC_IOC_NR, 3) +#define USBTMC_IOCTL_ABORT_BULK_IN _IO(USBTMC_IOC_NR, 4) +#define USBTMC_IOCTL_CLEAR_OUT_HALT _IO(USBTMC_IOC_NR, 6) +#define USBTMC_IOCTL_CLEAR_IN_HALT _IO(USBTMC_IOC_NR, 7) + +#endif -- cgit v1.2.3 From 55b447bf79ad25591437d24b78caa9d0ae4fec82 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 29 Jul 2008 15:26:15 +0200 Subject: USB: kill URBs permanently looking at usb_kill_urb() it seems to me that it is unnecessarily lenient. In the use case of disconnect() you never want to use the URB again (for the same device) But leaving urb->reject elevated will make it easier to avoid races between read/write and disconnect. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 94ac74aba6b..3371c91e7ff 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1459,6 +1459,8 @@ extern struct urb *usb_get_urb(struct urb *urb); extern int usb_submit_urb(struct urb *urb, gfp_t mem_flags); extern int usb_unlink_urb(struct urb *urb); extern void usb_kill_urb(struct urb *urb); +extern void usb_poison_urb(struct urb *urb); +extern void usb_unpoison_urb(struct urb *urb); extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor); extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); -- cgit v1.2.3 From 6a2839bedc1502b3f0366cc3ad1099a1d92cf8fb Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 29 Jul 2008 16:18:47 +0200 Subject: USB: extend poisoning to anchors this extends the poisoning concept to anchors. This way poisoning will work with fire and forget drivers. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 3371c91e7ff..d97927970f5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1135,6 +1135,7 @@ struct usb_anchor { struct list_head urb_list; wait_queue_head_t wait; spinlock_t lock; + unsigned int poisoned:1; }; static inline void init_usb_anchor(struct usb_anchor *anchor) @@ -1462,6 +1463,7 @@ extern void usb_kill_urb(struct urb *urb); extern void usb_poison_urb(struct urb *urb); extern void usb_unpoison_urb(struct urb *urb); extern void usb_kill_anchored_urbs(struct usb_anchor *anchor); +extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); extern void usb_unlink_anchored_urbs(struct usb_anchor *anchor); extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); extern void usb_unanchor_urb(struct urb *urb); -- cgit v1.2.3 From 60beed95e38793c0baff7f94433c1f639d8d5efd Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 18 Aug 2008 17:38:22 -0700 Subject: usb gadget: function activation/deactivation Add a new mechanism to the composite gadget framework, letting functions deactivate (and reactivate) themselves. Think of it as a refcounted wrapper for the software pullup control. A key example of why to use this mechanism involves functions that require a userspace daemon. Those functions shuld use this new mechanism to prevent the gadget from enumerating until those daemons are activated. Without this mechanism, hosts would see devices that malfunction until the relevant daemons start. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/composite.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index c932390c6da..935c380ffe4 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -130,6 +130,9 @@ struct usb_function { int usb_add_function(struct usb_configuration *, struct usb_function *); +int usb_function_deactivate(struct usb_function *); +int usb_function_activate(struct usb_function *); + int usb_interface_id(struct usb_configuration *, struct usb_function *); /** @@ -316,9 +319,13 @@ struct usb_composite_dev { struct usb_composite_driver *driver; u8 next_string_id; - spinlock_t lock; + /* the gadget driver won't enable the data pullup + * while the deactivation count is nonzero. + */ + unsigned deactivations; - /* REVISIT use and existence of lock ... */ + /* protects at least deactivation count */ + spinlock_t lock; }; extern int usb_string_id(struct usb_composite_dev *c); -- cgit v1.2.3 From 3086775a4916b0fe128d924d83f4e7d7c39e4d0e Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 18 Aug 2008 17:39:30 -0700 Subject: usb gadget: cdc obex glue The following patch introduces a new f_obex.c function driver. It allows userspace obex servers to use usb as transport layer for their messages. [ dbrownell@users.sourceforge.net: various fixes and cleanups ] Signed-off-by: Felipe Balbi Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/cdc.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h index ca228bb9421..18a729343ff 100644 --- a/include/linux/usb/cdc.h +++ b/include/linux/usb/cdc.h @@ -160,6 +160,15 @@ struct usb_cdc_mdlm_detail_desc { __u8 bDetailData[0]; } __attribute__ ((packed)); +/* "OBEX Control Model Functional Descriptor" */ +struct usb_cdc_obex_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __le16 bcdVersion; +} __attribute__ ((packed)); + /*-------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From 0b14c3881d4b91272b779f4037e263d392de058f Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Sat, 20 Sep 2008 14:41:47 -0700 Subject: USB: Fix spelling in usb/serial.h Fixes a minor typo in the comments for usb_set_serial_data. Signed-off-by: Geoff Levand Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/serial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 655341d0f53..0b8617a9176 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -192,7 +192,7 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * The driver.owner field should be set to the module owner of this driver. * The driver.name field should be set to the name of this driver (remember * it will show up in sysfs, so it needs to be short and to the point. - * Useing the module name is a good idea.) + * Using the module name is a good idea.) */ struct usb_serial_driver { const char *description; -- cgit v1.2.3 From cbc30118d7a376dab4113f299c0c8f035737a5c3 Mon Sep 17 00:00:00 2001 From: Stephen Ware Date: Tue, 30 Sep 2008 11:39:38 -0700 Subject: usb: vstusb.c : new driver for spectrometers used by Vernier Software & Technology, Inc. This patch adds the vstusb driver to the drivers/usb/misc directory. This driver provides support for Vernier Software & Technology spectrometers, all made by Ocean Optics. The driver provides both IOCTL and read()/write() methods for sending raw data to spectrometers across the bulk channel. Each method allows for a configured timeout. From: Stephen Ware Signed-off-by: Dennis O'Brien Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/Kbuild | 1 + include/linux/usb/vstusb.h | 71 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 include/linux/usb/vstusb.h (limited to 'include/linux') diff --git a/include/linux/usb/Kbuild b/include/linux/usb/Kbuild index 29fd73b0bff..54c446309a2 100644 --- a/include/linux/usb/Kbuild +++ b/include/linux/usb/Kbuild @@ -5,3 +5,4 @@ header-y += gadgetfs.h header-y += midi.h header-y += g_printer.h header-y += tmc.h +header-y += vstusb.h diff --git a/include/linux/usb/vstusb.h b/include/linux/usb/vstusb.h new file mode 100644 index 00000000000..1cfac67191f --- /dev/null +++ b/include/linux/usb/vstusb.h @@ -0,0 +1,71 @@ +/***************************************************************************** + * File: drivers/usb/misc/vstusb.h + * + * Purpose: Support for the bulk USB Vernier Spectrophotometers + * + * Author: EQware Engineering, Inc. + * Oregon City, OR, USA 97045 + * + * Copyright: 2007, 2008 + * Vernier Software & Technology + * Beaverton, OR, USA 97005 + * + * Web: www.vernier.com + * + * 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. + * + *****************************************************************************/ +/***************************************************************************** + * + * The vstusb module is a standard usb 'client' driver running on top of the + * standard usb host controller stack. + * + * In general, vstusb supports standard bulk usb pipes. It supports multiple + * devices and multiple pipes per device. + * + * The vstusb driver supports two interfaces: + * 1 - ioctl SEND_PIPE/RECV_PIPE - a general bulk write/read msg + * interface to any pipe with timeout support; + * 2 - standard read/write with ioctl config - offers standard read/write + * interface with ioctl configured pipes and timeouts. + * + * Both interfaces can be signal from other process and will abort its i/o + * operation. + * + * A timeout of 0 means NO timeout. The user can still terminate the read via + * signal. + * + * If using multiple threads with this driver, the user should ensure that + * any reads, writes, or ioctls are complete before closing the device. + * Changing read/write timeouts or pipes takes effect on next read/write. + * + *****************************************************************************/ + +struct vstusb_args { + union { + /* this struct is used for IOCTL_VSTUSB_SEND_PIPE, * + * IOCTL_VSTUSB_RECV_PIPE, and read()/write() fops */ + struct { + void __user *buffer; + size_t count; + unsigned int timeout_ms; + int pipe; + }; + + /* this one is used for IOCTL_VSTUSB_CONFIG_RW */ + struct { + int rd_pipe; + int rd_timeout_ms; + int wr_pipe; + int wr_timeout_ms; + }; + }; +}; + +#define VST_IOC_MAGIC 'L' +#define VST_IOC_FIRST 0x20 +#define IOCTL_VSTUSB_SEND_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST) +#define IOCTL_VSTUSB_RECV_PIPE _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 1) +#define IOCTL_VSTUSB_CONFIG_RW _IO(VST_IOC_MAGIC, VST_IOC_FIRST + 2) -- cgit v1.2.3 From 1987625226a918cd20c334ffce5e2a224cba0718 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Mon, 25 Aug 2008 22:40:25 +0200 Subject: USB: anchor API changes needed for btusb This extends the anchor API as btusb needs for autosuspend. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index d97927970f5..8fa973bede5 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1469,6 +1469,9 @@ extern void usb_anchor_urb(struct urb *urb, struct usb_anchor *anchor); extern void usb_unanchor_urb(struct urb *urb); extern int usb_wait_anchor_empty_timeout(struct usb_anchor *anchor, unsigned int timeout); +extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); +extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); +extern int usb_anchor_empty(struct usb_anchor *anchor); /** * usb_urb_dir_in - check if an URB describes an IN transfer -- cgit v1.2.3 From aaf7ea20000436df3cbb397ccb734ad1e2e5164d Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 15 Oct 2008 08:38:49 +0200 Subject: [MTD] [NAND] GPIO NAND flash driver The patch adds support for NAND flashes connected to GPIOs. Signed-off-by: Russell King Signed-off-by: Mike Rapoport Signed-off-by: David Woodhouse --- include/linux/mtd/nand-gpio.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 include/linux/mtd/nand-gpio.h (limited to 'include/linux') diff --git a/include/linux/mtd/nand-gpio.h b/include/linux/mtd/nand-gpio.h new file mode 100644 index 00000000000..51534e50f7f --- /dev/null +++ b/include/linux/mtd/nand-gpio.h @@ -0,0 +1,19 @@ +#ifndef __LINUX_MTD_NAND_GPIO_H +#define __LINUX_MTD_NAND_GPIO_H + +#include + +struct gpio_nand_platdata { + int gpio_nce; + int gpio_nwp; + int gpio_cle; + int gpio_ale; + int gpio_rdy; + void (*adjust_parts)(struct gpio_nand_platdata *, size_t); + struct mtd_partition *parts; + unsigned int num_parts; + unsigned int options; + int chip_delay; +}; + +#endif -- cgit v1.2.3 From dd3a1db900f2a215a7d7dd71b836e149a6cf5fed Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Thu, 16 Oct 2008 18:20:58 +0200 Subject: genirq: improve include files Move the irq_desc related iterators out of irq.h, into irqnr.h, also available via interrupt.h. This way non-genirq (and even non-hardirq) architectures get the common definitions and iterators. Signed-off-by: Thomas Gleixner Signed-off-by: Ingo Molnar --- include/linux/interrupt.h | 1 + include/linux/irq.h | 20 +------------------- include/linux/irqnr.h | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 19 deletions(-) create mode 100644 include/linux/irqnr.h (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 58ff4e74b2f..72fcfcff563 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/include/linux/irq.h b/include/linux/irq.h index 0618fb362cb..d058c57be02 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -11,25 +11,6 @@ #include -#ifndef CONFIG_GENERIC_HARDIRQS -# define nr_irqs NR_IRQS - -# 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--) -#endif - -#define for_each_irq_nr(irq) \ - for (irq = 0; irq < nr_irqs; irq++) - #ifndef CONFIG_S390 #include @@ -37,6 +18,7 @@ extern int nr_irqs; #include #include #include +#include #include #include diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h new file mode 100644 index 00000000000..3171ddc3b39 --- /dev/null +++ b/include/linux/irqnr.h @@ -0,0 +1,24 @@ +#ifndef _LINUX_IRQNR_H +#define _LINUX_IRQNR_H + +#ifndef CONFIG_GENERIC_HARDIRQS +#include +# define nr_irqs NR_IRQS + +# 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--) +#endif + +#define for_each_irq_nr(irq) \ + for (irq = 0; irq < nr_irqs; irq++) + +#endif -- cgit v1.2.3 From 5b6985ce8ec7127b4d60ad450b64ca8b82748a3b Mon Sep 17 00:00:00 2001 From: Fenghua Yu Date: Thu, 16 Oct 2008 18:02:32 -0700 Subject: intel-iommu: IA64 support The current Intel IOMMU code assumes that both host page size and Intel IOMMU page size are 4KiB. The first patch supports variable page size. This provides support for IA64 which has multiple page sizes. This patch also adds some other code hooks for IA64 platform including DMAR_OPERATION_TIMEOUT definition. [dwmw2: some cleanup] Signed-off-by: Fenghua Yu Signed-off-by: Tony Luck Signed-off-by: David Woodhouse --- include/linux/dma_remapping.h | 27 +++++++++++++-------------- include/linux/intel-iommu.h | 39 +++++++++++++++++++++++---------------- 2 files changed, 36 insertions(+), 30 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dma_remapping.h b/include/linux/dma_remapping.h index bff5c65f81d..952df39c989 100644 --- a/include/linux/dma_remapping.h +++ b/include/linux/dma_remapping.h @@ -2,15 +2,14 @@ #define _DMA_REMAPPING_H /* - * We need a fixed PAGE_SIZE of 4K irrespective of - * arch PAGE_SIZE for IOMMU page tables. + * VT-d hardware uses 4KiB page size regardless of host page size. */ -#define PAGE_SHIFT_4K (12) -#define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) -#define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) -#define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) +#define VTD_PAGE_SHIFT (12) +#define VTD_PAGE_SIZE (1UL << VTD_PAGE_SHIFT) +#define VTD_PAGE_MASK (((u64)-1) << VTD_PAGE_SHIFT) +#define VTD_PAGE_ALIGN(addr) (((addr) + VTD_PAGE_SIZE - 1) & VTD_PAGE_MASK) -#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K) +#define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT) #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) @@ -25,7 +24,7 @@ struct root_entry { u64 val; u64 rsvd1; }; -#define ROOT_ENTRY_NR (PAGE_SIZE_4K/sizeof(struct root_entry)) +#define ROOT_ENTRY_NR (VTD_PAGE_SIZE/sizeof(struct root_entry)) static inline bool root_present(struct root_entry *root) { return (root->val & 1); @@ -36,7 +35,7 @@ static inline void set_root_present(struct root_entry *root) } static inline void set_root_value(struct root_entry *root, unsigned long value) { - root->val |= value & PAGE_MASK_4K; + root->val |= value & VTD_PAGE_MASK; } struct context_entry; @@ -45,7 +44,7 @@ get_context_addr_from_root(struct root_entry *root) { return (struct context_entry *) (root_present(root)?phys_to_virt( - root->val & PAGE_MASK_4K): + root->val & VTD_PAGE_MASK) : NULL); } @@ -67,7 +66,7 @@ struct context_entry { #define context_present(c) ((c).lo & 1) #define context_fault_disable(c) (((c).lo >> 1) & 1) #define context_translation_type(c) (((c).lo >> 2) & 3) -#define context_address_root(c) ((c).lo & PAGE_MASK_4K) +#define context_address_root(c) ((c).lo & VTD_PAGE_MASK) #define context_address_width(c) ((c).hi & 7) #define context_domain_id(c) (((c).hi >> 8) & ((1 << 16) - 1)) @@ -81,7 +80,7 @@ struct context_entry { } while (0) #define CONTEXT_TT_MULTI_LEVEL 0 #define context_set_address_root(c, val) \ - do {(c).lo |= (val) & PAGE_MASK_4K;} while (0) + do {(c).lo |= (val) & VTD_PAGE_MASK; } while (0) #define context_set_address_width(c, val) do {(c).hi |= (val) & 7;} while (0) #define context_set_domain_id(c, val) \ do {(c).hi |= ((val) & ((1 << 16) - 1)) << 8;} while (0) @@ -107,9 +106,9 @@ struct dma_pte { #define dma_set_pte_writable(p) do {(p).val |= DMA_PTE_WRITE;} while (0) #define dma_set_pte_prot(p, prot) \ do {(p).val = ((p).val & ~3) | ((prot) & 3); } while (0) -#define dma_pte_addr(p) ((p).val & PAGE_MASK_4K) +#define dma_pte_addr(p) ((p).val & VTD_PAGE_MASK) #define dma_set_pte_addr(p, addr) do {\ - (p).val |= ((addr) & PAGE_MASK_4K); } while (0) + (p).val |= ((addr) & VTD_PAGE_MASK); } while (0) #define dma_pte_present(p) (((p).val & 3) != 0) struct intel_iommu; diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index afb0d2a5b7c..3d017cfd245 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -29,6 +29,7 @@ #include #include #include +#include /* * Intel IOMMU register specification per version 1.0 public spec. @@ -202,22 +203,21 @@ static inline void dmar_writeq(void __iomem *addr, u64 val) #define dma_frcd_type(d) ((d >> 30) & 1) #define dma_frcd_fault_reason(c) (c & 0xff) #define dma_frcd_source_id(c) (c & 0xffff) -#define dma_frcd_page_addr(d) (d & (((u64)-1) << 12)) /* low 64 bit */ - -#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000) /* 10sec */ - -#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ -{\ - cycles_t start_time = get_cycles();\ - while (1) {\ - sts = op (iommu->reg + offset);\ - if (cond)\ - break;\ +/* low 64 bit */ +#define dma_frcd_page_addr(d) (d & (((u64)-1) << PAGE_SHIFT)) + +#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \ +do { \ + cycles_t start_time = get_cycles(); \ + while (1) { \ + sts = op(iommu->reg + offset); \ + if (cond) \ + break; \ if (DMAR_OPERATION_TIMEOUT < (get_cycles() - start_time))\ - panic("DMAR hardware is malfunctioning\n");\ - cpu_relax();\ - }\ -} + panic("DMAR hardware is malfunctioning\n"); \ + cpu_relax(); \ + } \ +} while (0) #define QI_LENGTH 256 /* queue length */ @@ -244,7 +244,7 @@ enum { #define QI_IOTLB_DR(dr) (((u64)dr) << 7) #define QI_IOTLB_DW(dw) (((u64)dw) << 6) #define QI_IOTLB_GRAN(gran) (((u64)gran) >> (DMA_TLB_FLUSH_GRANU_OFFSET-4)) -#define QI_IOTLB_ADDR(addr) (((u64)addr) & PAGE_MASK_4K) +#define QI_IOTLB_ADDR(addr) (((u64)addr) & VTD_PAGE_MASK) #define QI_IOTLB_IH(ih) (((u64)ih) << 6) #define QI_IOTLB_AM(am) (((u8)am)) @@ -353,4 +353,11 @@ static inline int intel_iommu_found(void) } #endif /* CONFIG_DMAR */ +extern void *intel_alloc_coherent(struct device *, size_t, dma_addr_t *, gfp_t); +extern void intel_free_coherent(struct device *, size_t, void *, dma_addr_t); +extern dma_addr_t intel_map_single(struct device *, phys_addr_t, size_t, int); +extern void intel_unmap_single(struct device *, dma_addr_t, size_t, int); +extern int intel_map_sg(struct device *, struct scatterlist *, int, int); +extern void intel_unmap_sg(struct device *, struct scatterlist *, int, int); + #endif -- cgit v1.2.3 From 1c1b6ffce5737d764cc474b9bd6677bb9a344094 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 Sep 2008 23:36:23 +0200 Subject: mfd: provide and use setup hook for tc6393xb Instead of using bitfields for initial gpio setup, provide generic setup/teardown hooks that can be used to set the gpio states, register child devices, etc. Signed-off-by: Dmitry Baryshkov Signed-off-by: Samuel Ortiz --- include/linux/mfd/tc6393xb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index fec7b3f7a81..1fa820646d9 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h @@ -21,8 +21,6 @@ struct tc6393xb_platform_data { u16 scr_pll2cr; /* PLL2 Control */ u16 scr_gper; /* GP Enable */ - u32 scr_gpo_doecr; /* GPO Data OE Control */ - u32 scr_gpo_dsr; /* GPO Data Set */ int (*enable)(struct platform_device *dev); int (*disable)(struct platform_device *dev); @@ -31,6 +29,8 @@ struct tc6393xb_platform_data { int irq_base; /* base for subdevice irqs */ int gpio_base; + int (*setup)(struct platform_device *dev); + void (*teardown)(struct platform_device *dev); struct tmio_nand_data *nand_data; }; -- cgit v1.2.3 From f98a0bd0e4b77b12e49ce01f4c9f04503931c291 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 24 Sep 2008 23:46:10 +0200 Subject: mfd: do tcb6393xb state restore on resume only if requested As requested by Ian make state restore only if it's requested by platform data: some platforms do correctly save the state of the chip during suspend/resume, but some (like tosa) incorrectly power off the chip at suspend, so the driver supports restoring some bits of the tc6393xb state (not full, merely enough to support resume on tosa). With this patch this code is disabled by default. Signed-off-by: Dmitry Baryshkov Acked-by: Ian Molton Signed-off-by: Samuel Ortiz --- include/linux/mfd/tc6393xb.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index 1fa820646d9..3ce10ae0f39 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h @@ -33,6 +33,10 @@ struct tc6393xb_platform_data { void (*teardown)(struct platform_device *dev); struct tmio_nand_data *nand_data; + + unsigned resume_restore : 1; /* make special actions + to preserve the state + on suspend/resume */ }; /* -- cgit v1.2.3 From 51a55623565c6ca864f7cf19e87c2d4bde1c0c5e Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Fri, 3 Oct 2008 20:11:36 +0200 Subject: mfd: add OHCI cell to tc6393xb Add information regarding OHCI cell of the tc6393xb Signed-off-by: Dmitry Baryshkov Acked-by: Ian Molton Signed-off-by: Samuel Ortiz --- include/linux/mfd/tc6393xb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index 3ce10ae0f39..4437736ebe1 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h @@ -44,6 +44,7 @@ struct tc6393xb_platform_data { */ #define IRQ_TC6393_NAND 0 #define IRQ_TC6393_MMC 1 +#define IRQ_TC6393_OHCI 2 #define TC6393XB_NR_IRQS 8 -- cgit v1.2.3 From 9e78cfe53f3c2bc1b37870697c3cde1543fefa8b Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 4 Oct 2008 00:50:36 +0200 Subject: mfd: support tmiofb cell on tc6393xb Add support for tmiofb cell found in tc6393xb chip. Signed-off-by: Dmitry Baryshkov Cc: Ian Molton Signed-off-by: Samuel Ortiz --- include/linux/mfd/tc6393xb.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/tc6393xb.h b/include/linux/mfd/tc6393xb.h index 4437736ebe1..626e448205c 100644 --- a/include/linux/mfd/tc6393xb.h +++ b/include/linux/mfd/tc6393xb.h @@ -17,6 +17,8 @@ #ifndef MFD_TC6393XB_H #define MFD_TC6393XB_H +#include + /* Also one should provide the CK3P6MI clock */ struct tc6393xb_platform_data { u16 scr_pll2cr; /* PLL2 Control */ @@ -33,18 +35,24 @@ struct tc6393xb_platform_data { void (*teardown)(struct platform_device *dev); struct tmio_nand_data *nand_data; + struct tmio_fb_data *fb_data; unsigned resume_restore : 1; /* make special actions to preserve the state on suspend/resume */ }; +extern int tc6393xb_lcd_mode(struct platform_device *fb, + const struct fb_videomode *mode); +extern int tc6393xb_lcd_set_power(struct platform_device *fb, bool on); + /* * Relative to irq_base */ #define IRQ_TC6393_NAND 0 #define IRQ_TC6393_MMC 1 #define IRQ_TC6393_OHCI 2 +#define IRQ_TC6393_FB 4 #define TC6393XB_NR_IRQS 8 -- cgit v1.2.3 From a603a7fa8717fb778bba91b5a879babf333dc6a3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 15 Oct 2008 12:15:39 +0200 Subject: mfd: TWL4030 core driver This patch adds the core of the TWL4030 driver, which supports chips including the TPS65950. These chips are multi-function; see http://focus.ti.com/docs/prod/folders/print/tps65950.html Public specs are in the works. For now, the block diagram on the second page of the datasheet is fairly informative. There are some known issues with this core code. Most notably, the IRQ dispatching needs simplification (to use more of genirq), generalization (integrating support for secondary IRQ dispatch as well as primary, and removing the build dependency on OMAP), and then probably updating to leverage threaded IRQ support (expected to arrive in mainline "soon"). Once the core is in mainline, drivers for other parts of this chip can follow its lead and start swimming upstream too. Signed-off-by: David Brownell Signed-off-by: Samuel Ortiz --- include/linux/i2c/twl4030.h | 339 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 include/linux/i2c/twl4030.h (limited to 'include/linux') diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h new file mode 100644 index 00000000000..cdb453162a9 --- /dev/null +++ b/include/linux/i2c/twl4030.h @@ -0,0 +1,339 @@ +/* + * twl4030.h - header for TWL4030 PM and audio CODEC device + * + * Copyright (C) 2005-2006 Texas Instruments, Inc. + * + * Based on tlv320aic23.c: + * Copyright (c) by Kai Svahn + * + * 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 __TWL4030_H_ +#define __TWL4030_H_ + +/* + * Using the twl4030 core we address registers using a pair + * { module id, relative register offset } + * which that core then maps to the relevant + * { i2c slave, absolute register address } + * + * The module IDs are meaningful only to the twl4030 core code, + * which uses them as array indices to look up the first register + * address each module uses within a given i2c slave. + */ + +/* Slave 0 (i2c address 0x48) */ +#define TWL4030_MODULE_USB 0x00 + +/* Slave 1 (i2c address 0x49) */ +#define TWL4030_MODULE_AUDIO_VOICE 0x01 +#define TWL4030_MODULE_GPIO 0x02 +#define TWL4030_MODULE_INTBR 0x03 +#define TWL4030_MODULE_PIH 0x04 +#define TWL4030_MODULE_TEST 0x05 + +/* Slave 2 (i2c address 0x4a) */ +#define TWL4030_MODULE_KEYPAD 0x06 +#define TWL4030_MODULE_MADC 0x07 +#define TWL4030_MODULE_INTERRUPTS 0x08 +#define TWL4030_MODULE_LED 0x09 +#define TWL4030_MODULE_MAIN_CHARGE 0x0A +#define TWL4030_MODULE_PRECHARGE 0x0B +#define TWL4030_MODULE_PWM0 0x0C +#define TWL4030_MODULE_PWM1 0x0D +#define TWL4030_MODULE_PWMA 0x0E +#define TWL4030_MODULE_PWMB 0x0F + +/* Slave 3 (i2c address 0x4b) */ +#define TWL4030_MODULE_BACKUP 0x10 +#define TWL4030_MODULE_INT 0x11 +#define TWL4030_MODULE_PM_MASTER 0x12 +#define TWL4030_MODULE_PM_RECEIVER 0x13 +#define TWL4030_MODULE_RTC 0x14 +#define TWL4030_MODULE_SECURED_REG 0x15 + +/* + * Read and write single 8-bit registers + */ +int twl4030_i2c_write_u8(u8 mod_no, u8 val, u8 reg); +int twl4030_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); + +/* + * Read and write several 8-bit registers at once. + * + * IMPORTANT: For twl4030_i2c_write(), allocate num_bytes + 1 + * for the value, and populate your data starting at offset 1. + */ +int twl4030_i2c_write(u8 mod_no, u8 *value, u8 reg, u8 num_bytes); +int twl4030_i2c_read(u8 mod_no, u8 *value, u8 reg, u8 num_bytes); + +/*----------------------------------------------------------------------*/ + +/* + * NOTE: at up to 1024 registers, this is a big chip. + * + * Avoid putting register declarations in this file, instead of into + * a driver-private file, unless some of the registers in a block + * need to be shared with other drivers. One example is blocks that + * have Secondary IRQ Handler (SIH) registers. + */ + +#define TWL4030_SIH_CTRL_EXCLEN_MASK BIT(0) +#define TWL4030_SIH_CTRL_PENDDIS_MASK BIT(1) +#define TWL4030_SIH_CTRL_COR_MASK BIT(2) + +/*----------------------------------------------------------------------*/ + +/* + * GPIO Block Register offsets (use TWL4030_MODULE_GPIO) + */ + +#define REG_GPIODATAIN1 0x0 +#define REG_GPIODATAIN2 0x1 +#define REG_GPIODATAIN3 0x2 +#define REG_GPIODATADIR1 0x3 +#define REG_GPIODATADIR2 0x4 +#define REG_GPIODATADIR3 0x5 +#define REG_GPIODATAOUT1 0x6 +#define REG_GPIODATAOUT2 0x7 +#define REG_GPIODATAOUT3 0x8 +#define REG_CLEARGPIODATAOUT1 0x9 +#define REG_CLEARGPIODATAOUT2 0xA +#define REG_CLEARGPIODATAOUT3 0xB +#define REG_SETGPIODATAOUT1 0xC +#define REG_SETGPIODATAOUT2 0xD +#define REG_SETGPIODATAOUT3 0xE +#define REG_GPIO_DEBEN1 0xF +#define REG_GPIO_DEBEN2 0x10 +#define REG_GPIO_DEBEN3 0x11 +#define REG_GPIO_CTRL 0x12 +#define REG_GPIOPUPDCTR1 0x13 +#define REG_GPIOPUPDCTR2 0x14 +#define REG_GPIOPUPDCTR3 0x15 +#define REG_GPIOPUPDCTR4 0x16 +#define REG_GPIOPUPDCTR5 0x17 +#define REG_GPIO_ISR1A 0x19 +#define REG_GPIO_ISR2A 0x1A +#define REG_GPIO_ISR3A 0x1B +#define REG_GPIO_IMR1A 0x1C +#define REG_GPIO_IMR2A 0x1D +#define REG_GPIO_IMR3A 0x1E +#define REG_GPIO_ISR1B 0x1F +#define REG_GPIO_ISR2B 0x20 +#define REG_GPIO_ISR3B 0x21 +#define REG_GPIO_IMR1B 0x22 +#define REG_GPIO_IMR2B 0x23 +#define REG_GPIO_IMR3B 0x24 +#define REG_GPIO_EDR1 0x28 +#define REG_GPIO_EDR2 0x29 +#define REG_GPIO_EDR3 0x2A +#define REG_GPIO_EDR4 0x2B +#define REG_GPIO_EDR5 0x2C +#define REG_GPIO_SIH_CTRL 0x2D + +/* Up to 18 signals are available as GPIOs, when their + * pins are not assigned to another use (such as ULPI/USB). + */ +#define TWL4030_GPIO_MAX 18 + +/*----------------------------------------------------------------------*/ + +/* + * Keypad register offsets (use TWL4030_MODULE_KEYPAD) + * ... SIH/interrupt only + */ + +#define TWL4030_KEYPAD_KEYP_ISR1 0x11 +#define TWL4030_KEYPAD_KEYP_IMR1 0x12 +#define TWL4030_KEYPAD_KEYP_ISR2 0x13 +#define TWL4030_KEYPAD_KEYP_IMR2 0x14 +#define TWL4030_KEYPAD_KEYP_SIR 0x15 /* test register */ +#define TWL4030_KEYPAD_KEYP_EDR 0x16 +#define TWL4030_KEYPAD_KEYP_SIH_CTRL 0x17 + +/*----------------------------------------------------------------------*/ + +/* + * Multichannel ADC register offsets (use TWL4030_MODULE_MADC) + * ... SIH/interrupt only + */ + +#define TWL4030_MADC_ISR1 0x61 +#define TWL4030_MADC_IMR1 0x62 +#define TWL4030_MADC_ISR2 0x63 +#define TWL4030_MADC_IMR2 0x64 +#define TWL4030_MADC_SIR 0x65 /* test register */ +#define TWL4030_MADC_EDR 0x66 +#define TWL4030_MADC_SIH_CTRL 0x67 + +/*----------------------------------------------------------------------*/ + +/* + * Battery charger register offsets (use TWL4030_MODULE_INTERRUPTS) + */ + +#define TWL4030_INTERRUPTS_BCIISR1A 0x0 +#define TWL4030_INTERRUPTS_BCIISR2A 0x1 +#define TWL4030_INTERRUPTS_BCIIMR1A 0x2 +#define TWL4030_INTERRUPTS_BCIIMR2A 0x3 +#define TWL4030_INTERRUPTS_BCIISR1B 0x4 +#define TWL4030_INTERRUPTS_BCIISR2B 0x5 +#define TWL4030_INTERRUPTS_BCIIMR1B 0x6 +#define TWL4030_INTERRUPTS_BCIIMR2B 0x7 +#define TWL4030_INTERRUPTS_BCISIR1 0x8 /* test register */ +#define TWL4030_INTERRUPTS_BCISIR2 0x9 /* test register */ +#define TWL4030_INTERRUPTS_BCIEDR1 0xa +#define TWL4030_INTERRUPTS_BCIEDR2 0xb +#define TWL4030_INTERRUPTS_BCIEDR3 0xc +#define TWL4030_INTERRUPTS_BCISIHCTRL 0xd + +/*----------------------------------------------------------------------*/ + +/* + * Power Interrupt block register offsets (use TWL4030_MODULE_INT) + */ + +#define TWL4030_INT_PWR_ISR1 0x0 +#define TWL4030_INT_PWR_IMR1 0x1 +#define TWL4030_INT_PWR_ISR2 0x2 +#define TWL4030_INT_PWR_IMR2 0x3 +#define TWL4030_INT_PWR_SIR 0x4 /* test register */ +#define TWL4030_INT_PWR_EDR1 0x5 +#define TWL4030_INT_PWR_EDR2 0x6 +#define TWL4030_INT_PWR_SIH_CTRL 0x7 + +/*----------------------------------------------------------------------*/ + +struct twl4030_bci_platform_data { + int *battery_tmp_tbl; + unsigned int tblsize; +}; + +/* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */ +struct twl4030_gpio_platform_data { + int gpio_base; + unsigned irq_base, irq_end; + + /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup + * should be enabled. Else, if that bit is set in "pulldowns", + * that pulldown is enabled. Don't waste power by letting any + * digital inputs float... + */ + u32 pullups; + u32 pulldowns; + + int (*setup)(struct device *dev, + unsigned gpio, unsigned ngpio); + int (*teardown)(struct device *dev, + unsigned gpio, unsigned ngpio); +}; + +struct twl4030_madc_platform_data { + int irq_line; +}; + +struct twl4030_keypad_data { + int rows; + int cols; + int *keymap; + int irq; + unsigned int keymapsize; + unsigned int rep:1; +}; + +enum twl4030_usb_mode { + T2_USB_MODE_ULPI = 1, + T2_USB_MODE_CEA2011_3PIN = 2, +}; + +struct twl4030_usb_data { + enum twl4030_usb_mode usb_mode; +}; + +struct twl4030_platform_data { + unsigned irq_base, irq_end; + struct twl4030_bci_platform_data *bci; + struct twl4030_gpio_platform_data *gpio; + struct twl4030_madc_platform_data *madc; + struct twl4030_keypad_data *keypad; + struct twl4030_usb_data *usb; + + /* REVISIT more to come ... _nothing_ should be hard-wired */ +}; + +/*----------------------------------------------------------------------*/ + +/* + * FIXME completely stop using TWL4030_IRQ_BASE ... instead, pass the + * IRQ data to subsidiary devices using platform device resources. + */ + +/* IRQ information-need base */ +#include +/* TWL4030 interrupts */ + +/* #define TWL4030_MODIRQ_GPIO (TWL4030_IRQ_BASE + 0) */ +#define TWL4030_MODIRQ_KEYPAD (TWL4030_IRQ_BASE + 1) +#define TWL4030_MODIRQ_BCI (TWL4030_IRQ_BASE + 2) +#define TWL4030_MODIRQ_MADC (TWL4030_IRQ_BASE + 3) +/* #define TWL4030_MODIRQ_USB (TWL4030_IRQ_BASE + 4) */ +#define TWL4030_MODIRQ_PWR (TWL4030_IRQ_BASE + 5) + +#define TWL4030_PWRIRQ_PWRBTN (TWL4030_PWR_IRQ_BASE + 0) +#define TWL4030_PWRIRQ_CHG_PRES (TWL4030_PWR_IRQ_BASE + 1) +#define TWL4030_PWRIRQ_USB_PRES (TWL4030_PWR_IRQ_BASE + 2) +#define TWL4030_PWRIRQ_RTC (TWL4030_PWR_IRQ_BASE + 3) +#define TWL4030_PWRIRQ_HOT_DIE (TWL4030_PWR_IRQ_BASE + 4) +#define TWL4030_PWRIRQ_PWROK_TIMEOUT (TWL4030_PWR_IRQ_BASE + 5) +#define TWL4030_PWRIRQ_MBCHG (TWL4030_PWR_IRQ_BASE + 6) +#define TWL4030_PWRIRQ_SC_DETECT (TWL4030_PWR_IRQ_BASE + 7) + +/* Rest are unsued currently*/ + +/* Offsets to Power Registers */ +#define TWL4030_VDAC_DEV_GRP 0x3B +#define TWL4030_VDAC_DEDICATED 0x3E +#define TWL4030_VAUX1_DEV_GRP 0x17 +#define TWL4030_VAUX1_DEDICATED 0x1A +#define TWL4030_VAUX2_DEV_GRP 0x1B +#define TWL4030_VAUX2_DEDICATED 0x1E +#define TWL4030_VAUX3_DEV_GRP 0x1F +#define TWL4030_VAUX3_DEDICATED 0x22 + +/* TWL4030 GPIO interrupt definitions */ + +#define TWL4030_GPIO_IRQ_NO(n) (TWL4030_GPIO_IRQ_BASE + (n)) +#define TWL4030_GPIO_IS_ENABLE 1 + +/* + * Exported TWL4030 GPIO APIs + * + * WARNING -- use standard GPIO and IRQ calls instead; these will vanish. + */ +int twl4030_get_gpio_datain(int gpio); +int twl4030_request_gpio(int gpio); +int twl4030_set_gpio_debounce(int gpio, int enable); +int twl4030_free_gpio(int gpio); + +#if defined(CONFIG_TWL4030_BCI_BATTERY) || \ + defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) + extern int twl4030charger_usb_en(int enable); +#else + static inline int twl4030charger_usb_en(int enable) { return 0; } +#endif + +#endif /* End of __TWL4030_H */ -- cgit v1.2.3 From 26b8f5e1e2d1229c186d8e61d26513c43a058c5e Mon Sep 17 00:00:00 2001 From: Eric Miao Date: Wed, 15 Oct 2008 12:20:06 +0200 Subject: mfd: add base support for Dialog DA9030/DA9034 PMICs DA9030 (a.k.a ARAVA) and DA9034 (a.k.a MICCO) are PMICs designed by Dialog Semiconductor, usually found on PXA-based platforms. These PMICs are I2C-based, multi-function devices, usually with LEDs, PWMs for backlight, BUCKs and LDOs, ADCs and touchscreen controller (on DA9034). This is the base support for the I2C operations, event registration and handling, sub-devices management. Signed-off-by: Mike Rapoport Signed-off-by: Eric Miao Signed-off-by: Liam Girdwood Signed-off-by: Samuel Ortiz --- include/linux/mfd/da903x.h | 201 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 201 insertions(+) create mode 100644 include/linux/mfd/da903x.h (limited to 'include/linux') diff --git a/include/linux/mfd/da903x.h b/include/linux/mfd/da903x.h new file mode 100644 index 00000000000..cad314c1243 --- /dev/null +++ b/include/linux/mfd/da903x.h @@ -0,0 +1,201 @@ +#ifndef __LINUX_PMIC_DA903X_H +#define __LINUX_PMIC_DA903X_H + +/* Unified sub device IDs for DA9030/DA9034 */ +enum { + DA9030_ID_LED_1, + DA9030_ID_LED_2, + DA9030_ID_LED_3, + DA9030_ID_LED_4, + DA9030_ID_LED_PC, + DA9030_ID_VIBRA, + DA9030_ID_WLED, + DA9030_ID_BUCK1, + DA9030_ID_BUCK2, + DA9030_ID_LDO1, + DA9030_ID_LDO2, + DA9030_ID_LDO3, + DA9030_ID_LDO4, + DA9030_ID_LDO5, + DA9030_ID_LDO6, + DA9030_ID_LDO7, + DA9030_ID_LDO8, + DA9030_ID_LDO9, + DA9030_ID_LDO10, + DA9030_ID_LDO11, + DA9030_ID_LDO12, + DA9030_ID_LDO13, + DA9030_ID_LDO14, + DA9030_ID_LDO15, + DA9030_ID_LDO16, + DA9030_ID_LDO17, + DA9030_ID_LDO18, + DA9030_ID_LDO19, + DA9030_ID_LDO_INT, /* LDO Internal */ + + DA9034_ID_LED_1, + DA9034_ID_LED_2, + DA9034_ID_VIBRA, + DA9034_ID_WLED, + DA9034_ID_TOUCH, + + DA9034_ID_BUCK1, + DA9034_ID_BUCK2, + DA9034_ID_LDO1, + DA9034_ID_LDO2, + DA9034_ID_LDO3, + DA9034_ID_LDO4, + DA9034_ID_LDO5, + DA9034_ID_LDO6, + DA9034_ID_LDO7, + DA9034_ID_LDO8, + DA9034_ID_LDO9, + DA9034_ID_LDO10, + DA9034_ID_LDO11, + DA9034_ID_LDO12, + DA9034_ID_LDO13, + DA9034_ID_LDO14, + DA9034_ID_LDO15, +}; + +/* + * DA9030/DA9034 LEDs sub-devices uses generic "struct led_info" + * as the platform_data + */ + +/* DA9030 flags for "struct led_info" + */ +#define DA9030_LED_RATE_ON (0 << 5) +#define DA9030_LED_RATE_052S (1 << 5) +#define DA9030_LED_DUTY_1_16 (0 << 3) +#define DA9030_LED_DUTY_1_8 (1 << 3) +#define DA9030_LED_DUTY_1_4 (2 << 3) +#define DA9030_LED_DUTY_1_2 (3 << 3) + +#define DA9030_VIBRA_MODE_1P3V (0 << 1) +#define DA9030_VIBRA_MODE_2P7V (1 << 1) +#define DA9030_VIBRA_FREQ_1HZ (0 << 2) +#define DA9030_VIBRA_FREQ_2HZ (1 << 2) +#define DA9030_VIBRA_FREQ_4HZ (2 << 2) +#define DA9030_VIBRA_FREQ_8HZ (3 << 2) +#define DA9030_VIBRA_DUTY_ON (0 << 4) +#define DA9030_VIBRA_DUTY_75P (1 << 4) +#define DA9030_VIBRA_DUTY_50P (2 << 4) +#define DA9030_VIBRA_DUTY_25P (3 << 4) + +/* DA9034 flags for "struct led_info" */ +#define DA9034_LED_RAMP (1 << 7) + +/* DA9034 touch screen platform data */ +struct da9034_touch_pdata { + int interval_ms; /* sampling interval while pen down */ + int x_inverted; + int y_inverted; +}; + +struct da903x_subdev_info { + int id; + const char *name; + void *platform_data; +}; + +struct da903x_platform_data { + int num_subdevs; + struct da903x_subdev_info *subdevs; +}; + +/* bit definitions for DA9030 events */ +#define DA9030_EVENT_ONKEY (1 << 0) +#define DA9030_EVENT_PWREN (1 << 1) +#define DA9030_EVENT_EXTON (1 << 2) +#define DA9030_EVENT_CHDET (1 << 3) +#define DA9030_EVENT_TBAT (1 << 4) +#define DA9030_EVENT_VBATMON (1 << 5) +#define DA9030_EVENT_VBATMON_TXON (1 << 6) +#define DA9030_EVENT_CHIOVER (1 << 7) +#define DA9030_EVENT_TCTO (1 << 8) +#define DA9030_EVENT_CCTO (1 << 9) +#define DA9030_EVENT_ADC_READY (1 << 10) +#define DA9030_EVENT_VBUS_4P4 (1 << 11) +#define DA9030_EVENT_VBUS_4P0 (1 << 12) +#define DA9030_EVENT_SESS_VALID (1 << 13) +#define DA9030_EVENT_SRP_DETECT (1 << 14) +#define DA9030_EVENT_WATCHDOG (1 << 15) +#define DA9030_EVENT_LDO15 (1 << 16) +#define DA9030_EVENT_LDO16 (1 << 17) +#define DA9030_EVENT_LDO17 (1 << 18) +#define DA9030_EVENT_LDO18 (1 << 19) +#define DA9030_EVENT_LDO19 (1 << 20) +#define DA9030_EVENT_BUCK2 (1 << 21) + +/* bit definitions for DA9034 events */ +#define DA9034_EVENT_ONKEY (1 << 0) +#define DA9034_EVENT_EXTON (1 << 2) +#define DA9034_EVENT_CHDET (1 << 3) +#define DA9034_EVENT_TBAT (1 << 4) +#define DA9034_EVENT_VBATMON (1 << 5) +#define DA9034_EVENT_REV_IOVER (1 << 6) +#define DA9034_EVENT_CH_IOVER (1 << 7) +#define DA9034_EVENT_CH_TCTO (1 << 8) +#define DA9034_EVENT_CH_CCTO (1 << 9) +#define DA9034_EVENT_USB_DEV (1 << 10) +#define DA9034_EVENT_OTGCP_IOVER (1 << 11) +#define DA9034_EVENT_VBUS_4P55 (1 << 12) +#define DA9034_EVENT_VBUS_3P8 (1 << 13) +#define DA9034_EVENT_SESS_1P8 (1 << 14) +#define DA9034_EVENT_SRP_READY (1 << 15) +#define DA9034_EVENT_ADC_MAN (1 << 16) +#define DA9034_EVENT_ADC_AUTO4 (1 << 17) +#define DA9034_EVENT_ADC_AUTO5 (1 << 18) +#define DA9034_EVENT_ADC_AUTO6 (1 << 19) +#define DA9034_EVENT_PEN_DOWN (1 << 20) +#define DA9034_EVENT_TSI_READY (1 << 21) +#define DA9034_EVENT_UART_TX (1 << 22) +#define DA9034_EVENT_UART_RX (1 << 23) +#define DA9034_EVENT_HEADSET (1 << 25) +#define DA9034_EVENT_HOOKSWITCH (1 << 26) +#define DA9034_EVENT_WATCHDOG (1 << 27) + +extern int da903x_register_notifier(struct device *dev, + struct notifier_block *nb, unsigned int events); +extern int da903x_unregister_notifier(struct device *dev, + struct notifier_block *nb, unsigned int events); + +/* Status Query Interface */ +#define DA9030_STATUS_ONKEY (1 << 0) +#define DA9030_STATUS_PWREN1 (1 << 1) +#define DA9030_STATUS_EXTON (1 << 2) +#define DA9030_STATUS_CHDET (1 << 3) +#define DA9030_STATUS_TBAT (1 << 4) +#define DA9030_STATUS_VBATMON (1 << 5) +#define DA9030_STATUS_VBATMON_TXON (1 << 6) +#define DA9030_STATUS_MCLKDET (1 << 7) + +#define DA9034_STATUS_ONKEY (1 << 0) +#define DA9034_STATUS_EXTON (1 << 2) +#define DA9034_STATUS_CHDET (1 << 3) +#define DA9034_STATUS_TBAT (1 << 4) +#define DA9034_STATUS_VBATMON (1 << 5) +#define DA9034_STATUS_PEN_DOWN (1 << 6) +#define DA9034_STATUS_MCLKDET (1 << 7) +#define DA9034_STATUS_USB_DEV (1 << 8) +#define DA9034_STATUS_HEADSET (1 << 9) +#define DA9034_STATUS_HOOKSWITCH (1 << 10) +#define DA9034_STATUS_REMCON (1 << 11) +#define DA9034_STATUS_VBUS_VALID_4P55 (1 << 12) +#define DA9034_STATUS_VBUS_VALID_3P8 (1 << 13) +#define DA9034_STATUS_SESS_VALID_1P8 (1 << 14) +#define DA9034_STATUS_SRP_READY (1 << 15) + +extern int da903x_query_status(struct device *dev, unsigned int status); + + +/* NOTE: the two functions below are not intended for use outside + * of the DA9034 sub-device drivers + */ +extern int da903x_write(struct device *dev, int reg, uint8_t val); +extern int da903x_read(struct device *dev, int reg, uint8_t *val); +extern int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask); +extern int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask); +#endif /* __LINUX_PMIC_DA903X_H */ -- cgit v1.2.3 From 7acb706ca97fce84bda4a902a33de2f3dae10260 Mon Sep 17 00:00:00 2001 From: Ian Molton Date: Thu, 9 Oct 2008 20:06:09 +0200 Subject: mfd: update TMIO drivers to use the clock API This patch updates the remaining two TMIO drivers to use the clock API rather than callback hooks into platform code. Signed-off-by: Ian Molton Signed-off-by: Samuel Ortiz --- include/linux/mfd/t7l66xb.h | 2 -- include/linux/mfd/tc6387xb.h | 3 --- 2 files changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mfd/t7l66xb.h b/include/linux/mfd/t7l66xb.h index e83c7f2036f..b4629818aea 100644 --- a/include/linux/mfd/t7l66xb.h +++ b/include/linux/mfd/t7l66xb.h @@ -15,8 +15,6 @@ #include struct t7l66xb_platform_data { - int (*enable_clk32k)(struct platform_device *dev); - void (*disable_clk32k)(struct platform_device *dev); int (*enable)(struct platform_device *dev); int (*disable)(struct platform_device *dev); int (*suspend)(struct platform_device *dev); diff --git a/include/linux/mfd/tc6387xb.h b/include/linux/mfd/tc6387xb.h index fa06e0610b8..b4888209494 100644 --- a/include/linux/mfd/tc6387xb.h +++ b/include/linux/mfd/tc6387xb.h @@ -11,9 +11,6 @@ #define MFD_TC6387XB_H struct tc6387xb_platform_data { - int (*enable_clk32k)(struct platform_device *dev); - void (*disable_clk32k)(struct platform_device *dev); - int (*enable)(struct platform_device *dev); int (*disable)(struct platform_device *dev); int (*suspend)(struct platform_device *dev); -- cgit v1.2.3 From ffda12a17a324103e9900fa1035309811eecbfe5 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Fri, 17 Oct 2008 19:27:02 +0200 Subject: sched: optimize group load balancer I noticed that tg_shares_up() unconditionally takes rq-locks for all cpus in the sched_domain. This hurts. We need the rq-locks whenever we change the weight of the per-cpu group sched entities. To allevate this a little, only change the weight when the new weight is at least shares_thresh away from the old value. This avoids the rq-lock for the top level entries, since those will never be re-weighted, and fuzzes the lower level entries a little to gain performance in semi-stable situations. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/sched.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 6eda6ad735d..4f59c8e8597 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1621,6 +1621,7 @@ extern unsigned int sysctl_sched_features; extern unsigned int sysctl_sched_migration_cost; extern unsigned int sysctl_sched_nr_migrate; extern unsigned int sysctl_sched_shares_ratelimit; +extern unsigned int sysctl_sched_shares_thresh; int sched_nr_latency_handler(struct ctl_table *table, int write, struct file *file, void __user *buffer, size_t *length, -- cgit v1.2.3 From 592aa999d6a272856c9bfbdaac0cfba1bb37c24c Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 20 Oct 2008 16:38:19 +0200 Subject: hrtimers: add missing docbook comments to struct hrtimer Signed-off-by: Thomas Gleixner --- include/linux/hrtimer.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index cb25c1cc235..58bca8e9bae 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -103,9 +103,14 @@ enum hrtimer_cb_mode { /** * struct hrtimer - the basic hrtimer structure * @node: red black tree node for time ordered insertion - * @expires: the absolute expiry time in the hrtimers internal + * @_expires: the absolute expiry time in the hrtimers internal * representation. The time is related to the clock on - * which the timer is based. + * which the timer is based. Is setup by adding + * slack to the _softexpires value. For non range timers + * identical to _softexpires. + * @_softexpires: the absolute earliest expiry time of the hrtimer. + * The time which was given as expiry time when the timer + * was armed. * @function: timer expiry callback function * @base: pointer to the timer base (per cpu and per clock) * @state: state information (See bit values above) -- cgit v1.2.3 From 62695a84eb8f2e718bf4dfb21700afaa7a08e0ea Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:26:09 -0700 Subject: vmscan: move isolate_lru_page() to vmscan.c On large memory systems, the VM can spend way too much time scanning through pages that it cannot (or should not) evict from memory. Not only does it use up CPU time, but it also provokes lock contention and can leave large systems under memory presure in a catatonic state. This patch series improves VM scalability by: 1) putting filesystem backed, swap backed and unevictable pages onto their own LRUs, so the system only scans the pages that it can/should evict from memory 2) switching to two handed clock replacement for the anonymous LRUs, so the number of pages that need to be scanned when the system starts swapping is bound to a reasonable number 3) keeping unevictable pages off the LRU completely, so the VM does not waste CPU time scanning them. ramfs, ramdisk, SHM_LOCKED shared memory segments and mlock()ed VMA pages are keept on the unevictable list. This patch: isolate_lru_page logically belongs to be in vmscan.c than migrate.c. It is tough, because we don't need that function without memory migration so there is a valid argument to have it in migrate.c. However a subsequent patch needs to make use of it in the core mm, so we can happily move it to vmscan.c. Also, make the function a little more generic by not requiring that it adds an isolated page to a given list. Callers can do that. Note that we now have '__isolate_lru_page()', that does something quite different, visible outside of vmscan.c for use with memory controller. Methinks we need to rationalize these names/purposes. --lts [akpm@linux-foundation.org: fix mm/memory_hotplug.c build] Signed-off-by: Nick Piggin Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/migrate.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 03aea612d28..3f34005068d 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -7,7 +7,6 @@ typedef struct page *new_page_t(struct page *, unsigned long private, int **); #ifdef CONFIG_MIGRATION -extern int isolate_lru_page(struct page *p, struct list_head *pagelist); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct address_space *, struct page *, struct page *); @@ -21,8 +20,6 @@ extern int migrate_vmas(struct mm_struct *mm, const nodemask_t *from, const nodemask_t *to, unsigned long flags); #else -static inline int isolate_lru_page(struct page *p, struct list_head *list) - { return -ENOSYS; } static inline int putback_lru_pages(struct list_head *l) { return 0; } static inline int migrate_pages(struct list_head *l, new_page_t x, unsigned long private) { return -ENOSYS; } -- cgit v1.2.3 From b69408e88bd86b98feb7b9a38fd865e1ddb29827 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sat, 18 Oct 2008 20:26:14 -0700 Subject: vmscan: Use an indexed array for LRU variables Currently we are defining explicit variables for the inactive and active list. An indexed array can be more generic and avoid repeating similar code in several places in the reclaim code. We are saving a few bytes in terms of code size: Before: text data bss dec hex filename 4097753 573120 4092484 8763357 85b7dd vmlinux After: text data bss dec hex filename 4097729 573120 4092484 8763333 85b7c5 vmlinux Having an easy way to add new lru lists may ease future work on the reclaim code. Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Signed-off-by: Christoph Lameter Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 17 +++++----------- include/linux/mm_inline.h | 49 +++++++++++++++++++++++++++++++++++----------- include/linux/mmzone.h | 26 ++++++++++++++++++------ 3 files changed, 63 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index fdf3967e139..a6ac0d491fe 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -69,10 +69,8 @@ extern void mem_cgroup_note_reclaim_priority(struct mem_cgroup *mem, extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, int priority); -extern long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem, - struct zone *zone, int priority); -extern long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, - struct zone *zone, int priority); +extern long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, struct zone *zone, + int priority, enum lru_list lru); #else /* CONFIG_CGROUP_MEM_RES_CTLR */ static inline void page_reset_bad_cgroup(struct page *page) @@ -159,14 +157,9 @@ static inline void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, { } -static inline long mem_cgroup_calc_reclaim_active(struct mem_cgroup *mem, - struct zone *zone, int priority) -{ - return 0; -} - -static inline long mem_cgroup_calc_reclaim_inactive(struct mem_cgroup *mem, - struct zone *zone, int priority) +static inline long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, + struct zone *zone, int priority, + enum lru_list lru) { return 0; } diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 895bc4e9303..2704729777e 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -1,40 +1,67 @@ +static inline void +add_page_to_lru_list(struct zone *zone, struct page *page, enum lru_list l) +{ + list_add(&page->lru, &zone->lru[l].list); + __inc_zone_state(zone, NR_LRU_BASE + l); +} + +static inline void +del_page_from_lru_list(struct zone *zone, struct page *page, enum lru_list l) +{ + list_del(&page->lru); + __dec_zone_state(zone, NR_LRU_BASE + l); +} + static inline void add_page_to_active_list(struct zone *zone, struct page *page) { - list_add(&page->lru, &zone->active_list); - __inc_zone_state(zone, NR_ACTIVE); + add_page_to_lru_list(zone, page, LRU_ACTIVE); } static inline void add_page_to_inactive_list(struct zone *zone, struct page *page) { - list_add(&page->lru, &zone->inactive_list); - __inc_zone_state(zone, NR_INACTIVE); + add_page_to_lru_list(zone, page, LRU_INACTIVE); } static inline void del_page_from_active_list(struct zone *zone, struct page *page) { - list_del(&page->lru); - __dec_zone_state(zone, NR_ACTIVE); + del_page_from_lru_list(zone, page, LRU_ACTIVE); } static inline void del_page_from_inactive_list(struct zone *zone, struct page *page) { - list_del(&page->lru); - __dec_zone_state(zone, NR_INACTIVE); + del_page_from_lru_list(zone, page, LRU_INACTIVE); } static inline void del_page_from_lru(struct zone *zone, struct page *page) { + enum lru_list l = LRU_INACTIVE; + list_del(&page->lru); if (PageActive(page)) { __ClearPageActive(page); - __dec_zone_state(zone, NR_ACTIVE); - } else { - __dec_zone_state(zone, NR_INACTIVE); + l = LRU_ACTIVE; } + __dec_zone_state(zone, NR_LRU_BASE + l); } +/** + * page_lru - which LRU list should a page be on? + * @page: the page to test + * + * Returns the LRU list a page should be on, as an index + * into the array of LRU lists. + */ +static inline enum lru_list page_lru(struct page *page) +{ + enum lru_list lru = LRU_BASE; + + if (PageActive(page)) + lru += LRU_ACTIVE; + + return lru; +} diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 428328a05fa..156e18f3919 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -81,8 +81,9 @@ struct zone_padding { enum zone_stat_item { /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, - NR_INACTIVE, - NR_ACTIVE, + NR_LRU_BASE, + NR_INACTIVE = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */ + NR_ACTIVE, /* " " " " " */ NR_ANON_PAGES, /* Mapped anonymous pages */ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. only modified from process context */ @@ -107,6 +108,19 @@ enum zone_stat_item { #endif NR_VM_ZONE_STAT_ITEMS }; +enum lru_list { + LRU_BASE, + LRU_INACTIVE=LRU_BASE, /* must match order of NR_[IN]ACTIVE */ + LRU_ACTIVE, /* " " " " " */ + NR_LRU_LISTS }; + +#define for_each_lru(l) for (l = 0; l < NR_LRU_LISTS; l++) + +static inline int is_active_lru(enum lru_list l) +{ + return (l == LRU_ACTIVE); +} + struct per_cpu_pages { int count; /* number of pages in the list */ int high; /* high watermark, emptying needed */ @@ -251,10 +265,10 @@ struct zone { /* Fields commonly accessed by the page reclaim scanner */ spinlock_t lru_lock; - struct list_head active_list; - struct list_head inactive_list; - unsigned long nr_scan_active; - unsigned long nr_scan_inactive; + struct { + struct list_head list; + unsigned long nr_scan; + } lru[NR_LRU_LISTS]; unsigned long pages_scanned; /* since last reclaim */ unsigned long flags; /* zone flags, see below */ -- cgit v1.2.3 From f04e9ebbe4909f9a41efd55149bc353299f4e83b Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Sat, 18 Oct 2008 20:26:19 -0700 Subject: swap: use an array for the LRU pagevecs Turn the pagevecs into an array just like the LRUs. This significantly cleans up the source code and reduces the size of the kernel by about 13kB after all the LRU lists have been created further down in the split VM patch series. Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagevec.h | 13 +++++++++++-- include/linux/swap.h | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 8eb7fa76c1d..6b8f11bcc94 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -23,8 +23,7 @@ struct pagevec { void __pagevec_release(struct pagevec *pvec); void __pagevec_release_nonlru(struct pagevec *pvec); void __pagevec_free(struct pagevec *pvec); -void __pagevec_lru_add(struct pagevec *pvec); -void __pagevec_lru_add_active(struct pagevec *pvec); +void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru); void pagevec_strip(struct pagevec *pvec); unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, pgoff_t start, unsigned nr_pages); @@ -81,6 +80,16 @@ static inline void pagevec_free(struct pagevec *pvec) __pagevec_free(pvec); } +static inline void __pagevec_lru_add(struct pagevec *pvec) +{ + ____pagevec_lru_add(pvec, LRU_INACTIVE); +} + +static inline void __pagevec_lru_add_active(struct pagevec *pvec) +{ + ____pagevec_lru_add(pvec, LRU_ACTIVE); +} + static inline void pagevec_lru_add(struct pagevec *pvec) { if (pagevec_count(pvec)) diff --git a/include/linux/swap.h b/include/linux/swap.h index de40f169a4e..fcc169610d0 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -171,8 +171,8 @@ extern unsigned int nr_free_pagecache_pages(void); /* linux/mm/swap.c */ -extern void lru_cache_add(struct page *); -extern void lru_cache_add_active(struct page *); +extern void __lru_cache_add(struct page *, enum lru_list lru); +extern void lru_cache_add_lru(struct page *, enum lru_list lru); extern void activate_page(struct page *); extern void mark_page_accessed(struct page *); extern void lru_add_drain(void); @@ -180,6 +180,20 @@ extern int lru_add_drain_all(void); extern void rotate_reclaimable_page(struct page *page); extern void swap_setup(void); +/** + * lru_cache_add: add a page to the page lists + * @page: the page to add + */ +static inline void lru_cache_add(struct page *page) +{ + __lru_cache_add(page, LRU_INACTIVE); +} + +static inline void lru_cache_add_active(struct page *page) +{ + __lru_cache_add(page, LRU_ACTIVE); +} + /* linux/mm/vmscan.c */ extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask); -- cgit v1.2.3 From 68a22394c286a2daf06ee8d65d8835f738faefa5 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sat, 18 Oct 2008 20:26:23 -0700 Subject: vmscan: free swap space on swap-in/activation If vm_swap_full() (swap space more than 50% full), the system will free swap space at swapin time. With this patch, the system will also free the swap space in the pageout code, when we decide that the page is not a candidate for swapout (and just wasting swap space). Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Signed-off-by: MinChan Kim Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagevec.h | 1 + include/linux/swap.h | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 6b8f11bcc94..fea3a982ee5 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -25,6 +25,7 @@ void __pagevec_release_nonlru(struct pagevec *pvec); void __pagevec_free(struct pagevec *pvec); void ____pagevec_lru_add(struct pagevec *pvec, enum lru_list lru); void pagevec_strip(struct pagevec *pvec); +void pagevec_swap_free(struct pagevec *pvec); unsigned pagevec_lookup(struct pagevec *pvec, struct address_space *mapping, pgoff_t start, unsigned nr_pages); unsigned pagevec_lookup_tag(struct pagevec *pvec, diff --git a/include/linux/swap.h b/include/linux/swap.h index fcc169610d0..833be56ad83 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -265,6 +265,7 @@ extern sector_t swapdev_block(int, pgoff_t); extern struct swap_info_struct *get_swap_info_struct(unsigned); extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); +extern int remove_exclusive_swap_page_ref(struct page *); struct backing_dev_info; /* linux/mm/thrash.c */ @@ -353,6 +354,11 @@ static inline int remove_exclusive_swap_page(struct page *p) return 0; } +static inline int remove_exclusive_swap_page_ref(struct page *page) +{ + return 0; +} + static inline swp_entry_t get_swap_page(void) { swp_entry_t entry; -- cgit v1.2.3 From b2e185384f534781fd22f5ce170b2ad26f97df70 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sat, 18 Oct 2008 20:26:30 -0700 Subject: define page_file_cache() function Define page_file_cache() function to answer the question: is page backed by a file? Originally part of Rik van Riel's split-lru patch. Extracted to make available for other, independent reclaim patches. Moved inline function to linux/mm_inline.h where it will be needed by subsequent "split LRU" and "noreclaim" patches. Unfortunately this needs to use a page flag, since the PG_swapbacked state needs to be preserved all the way to the point where the page is last removed from the LRU. Trying to derive the status from other info in the page resulted in wrong VM statistics in earlier split VM patchsets. The total number of page flags in use on a 32 bit machine after this patch is 19. [akpm@linux-foundation.org: fix up out-of-order merge fallout] [hugh@veritas.com: splitlru: shmem_getpage SetPageSwapBacked sooner[ Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Signed-off-by: MinChan Kim Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_inline.h | 27 +++++++++++++++++++++++++++ include/linux/page-flags.h | 8 ++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 2704729777e..96e970485b6 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -1,3 +1,28 @@ +#ifndef LINUX_MM_INLINE_H +#define LINUX_MM_INLINE_H + +/** + * page_is_file_cache - should the page be on a file LRU or anon LRU? + * @page: the page to test + * + * Returns !0 if @page is page cache page backed by a regular filesystem, + * or 0 if @page is anonymous, tmpfs or otherwise ram or swap backed. + * Used by functions that manipulate the LRU lists, to sort a page + * onto the right LRU list. + * + * We would like to get this info without a page flag, but the state + * needs to survive until the page is last deleted from the LRU, which + * could be as far down as __page_cache_release. + */ +static inline int page_is_file_cache(struct page *page) +{ + if (PageSwapBacked(page)) + return 0; + + /* The page is page cache backed by a normal filesystem. */ + return 1; +} + static inline void add_page_to_lru_list(struct zone *zone, struct page *page, enum lru_list l) { @@ -65,3 +90,5 @@ static inline enum lru_list page_lru(struct page *page) return lru; } + +#endif diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index c74d3e87531..57b688cfb5e 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -93,6 +93,7 @@ enum pageflags { PG_mappedtodisk, /* Has blocks allocated on-disk */ PG_reclaim, /* To be reclaimed asap */ PG_buddy, /* Page is free, on buddy lists */ + PG_swapbacked, /* Page is backed by RAM/swap */ #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR PG_uncached, /* Page has been mapped as uncached */ #endif @@ -176,6 +177,7 @@ PAGEFLAG(SavePinned, savepinned); /* Xen */ PAGEFLAG(Reserved, reserved) __CLEARPAGEFLAG(Reserved, reserved) PAGEFLAG(Private, private) __CLEARPAGEFLAG(Private, private) __SETPAGEFLAG(Private, private) +PAGEFLAG(SwapBacked, swapbacked) __CLEARPAGEFLAG(SwapBacked, swapbacked) __PAGEFLAG(SlobPage, slob_page) __PAGEFLAG(SlobFree, slob_free) @@ -334,7 +336,8 @@ static inline void __ClearPageTail(struct page *page) * Flags checked in bad_page(). Pages on the free list should not have * these flags set. It they are, there is a problem. */ -#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | 1 << PG_reclaim | 1 << PG_dirty) +#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | \ + 1 << PG_reclaim | 1 << PG_dirty | 1 << PG_swapbacked) /* * Flags checked when a page is freed. Pages being freed should not have @@ -347,7 +350,8 @@ static inline void __ClearPageTail(struct page *page) * Pages being prepped should not have these flags set. It they are, there * is a problem. */ -#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | 1 << PG_reserved | 1 << PG_dirty) +#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | \ + 1 << PG_reserved | 1 << PG_dirty | 1 << PG_swapbacked) #endif /* !__GENERATING_BOUNDS_H */ #endif /* PAGE_FLAGS_H */ -- cgit v1.2.3 From 4f98a2fee8acdb4ac84545df98cccecfd130f8db Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sat, 18 Oct 2008 20:26:32 -0700 Subject: vmscan: split LRU lists into anon & file sets Split the LRU lists in two, one set for pages that are backed by real file systems ("file") and one for pages that are backed by memory and swap ("anon"). The latter includes tmpfs. The advantage of doing this is that the VM will not have to scan over lots of anonymous pages (which we generally do not want to swap out), just to find the page cache pages that it should evict. This patch has the infrastructure and a basic policy to balance how much we scan the anon lists and how much we scan the file lists. The big policy changes are in separate patches. [lee.schermerhorn@hp.com: collect lru meminfo statistics from correct offset] [kosaki.motohiro@jp.fujitsu.com: prevent incorrect oom under split_lru] [kosaki.motohiro@jp.fujitsu.com: fix pagevec_move_tail() doesn't treat unevictable page] [hugh@veritas.com: memcg swapbacked pages active] [hugh@veritas.com: splitlru: BDI_CAP_SWAP_BACKED] [akpm@linux-foundation.org: fix /proc/vmstat units] [nishimura@mxp.nes.nec.co.jp: memcg: fix handling of shmem migration] [kosaki.motohiro@jp.fujitsu.com: adjust Quicklists field of /proc/meminfo] [kosaki.motohiro@jp.fujitsu.com: fix style issue of get_scan_ratio()] Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Signed-off-by: KOSAKI Motohiro Signed-off-by: Hugh Dickins Signed-off-by: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/backing-dev.h | 13 ++++++++++++ include/linux/memcontrol.h | 2 +- include/linux/mm_inline.h | 50 ++++++++++++++++++++++++++++++++++----------- include/linux/mmzone.h | 47 +++++++++++++++++++++++++++++++++++------- include/linux/pagevec.h | 29 ++++++++++++++++++++------ include/linux/swap.h | 20 +++++++++++++----- include/linux/vmstat.h | 10 +++++++++ 7 files changed, 140 insertions(+), 31 deletions(-) (limited to 'include/linux') diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 0a24d5550eb..bee52abb8a4 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -175,6 +175,8 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); * BDI_CAP_READ_MAP: Can be mapped for reading * BDI_CAP_WRITE_MAP: Can be mapped for writing * BDI_CAP_EXEC_MAP: Can be mapped for execution + * + * BDI_CAP_SWAP_BACKED: Count shmem/tmpfs objects as swap-backed. */ #define BDI_CAP_NO_ACCT_DIRTY 0x00000001 #define BDI_CAP_NO_WRITEBACK 0x00000002 @@ -184,6 +186,7 @@ int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio); #define BDI_CAP_WRITE_MAP 0x00000020 #define BDI_CAP_EXEC_MAP 0x00000040 #define BDI_CAP_NO_ACCT_WB 0x00000080 +#define BDI_CAP_SWAP_BACKED 0x00000100 #define BDI_CAP_VMFLAGS \ (BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP) @@ -248,6 +251,11 @@ static inline bool bdi_cap_account_writeback(struct backing_dev_info *bdi) BDI_CAP_NO_WRITEBACK)); } +static inline bool bdi_cap_swap_backed(struct backing_dev_info *bdi) +{ + return bdi->capabilities & BDI_CAP_SWAP_BACKED; +} + static inline bool mapping_cap_writeback_dirty(struct address_space *mapping) { return bdi_cap_writeback_dirty(mapping->backing_dev_info); @@ -258,4 +266,9 @@ static inline bool mapping_cap_account_dirty(struct address_space *mapping) return bdi_cap_account_dirty(mapping->backing_dev_info); } +static inline bool mapping_cap_swap_backed(struct address_space *mapping) +{ + return bdi_cap_swap_backed(mapping->backing_dev_info); +} + #endif /* _LINUX_BACKING_DEV_H */ diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index a6ac0d491fe..8d8f05c1515 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -44,7 +44,7 @@ extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, unsigned long *scanned, int order, int mode, struct zone *z, struct mem_cgroup *mem_cont, - int active); + int active, int file); extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 96e970485b6..2eb599465d5 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -5,7 +5,7 @@ * page_is_file_cache - should the page be on a file LRU or anon LRU? * @page: the page to test * - * Returns !0 if @page is page cache page backed by a regular filesystem, + * Returns LRU_FILE if @page is page cache page backed by a regular filesystem, * or 0 if @page is anonymous, tmpfs or otherwise ram or swap backed. * Used by functions that manipulate the LRU lists, to sort a page * onto the right LRU list. @@ -20,7 +20,7 @@ static inline int page_is_file_cache(struct page *page) return 0; /* The page is page cache backed by a normal filesystem. */ - return 1; + return LRU_FILE; } static inline void @@ -38,39 +38,64 @@ del_page_from_lru_list(struct zone *zone, struct page *page, enum lru_list l) } static inline void -add_page_to_active_list(struct zone *zone, struct page *page) +add_page_to_inactive_anon_list(struct zone *zone, struct page *page) { - add_page_to_lru_list(zone, page, LRU_ACTIVE); + add_page_to_lru_list(zone, page, LRU_INACTIVE_ANON); } static inline void -add_page_to_inactive_list(struct zone *zone, struct page *page) +add_page_to_active_anon_list(struct zone *zone, struct page *page) { - add_page_to_lru_list(zone, page, LRU_INACTIVE); + add_page_to_lru_list(zone, page, LRU_ACTIVE_ANON); } static inline void -del_page_from_active_list(struct zone *zone, struct page *page) +add_page_to_inactive_file_list(struct zone *zone, struct page *page) { - del_page_from_lru_list(zone, page, LRU_ACTIVE); + add_page_to_lru_list(zone, page, LRU_INACTIVE_FILE); } static inline void -del_page_from_inactive_list(struct zone *zone, struct page *page) +add_page_to_active_file_list(struct zone *zone, struct page *page) { - del_page_from_lru_list(zone, page, LRU_INACTIVE); + add_page_to_lru_list(zone, page, LRU_ACTIVE_FILE); +} + +static inline void +del_page_from_inactive_anon_list(struct zone *zone, struct page *page) +{ + del_page_from_lru_list(zone, page, LRU_INACTIVE_ANON); +} + +static inline void +del_page_from_active_anon_list(struct zone *zone, struct page *page) +{ + del_page_from_lru_list(zone, page, LRU_ACTIVE_ANON); +} + +static inline void +del_page_from_inactive_file_list(struct zone *zone, struct page *page) +{ + del_page_from_lru_list(zone, page, LRU_INACTIVE_FILE); +} + +static inline void +del_page_from_active_file_list(struct zone *zone, struct page *page) +{ + del_page_from_lru_list(zone, page, LRU_INACTIVE_FILE); } static inline void del_page_from_lru(struct zone *zone, struct page *page) { - enum lru_list l = LRU_INACTIVE; + enum lru_list l = LRU_BASE; list_del(&page->lru); if (PageActive(page)) { __ClearPageActive(page); - l = LRU_ACTIVE; + l += LRU_ACTIVE; } + l += page_is_file_cache(page); __dec_zone_state(zone, NR_LRU_BASE + l); } @@ -87,6 +112,7 @@ static inline enum lru_list page_lru(struct page *page) if (PageActive(page)) lru += LRU_ACTIVE; + lru += page_is_file_cache(page); return lru; } diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 156e18f3919..59a4c8fd6eb 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -82,21 +82,23 @@ enum zone_stat_item { /* First 128 byte cacheline (assuming 64 bit words) */ NR_FREE_PAGES, NR_LRU_BASE, - NR_INACTIVE = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */ - NR_ACTIVE, /* " " " " " */ + NR_INACTIVE_ANON = NR_LRU_BASE, /* must match order of LRU_[IN]ACTIVE */ + NR_ACTIVE_ANON, /* " " " " " */ + NR_INACTIVE_FILE, /* " " " " " */ + NR_ACTIVE_FILE, /* " " " " " */ NR_ANON_PAGES, /* Mapped anonymous pages */ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. only modified from process context */ NR_FILE_PAGES, NR_FILE_DIRTY, NR_WRITEBACK, - /* Second 128 byte cacheline */ NR_SLAB_RECLAIMABLE, NR_SLAB_UNRECLAIMABLE, NR_PAGETABLE, /* used for pagetables */ NR_UNSTABLE_NFS, /* NFS unstable pages */ NR_BOUNCE, NR_VMSCAN_WRITE, + /* Second 128 byte cacheline */ NR_WRITEBACK_TEMP, /* Writeback using temporary buffers */ #ifdef CONFIG_NUMA NUMA_HIT, /* allocated in intended node */ @@ -108,17 +110,36 @@ enum zone_stat_item { #endif NR_VM_ZONE_STAT_ITEMS }; +/* + * We do arithmetic on the LRU lists in various places in the code, + * so it is important to keep the active lists LRU_ACTIVE higher in + * the array than the corresponding inactive lists, and to keep + * the *_FILE lists LRU_FILE higher than the corresponding _ANON lists. + * + * This has to be kept in sync with the statistics in zone_stat_item + * above and the descriptions in vmstat_text in mm/vmstat.c + */ +#define LRU_BASE 0 +#define LRU_ACTIVE 1 +#define LRU_FILE 2 + enum lru_list { - LRU_BASE, - LRU_INACTIVE=LRU_BASE, /* must match order of NR_[IN]ACTIVE */ - LRU_ACTIVE, /* " " " " " */ + LRU_INACTIVE_ANON = LRU_BASE, + LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE, + LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE, + LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE, NR_LRU_LISTS }; #define for_each_lru(l) for (l = 0; l < NR_LRU_LISTS; l++) +static inline int is_file_lru(enum lru_list l) +{ + return (l == LRU_INACTIVE_FILE || l == LRU_ACTIVE_FILE); +} + static inline int is_active_lru(enum lru_list l) { - return (l == LRU_ACTIVE); + return (l == LRU_ACTIVE_ANON || l == LRU_ACTIVE_FILE); } struct per_cpu_pages { @@ -269,6 +290,18 @@ struct zone { struct list_head list; unsigned long nr_scan; } lru[NR_LRU_LISTS]; + + /* + * The pageout code in vmscan.c keeps track of how many of the + * mem/swap backed and file backed pages are refeferenced. + * The higher the rotated/scanned ratio, the more valuable + * that cache is. + * + * The anon LRU stats live in [0], file LRU stats in [1] + */ + unsigned long recent_rotated[2]; + unsigned long recent_scanned[2]; + unsigned long pages_scanned; /* since last reclaim */ unsigned long flags; /* zone flags, see below */ diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index fea3a982ee5..5fc96a4e760 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -81,20 +81,37 @@ static inline void pagevec_free(struct pagevec *pvec) __pagevec_free(pvec); } -static inline void __pagevec_lru_add(struct pagevec *pvec) +static inline void __pagevec_lru_add_anon(struct pagevec *pvec) { - ____pagevec_lru_add(pvec, LRU_INACTIVE); + ____pagevec_lru_add(pvec, LRU_INACTIVE_ANON); } -static inline void __pagevec_lru_add_active(struct pagevec *pvec) +static inline void __pagevec_lru_add_active_anon(struct pagevec *pvec) { - ____pagevec_lru_add(pvec, LRU_ACTIVE); + ____pagevec_lru_add(pvec, LRU_ACTIVE_ANON); } -static inline void pagevec_lru_add(struct pagevec *pvec) +static inline void __pagevec_lru_add_file(struct pagevec *pvec) +{ + ____pagevec_lru_add(pvec, LRU_INACTIVE_FILE); +} + +static inline void __pagevec_lru_add_active_file(struct pagevec *pvec) +{ + ____pagevec_lru_add(pvec, LRU_ACTIVE_FILE); +} + + +static inline void pagevec_lru_add_file(struct pagevec *pvec) +{ + if (pagevec_count(pvec)) + __pagevec_lru_add_file(pvec); +} + +static inline void pagevec_lru_add_anon(struct pagevec *pvec) { if (pagevec_count(pvec)) - __pagevec_lru_add(pvec); + __pagevec_lru_add_anon(pvec); } #endif /* _LINUX_PAGEVEC_H */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 833be56ad83..7d09d79997a 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -184,14 +184,24 @@ extern void swap_setup(void); * lru_cache_add: add a page to the page lists * @page: the page to add */ -static inline void lru_cache_add(struct page *page) +static inline void lru_cache_add_anon(struct page *page) { - __lru_cache_add(page, LRU_INACTIVE); + __lru_cache_add(page, LRU_INACTIVE_ANON); } -static inline void lru_cache_add_active(struct page *page) +static inline void lru_cache_add_active_anon(struct page *page) { - __lru_cache_add(page, LRU_ACTIVE); + __lru_cache_add(page, LRU_ACTIVE_ANON); +} + +static inline void lru_cache_add_file(struct page *page) +{ + __lru_cache_add(page, LRU_INACTIVE_FILE); +} + +static inline void lru_cache_add_active_file(struct page *page) +{ + __lru_cache_add(page, LRU_ACTIVE_FILE); } /* linux/mm/vmscan.c */ @@ -199,7 +209,7 @@ extern unsigned long try_to_free_pages(struct zonelist *zonelist, int order, gfp_t gfp_mask); extern unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *mem, gfp_t gfp_mask); -extern int __isolate_lru_page(struct page *page, int mode); +extern int __isolate_lru_page(struct page *page, int mode, int file); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 58334d43951..ff5179f2b15 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -159,6 +159,16 @@ static inline unsigned long zone_page_state(struct zone *zone, return x; } +extern unsigned long global_lru_pages(void); + +static inline unsigned long zone_lru_pages(struct zone *zone) +{ + return (zone_page_state(zone, NR_ACTIVE_ANON) + + zone_page_state(zone, NR_ACTIVE_FILE) + + zone_page_state(zone, NR_INACTIVE_ANON) + + zone_page_state(zone, NR_INACTIVE_FILE)); +} + #ifdef CONFIG_NUMA /* * Determine the per node value of a stat item. This function -- cgit v1.2.3 From 556adecba110bf5f1db6c6b56416cfab5bcab698 Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Sat, 18 Oct 2008 20:26:34 -0700 Subject: vmscan: second chance replacement for anonymous pages We avoid evicting and scanning anonymous pages for the most part, but under some workloads we can end up with most of memory filled with anonymous pages. At that point, we suddenly need to clear the referenced bits on all of memory, which can take ages on very large memory systems. We can reduce the maximum number of pages that need to be scanned by not taking the referenced state into account when deactivating an anonymous page. After all, every anonymous page starts out referenced, so why check? If an anonymous page gets referenced again before it reaches the end of the inactive list, we move it back to the active list. To keep the maximum amount of necessary work reasonable, we scale the active to inactive ratio with the size of memory, using the formula active:inactive ratio = sqrt(memory in GB * 10). Kswapd CPU use now seems to scale by the amount of pageout bandwidth, instead of by the amount of memory present in the system. [kamezawa.hiroyu@jp.fujitsu.com: fix OOM with memcg] [kamezawa.hiroyu@jp.fujitsu.com: memcg: lru scan fix] Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_inline.h | 19 +++++++++++++++++++ include/linux/mmzone.h | 6 ++++++ 2 files changed, 25 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 2eb599465d5..f451fedd1e7 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -117,4 +117,23 @@ static inline enum lru_list page_lru(struct page *page) return lru; } +/** + * inactive_anon_is_low - check if anonymous pages need to be deactivated + * @zone: zone to check + * + * Returns true if the zone does not have enough inactive anon pages, + * meaning some active anon pages need to be deactivated. + */ +static inline int inactive_anon_is_low(struct zone *zone) +{ + unsigned long active, inactive; + + active = zone_page_state(zone, NR_ACTIVE_ANON); + inactive = zone_page_state(zone, NR_INACTIVE_ANON); + + if (inactive * zone->inactive_ratio < active) + return 1; + + return 0; +} #endif diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 59a4c8fd6eb..9c5111f49a3 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -323,6 +323,12 @@ struct zone { */ int prev_priority; + /* + * The target ratio of ACTIVE_ANON to INACTIVE_ANON pages on + * this zone's LRU. Maintained by the pageout code. + */ + unsigned int inactive_ratio; + ZONE_PADDING(_pad2_) /* Rarely used or read-mostly fields */ -- cgit v1.2.3 From 8a7a8544a4f6554ec2d8048ac9f9672f442db5a2 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:37 -0700 Subject: pageflag helpers for configed-out flags Define proper false/noop inline functions for noreclaim page flags when !defined(CONFIG_UNEVICTABLE_LRU) Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page-flags.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include/linux') diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 57b688cfb5e..3d31616dcd2 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -162,6 +162,18 @@ static inline int Page##uname(struct page *page) \ #define TESTSCFLAG(uname, lname) \ TESTSETFLAG(uname, lname) TESTCLEARFLAG(uname, lname) +#define SETPAGEFLAG_NOOP(uname) \ +static inline void SetPage##uname(struct page *page) { } + +#define CLEARPAGEFLAG_NOOP(uname) \ +static inline void ClearPage##uname(struct page *page) { } + +#define __CLEARPAGEFLAG_NOOP(uname) \ +static inline void __ClearPage##uname(struct page *page) { } + +#define TESTCLEARFLAG_FALSE(uname) \ +static inline int TestClearPage##uname(struct page *page) { return 0; } + struct page; /* forward declaration */ TESTPAGEFLAG(Locked, locked) -- cgit v1.2.3 From 894bc310419ac95f4fa4142dc364401a7e607f65 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:39 -0700 Subject: Unevictable LRU Infrastructure When the system contains lots of mlocked or otherwise unevictable pages, the pageout code (kswapd) can spend lots of time scanning over these pages. Worse still, the presence of lots of unevictable pages can confuse kswapd into thinking that more aggressive pageout modes are required, resulting in all kinds of bad behaviour. Infrastructure to manage pages excluded from reclaim--i.e., hidden from vmscan. Based on a patch by Larry Woodman of Red Hat. Reworked to maintain "unevictable" pages on a separate per-zone LRU list, to "hide" them from vmscan. Kosaki Motohiro added the support for the memory controller unevictable lru list. Pages on the unevictable list have both PG_unevictable and PG_lru set. Thus, PG_unevictable is analogous to and mutually exclusive with PG_active--it specifies which LRU list the page is on. The unevictable infrastructure is enabled by a new mm Kconfig option [CONFIG_]UNEVICTABLE_LRU. A new function 'page_evictable(page, vma)' in vmscan.c tests whether or not a page may be evictable. Subsequent patches will add the various !evictable tests. We'll want to keep these tests light-weight for use in shrink_active_list() and, possibly, the fault path. To avoid races between tasks putting pages [back] onto an LRU list and tasks that might be moving the page from non-evictable to evictable state, the new function 'putback_lru_page()' -- inverse to 'isolate_lru_page()' -- tests the "evictability" of a page after placing it on the LRU, before dropping the reference. If the page has become unevictable, putback_lru_page() will redo the 'putback', thus moving the page to the unevictable list. This way, we avoid "stranding" evictable pages on the unevictable list. [akpm@linux-foundation.org: fix fallout from out-of-order merge] [riel@redhat.com: fix UNEVICTABLE_LRU and !PROC_PAGE_MONITOR build] [nishimura@mxp.nes.nec.co.jp: remove redundant mapping check] [kosaki.motohiro@jp.fujitsu.com: unevictable-lru-infrastructure: putback_lru_page()/unevictable page handling rework] [kosaki.motohiro@jp.fujitsu.com: kill unnecessary lock_page() in vmscan.c] [kosaki.motohiro@jp.fujitsu.com: revert migration change of unevictable lru infrastructure] [kosaki.motohiro@jp.fujitsu.com: revert to unevictable-lru-infrastructure-kconfig-fix.patch] [kosaki.motohiro@jp.fujitsu.com: restore patch failure of vmstat-unevictable-and-mlocked-pages-vm-events.patch] Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Debugged-by: Benjamin Kidwell Signed-off-by: Daisuke Nishimura Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 2 +- include/linux/mm_inline.h | 23 ++++++++++++++++------- include/linux/mmzone.h | 24 +++++++++++++++++++++++- include/linux/page-flags.h | 22 +++++++++++++++++++++- include/linux/pagevec.h | 1 - include/linux/swap.h | 12 ++++++++++++ 6 files changed, 73 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index 8d8f05c1515..ee1b2fcb441 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -34,9 +34,9 @@ extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); +extern void mem_cgroup_move_lists(struct page *page, enum lru_list lru); extern void mem_cgroup_uncharge_page(struct page *page); extern void mem_cgroup_uncharge_cache_page(struct page *page); -extern void mem_cgroup_move_lists(struct page *page, bool active); extern int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask); extern unsigned long mem_cgroup_isolate_pages(unsigned long nr_to_scan, diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index f451fedd1e7..67d7697fd01 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -91,11 +91,16 @@ del_page_from_lru(struct zone *zone, struct page *page) enum lru_list l = LRU_BASE; list_del(&page->lru); - if (PageActive(page)) { - __ClearPageActive(page); - l += LRU_ACTIVE; + if (PageUnevictable(page)) { + __ClearPageUnevictable(page); + l = LRU_UNEVICTABLE; + } else { + if (PageActive(page)) { + __ClearPageActive(page); + l += LRU_ACTIVE; + } + l += page_is_file_cache(page); } - l += page_is_file_cache(page); __dec_zone_state(zone, NR_LRU_BASE + l); } @@ -110,9 +115,13 @@ static inline enum lru_list page_lru(struct page *page) { enum lru_list lru = LRU_BASE; - if (PageActive(page)) - lru += LRU_ACTIVE; - lru += page_is_file_cache(page); + if (PageUnevictable(page)) + lru = LRU_UNEVICTABLE; + else { + if (PageActive(page)) + lru += LRU_ACTIVE; + lru += page_is_file_cache(page); + } return lru; } diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9c5111f49a3..d1f60d5fe2e 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -86,6 +86,11 @@ enum zone_stat_item { NR_ACTIVE_ANON, /* " " " " " */ NR_INACTIVE_FILE, /* " " " " " */ NR_ACTIVE_FILE, /* " " " " " */ +#ifdef CONFIG_UNEVICTABLE_LRU + NR_UNEVICTABLE, /* " " " " " */ +#else + NR_UNEVICTABLE = NR_ACTIVE_FILE, /* avoid compiler errors in dead code */ +#endif NR_ANON_PAGES, /* Mapped anonymous pages */ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. only modified from process context */ @@ -128,10 +133,18 @@ enum lru_list { LRU_ACTIVE_ANON = LRU_BASE + LRU_ACTIVE, LRU_INACTIVE_FILE = LRU_BASE + LRU_FILE, LRU_ACTIVE_FILE = LRU_BASE + LRU_FILE + LRU_ACTIVE, - NR_LRU_LISTS }; +#ifdef CONFIG_UNEVICTABLE_LRU + LRU_UNEVICTABLE, +#else + LRU_UNEVICTABLE = LRU_ACTIVE_FILE, /* avoid compiler errors in dead code */ +#endif + NR_LRU_LISTS +}; #define for_each_lru(l) for (l = 0; l < NR_LRU_LISTS; l++) +#define for_each_evictable_lru(l) for (l = 0; l <= LRU_ACTIVE_FILE; l++) + static inline int is_file_lru(enum lru_list l) { return (l == LRU_INACTIVE_FILE || l == LRU_ACTIVE_FILE); @@ -142,6 +155,15 @@ static inline int is_active_lru(enum lru_list l) return (l == LRU_ACTIVE_ANON || l == LRU_ACTIVE_FILE); } +static inline int is_unevictable_lru(enum lru_list l) +{ +#ifdef CONFIG_UNEVICTABLE_LRU + return (l == LRU_UNEVICTABLE); +#else + return 0; +#endif +} + struct per_cpu_pages { int count; /* number of pages in the list */ int high; /* high watermark, emptying needed */ diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index 3d31616dcd2..ec1a1baad34 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -94,6 +94,9 @@ enum pageflags { PG_reclaim, /* To be reclaimed asap */ PG_buddy, /* Page is free, on buddy lists */ PG_swapbacked, /* Page is backed by RAM/swap */ +#ifdef CONFIG_UNEVICTABLE_LRU + PG_unevictable, /* Page is "unevictable" */ +#endif #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR PG_uncached, /* Page has been mapped as uncached */ #endif @@ -182,6 +185,7 @@ PAGEFLAG(Referenced, referenced) TESTCLEARFLAG(Referenced, referenced) PAGEFLAG(Dirty, dirty) TESTSCFLAG(Dirty, dirty) __CLEARPAGEFLAG(Dirty, dirty) PAGEFLAG(LRU, lru) __CLEARPAGEFLAG(LRU, lru) PAGEFLAG(Active, active) __CLEARPAGEFLAG(Active, active) + TESTCLEARFLAG(Active, active) __PAGEFLAG(Slab, slab) PAGEFLAG(Checked, checked) /* Used by some filesystems */ PAGEFLAG(Pinned, pinned) TESTSCFLAG(Pinned, pinned) /* Xen */ @@ -225,6 +229,15 @@ PAGEFLAG(SwapCache, swapcache) PAGEFLAG_FALSE(SwapCache) #endif +#ifdef CONFIG_UNEVICTABLE_LRU +PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) + TESTCLEARFLAG(Unevictable, unevictable) +#else +PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable) + SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable) + __CLEARPAGEFLAG_NOOP(Unevictable) +#endif + #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR PAGEFLAG(Uncached, uncached) #else @@ -340,9 +353,16 @@ static inline void __ClearPageTail(struct page *page) #endif /* !PAGEFLAGS_EXTENDED */ +#ifdef CONFIG_UNEVICTABLE_LRU +#define __PG_UNEVICTABLE (1 << PG_unevictable) +#else +#define __PG_UNEVICTABLE 0 +#endif + #define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \ 1 << PG_buddy | 1 << PG_writeback | \ - 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active) + 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \ + __PG_UNEVICTABLE) /* * Flags checked in bad_page(). Pages on the free list should not have diff --git a/include/linux/pagevec.h b/include/linux/pagevec.h index 5fc96a4e760..e90a2cb0291 100644 --- a/include/linux/pagevec.h +++ b/include/linux/pagevec.h @@ -101,7 +101,6 @@ static inline void __pagevec_lru_add_active_file(struct pagevec *pvec) ____pagevec_lru_add(pvec, LRU_ACTIVE_FILE); } - static inline void pagevec_lru_add_file(struct pagevec *pvec) { if (pagevec_count(pvec)) diff --git a/include/linux/swap.h b/include/linux/swap.h index 7d09d79997a..a2113044d20 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -180,6 +180,8 @@ extern int lru_add_drain_all(void); extern void rotate_reclaimable_page(struct page *page); extern void swap_setup(void); +extern void add_page_to_unevictable_list(struct page *page); + /** * lru_cache_add: add a page to the page lists * @page: the page to add @@ -228,6 +230,16 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) } #endif +#ifdef CONFIG_UNEVICTABLE_LRU +extern int page_evictable(struct page *page, struct vm_area_struct *vma); +#else +static inline int page_evictable(struct page *page, + struct vm_area_struct *vma) +{ + return 1; +} +#endif + extern int kswapd_run(int nid); #ifdef CONFIG_MMU -- cgit v1.2.3 From bbfd28eee9fbd73e780b19beb3dc562befbb94fa Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:40 -0700 Subject: unevictable lru: add event counting with statistics Fix to unevictable-lru-page-statistics.patch Add unevictable lru infrastructure vm events to the statistics patch. Rename the "NORECL_" and "noreclaim_" symbols and text strings to "UNEVICTABLE_" and "unevictable_", respectively. Currently, both the infrastructure and the mlocked pages event are added by a single patch later in the series. This makes it difficult to add or rework the incremental patches. The events actually "belong" with the stats, so pull them up to here. Also, restore the event counting to putback_lru_page(). This was removed from previous patch in series where it was "misplaced". The actual events weren't defined that early. Signed-off-by: Lee Schermerhorn Cc: Rik van Riel Reviewed-by: KOSAKI Motohiro Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index ff5179f2b15..135840cd7fe 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -40,6 +40,11 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, PAGEOUTRUN, ALLOCSTALL, PGROTATED, #ifdef CONFIG_HUGETLB_PAGE HTLB_BUDDY_PGALLOC, HTLB_BUDDY_PGALLOC_FAIL, +#endif +#ifdef CONFIG_UNEVICTABLE_LRU + UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ + UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ + UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ #endif NR_VM_EVENT_ITEMS }; -- cgit v1.2.3 From ba9ddf49391645e6bb93219131a40446538a5e76 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:42 -0700 Subject: Ramfs and Ram Disk pages are unevictable Christoph Lameter pointed out that ram disk pages also clutter the LRU lists. When vmscan finds them dirty and tries to clean them, the ram disk writeback function just redirties the page so that it goes back onto the active list. Round and round she goes... With the ram disk driver [rd.c] replaced by the newer 'brd.c', this is no longer the case, as ram disk pages are no longer maintained on the lru. [This makes them unmigratable for defrag or memory hot remove, but that can be addressed by a separate patch series.] However, the ramfs pages behave like ram disk pages used to, so: Define new address_space flag [shares address_space flags member with mapping's gfp mask] to indicate that the address space contains all unevictable pages. This will provide for efficient testing of ramfs pages in page_evictable(). Also provide wrapper functions to set/test the unevictable state to minimize #ifdefs in ramfs driver and any other users of this facility. Set the unevictable state on address_space structures for new ramfs inodes. Test the unevictable state in page_evictable() to cull unevictable pages. These changes depend on [CONFIG_]UNEVICTABLE_LRU. [riel@redhat.com: undo the brd.c part] Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Debugged-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 5da31c12101..09164d2c5c2 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -32,6 +32,28 @@ static inline void mapping_set_error(struct address_space *mapping, int error) } } +#ifdef CONFIG_UNEVICTABLE_LRU +#define AS_UNEVICTABLE (__GFP_BITS_SHIFT + 2) /* e.g., ramdisk, SHM_LOCK */ + +static inline void mapping_set_unevictable(struct address_space *mapping) +{ + set_bit(AS_UNEVICTABLE, &mapping->flags); +} + +static inline int mapping_unevictable(struct address_space *mapping) +{ + if (mapping && (mapping->flags & AS_UNEVICTABLE)) + return 1; + return 0; +} +#else +static inline void mapping_set_unevictable(struct address_space *mapping) { } +static inline int mapping_unevictable(struct address_space *mapping) +{ + return 0; +} +#endif + static inline gfp_t mapping_gfp_mask(struct address_space * mapping) { return (__force gfp_t)mapping->flags & __GFP_BITS_MASK; -- cgit v1.2.3 From 89e004ea55abe201b29e2d6e35124101f1288ef7 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:43 -0700 Subject: SHM_LOCKED pages are unevictable Shmem segments locked into memory via shmctl(SHM_LOCKED) should not be kept on the normal LRU, since scanning them is a waste of time and might throw off kswapd's balancing algorithms. Place them on the unevictable LRU list instead. Use the AS_UNEVICTABLE flag to mark address_space of SHM_LOCKed shared memory regions as unevictable. Then these pages will be culled off the normal LRU lists during vmscan. Add new wrapper function to clear the mapping's unevictable state when/if shared memory segment is munlocked. Add 'scan_mapping_unevictable_page()' to mm/vmscan.c to scan all pages in the shmem segment's mapping [struct address_space] for evictability now that they're no longer locked. If so, move them to the appropriate zone lru list. Changes depend on [CONFIG_]UNEVICTABLE_LRU. [kosaki.motohiro@jp.fujitsu.com: revert shm change] Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: Kosaki Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 4 ++-- include/linux/pagemap.h | 12 +++++++++--- include/linux/swap.h | 4 ++++ 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index c61ba10768e..40236290e2a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -700,10 +700,10 @@ static inline int page_mapped(struct page *page) extern void show_free_areas(void); #ifdef CONFIG_SHMEM -int shmem_lock(struct file *file, int lock, struct user_struct *user); +extern int shmem_lock(struct file *file, int lock, struct user_struct *user); #else static inline int shmem_lock(struct file *file, int lock, - struct user_struct *user) + struct user_struct *user) { return 0; } diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 09164d2c5c2..4b6c4d8d26b 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -40,14 +40,20 @@ static inline void mapping_set_unevictable(struct address_space *mapping) set_bit(AS_UNEVICTABLE, &mapping->flags); } +static inline void mapping_clear_unevictable(struct address_space *mapping) +{ + clear_bit(AS_UNEVICTABLE, &mapping->flags); +} + static inline int mapping_unevictable(struct address_space *mapping) { - if (mapping && (mapping->flags & AS_UNEVICTABLE)) - return 1; - return 0; + if (likely(mapping)) + return test_bit(AS_UNEVICTABLE, &mapping->flags); + return !!mapping; } #else static inline void mapping_set_unevictable(struct address_space *mapping) { } +static inline void mapping_clear_unevictable(struct address_space *mapping) { } static inline int mapping_unevictable(struct address_space *mapping) { return 0; diff --git a/include/linux/swap.h b/include/linux/swap.h index a2113044d20..7edb4cbc29f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -232,12 +232,16 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) #ifdef CONFIG_UNEVICTABLE_LRU extern int page_evictable(struct page *page, struct vm_area_struct *vma); +extern void scan_mapping_unevictable_pages(struct address_space *); #else static inline int page_evictable(struct page *page, struct vm_area_struct *vma) { return 1; } +static inline void scan_mapping_unevictable_pages(struct address_space *mapping) +{ +} #endif extern int kswapd_run(int nid); -- cgit v1.2.3 From b291f000393f5a0b679012b39d79fbc85c018233 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:26:44 -0700 Subject: mlock: mlocked pages are unevictable Make sure that mlocked pages also live on the unevictable LRU, so kswapd will not scan them over and over again. This is achieved through various strategies: 1) add yet another page flag--PG_mlocked--to indicate that the page is locked for efficient testing in vmscan and, optionally, fault path. This allows early culling of unevictable pages, preventing them from getting to page_referenced()/try_to_unmap(). Also allows separate accounting of mlock'd pages, as Nick's original patch did. Note: Nick's original mlock patch used a PG_mlocked flag. I had removed this in favor of the PG_unevictable flag + an mlock_count [new page struct member]. I restored the PG_mlocked flag to eliminate the new count field. 2) add the mlock/unevictable infrastructure to mm/mlock.c, with internal APIs in mm/internal.h. This is a rework of Nick's original patch to these files, taking into account that mlocked pages are now kept on unevictable LRU list. 3) update vmscan.c:page_evictable() to check PageMlocked() and, if vma passed in, the vm_flags. Note that the vma will only be passed in for new pages in the fault path; and then only if the "cull unevictable pages in fault path" patch is included. 4) add try_to_unlock() to rmap.c to walk a page's rmap and ClearPageMlocked() if no other vmas have it mlocked. Reuses as much of try_to_unmap() as possible. This effectively replaces the use of one of the lru list links as an mlock count. If this mechanism let's pages in mlocked vmas leak through w/o PG_mlocked set [I don't know that it does], we should catch them later in try_to_unmap(). One hopes this will be rare, as it will be relatively expensive. Original mm/internal.h, mm/rmap.c and mm/mlock.c changes: Signed-off-by: Nick Piggin splitlru: introduce __get_user_pages(): New munlock processing need to GUP_FLAGS_IGNORE_VMA_PERMISSIONS. because current get_user_pages() can't grab PROT_NONE pages theresore it cause PROT_NONE pages can't munlock. [akpm@linux-foundation.org: fix this for pagemap-pass-mm-into-pagewalkers.patch] [akpm@linux-foundation.org: untangle patch interdependencies] [akpm@linux-foundation.org: fix things after out-of-order merging] [hugh@veritas.com: fix page-flags mess] [lee.schermerhorn@hp.com: fix munlock page table walk - now requires 'mm'] [kosaki.motohiro@jp.fujitsu.com: build fix] [kosaki.motohiro@jp.fujitsu.com: fix truncate race and sevaral comments] [kosaki.motohiro@jp.fujitsu.com: splitlru: introduce __get_user_pages()] Signed-off-by: KOSAKI Motohiro Signed-off-by: Rik van Riel Signed-off-by: Lee Schermerhorn Cc: Nick Piggin Cc: Dave Hansen Cc: Matt Mackall Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 5 +++++ include/linux/page-flags.h | 19 ++++++++++++++++--- include/linux/rmap.h | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 40236290e2a..ffee2f74341 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -131,6 +131,11 @@ extern unsigned int kobjsize(const void *objp); #define VM_SequentialReadHint(v) ((v)->vm_flags & VM_SEQ_READ) #define VM_RandomReadHint(v) ((v)->vm_flags & VM_RAND_READ) +/* + * special vmas that are non-mergable, non-mlock()able + */ +#define VM_SPECIAL (VM_IO | VM_DONTEXPAND | VM_RESERVED | VM_PFNMAP) + /* * mapping from the currently active vm_flags protection bits (the * low four bits) to a page protection mask.. diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index ec1a1baad34..b12f93a3c34 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -96,6 +96,7 @@ enum pageflags { PG_swapbacked, /* Page is backed by RAM/swap */ #ifdef CONFIG_UNEVICTABLE_LRU PG_unevictable, /* Page is "unevictable" */ + PG_mlocked, /* Page is vma mlocked */ #endif #ifdef CONFIG_IA64_UNCACHED_ALLOCATOR PG_uncached, /* Page has been mapped as uncached */ @@ -232,7 +233,17 @@ PAGEFLAG_FALSE(SwapCache) #ifdef CONFIG_UNEVICTABLE_LRU PAGEFLAG(Unevictable, unevictable) __CLEARPAGEFLAG(Unevictable, unevictable) TESTCLEARFLAG(Unevictable, unevictable) + +#define MLOCK_PAGES 1 +PAGEFLAG(Mlocked, mlocked) __CLEARPAGEFLAG(Mlocked, mlocked) + TESTSCFLAG(Mlocked, mlocked) + #else + +#define MLOCK_PAGES 0 +PAGEFLAG_FALSE(Mlocked) + SETPAGEFLAG_NOOP(Mlocked) TESTCLEARFLAG_FALSE(Mlocked) + PAGEFLAG_FALSE(Unevictable) TESTCLEARFLAG_FALSE(Unevictable) SETPAGEFLAG_NOOP(Unevictable) CLEARPAGEFLAG_NOOP(Unevictable) __CLEARPAGEFLAG_NOOP(Unevictable) @@ -354,15 +365,17 @@ static inline void __ClearPageTail(struct page *page) #endif /* !PAGEFLAGS_EXTENDED */ #ifdef CONFIG_UNEVICTABLE_LRU -#define __PG_UNEVICTABLE (1 << PG_unevictable) +#define __PG_UNEVICTABLE (1 << PG_unevictable) +#define __PG_MLOCKED (1 << PG_mlocked) #else -#define __PG_UNEVICTABLE 0 +#define __PG_UNEVICTABLE 0 +#define __PG_MLOCKED 0 #endif #define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \ 1 << PG_buddy | 1 << PG_writeback | \ 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active | \ - __PG_UNEVICTABLE) + __PG_UNEVICTABLE | __PG_MLOCKED) /* * Flags checked in bad_page(). Pages on the free list should not have diff --git a/include/linux/rmap.h b/include/linux/rmap.h index fed6f5e0b41..955667e6a52 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -117,6 +117,19 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); */ int page_mkclean(struct page *); +#ifdef CONFIG_UNEVICTABLE_LRU +/* + * called in munlock()/munmap() path to check for other vmas holding + * the page mlocked. + */ +int try_to_munlock(struct page *); +#else +static inline int try_to_munlock(struct page *page) +{ + return 0; /* a.k.a. SWAP_SUCCESS */ +} +#endif + #else /* !CONFIG_MMU */ #define anon_vma_init() do {} while (0) @@ -140,5 +153,6 @@ static inline int page_mkclean(struct page *page) #define SWAP_SUCCESS 0 #define SWAP_AGAIN 1 #define SWAP_FAIL 2 +#define SWAP_MLOCK 3 #endif /* _LINUX_RMAP_H */ -- cgit v1.2.3 From 5344b7e648980cc2ca613ec03a56a8222ff48820 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:26:51 -0700 Subject: vmstat: mlocked pages statistics Add NR_MLOCK zone page state, which provides a (conservative) count of mlocked pages (actually, the number of mlocked pages moved off the LRU). Reworked by lts to fit in with the modified mlock page support in the Reclaim Scalability series. [kosaki.motohiro@jp.fujitsu.com: fix incorrect Mlocked field of /proc/meminfo] [lee.schermerhorn@hp.com: mlocked-pages: add event counting with statistics] Signed-off-by: Nick Piggin Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 2 ++ include/linux/vmstat.h | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index d1f60d5fe2e..da2d053a95f 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -88,8 +88,10 @@ enum zone_stat_item { NR_ACTIVE_FILE, /* " " " " " */ #ifdef CONFIG_UNEVICTABLE_LRU NR_UNEVICTABLE, /* " " " " " */ + NR_MLOCK, /* mlock()ed pages found and moved off LRU */ #else NR_UNEVICTABLE = NR_ACTIVE_FILE, /* avoid compiler errors in dead code */ + NR_MLOCK = NR_ACTIVE_FILE, #endif NR_ANON_PAGES, /* Mapped anonymous pages */ NR_FILE_MAPPED, /* pagecache pages mapped into pagetables. diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 135840cd7fe..05b805020be 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -45,6 +45,10 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, UNEVICTABLE_PGCULLED, /* culled to noreclaim list */ UNEVICTABLE_PGSCANNED, /* scanned for reclaimability */ UNEVICTABLE_PGRESCUED, /* rescued from noreclaim list */ + UNEVICTABLE_PGMLOCKED, + UNEVICTABLE_PGMUNLOCKED, + UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ + UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ #endif NR_VM_EVENT_ITEMS }; -- cgit v1.2.3 From 64d6519dda3905dfb94d3f93c07c5f263f41813f Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:52 -0700 Subject: swap: cull unevictable pages in fault path In the fault paths that install new anonymous pages, check whether the page is evictable or not using lru_cache_add_active_or_unevictable(). If the page is evictable, just add it to the active lru list [via the pagevec cache], else add it to the unevictable list. This "proactive" culling in the fault path mimics the handling of mlocked pages in Nick Piggin's series to keep mlocked pages off the lru lists. Notes: 1) This patch is optional--e.g., if one is concerned about the additional test in the fault path. We can defer the moving of nonreclaimable pages until when vmscan [shrink_*_list()] encounters them. Vmscan will only need to handle such pages once, but if there are a lot of them it could impact system performance. 2) The 'vma' argument to page_evictable() is require to notice that we're faulting a page into an mlock()ed vma w/o having to scan the page's rmap in the fault path. Culling mlock()ed anon pages is currently the only reason for this patch. 3) We can't cull swap pages in read_swap_cache_async() because the vma argument doesn't necessarily correspond to the swap cache offset passed in by swapin_readahead(). This could [did!] result in mlocking pages in non-VM_LOCKED vmas if [when] we tried to cull in this path. 4) Move set_pte_at() to after where we add page to lru to keep it hidden from other tasks that might walk the page table. We already do it in this order in do_anonymous() page. And, these are COW'd anon pages. Is this safe? [riel@redhat.com: undo an overzealous code cleanup] Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index 7edb4cbc29f..07eda69412f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -173,6 +173,8 @@ extern unsigned int nr_free_pagecache_pages(void); /* linux/mm/swap.c */ extern void __lru_cache_add(struct page *, enum lru_list lru); extern void lru_cache_add_lru(struct page *, enum lru_list lru); +extern void lru_cache_add_active_or_unevictable(struct page *, + struct vm_area_struct *); extern void activate_page(struct page *); extern void mark_page_accessed(struct page *); extern void lru_add_drain(void); -- cgit v1.2.3 From af936a1606246a10c145feac3770f6287f483f02 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:53 -0700 Subject: vmscan: unevictable LRU scan sysctl This patch adds a function to scan individual or all zones' unevictable lists and move any pages that have become evictable onto the respective zone's inactive list, where shrink_inactive_list() will deal with them. Adds sysctl to scan all nodes, and per node attributes to individual nodes' zones. Kosaki: If evictable page found in unevictable lru when write /proc/sys/vm/scan_unevictable_pages, print filename and file offset of these pages. [akpm@linux-foundation.org: fix one CONFIG_MMU=n build error] [kosaki.motohiro@jp.fujitsu.com: adapt vmscan-unevictable-lru-scan-sysctl.patch to new sysfs API] Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: KOSAKI Motohiro Signed-off-by: KOSAKI Motohiro Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rmap.h | 3 +++ include/linux/swap.h | 15 +++++++++++++++ 2 files changed, 18 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 955667e6a52..1da48db8db0 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -75,6 +75,9 @@ void anon_vma_unlink(struct vm_area_struct *); void anon_vma_link(struct vm_area_struct *); void __anon_vma_link(struct vm_area_struct *); +extern struct anon_vma *page_lock_anon_vma(struct page *page); +extern void page_unlock_anon_vma(struct anon_vma *anon_vma); + /* * rmap interfaces called when adding or removing pte of page */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 07eda69412f..a3af95b2cb6 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -235,15 +236,29 @@ static inline int zone_reclaim(struct zone *z, gfp_t mask, unsigned int order) #ifdef CONFIG_UNEVICTABLE_LRU extern int page_evictable(struct page *page, struct vm_area_struct *vma); extern void scan_mapping_unevictable_pages(struct address_space *); + +extern unsigned long scan_unevictable_pages; +extern int scan_unevictable_handler(struct ctl_table *, int, struct file *, + void __user *, size_t *, loff_t *); +extern int scan_unevictable_register_node(struct node *node); +extern void scan_unevictable_unregister_node(struct node *node); #else static inline int page_evictable(struct page *page, struct vm_area_struct *vma) { return 1; } + static inline void scan_mapping_unevictable_pages(struct address_space *mapping) { } + +static inline int scan_unevictable_register_node(struct node *node) +{ + return 0; +} + +static inline void scan_unevictable_unregister_node(struct node *node) { } #endif extern int kswapd_run(int nid); -- cgit v1.2.3 From 985737cf2ea096ea946aed82c7484d40defc71a8 Mon Sep 17 00:00:00 2001 From: Lee Schermerhorn Date: Sat, 18 Oct 2008 20:26:53 -0700 Subject: mlock: count attempts to free mlocked page Allow free of mlock()ed pages. This shouldn't happen, but during developement, it occasionally did. This patch allows us to survive that condition, while keeping the statistics and events correct for debug. Signed-off-by: Lee Schermerhorn Signed-off-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmstat.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 05b805020be..9cd3ab0f554 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -49,6 +49,7 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, UNEVICTABLE_PGMUNLOCKED, UNEVICTABLE_PGCLEARED, /* on COW, page truncate */ UNEVICTABLE_PGSTRANDED, /* unable to isolate on unlock */ + UNEVICTABLE_MLOCKFREED, #endif NR_VM_EVENT_ITEMS }; -- cgit v1.2.3 From 902d2e8ae0de29f483840ba1134af27343b9564d Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Sat, 18 Oct 2008 20:26:54 -0700 Subject: vmscan: kill unused lru functions Several LRU manupuration function are not used now. So they can be removed. Signed-off-by: KOSAKI Motohiro Acked-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm_inline.h | 48 ----------------------------------------------- 1 file changed, 48 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index 67d7697fd01..c948350c378 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -37,54 +37,6 @@ del_page_from_lru_list(struct zone *zone, struct page *page, enum lru_list l) __dec_zone_state(zone, NR_LRU_BASE + l); } -static inline void -add_page_to_inactive_anon_list(struct zone *zone, struct page *page) -{ - add_page_to_lru_list(zone, page, LRU_INACTIVE_ANON); -} - -static inline void -add_page_to_active_anon_list(struct zone *zone, struct page *page) -{ - add_page_to_lru_list(zone, page, LRU_ACTIVE_ANON); -} - -static inline void -add_page_to_inactive_file_list(struct zone *zone, struct page *page) -{ - add_page_to_lru_list(zone, page, LRU_INACTIVE_FILE); -} - -static inline void -add_page_to_active_file_list(struct zone *zone, struct page *page) -{ - add_page_to_lru_list(zone, page, LRU_ACTIVE_FILE); -} - -static inline void -del_page_from_inactive_anon_list(struct zone *zone, struct page *page) -{ - del_page_from_lru_list(zone, page, LRU_INACTIVE_ANON); -} - -static inline void -del_page_from_active_anon_list(struct zone *zone, struct page *page) -{ - del_page_from_lru_list(zone, page, LRU_ACTIVE_ANON); -} - -static inline void -del_page_from_inactive_file_list(struct zone *zone, struct page *page) -{ - del_page_from_lru_list(zone, page, LRU_INACTIVE_FILE); -} - -static inline void -del_page_from_active_file_list(struct zone *zone, struct page *page) -{ - del_page_from_lru_list(zone, page, LRU_INACTIVE_FILE); -} - static inline void del_page_from_lru(struct zone *zone, struct page *page) { -- cgit v1.2.3 From f45840b5c128445da70e7ec33adc47b4a12bdaf4 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:26:57 -0700 Subject: mm: pagecache insertion fewer atomics Setting and clearing the page locked when inserting it into swapcache / pagecache when it has no other references can use non-atomic page flags operations because no other CPU may be operating on it at this time. This saves one atomic operation when inserting a page into pagecache. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 4b6c4d8d26b..7334b2b6c4c 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -299,14 +299,14 @@ extern int __lock_page_killable(struct page *page); extern void __lock_page_nosync(struct page *page); extern void unlock_page(struct page *page); -static inline void set_page_locked(struct page *page) +static inline void __set_page_locked(struct page *page) { - set_bit(PG_locked, &page->flags); + __set_bit(PG_locked, &page->flags); } -static inline void clear_page_locked(struct page *page) +static inline void __clear_page_locked(struct page *page) { - clear_bit(PG_locked, &page->flags); + __clear_bit(PG_locked, &page->flags); } static inline int trylock_page(struct page *page) @@ -438,17 +438,17 @@ extern void __remove_from_page_cache(struct page *page); /* * Like add_to_page_cache_locked, but used to add newly allocated pages: - * the page is new, so we can just run set_page_locked() against it. + * the page is new, so we can just run __set_page_locked() against it. */ static inline int add_to_page_cache(struct page *page, struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask) { int error; - set_page_locked(page); + __set_page_locked(page); error = add_to_page_cache_locked(page, mapping, offset, gfp_mask); if (unlikely(error)) - clear_page_locked(page); + __clear_page_locked(page); return error; } -- cgit v1.2.3 From 8413ac9d8c9a1366a4f57880723126cd24e5a5c3 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:26:59 -0700 Subject: mm: page lock use lock bitops trylock_page, unlock_page open and close a critical section. Hence, we can use the lock bitops to get the desired memory ordering. Also, mark trylock as likely to succeed (and remove the annotation from callers). Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 7334b2b6c4c..709742be02f 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -311,7 +311,7 @@ static inline void __clear_page_locked(struct page *page) static inline int trylock_page(struct page *page) { - return !test_and_set_bit(PG_locked, &page->flags); + return (likely(!test_and_set_bit_lock(PG_locked, &page->flags))); } /* -- cgit v1.2.3 From 51b07fc3c5c830bb49c80fc5eac041e1f66a72e7 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:27:00 -0700 Subject: fs: buffer lock use lock bitops trylock_buffer and unlock_buffer open and close a critical section. Hence, we can use the lock bitops to get the desired memory ordering. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/buffer_head.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index eadaab44015..3ce64b90118 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -322,7 +322,7 @@ static inline void wait_on_buffer(struct buffer_head *bh) static inline int trylock_buffer(struct buffer_head *bh) { - return likely(!test_and_set_bit(BH_Lock, &bh->b_state)); + return likely(!test_and_set_bit_lock(BH_Lock, &bh->b_state)); } static inline void lock_buffer(struct buffer_head *bh) -- cgit v1.2.3 From db64fe02258f1507e13fe5212a989922323685ce Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Sat, 18 Oct 2008 20:27:03 -0700 Subject: mm: rewrite vmap layer Rewrite the vmap allocator to use rbtrees and lazy tlb flushing, and provide a fast, scalable percpu frontend for small vmaps (requires a slightly different API, though). The biggest problem with vmap is actually vunmap. Presently this requires a global kernel TLB flush, which on most architectures is a broadcast IPI to all CPUs to flush the cache. This is all done under a global lock. As the number of CPUs increases, so will the number of vunmaps a scaled workload will want to perform, and so will the cost of a global TLB flush. This gives terrible quadratic scalability characteristics. Another problem is that the entire vmap subsystem works under a single lock. It is a rwlock, but it is actually taken for write in all the fast paths, and the read locking would likely never be run concurrently anyway, so it's just pointless. This is a rewrite of vmap subsystem to solve those problems. The existing vmalloc API is implemented on top of the rewritten subsystem. The TLB flushing problem is solved by using lazy TLB unmapping. vmap addresses do not have to be flushed immediately when they are vunmapped, because the kernel will not reuse them again (would be a use-after-free) until they are reallocated. So the addresses aren't allocated again until a subsequent TLB flush. A single TLB flush then can flush multiple vunmaps from each CPU. XEN and PAT and such do not like deferred TLB flushing because they can't always handle multiple aliasing virtual addresses to a physical address. They now call vm_unmap_aliases() in order to flush any deferred mappings. That call is very expensive (well, actually not a lot more expensive than a single vunmap under the old scheme), however it should be OK if not called too often. The virtual memory extent information is stored in an rbtree rather than a linked list to improve the algorithmic scalability. There is a per-CPU allocator for small vmaps, which amortizes or avoids global locking. To use the per-CPU interface, the vm_map_ram / vm_unmap_ram interfaces must be used in place of vmap and vunmap. Vmalloc does not use these interfaces at the moment, so it will not be quite so scalable (although it will use lazy TLB flushing). As a quick test of performance, I ran a test that loops in the kernel, linearly mapping then touching then unmapping 4 pages. Different numbers of tests were run in parallel on an 4 core, 2 socket opteron. Results are in nanoseconds per map+touch+unmap. threads vanilla vmap rewrite 1 14700 2900 2 33600 3000 4 49500 2800 8 70631 2900 So with a 8 cores, the rewritten version is already 25x faster. In a slightly more realistic test (although with an older and less scalable version of the patch), I ripped the not-very-good vunmap batching code out of XFS, and implemented the large buffer mapping with vm_map_ram and vm_unmap_ram... along with a couple of other tricks, I was able to speed up a large directory workload by 20x on a 64 CPU system. I believe vmap/vunmap is actually sped up a lot more than 20x on such a system, but I'm running into other locks now. vmap is pretty well blown off the profiles. Before: 1352059 total 0.1401 798784 _write_lock 8320.6667 <- vmlist_lock 529313 default_idle 1181.5022 15242 smp_call_function 15.8771 <- vmap tlb flushing 2472 __get_vm_area_node 1.9312 <- vmap 1762 remove_vm_area 4.5885 <- vunmap 316 map_vm_area 0.2297 <- vmap 312 kfree 0.1950 300 _spin_lock 3.1250 252 sn_send_IPI_phys 0.4375 <- tlb flushing 238 vmap 0.8264 <- vmap 216 find_lock_page 0.5192 196 find_next_bit 0.3603 136 sn2_send_IPI 0.2024 130 pio_phys_write_mmr 2.0312 118 unmap_kernel_range 0.1229 After: 78406 total 0.0081 40053 default_idle 89.4040 33576 ia64_spinlock_contention 349.7500 1650 _spin_lock 17.1875 319 __reg_op 0.5538 281 _atomic_dec_and_lock 1.0977 153 mutex_unlock 1.5938 123 iget_locked 0.1671 117 xfs_dir_lookup 0.1662 117 dput 0.1406 114 xfs_iget_core 0.0268 92 xfs_da_hashname 0.1917 75 d_alloc 0.0670 68 vmap_page_range 0.0462 <- vmap 58 kmem_cache_alloc 0.0604 57 memset 0.0540 52 rb_next 0.1625 50 __copy_user 0.0208 49 bitmap_find_free_region 0.2188 <- vmap 46 ia64_sn_udelay 0.1106 45 find_inode_fast 0.1406 42 memcmp 0.2188 42 finish_task_switch 0.1094 42 __d_lookup 0.0410 40 radix_tree_lookup_slot 0.1250 37 _spin_unlock_irqrestore 0.3854 36 xfs_bmapi 0.0050 36 kmem_cache_free 0.0256 35 xfs_vn_getattr 0.0322 34 radix_tree_lookup 0.1062 33 __link_path_walk 0.0035 31 xfs_da_do_buf 0.0091 30 _xfs_buf_find 0.0204 28 find_get_page 0.0875 27 xfs_iread 0.0241 27 __strncpy_from_user 0.2812 26 _xfs_buf_initialize 0.0406 24 _xfs_buf_lookup_pages 0.0179 24 vunmap_page_range 0.0250 <- vunmap 23 find_lock_page 0.0799 22 vm_map_ram 0.0087 <- vmap 20 kfree 0.0125 19 put_page 0.0330 18 __kmalloc 0.0176 17 xfs_da_node_lookup_int 0.0086 17 _read_lock 0.0885 17 page_waitqueue 0.0664 vmap has gone from being the top 5 on the profiles and flushing the crap out of all TLBs, to using less than 1% of kernel time. [akpm@linux-foundation.org: cleanups, section fix] [akpm@linux-foundation.org: fix build on alpha] Signed-off-by: Nick Piggin Cc: Jeremy Fitzhardinge Cc: Krzysztof Helt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 328eb402272..4c28c4d564e 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -2,6 +2,7 @@ #define _LINUX_VMALLOC_H #include +#include #include /* pgprot_t */ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ @@ -23,7 +24,6 @@ struct vm_area_struct; /* vma defining user mapping in mm_types.h */ #endif struct vm_struct { - /* keep next,addr,size together to speedup lookups */ struct vm_struct *next; void *addr; unsigned long size; @@ -37,6 +37,19 @@ struct vm_struct { /* * Highlevel APIs for driver use */ +extern void vm_unmap_ram(const void *mem, unsigned int count); +extern void *vm_map_ram(struct page **pages, unsigned int count, + int node, pgprot_t prot); +extern void vm_unmap_aliases(void); + +#ifdef CONFIG_MMU +extern void __init vmalloc_init(void); +#else +static inline void vmalloc_init(void) +{ +} +#endif + extern void *vmalloc(unsigned long size); extern void *vmalloc_user(unsigned long size); extern void *vmalloc_node(unsigned long size, int node); -- cgit v1.2.3 From e575f111dc0f27044e170580e7de50985ab3e011 Mon Sep 17 00:00:00 2001 From: KOSAKI Motohiro Date: Sat, 18 Oct 2008 20:27:08 -0700 Subject: coredump_filter: add hugepage dumping Presently hugepage's vma has a VM_RESERVED flag in order not to be swapped. But a VM_RESERVED vma isn't core dumped because this flag is often used for some kernel vmas (e.g. vmalloc, sound related). Thus hugepages are never dumped and it can't be debugged easily. Many developers want hugepages to be included into core-dump. However, We can't read generic VM_RESERVED area because this area is often IO mapping area. then these area reading may change device state. it is definitly undesiable side-effect. So adding a hugepage specific bit to the coredump filter is better. It will be able to hugepage core dumping and doesn't cause any side-effect to any i/o devices. In additional, libhugetlb use hugetlb private mapping pages as anonymous page. Then, hugepage private mapping pages should be core dumped by default. Then, /proc/[pid]/core_dump_filter has two new bits. - bit 5 mean hugetlb private mapping pages are dumped or not. (default: yes) - bit 6 mean hugetlb shared mapping pages are dumped or not. (default: no) I tested by following method. % ulimit -c unlimited % ./crash_hugepage 50 % ./crash_hugepage 50 -p % ls -lh % gdb ./crash_hugepage core % % echo 0x43 > /proc/self/coredump_filter % ./crash_hugepage 50 % ./crash_hugepage 50 -p % ls -lh % gdb ./crash_hugepage core #include #include #include #include #include #include "hugetlbfs.h" int main(int argc, char** argv){ char* p; int ch; int mmap_flags = MAP_SHARED; int fd; int nr_pages; while((ch = getopt(argc, argv, "p")) != -1) { switch (ch) { case 'p': mmap_flags &= ~MAP_SHARED; mmap_flags |= MAP_PRIVATE; break; default: /* nothing*/ break; } } argc -= optind; argv += optind; if (argc == 0){ printf("need # of pages\n"); exit(1); } nr_pages = atoi(argv[0]); if (nr_pages < 2) { printf("nr_pages must >2\n"); exit(1); } fd = hugetlbfs_unlinked_fd(); p = mmap(NULL, nr_pages * gethugepagesize(), PROT_READ|PROT_WRITE, mmap_flags, fd, 0); sleep(2); *(p + gethugepagesize()) = 1; /* COW */ sleep(2); /* crash! */ *(int*)0 = 1; return 0; } Signed-off-by: KOSAKI Motohiro Reviewed-by: Kawai Hidehiro Cc: Hugh Dickins Cc: William Irwin Cc: Adam Litke Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index c226c7b8294..017cc914ef1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -403,12 +403,15 @@ extern int get_dumpable(struct mm_struct *mm); #define MMF_DUMP_MAPPED_PRIVATE 4 #define MMF_DUMP_MAPPED_SHARED 5 #define MMF_DUMP_ELF_HEADERS 6 +#define MMF_DUMP_HUGETLB_PRIVATE 7 +#define MMF_DUMP_HUGETLB_SHARED 8 #define MMF_DUMP_FILTER_SHIFT MMF_DUMPABLE_BITS -#define MMF_DUMP_FILTER_BITS 5 +#define MMF_DUMP_FILTER_BITS 7 #define MMF_DUMP_FILTER_MASK \ (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) #define MMF_DUMP_FILTER_DEFAULT \ - ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED)) + ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\ + (1 << MMF_DUMP_HUGETLB_PRIVATE)) struct sighand_struct { atomic_t count; -- cgit v1.2.3 From 8174f1503f4bf7e9a14b3fbbfdb30c6be6e29f77 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Sat, 18 Oct 2008 20:27:19 -0700 Subject: container freezer: make refrigerator always available Now that the TIF_FREEZE flag is available in all architectures, extract the refrigerator() and freeze_task() from kernel/power/process.c and make it available to all. The refrigerator() can now be used in a control group subsystem implementing a control group freezer. Signed-off-by: Cedric Le Goater Signed-off-by: Matt Helsley Acked-by: Serge E. Hallyn Tested-by: Matt Helsley Cc: "Rafael J. Wysocki" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/freezer.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/freezer.h b/include/linux/freezer.h index deddeedf325..17e3bb42dd3 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -6,7 +6,7 @@ #include #include -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_FREEZER /* * Check if a process has been frozen */ @@ -39,6 +39,11 @@ static inline void clear_freeze_flag(struct task_struct *p) clear_tsk_thread_flag(p, TIF_FREEZE); } +static inline bool should_send_signal(struct task_struct *p) +{ + return !(p->flags & PF_FREEZER_NOSIG); +} + /* * Wake up a frozen process * @@ -75,6 +80,9 @@ static inline int try_to_freeze(void) return 0; } +extern bool freeze_task(struct task_struct *p, bool sig_only); +extern void cancel_freezing(struct task_struct *p); + /* * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it * calls wait_for_completion(&vfork) and reset right after it returns from this @@ -166,7 +174,7 @@ static inline void set_freezable_with_signal(void) } while (try_to_freeze()); \ __retval; \ }) -#else /* !CONFIG_PM_SLEEP */ +#else /* !CONFIG_FREEZER */ static inline int frozen(struct task_struct *p) { return 0; } static inline int freezing(struct task_struct *p) { return 0; } static inline void set_freeze_flag(struct task_struct *p) {} @@ -191,6 +199,6 @@ static inline void set_freezable_with_signal(void) {} #define wait_event_freezable_timeout(wq, condition, timeout) \ wait_event_interruptible_timeout(wq, condition, timeout) -#endif /* !CONFIG_PM_SLEEP */ +#endif /* !CONFIG_FREEZER */ #endif /* FREEZER_H_INCLUDED */ -- cgit v1.2.3 From dc52ddc0e6f45b04780b26fc0813509f8e798c42 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Sat, 18 Oct 2008 20:27:21 -0700 Subject: container freezer: implement freezer cgroup subsystem This patch implements a new freezer subsystem in the control groups framework. It provides a way to stop and resume execution of all tasks in a cgroup by writing in the cgroup filesystem. The freezer subsystem in the container filesystem defines a file named freezer.state. Writing "FROZEN" to the state file will freeze all tasks in the cgroup. Subsequently writing "RUNNING" will unfreeze the tasks in the cgroup. Reading will return the current state. * Examples of usage : # mkdir /containers/freezer # mount -t cgroup -ofreezer freezer /containers # mkdir /containers/0 # echo $some_pid > /containers/0/tasks to get status of the freezer subsystem : # cat /containers/0/freezer.state RUNNING to freeze all tasks in the container : # echo FROZEN > /containers/0/freezer.state # cat /containers/0/freezer.state FREEZING # cat /containers/0/freezer.state FROZEN to unfreeze all tasks in the container : # echo RUNNING > /containers/0/freezer.state # cat /containers/0/freezer.state RUNNING This is the basic mechanism which should do the right thing for user space task in a simple scenario. It's important to note that freezing can be incomplete. In that case we return EBUSY. This means that some tasks in the cgroup are busy doing something that prevents us from completely freezing the cgroup at this time. After EBUSY, the cgroup will remain partially frozen -- reflected by freezer.state reporting "FREEZING" when read. The state will remain "FREEZING" until one of these things happens: 1) Userspace cancels the freezing operation by writing "RUNNING" to the freezer.state file 2) Userspace retries the freezing operation by writing "FROZEN" to the freezer.state file (writing "FREEZING" is not legal and returns EIO) 3) The tasks that blocked the cgroup from entering the "FROZEN" state disappear from the cgroup's set of tasks. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: export thaw_process] Signed-off-by: Cedric Le Goater Signed-off-by: Matt Helsley Acked-by: Serge E. Hallyn Tested-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup_subsys.h | 6 ++++++ include/linux/freezer.h | 29 ++++++++++------------------- 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cgroup_subsys.h b/include/linux/cgroup_subsys.h index e2877454ec8..9c22396e8b5 100644 --- a/include/linux/cgroup_subsys.h +++ b/include/linux/cgroup_subsys.h @@ -48,3 +48,9 @@ SUBSYS(devices) #endif /* */ + +#ifdef CONFIG_CGROUP_FREEZER +SUBSYS(freezer) +#endif + +/* */ diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 17e3bb42dd3..8f225339eee 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -46,26 +46,11 @@ static inline bool should_send_signal(struct task_struct *p) /* * Wake up a frozen process - * - * task_lock() is taken to prevent the race with refrigerator() which may - * occur if the freezing of tasks fails. Namely, without the lock, if the - * freezing of tasks failed, thaw_tasks() might have run before a task in - * refrigerator() could call frozen_process(), in which case the task would be - * frozen and no one would thaw it. */ -static inline int thaw_process(struct task_struct *p) -{ - task_lock(p); - if (frozen(p)) { - p->flags &= ~PF_FROZEN; - task_unlock(p); - wake_up_process(p); - return 1; - } - clear_freeze_flag(p); - task_unlock(p); - return 0; -} +extern int __thaw_process(struct task_struct *p); + +/* Takes and releases task alloc lock using task_lock() */ +extern int thaw_process(struct task_struct *p); extern void refrigerator(void); extern int freeze_processes(void); @@ -83,6 +68,12 @@ static inline int try_to_freeze(void) extern bool freeze_task(struct task_struct *p, bool sig_only); extern void cancel_freezing(struct task_struct *p); +#ifdef CONFIG_CGROUP_FREEZER +extern int cgroup_frozen(struct task_struct *task); +#else /* !CONFIG_CGROUP_FREEZER */ +static inline int cgroup_frozen(struct task_struct *task) { return 0; } +#endif /* !CONFIG_CGROUP_FREEZER */ + /* * The PF_FREEZER_SKIP flag should be set by a vfork parent right before it * calls wait_for_completion(&vfork) and reset right after it returns from this -- cgit v1.2.3 From 3e680aae4e53ab54cdbb0c29257dae0cbb158e1c Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sat, 18 Oct 2008 20:27:51 -0700 Subject: fb: convert lock/unlock_kernel() into local fb mutex Change lock_kernel()/unlock_kernel() to local fb mutex. Each frame buffer instance has its own mutex. The one line try_to_load() function is unrolled to request_module() in two places for readability. [righi.andrea@gmail.com: fb: fix NULL pointer BUG dereference in fb_open()] Signed-off-by: Krzysztof Helt Signed-off-by: Andrea Righi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/fb.h b/include/linux/fb.h index 531ccd5f596..75a81eaf343 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -808,6 +808,7 @@ struct fb_tile_ops { struct fb_info { int node; int flags; + struct mutex lock; /* Lock for open/release/ioctl funcs */ struct fb_var_screeninfo var; /* Current var */ struct fb_fix_screeninfo fix; /* Current fix */ struct fb_monspecs monspecs; /* Current Monitor specs */ -- cgit v1.2.3 From 0e4fb5e283870757024294bc4567a7c59d936f0b Mon Sep 17 00:00:00 2001 From: Hidehiro Kawai Date: Sat, 18 Oct 2008 20:27:57 -0700 Subject: ext3: add an option to control error handling on file data If the journal doesn't abort when it gets an IO error in file data blocks, the file data corruption will spread silently. Because most of applications and commands do buffered writes without fsync(), they don't notice the IO error. It's scary for mission critical systems. On the other hand, if the journal aborts whenever it gets an IO error in file data blocks, the system will easily become inoperable. So this patch introduces a filesystem option to determine whether it aborts the journal or just call printk() when it gets an IO error in file data. If you mount a ext3 fs with data_err=abort option, it aborts on file data write error. If you mount it with data_err=ignore, it doesn't abort, just call printk(). data_err=ignore is the default. Signed-off-by: Hidehiro Kawai Cc: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ext3_fs.h | 2 ++ include/linux/jbd.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h index 159d9b476cd..d14f0291848 100644 --- a/include/linux/ext3_fs.h +++ b/include/linux/ext3_fs.h @@ -380,6 +380,8 @@ struct ext3_inode { #define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */ #define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */ #define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */ +#define EXT3_MOUNT_DATA_ERR_ABORT 0x400000 /* Abort on file data write + * error in ordered mode */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ #ifndef _LINUX_EXT2_FS_H diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 7ebbcb1c9ba..35d4f6342fa 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -816,6 +816,9 @@ struct journal_s #define JFS_FLUSHED 0x008 /* The journal superblock has been flushed */ #define JFS_LOADED 0x010 /* The journal superblock has been loaded */ #define JFS_BARRIER 0x020 /* Use IDE barriers */ +#define JFS_ABORT_ON_SYNCDATA_ERR 0x040 /* Abort the journal on file + * data write error in ordered + * mode */ /* * Function declarations for the journaling transaction and buffer -- cgit v1.2.3 From 146aa1bd0511f88ddb4e92fafa2b8aad4f2f65f3 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 18 Oct 2008 20:28:03 -0700 Subject: cgroups: fix probable race with put_css_set[_taskexit] and find_css_set put_css_set_taskexit may be called when find_css_set is called on other cpu. And the race will occur: put_css_set_taskexit side find_css_set side | atomic_dec_and_test(&kref->refcount) | /* kref->refcount = 0 */ | .................................................................... | read_lock(&css_set_lock) | find_existing_css_set | get_css_set | read_unlock(&css_set_lock); .................................................................... __release_css_set | .................................................................... | /* use a released css_set */ | [put_css_set is the same. But in the current code, all put_css_set are put into cgroup mutex critical region as the same as find_css_set.] [akpm@linux-foundation.org: repair comments] [menage@google.com: eliminate race in css_set refcounting] Signed-off-by: Lai Jiangshan Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Signed-off-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 30934e4bfaa..7166023e07d 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -149,7 +148,7 @@ struct cgroup { struct css_set { /* Reference count */ - struct kref ref; + atomic_t refcount; /* * List running through all cgroup groups in the same hash -- cgit v1.2.3 From cc31edceee04a7b87f2be48f9489ebb72d264844 Mon Sep 17 00:00:00 2001 From: Paul Menage Date: Sat, 18 Oct 2008 20:28:04 -0700 Subject: cgroups: convert tasks file to use a seq_file with shared pid array Rather than pre-generating the entire text for the "tasks" file each time the file is opened, we instead just generate/update the array of process ids and use a seq_file to report these to userspace. All open file handles on the same "tasks" file can share a pid array, which may be updated any time that no thread is actively reading the array. By sharing the array, the potential for userspace to DoS the system by opening many handles on the same "tasks" file is removed. [Based on a patch by Lai Jiangshan, extended to use seq_file] Signed-off-by: Paul Menage Reviewed-by: Lai Jiangshan Cc: Serge Hallyn Cc: Balbir Singh Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 7166023e07d..8ab91880a0a 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef CONFIG_CGROUPS @@ -136,6 +137,15 @@ struct cgroup { * release_list_lock */ struct list_head release_list; + + /* pids_mutex protects the fields below */ + struct rw_semaphore pids_mutex; + /* Array of process ids in the cgroup */ + pid_t *tasks_pids; + /* How many files are using the current tasks_pids array */ + int pids_use_count; + /* Length of the current tasks_pids array */ + int pids_length; }; /* A css_set is a structure holding pointers to a set of -- cgit v1.2.3 From 886465f407e57d6c3c81013c919ea670ce1ae0d0 Mon Sep 17 00:00:00 2001 From: Paul Menage Date: Sat, 18 Oct 2008 20:28:05 -0700 Subject: cgroups: fix declaration of cgroup_mm_owner_callbacks The choice of real/dummy declaration for cgroup_mm_owner_callbacks() shouldn't be based on CONFIG_MM_OWNER, but on CONFIG_CGROUPS. Otherwise kernel/exit.c fails to compile when something other than a cgroups controller selects CONFIG_MM_OWNER Signed-off-by: Paul Menage Acked-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 8ab91880a0a..8b00f6643e9 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -403,6 +403,9 @@ void cgroup_iter_end(struct cgroup *cgrp, struct cgroup_iter *it); int cgroup_scan_tasks(struct cgroup_scanner *scan); int cgroup_attach_task(struct cgroup *, struct task_struct *); +void cgroup_mm_owner_callbacks(struct task_struct *old, + struct task_struct *new); + #else /* !CONFIG_CGROUPS */ static inline int cgroup_init_early(void) { return 0; } @@ -421,15 +424,9 @@ static inline int cgroupstats_build(struct cgroupstats *stats, return -EINVAL; } +static inline void cgroup_mm_owner_callbacks(struct task_struct *old, + struct task_struct *new) {} + #endif /* !CONFIG_CGROUPS */ -#ifdef CONFIG_MM_OWNER -extern void -cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new); -#else /* !CONFIG_MM_OWNER */ -static inline void -cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new) -{ -} -#endif /* CONFIG_MM_OWNER */ #endif /* _LINUX_CGROUP_H */ -- cgit v1.2.3 From 52d4b9ac0b985168009c2a57098324e67bae171f Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Sat, 18 Oct 2008 20:28:16 -0700 Subject: memcg: allocate all page_cgroup at boot Allocate all page_cgroup at boot and remove page_cgroup poitner from struct page. This patch adds an interface as struct page_cgroup *lookup_page_cgroup(struct page*) All FLATMEM/DISCONTIGMEM/SPARSEMEM and MEMORY_HOTPLUG is supported. Remove page_cgroup pointer reduces the amount of memory by - 4 bytes per PAGE_SIZE. - 8 bytes per PAGE_SIZE if memory controller is disabled. (even if configured.) On usual 8GB x86-32 server, this saves 8MB of NORMAL_ZONE memory. On my x86-64 server with 48GB of memory, this saves 96MB of memory. I think this reduction makes sense. By pre-allocation, kmalloc/kfree in charge/uncharge are removed. This means - we're not necessary to be afraid of kmalloc faiulre. (this can happen because of gfp_mask type.) - we can avoid calling kmalloc/kfree. - we can avoid allocating tons of small objects which can be fragmented. - we can know what amount of memory will be used for this extra-lru handling. I added printk message as "allocated %ld bytes of page_cgroup" "please try cgroup_disable=memory option if you don't want" maybe enough informative for users. Signed-off-by: KAMEZAWA Hiroyuki Reviewed-by: Balbir Singh Cc: Daisuke Nishimura Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/memcontrol.h | 13 +----- include/linux/mm_types.h | 3 -- include/linux/mmzone.h | 14 +++++- include/linux/page_cgroup.h | 103 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 16 deletions(-) create mode 100644 include/linux/page_cgroup.h (limited to 'include/linux') diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h index ee1b2fcb441..1fbe14d3952 100644 --- a/include/linux/memcontrol.h +++ b/include/linux/memcontrol.h @@ -27,9 +27,6 @@ struct mm_struct; #ifdef CONFIG_CGROUP_MEM_RES_CTLR -#define page_reset_bad_cgroup(page) ((page)->page_cgroup = 0) - -extern struct page_cgroup *page_get_page_cgroup(struct page *page); extern int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask); extern int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, @@ -72,16 +69,8 @@ extern void mem_cgroup_record_reclaim_priority(struct mem_cgroup *mem, extern long mem_cgroup_calc_reclaim(struct mem_cgroup *mem, struct zone *zone, int priority, enum lru_list lru); -#else /* CONFIG_CGROUP_MEM_RES_CTLR */ -static inline void page_reset_bad_cgroup(struct page *page) -{ -} - -static inline struct page_cgroup *page_get_page_cgroup(struct page *page) -{ - return NULL; -} +#else /* CONFIG_CGROUP_MEM_RES_CTLR */ static inline int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask) { diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 9d49fa36bbe..fe825471d5a 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -94,9 +94,6 @@ struct page { void *virtual; /* Kernel virtual address (NULL if not kmapped, ie. highmem) */ #endif /* WANT_PAGE_VIRTUAL */ -#ifdef CONFIG_CGROUP_MEM_RES_CTLR - unsigned long page_cgroup; -#endif }; /* diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index da2d053a95f..35a7b5e1946 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -601,8 +601,11 @@ typedef struct pglist_data { struct zone node_zones[MAX_NR_ZONES]; struct zonelist node_zonelists[MAX_ZONELISTS]; int nr_zones; -#ifdef CONFIG_FLAT_NODE_MEM_MAP +#ifdef CONFIG_FLAT_NODE_MEM_MAP /* means !SPARSEMEM */ struct page *node_mem_map; +#ifdef CONFIG_CGROUP_MEM_RES_CTLR + struct page_cgroup *node_page_cgroup; +#endif #endif struct bootmem_data *bdata; #ifdef CONFIG_MEMORY_HOTPLUG @@ -931,6 +934,7 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn) #endif struct page; +struct page_cgroup; struct mem_section { /* * This is, logically, a pointer to an array of struct @@ -948,6 +952,14 @@ struct mem_section { /* See declaration of similar field in struct zone */ unsigned long *pageblock_flags; +#ifdef CONFIG_CGROUP_MEM_RES_CTLR + /* + * If !SPARSEMEM, pgdat doesn't have page_cgroup pointer. We use + * section. (see memcontrol.h/page_cgroup.h about this.) + */ + struct page_cgroup *page_cgroup; + unsigned long pad; +#endif }; #ifdef CONFIG_SPARSEMEM_EXTREME diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h new file mode 100644 index 00000000000..0fd39f2231e --- /dev/null +++ b/include/linux/page_cgroup.h @@ -0,0 +1,103 @@ +#ifndef __LINUX_PAGE_CGROUP_H +#define __LINUX_PAGE_CGROUP_H + +#ifdef CONFIG_CGROUP_MEM_RES_CTLR +#include +/* + * Page Cgroup can be considered as an extended mem_map. + * A page_cgroup page is associated with every page descriptor. The + * page_cgroup helps us identify information about the cgroup + * All page cgroups are allocated at boot or memory hotplug event, + * then the page cgroup for pfn always exists. + */ +struct page_cgroup { + unsigned long flags; + struct mem_cgroup *mem_cgroup; + struct page *page; + struct list_head lru; /* per cgroup LRU list */ +}; + +void __init pgdat_page_cgroup_init(struct pglist_data *pgdat); +void __init page_cgroup_init(void); +struct page_cgroup *lookup_page_cgroup(struct page *page); + +enum { + /* flags for mem_cgroup */ + PCG_LOCK, /* page cgroup is locked */ + PCG_CACHE, /* charged as cache */ + PCG_USED, /* this object is in use. */ + /* flags for LRU placement */ + PCG_ACTIVE, /* page is active in this cgroup */ + PCG_FILE, /* page is file system backed */ + PCG_UNEVICTABLE, /* page is unevictableable */ +}; + +#define TESTPCGFLAG(uname, lname) \ +static inline int PageCgroup##uname(struct page_cgroup *pc) \ + { return test_bit(PCG_##lname, &pc->flags); } + +#define SETPCGFLAG(uname, lname) \ +static inline void SetPageCgroup##uname(struct page_cgroup *pc)\ + { set_bit(PCG_##lname, &pc->flags); } + +#define CLEARPCGFLAG(uname, lname) \ +static inline void ClearPageCgroup##uname(struct page_cgroup *pc) \ + { clear_bit(PCG_##lname, &pc->flags); } + +/* Cache flag is set only once (at allocation) */ +TESTPCGFLAG(Cache, CACHE) + +TESTPCGFLAG(Used, USED) +CLEARPCGFLAG(Used, USED) + +/* LRU management flags (from global-lru definition) */ +TESTPCGFLAG(File, FILE) +SETPCGFLAG(File, FILE) +CLEARPCGFLAG(File, FILE) + +TESTPCGFLAG(Active, ACTIVE) +SETPCGFLAG(Active, ACTIVE) +CLEARPCGFLAG(Active, ACTIVE) + +TESTPCGFLAG(Unevictable, UNEVICTABLE) +SETPCGFLAG(Unevictable, UNEVICTABLE) +CLEARPCGFLAG(Unevictable, UNEVICTABLE) + +static inline int page_cgroup_nid(struct page_cgroup *pc) +{ + return page_to_nid(pc->page); +} + +static inline enum zone_type page_cgroup_zid(struct page_cgroup *pc) +{ + return page_zonenum(pc->page); +} + +static inline void lock_page_cgroup(struct page_cgroup *pc) +{ + bit_spin_lock(PCG_LOCK, &pc->flags); +} + +static inline int trylock_page_cgroup(struct page_cgroup *pc) +{ + return bit_spin_trylock(PCG_LOCK, &pc->flags); +} + +static inline void unlock_page_cgroup(struct page_cgroup *pc) +{ + bit_spin_unlock(PCG_LOCK, &pc->flags); +} + +#else /* CONFIG_CGROUP_MEM_RES_CTLR */ +struct page_cgroup; + +static inline void pgdat_page_cgroup_init(struct pglist_data *pgdat) +{ +} + +static inline struct page_cgroup *lookup_page_cgroup(struct page *page) +{ + return NULL; +} +#endif +#endif -- cgit v1.2.3 From 3eda20118000941e7e8994fc5fac8706d8c10f00 Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 18 Oct 2008 20:28:19 -0700 Subject: seq_file: add seq_cpumask_list(), seq_nodemask_list() seq_cpumask_list(), seq_nodemask_list() are very like seq_cpumask(), seq_nodemask(), but they print human readable string. Signed-off-by: Lai Jiangshan Cc: Alexey Dobriyan Cc: Paul Menage Cc: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/seq_file.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h index a1783b229ef..dc50bcc282a 100644 --- a/include/linux/seq_file.h +++ b/include/linux/seq_file.h @@ -60,6 +60,19 @@ static inline int seq_nodemask(struct seq_file *m, nodemask_t *mask) return seq_bitmap(m, mask->bits, MAX_NUMNODES); } +int seq_bitmap_list(struct seq_file *m, unsigned long *bits, + unsigned int nr_bits); + +static inline int seq_cpumask_list(struct seq_file *m, cpumask_t *mask) +{ + return seq_bitmap_list(m, mask->bits, NR_CPUS); +} + +static inline int seq_nodemask_list(struct seq_file *m, nodemask_t *mask) +{ + return seq_bitmap_list(m, mask->bits, MAX_NUMNODES); +} + int single_open(struct file *, int (*)(struct seq_file *, void *), void *); int single_release(struct inode *, struct file *); void *__seq_open_private(struct file *, const struct seq_operations *, int); -- cgit v1.2.3 From c4596435404976b0ded9cdf18b456ca2e1408ddd Mon Sep 17 00:00:00 2001 From: Lai Jiangshan Date: Sat, 18 Oct 2008 20:28:21 -0700 Subject: bitmask: remove bitmap_scnprintf_len() bitmap_scnprintf_len() is not used now, so we remove it. Otherwise we have to maintain it and make its return value always equal to bitmap_scnprintf()'s return value. Signed-off-by: Lai Jiangshan Cc: Alexey Dobriyan Cc: Paul Menage Cc: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bitmap.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h index 89781fd4885..1abfe664c44 100644 --- a/include/linux/bitmap.h +++ b/include/linux/bitmap.h @@ -110,7 +110,6 @@ extern int __bitmap_weight(const unsigned long *bitmap, int bits); extern int bitmap_scnprintf(char *buf, unsigned int len, const unsigned long *src, int nbits); -extern int bitmap_scnprintf_len(unsigned int nr_bits); extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user, unsigned long *dst, int nbits); extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen, -- cgit v1.2.3 From b747c8c102cc0677a7a8056a093f58d7c9b500e7 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 18 Oct 2008 20:28:21 -0700 Subject: make ptrace_untrace() static ptrace_untrace() can now become static. Signed-off-by: Adrian Bunk Cc: Oleg Nesterov Cc: Roland McGrath Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index ea7416c901d..22641d5d45d 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -94,7 +94,6 @@ extern void ptrace_notify(int exit_code); extern void __ptrace_link(struct task_struct *child, struct task_struct *new_parent); extern void __ptrace_unlink(struct task_struct *child); -extern void ptrace_untrace(struct task_struct *child); #define PTRACE_MODE_READ 1 #define PTRACE_MODE_ATTACH 2 /* Returns 0 on success, -errno on denial. */ -- cgit v1.2.3 From 656eb2cd5da153762f2e8419ca117ce12ef522c3 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sat, 18 Oct 2008 20:28:23 -0700 Subject: add CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS This adds a kconfig option to change the /proc/PID/coredump_filter default. Fedora has been carrying a trivial patch to change the hard-wired value for this default, since Fedora 8. The default default can't change safely because there are old GDB versions out there (all before 6.7) that are confused by the core dump files created by the MMF_DUMP_ELF_HEADERS setting. Signed-off-by: Roland McGrath Cc: Michael Kerrisk Cc: Oleg Nesterov Cc: Alan Cox Cc: Andi Kleen Cc: KOSAKI Motohiro Cc: Kawai Hidehiro Cc: Ingo Molnar Cc: David Jones Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sched.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 017cc914ef1..f52dbd3587a 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -411,7 +411,13 @@ extern int get_dumpable(struct mm_struct *mm); (((1 << MMF_DUMP_FILTER_BITS) - 1) << MMF_DUMP_FILTER_SHIFT) #define MMF_DUMP_FILTER_DEFAULT \ ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED) |\ - (1 << MMF_DUMP_HUGETLB_PRIVATE)) + (1 << MMF_DUMP_HUGETLB_PRIVATE) | MMF_DUMP_MASK_DEFAULT_ELF) + +#ifdef CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS +# define MMF_DUMP_MASK_DEFAULT_ELF (1 << MMF_DUMP_ELF_HEADERS) +#else +# define MMF_DUMP_MASK_DEFAULT_ELF 0 +#endif struct sighand_struct { atomic_t count; -- cgit v1.2.3 From 57cac4d1880527e0baf6c2fda529d2ad1d815aec Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Sat, 18 Oct 2008 20:28:25 -0700 Subject: kdump: make elfcorehdr_addr independent of CONFIG_PROC_VMCORE o elfcorehdr_addr is used by not only the code under CONFIG_PROC_VMCORE but also by the code which is not inside CONFIG_PROC_VMCORE. For example, is_kdump_kernel() is used by powerpc code to determine if kernel is booting after a panic then use previous kernel's TCE table. So even if CONFIG_PROC_VMCORE is not set in second kernel, one should be able to correctly determine that we are booting after a panic and setup calgary iommu accordingly. o So remove the assumption that elfcorehdr_addr is under CONFIG_PROC_VMCORE. o Move definition of elfcorehdr_addr to arch dependent crash files. (Unfortunately crash dump does not have an arch independent file otherwise that would have been the best place). o kexec.c is not the right place as one can Have CRASH_DUMP enabled in second kernel without KEXEC being enabled. o I don't see sh setup code parsing the command line for elfcorehdr_addr. I am wondering how does vmcore interface work on sh. Anyway, I am atleast defining elfcoredhr_addr so that compilation is not broken on sh. Signed-off-by: Vivek Goyal Acked-by: "Eric W. Biederman" Acked-by: Simon Horman Acked-by: Paul Mundt Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/crash_dump.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 025e4f57510..de027d1db74 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -9,11 +9,7 @@ #define ELFCORE_ADDR_MAX (-1ULL) -#ifdef CONFIG_PROC_VMCORE extern unsigned long long elfcorehdr_addr; -#else -static const unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; -#endif extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); @@ -28,6 +24,16 @@ extern struct proc_dir_entry *proc_vmcore; #define vmcore_elf_check_arch(x) (elf_check_arch(x) || vmcore_elf_check_arch_cross(x)) +/* + * is_kdump_kernel() checks whether this kernel is booting after a panic of + * previous kernel or not. This is determined by checking if previous kernel + * has passed the elf core header address on command line. + * + * This is not just a test if CONFIG_CRASH_DUMP is enabled or not. It will + * return 1 if CONFIG_CRASH_DUMP=y and if kernel is booting after a panic of + * previous kernel. + */ + static inline int is_kdump_kernel(void) { return (elfcorehdr_addr != ELFCORE_ADDR_MAX) ? 1 : 0; -- cgit v1.2.3 From 85a0ee342e0c06c19d78fdf48307211c6cf18fcb Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Sat, 18 Oct 2008 20:28:29 -0700 Subject: kdump: add is_vmcore_usable() and vmcore_unusable() The usage of elfcorehdr_addr has changed recently such that being set to ELFCORE_ADDR_MAX is used by is_kdump_kernel() to indicate if the code is executing in a kernel executed as a crash kernel. However, arch/ia64/kernel/setup.c:reserve_elfcorehdr will rest elfcorehdr_addr to ELFCORE_ADDR_MAX on error, which means any subsequent calls to is_kdump_kernel() will return 0, even though they should return 1. Ok, at this point in time there are no subsequent calls, but I think its fair to say that there is ample scope for error or at the very least confusion. This patch add an extra state, ELFCORE_ADDR_ERR, which indicates that elfcorehdr_addr was passed on the command line, and thus execution is taking place in a crashdump kernel, but vmcore can't be used for some reason. This is tested for using is_vmcore_usable() and set using vmcore_unusable(). A subsequent patch makes use of this new code. To summarise, the states that elfcorehdr_addr can now be in are as follows: ELFCORE_ADDR_MAX: not a crashdump kernel ELFCORE_ADDR_ERR: crashdump kernel but vmcore is unusable any other value: crash dump kernel and vmcore is usable Signed-off-by: Simon Horman Cc: Vivek Goyal Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/crash_dump.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'include/linux') diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index de027d1db74..0acf3b737e2 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -8,6 +8,7 @@ #include #define ELFCORE_ADDR_MAX (-1ULL) +#define ELFCORE_ADDR_ERR (-2ULL) extern unsigned long long elfcorehdr_addr; @@ -38,6 +39,29 @@ static inline int is_kdump_kernel(void) { return (elfcorehdr_addr != ELFCORE_ADDR_MAX) ? 1 : 0; } + +/* is_vmcore_usable() checks if the kernel is booting after a panic and + * the vmcore region is usable. + * + * This makes use of the fact that due to alignment -2ULL is not + * a valid pointer, much in the vain of IS_ERR(), except + * dealing directly with an unsigned long long rather than a pointer. + */ + +static inline int is_vmcore_usable(void) +{ + return is_kdump_kernel() && elfcorehdr_addr != ELFCORE_ADDR_ERR ? 1 : 0; +} + +/* vmcore_unusable() marks the vmcore as unusable, + * without disturbing the logic of is_kdump_kernel() + */ + +static inline void vmcore_unusable(void) +{ + if (is_kdump_kernel()) + elfcorehdr_addr = ELFCORE_ADDR_ERR; +} #else /* !CONFIG_CRASH_DUMP */ static inline int is_kdump_kernel(void) { return 0; } #endif /* CONFIG_CRASH_DUMP */ -- cgit v1.2.3 From b8e465f4945bc0e9f324e3bbe15f5180a8e9a6fe Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 18 Oct 2008 20:28:35 -0700 Subject: byteorder: add new headers for make headers-install Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/Kbuild | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/Kbuild b/include/linux/Kbuild index bf9aca548f1..e531783e5d7 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -183,6 +183,7 @@ unifdef-y += auto_fs.h unifdef-y += auxvec.h unifdef-y += binfmts.h unifdef-y += blktrace_api.h +unifdef-y += byteorder.h unifdef-y += capability.h unifdef-y += capi.h unifdef-y += cciss_ioctl.h @@ -340,6 +341,7 @@ unifdef-y += soundcard.h unifdef-y += stat.h unifdef-y += stddef.h unifdef-y += string.h +unifdef-y += swab.h unifdef-y += synclink.h unifdef-y += sysctl.h unifdef-y += tcp.h -- cgit v1.2.3 From acf0108a84edae22b99655eb2f6f6c9f7ec4d449 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 18 Oct 2008 20:28:36 -0700 Subject: byteorder: use generic C version for value byteswapping This makes the new implementation of the byteorder helpers match the old in how it degraded when an arch-defined version was not available: 1) swab() - look for arch defined - if not, use generic c version 2) swabp() - look for arch-defined - if not, deref pointer and use swab() 3) swabs() - look for arch defined - if not, use swabp Signed-off-by: Harvey Harrison Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swab.h | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'include/linux') diff --git a/include/linux/swab.h b/include/linux/swab.h index 270d5c208a8..bbed279f3b3 100644 --- a/include/linux/swab.h +++ b/include/linux/swab.h @@ -47,8 +47,6 @@ static inline __attribute_const__ __u16 ___swab16(__u16 val) { #ifdef __arch_swab16 return __arch_swab16(val); -#elif defined(__arch_swab16p) - return __arch_swab16p(&val); #else return __const_swab16(val); #endif @@ -58,8 +56,6 @@ static inline __attribute_const__ __u32 ___swab32(__u32 val) { #ifdef __arch_swab32 return __arch_swab32(val); -#elif defined(__arch_swab32p) - return __arch_swab32p(&val); #else return __const_swab32(val); #endif @@ -69,8 +65,6 @@ static inline __attribute_const__ __u64 ___swab64(__u64 val) { #ifdef __arch_swab64 return __arch_swab64(val); -#elif defined(__arch_swab64p) - return __arch_swab64p(&val); #elif defined(__SWAB_64_THRU_32__) __u32 h = val >> 32; __u32 l = val & ((1ULL << 32) - 1); @@ -84,8 +78,6 @@ static inline __attribute_const__ __u32 ___swahw32(__u32 val) { #ifdef __arch_swahw32 return __arch_swahw32(val); -#elif defined(__arch_swahw32p) - return __arch_swahw32p(&val); #else return __const_swahw32(val); #endif @@ -95,8 +87,6 @@ static inline __attribute_const__ __u32 ___swahb32(__u32 val) { #ifdef __arch_swahb32 return __arch_swahb32(val); -#elif defined(__arch_swahb32p) - return __arch_swahb32p(&val); #else return __const_swahb32(val); #endif -- cgit v1.2.3 From 1d8cca44b6a244b7e378546d719041819049a0f9 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sat, 18 Oct 2008 20:28:37 -0700 Subject: byteorder: provide swabb.h generically in asm/byteorder.h This is needed during the transition to the new byteorder headers as the swabb.h functionality will be provided from asm/byteorder.h in the new version. To avoid breakage on arches still using the old implementation, provide swabb.h from asm/byteorder.h as well. Signed-off-by: Harvey Harrison Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/byteorder/Kbuild | 1 + include/linux/byteorder/big_endian.h | 1 + include/linux/byteorder/little_endian.h | 1 + 3 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/byteorder/Kbuild b/include/linux/byteorder/Kbuild index 1133d5f9d81..fbaa7f9cee3 100644 --- a/include/linux/byteorder/Kbuild +++ b/include/linux/byteorder/Kbuild @@ -1,3 +1,4 @@ unifdef-y += big_endian.h unifdef-y += little_endian.h unifdef-y += swab.h +unifdef-y += swabb.h diff --git a/include/linux/byteorder/big_endian.h b/include/linux/byteorder/big_endian.h index 44f95b92393..1cba3f3efe5 100644 --- a/include/linux/byteorder/big_endian.h +++ b/include/linux/byteorder/big_endian.h @@ -10,6 +10,7 @@ #include #include +#include #define __constant_htonl(x) ((__force __be32)(__u32)(x)) #define __constant_ntohl(x) ((__force __u32)(__be32)(x)) diff --git a/include/linux/byteorder/little_endian.h b/include/linux/byteorder/little_endian.h index 4cc170a3176..cedc1b5a289 100644 --- a/include/linux/byteorder/little_endian.h +++ b/include/linux/byteorder/little_endian.h @@ -10,6 +10,7 @@ #include #include +#include #define __constant_htonl(x) ((__force __be32)___constant_swab32((x))) #define __constant_ntohl(x) ___constant_swab32((__force __be32)(x)) -- cgit v1.2.3 From fdd2e5f88a259a537bb239e0c03c973cb6ea402a Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 18 Oct 2008 20:28:38 -0700 Subject: make mm/rmap.c:anon_vma_cachep static This patch makes the needlessly global anon_vma_cachep static. Signed-off-by: Adrian Bunk Reviewed-by: KOSAKI Motohiro Acked-by: Rik van Riel Acked-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rmap.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 1da48db8db0..89f0564b10c 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -39,18 +39,6 @@ struct anon_vma { #ifdef CONFIG_MMU -extern struct kmem_cache *anon_vma_cachep; - -static inline struct anon_vma *anon_vma_alloc(void) -{ - return kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL); -} - -static inline void anon_vma_free(struct anon_vma *anon_vma) -{ - kmem_cache_free(anon_vma_cachep, anon_vma); -} - static inline void anon_vma_lock(struct vm_area_struct *vma) { struct anon_vma *anon_vma = vma->anon_vma; -- cgit v1.2.3 From a0098efd6ee4e8c04d82d761aa1bb9ec7a0aa32d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 18 Oct 2008 20:28:47 -0700 Subject: remove the obsolete BCD*BIN/BIN*BCD macros Remove the following obsolete macros: - BCD2BIN - BIN2BCD - BCD_TO_BIN - BIN_TO_BCD Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bcd.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bcd.h b/include/linux/bcd.h index 7ac518e3c15..75f6d6e699a 100644 --- a/include/linux/bcd.h +++ b/include/linux/bcd.h @@ -15,11 +15,4 @@ unsigned bcd2bin(unsigned char val) __attribute_const__; unsigned char bin2bcd(unsigned val) __attribute_const__; -#define BCD2BIN(val) bcd2bin(val) -#define BIN2BCD(val) bin2bcd(val) - -/* backwards compat */ -#define BCD_TO_BIN(val) ((val)=BCD2BIN(val)) -#define BIN_TO_BCD(val) ((val)=BIN2BCD(val)) - #endif /* _BCD_H */ -- cgit v1.2.3 From 5a85a7dda15f88b7f9c96c67fe826b5d0486d601 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 18 Oct 2008 20:28:48 -0700 Subject: include/linux/bcd.h: remove comments - the macros are gone - there's no more code in this file, LGPL + GPL = GPL, and the code that was moved to lib/bcd.c is anyway trivial Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bcd.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bcd.h b/include/linux/bcd.h index 75f6d6e699a..22ea563ba3e 100644 --- a/include/linux/bcd.h +++ b/include/linux/bcd.h @@ -1,12 +1,3 @@ -/* Permission is hereby granted to copy, modify and redistribute this code - * in terms of the GNU Library General Public License, Version 2 or later, - * at your option. - */ - -/* macros to translate to/from binary and binary-coded decimal (frequently - * found in RTC chips). - */ - #ifndef _BCD_H #define _BCD_H -- cgit v1.2.3 From 01e8ef11bc1a74e65678ed55795f59266d4add01 Mon Sep 17 00:00:00 2001 From: Parag Warudkar Date: Sat, 18 Oct 2008 20:28:50 -0700 Subject: x86: sysfs: kill owner field from attribute Tejun's commit 7b595756ec1f49e0049a9e01a1298d53a7faaa15 made sysfs attribute->owner unnecessary. But the field was left in the structure to ease the merge. It's been over a year since that change and it is now time to start killing attribute->owner along with its users - one arch at a time! This patch is attempt #1 to get rid of attribute->owner only for CONFIG_X86_64 or CONFIG_X86_32 . We will deal with other arches later on as and when possible - avr32 will be the next since that is something I can test. Compile (make allyesconfig / make allmodconfig / custom config) and boot tested. akpm: the idea is that we put the declaration of sttribute.owner inside `#ifndef CONFIG_X86'. But that proved to be too ambitious for now because new usages kept on turning up in subsystem trees. [akpm: remove the ifdef for now] Signed-off-by: Parag Warudkar Cc: Greg KH Cc: Ingo Molnar Cc: Tejun Heo Cc: Len Brown Cc: Jens Axboe Cc: Jean Delvare Cc: Roland Dreier Cc: David Brownell Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sysfs.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index b330e289d71..9d68fed50f1 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -21,8 +21,9 @@ struct kobject; struct module; /* FIXME - * The *owner field is no longer used, but leave around - * until the tree gets cleaned up fully. + * The *owner field is no longer used. + * x86 tree has been cleaned up. The owner + * attribute is still left for other arches. */ struct attribute { const char *name; -- cgit v1.2.3 From 606576ce816603d9fe1fb453a88bc6eea16ca709 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 6 Oct 2008 19:06:12 -0400 Subject: ftrace: rename FTRACE to FUNCTION_TRACER Due to confusion between the ftrace infrastructure and the gcc profiling tracer "ftrace", this patch renames the config options from FTRACE to FUNCTION_TRACER. The other two names that are offspring from FTRACE DYNAMIC_FTRACE and FTRACE_MCOUNT_RECORD will stay the same. This patch was generated mostly by script, and partially by hand. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index a3d46151be1..0e952958915 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -8,7 +8,7 @@ #include #include -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER extern int ftrace_enabled; extern int @@ -36,12 +36,12 @@ void clear_ftrace_function(void); extern void ftrace_stub(unsigned long a0, unsigned long a1); -#else /* !CONFIG_FTRACE */ +#else /* !CONFIG_FUNCTION_TRACER */ # define register_ftrace_function(ops) do { } while (0) # define unregister_ftrace_function(ops) do { } while (0) # define clear_ftrace_function(ops) do { } while (0) static inline void ftrace_kill_atomic(void) { } -#endif /* CONFIG_FTRACE */ +#endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_DYNAMIC_FTRACE # define FTRACE_HASHBITS 10 @@ -101,7 +101,7 @@ void ftrace_kill_atomic(void); static inline void tracer_disable(void) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER ftrace_enabled = 0; #endif } @@ -113,7 +113,7 @@ static inline void tracer_disable(void) */ static inline int __ftrace_enabled_save(void) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER int saved_ftrace_enabled = ftrace_enabled; ftrace_enabled = 0; return saved_ftrace_enabled; @@ -124,7 +124,7 @@ static inline int __ftrace_enabled_save(void) static inline void __ftrace_enabled_restore(int enabled) { -#ifdef CONFIG_FTRACE +#ifdef CONFIG_FUNCTION_TRACER ftrace_enabled = enabled; #endif } -- cgit v1.2.3 From edbc25caaa492a82e19baa915f1f6b0a0db6554d Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Thu, 10 Jul 2008 16:29:37 -0500 Subject: PCI: remove dynids.use_driver_data The driver flag dynids.use_driver_data is almost consistently not set, and causes more problems than it solves. It was initially intended as a flag to indicate whether a driver's usage of driver_data had been carefully inspected and was ready for values from userspace. That audit was never done, so most drivers just get a 0 for driver_data when new IDs are added from userspace via sysfs. So remove the flag, allowing drivers to see the data directly (a followon patch validates the passed driver_data value against what the drivers expect). Acked-by: Greg Kroah-Hartman Acked-by: Jean Delvare Signed-off-by: Milton Miller Signed-off-by: Jesse Barnes --- include/linux/pci.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index acf8f24037c..c989f58d09b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -347,7 +347,6 @@ struct pci_bus_region { struct pci_dynids { spinlock_t lock; /* protects list, index */ struct list_head list; /* for IDs added at runtime */ - unsigned int use_driver_data:1; /* pci_device_id->driver_data is used */ }; /* ---------------------------------------------------------------- */ -- cgit v1.2.3 From 0235c4fc7fc6f621dc0dd89eba102ad5aa373390 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 18 Aug 2008 21:38:00 +0200 Subject: PCI PM: Introduce function pci_wake_from_d3 Many device drivers use the following sequence of statements to enable the device to wake up the system while being in the D3_hot or D3_cold low power state: pci_enable_wake(pdev, PCI_D3hot, 1); pci_enable_wake(pdev, PCI_D3cold, 1); However, the second call is not necessary if the first one succeeds (the ordering of the statements above doesn't matter here) and it may even be harmful, because we are not supposed to enable PME# after the wake-up power has been enabled for the device. To allow drivers to overcome this problem, introduce function pci_wake_from_d3() that will enable the device to wake up the system from any of D3_hot and D3_cold as long as the wake-up from at least one of them is supported. Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index c989f58d09b..f7e7dbc0919 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -644,6 +644,7 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); bool pci_pme_capable(struct pci_dev *dev, pci_power_t state); void pci_pme_active(struct pci_dev *dev, bool enable); int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +int pci_wake_from_d3(struct pci_dev *dev, bool enable); pci_power_t pci_target_state(struct pci_dev *dev); int pci_prepare_to_sleep(struct pci_dev *dev); int pci_back_from_sleep(struct pci_dev *dev); -- cgit v1.2.3 From 16dbef4a831782466b10d4ae56837c5ba17d1948 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Fri, 15 Aug 2008 19:36:45 -0700 Subject: PCI: change MSI-x vector to 32bit We are using 28bit pci (bus/dev/fn + 12 bits) as irq number, so the cache for irq number should be 32 bit too. Signed-off-by: Yinghai Lu Cc: Andrew Vasquez Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index f7e7dbc0919..8a4d0bebc31 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -725,7 +725,7 @@ enum pci_dma_burst_strategy { }; struct msix_entry { - u16 vector; /* kernel uses to write allocated vector */ + u32 vector; /* kernel uses to write allocated vector */ u16 entry; /* driver uses to specify entry, OS writes */ }; -- cgit v1.2.3 From 37a84ec668ba251ae02cf2c2c664baf6b247ae1f Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Thu, 28 Aug 2008 15:40:59 -0700 Subject: x86/PCI: irq and pci_ids patch for Intel Ibex Peak DeviceIDs This patch updates the Intel Ibex Peak (PCH) LPC and SMBus Controller DeviceIDs. The LPC Controller ID is set by Firmware within the range of 0x3b00-3b1f. This range is included in pci_ids.h using min and max values, and irq.c now has code to handle the range (in lieu of 32 additions to a SWITCH statement). The SMBus Controller ID is a fixed-value and will not change. Signed-off-by: Seth Heasley Acked-by: Jean Delvare Signed-off-by: Jesse Barnes --- include/linux/pci_ids.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8edddc240e4..e5d344bfcb7 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2454,9 +2454,9 @@ #define PCI_DEVICE_ID_INTEL_ICH10_3 0x3a1a #define PCI_DEVICE_ID_INTEL_ICH10_4 0x3a30 #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 -#define PCI_DEVICE_ID_INTEL_PCH_0 0x3b10 -#define PCI_DEVICE_ID_INTEL_PCH_1 0x3b11 -#define PCI_DEVICE_ID_INTEL_PCH_2 0x3b30 +#define PCI_DEVICE_ID_INTEL_PCH_LPC_MIN 0x3b00 +#define PCI_DEVICE_ID_INTEL_PCH_LPC_MAX 0x3b1f +#define PCI_DEVICE_ID_INTEL_PCH_SMBUS 0x3b30 #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 -- cgit v1.2.3 From c322b28a04c084a467a862766f74c40c917a721c Mon Sep 17 00:00:00 2001 From: "Zhao, Yu" Date: Mon, 13 Oct 2008 19:36:05 +0800 Subject: PCI: use same arg names in PCI_VDEVICE comment This cleanup makes the argument names in PCI_VDEVICE comment consistent with those used in its definition. Signed-off-by: Yu Zhao Signed-off-by: Jesse Barnes --- include/linux/pci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 8a4d0bebc31..008005674b6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -455,8 +455,8 @@ struct pci_driver { /** * PCI_VDEVICE - macro used to describe a specific pci device in short form - * @vend: the vendor name - * @dev: the 16 bit PCI Device ID + * @vendor: the vendor name + * @device: the 16 bit PCI Device ID * * This macro is used to create a struct pci_device_id that matches a * specific PCI device. The subvendor, and subdevice fields will be set -- cgit v1.2.3 From 58c3a727cb73b75a9104d295f096cca12959a5a5 Mon Sep 17 00:00:00 2001 From: Yu Zhao Date: Tue, 14 Oct 2008 14:02:53 +0800 Subject: PCI: support PCIe ARI capability This patch adds support for PCI Express Alternative Routing-ID Interpretation (ARI) capability. The ARI capability extends the Function Number field of the PCI Express Endpoint by reusing the Device Number which is otherwise hardwired to 0. With ARI, an Endpoint can have up to 256 functions. Signed-off-by: Yu Zhao Signed-off-by: Jesse Barnes --- include/linux/pci.h | 1 + include/linux/pci_regs.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 008005674b6..7e9a1f0715e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -214,6 +214,7 @@ struct pci_dev { unsigned int broken_parity_status:1; /* Device generates false positive parity */ unsigned int msi_enabled:1; unsigned int msix_enabled:1; + unsigned int ari_enabled:1; /* ARI forwarding */ unsigned int is_managed:1; unsigned int is_pcie:1; pci_dev_flags_t dev_flags; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 450684f7eaa..eb6686b88f9 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -419,6 +419,10 @@ #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ #define PCI_EXP_RTSTA 32 /* Root Status */ +#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ +#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ +#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ +#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */ /* Extended Capabilities (PCI-X 2.0 and Express) */ #define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) @@ -429,6 +433,7 @@ #define PCI_EXT_CAP_ID_VC 2 #define PCI_EXT_CAP_ID_DSN 3 #define PCI_EXT_CAP_ID_PWR 4 +#define PCI_EXT_CAP_ID_ARI 14 /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ @@ -536,5 +541,14 @@ #define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ #define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ +/* Alternative Routing-ID Interpretation */ +#define PCI_ARI_CAP 0x04 /* ARI Capability Register */ +#define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */ +#define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */ +#define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */ +#define PCI_ARI_CTRL 0x06 /* ARI Control Register */ +#define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */ +#define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */ +#define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */ #endif /* LINUX_PCI_REGS_H */ -- cgit v1.2.3 From aa42d7c6138afdc54f74e971456a0fbfec16b77b Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Sun, 28 Sep 2008 16:36:11 -0700 Subject: PCI: introduce an pci_ioremap(pdev, barnr) function A common thing in many PCI drivers is to ioremap() an entire bar. This is a slightly fragile thing right now, needing both an address and a size, and many driver writers do.. various things there. This patch introduces an pci_ioremap() function taking just a PCI device struct and the bar number as arguments, and figures this all out itself, in one place. In addition, we can add various sanity checks to this function (the patch already checks to make sure that the bar in question really is a MEM bar; few to no drivers do that sort of thing). Hopefully with this type of API we get less chance of mistakes in drivers with ioremap() operations. Signed-off-by: Arjan van de Ven Signed-off-by: Jesse Barnes --- include/linux/pci.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 7e9a1f0715e..46ad282ffe4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1119,5 +1119,18 @@ static inline void pci_mmcfg_early_init(void) { } static inline void pci_mmcfg_late_init(void) { } #endif +static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar) +{ + /* + * Make sure the BAR is actually a memory resource, not an IO resource + */ + if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { + WARN_ON(1); + return NULL; + } + return ioremap_nocache(pci_resource_start(pdev, bar), + pci_resource_len(pdev, bar)); +} + #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */ -- cgit v1.2.3 From 0927678f55c9a50c296f7e6dae85e87b8236e155 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 18 Oct 2008 17:33:19 -0700 Subject: PCI: use pci_find_ext_capability everywhere Remove some open coded (and buggy) versions of pci_find_ext_capability in favor of the real routine in the PCI core. Tested-by: Tomasz Czernecki Acked-by: Andrew Vasquez Reviewed-by: Matthew Wilcox Signed-off-by: Jesse Barnes --- include/linux/aer.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/aer.h b/include/linux/aer.h index f2518141de8..a2383a72356 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -18,10 +18,6 @@ static inline int pci_enable_pcie_error_reporting(struct pci_dev *dev) { return -EINVAL; } -static inline int pci_find_aer_capability(struct pci_dev *dev) -{ - return 0; -} static inline int pci_disable_pcie_error_reporting(struct pci_dev *dev) { return -EINVAL; -- cgit v1.2.3 From 270c66be9b4a6f2be53ef3aec5dc8e7b07782ec9 Mon Sep 17 00:00:00 2001 From: Yu Zhao Date: Sun, 19 Oct 2008 20:35:20 +0800 Subject: PCI: fix AER capability check The 'use pci_find_ext_capability everywhere' cleanup brought a new bug, which makes the AER stop working. Fix it by actually using find_ext_cap instead of just find_cap. Drop the unused config space size define while we're at it. Signed-off-by: Yu Zhao Signed-off-by: Jesse Barnes --- include/linux/aer.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/aer.h b/include/linux/aer.h index a2383a72356..f7df1eefc10 100644 --- a/include/linux/aer.h +++ b/include/linux/aer.h @@ -10,7 +10,6 @@ #if defined(CONFIG_PCIEAER) /* pci-e port driver needs this function to enable aer */ extern int pci_enable_pcie_error_reporting(struct pci_dev *dev); -extern int pci_find_aer_capability(struct pci_dev *dev); extern int pci_disable_pcie_error_reporting(struct pci_dev *dev); extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev); #else -- cgit v1.2.3 From 96499871f45b9126157b1a5c512d6e30f1635225 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 20 Oct 2008 19:45:43 +0200 Subject: PCI: fix pci_ioremap_bar() on s390 s390 doesn't have ioremap_*, so protect the definition of the new pci_ioremap_bar function with CONFIG_HAS_IOMEM to avoid build breakage. Acked-by: Arjan van de Ven Signed-off-by: Heiko Carstens Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 46ad282ffe4..085187be29c 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1119,6 +1119,7 @@ static inline void pci_mmcfg_early_init(void) { } static inline void pci_mmcfg_late_init(void) { } #endif +#ifdef CONFIG_HAS_IOMEM static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar) { /* @@ -1131,6 +1132,7 @@ static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar) return ioremap_nocache(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar)); } +#endif #endif /* __KERNEL__ */ #endif /* LINUX_PCI_H */ -- cgit v1.2.3 From 326bb8a5a12c6298a6bf6c74af490b1858b2f12c Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Mon, 13 Oct 2008 10:13:01 +0100 Subject: leds: Make default trigger fields const The default_trigger fields of struct gpio_led and thus struct led_classdev are pretty much always assigned from a string literal, which means the string can't be modified. Which is fine, since there is no reason to modify the string and in fact it never is. But they should be marked const to prevent such code from being added, to prevent warnings if -Wwrite-strings is used, when assigned from a constant string other than a string literal (which produces a warning under current kernel compiler flags), and for general good coding practices. Signed-off-by: Trent Piepho Signed-off-by: Richard Purdie --- include/linux/leds.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/leds.h b/include/linux/leds.h index d41ccb56146..d3a73f5a48c 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -123,7 +123,7 @@ extern void ledtrig_ide_activity(void); */ struct led_info { const char *name; - char *default_trigger; + const char *default_trigger; int flags; }; @@ -135,7 +135,7 @@ struct led_platform_data { /* For the leds-gpio driver */ struct gpio_led { const char *name; - char *default_trigger; + const char *default_trigger; unsigned gpio; u8 active_low; }; -- cgit v1.2.3 From b62b75905d571c29262a6c38cf9e5f089c203871 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Oct 2008 13:25:21 +1100 Subject: md: use sysfs_notify_dirent to notify changes to md/array_state Now that we have sysfs_notify_dirent, use it to notify changes to md/array_state. As sysfs_notify_dirent can be called in atomic context, we can remove the delayed notify and the MD_NOTIFY_ARRAY_STATE flag. Signed-off-by: NeilBrown --- include/linux/raid/md_k.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index c200b9a34af..b16ad867e94 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -128,7 +128,6 @@ struct mddev_s #define MD_CHANGE_DEVS 0 /* Some device status has changed */ #define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */ #define MD_CHANGE_PENDING 2 /* superblock update in progress */ -#define MD_NOTIFY_ARRAY_STATE 3 /* atomic context wants to notify userspace */ int ro; @@ -239,6 +238,10 @@ struct mddev_s sector_t resync_max; /* resync should pause * when it gets here */ + struct sysfs_dirent *sysfs_state; /* handle for 'array_state' + * file in sysfs. + */ + spinlock_t write_lock; wait_queue_head_t sb_wait; /* for waiting on superblock updates */ atomic_t pending_writes; /* number of active superblock writes */ -- cgit v1.2.3 From 3c0ee63a64a20351ed6c16ec797e1f8c850741ea Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 21 Oct 2008 13:25:28 +1100 Subject: md: use sysfs_notify_dirent to notify changes to md/dev-xxx/state The 'state' file for a device reports, for example, when the device has failed. Changes should be reported to userspace ASAP without the possibility of blocking on low-memory. sysfs_notify does have that possibility (as it takes a mutex which can be held across a kmalloc) so use sysfs_notify_dirent instead. Signed-off-by: NeilBrown --- include/linux/raid/md_k.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index b16ad867e94..8fc909ef678 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h @@ -115,6 +115,9 @@ struct mdk_rdev_s * in superblock. */ struct work_struct del_work; /* used for delayed sysfs removal */ + + struct sysfs_dirent *sysfs_state; /* handle for 'state' + * sysfs entry */ }; struct mddev_s -- cgit v1.2.3 From a5598ca0d49821912a5053c05f07fd650671eb6d Mon Sep 17 00:00:00 2001 From: Carl Love Date: Tue, 14 Oct 2008 23:37:01 +0000 Subject: powerpc/oprofile: Fix mutex locking for cell spu-oprofile The issue is the SPU code is not holding the kernel mutex lock while adding samples to the kernel buffer. This patch creates per SPU buffers to hold the data. Data is added to the buffers from in interrupt context. The data is periodically pushed to the kernel buffer via a new Oprofile function oprofile_put_buff(). The oprofile_put_buff() function is called via a work queue enabling the funtion to acquire the mutex lock. The existing user controls for adjusting the per CPU buffer size is used to control the size of the per SPU buffers. Similarly, overflows of the SPU buffers are reported by incrementing the per CPU buffer stats. This eliminates the need to have architecture specific controls for the per SPU buffers which is not acceptable to the OProfile user tool maintainer. The export of the oprofile add_event_entry() is removed as it is no longer needed given this patch. Note, this patch has not addressed the issue of indexing arrays by the spu number. This still needs to be fixed as the spu numbering is not guarenteed to be 0 to max_num_spus-1. Signed-off-by: Carl Love Signed-off-by: Maynard Johnson Signed-off-by: Arnd Bergmann Acked-by: Acked-by: Robert Richter Signed-off-by: Benjamin Herrenschmidt --- include/linux/oprofile.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h index bcb8f725427..5231861f357 100644 --- a/include/linux/oprofile.h +++ b/include/linux/oprofile.h @@ -85,13 +85,6 @@ int oprofile_arch_init(struct oprofile_operations * ops); */ void oprofile_arch_exit(void); -/** - * Add data to the event buffer. - * The data passed is free-form, but typically consists of - * file offsets, dcookies, context information, and ESCAPE codes. - */ -void add_event_entry(unsigned long data); - /** * Add a sample. This may be called from any context. Pass * smp_processor_id() as cpu. @@ -162,5 +155,14 @@ int oprofilefs_ulong_from_user(unsigned long * val, char const __user * buf, siz /** lock for read/write safety */ extern spinlock_t oprofilefs_lock; + +/** + * Add the contents of a circular buffer to the event buffer. + */ +void oprofile_put_buff(unsigned long *buf, unsigned int start, + unsigned int stop, unsigned int max); + +unsigned long oprofile_get_cpu_buffer_size(void); +void oprofile_cpu_buffer_inc_smpl_lost(void); #endif /* OPROFILE_H */ -- cgit v1.2.3 From aeb5d727062a0238a2f96c9c380fbd2be4640c6f Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Sep 2008 15:28:45 -0400 Subject: [PATCH] introduce fmode_t, do annotations Signed-off-by: Al Viro --- include/linux/blkdev.h | 3 ++- include/linux/device-mapper.h | 8 ++++---- include/linux/file.h | 4 ++-- include/linux/fs.h | 16 ++++++++-------- include/linux/fsnotify.h | 2 +- include/linux/types.h | 1 + 6 files changed, 18 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b4fe68fe3a5..a4413ec3cb3 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -910,7 +910,8 @@ static inline int sb_issue_discard(struct super_block *sb, * command filter functions */ extern int blk_verify_command(struct blk_cmd_filter *filter, - unsigned char *cmd, int has_write_perm); + unsigned char *cmd, fmode_t has_write_perm); +extern void blk_unregister_filter(struct gendisk *disk); extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter); #define MAX_PHYS_SEGMENTS 128 diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 08d783592b7..3f8d4e76367 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -85,7 +85,7 @@ void dm_set_device_limits(struct dm_target *ti, struct block_device *bdev); struct dm_dev { struct block_device *bdev; - int mode; + fmode_t mode; char name[16]; }; @@ -95,7 +95,7 @@ struct dm_dev { * FIXME: too many arguments. */ int dm_get_device(struct dm_target *ti, const char *path, sector_t start, - sector_t len, int mode, struct dm_dev **result); + sector_t len, fmode_t mode, struct dm_dev **result); void dm_put_device(struct dm_target *ti, struct dm_dev *d); /* @@ -223,7 +223,7 @@ int dm_set_geometry(struct mapped_device *md, struct hd_geometry *geo); /* * First create an empty table. */ -int dm_table_create(struct dm_table **result, int mode, +int dm_table_create(struct dm_table **result, fmode_t mode, unsigned num_targets, struct mapped_device *md); /* @@ -254,7 +254,7 @@ void dm_table_put(struct dm_table *t); */ sector_t dm_table_get_size(struct dm_table *t); unsigned int dm_table_get_num_targets(struct dm_table *t); -int dm_table_get_mode(struct dm_table *t); +fmode_t dm_table_get_mode(struct dm_table *t); struct mapped_device *dm_table_get_md(struct dm_table *t); /* diff --git a/include/linux/file.h b/include/linux/file.h index a20259e248a..335a0a5c316 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -19,10 +19,10 @@ struct file_operations; struct vfsmount; struct dentry; extern int init_file(struct file *, struct vfsmount *mnt, - struct dentry *dentry, mode_t mode, + struct dentry *dentry, fmode_t mode, const struct file_operations *fop); extern struct file *alloc_file(struct vfsmount *, struct dentry *dentry, - mode_t mode, const struct file_operations *fop); + fmode_t mode, const struct file_operations *fop); static inline void fput_light(struct file *file, int fput_needed) { diff --git a/include/linux/fs.h b/include/linux/fs.h index a6a625be13f..60a7a581ba9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -63,18 +63,18 @@ extern int dir_notify_enable; #define MAY_ACCESS 16 #define MAY_OPEN 32 -#define FMODE_READ 1 -#define FMODE_WRITE 2 +#define FMODE_READ ((__force fmode_t)1) +#define FMODE_WRITE ((__force fmode_t)2) /* Internal kernel extensions */ -#define FMODE_LSEEK 4 -#define FMODE_PREAD 8 +#define FMODE_LSEEK ((__force fmode_t)4) +#define FMODE_PREAD ((__force fmode_t)8) #define FMODE_PWRITE FMODE_PREAD /* These go hand in hand */ /* File is being opened for execution. Primary users of this flag are distributed filesystems that can use it to achieve correct ETXTBUSY behavior for cross-node execution/opening_for_writing of files */ -#define FMODE_EXEC 16 +#define FMODE_EXEC ((__force fmode_t)16) #define RW_MASK 1 #define RWA_MASK 2 @@ -825,7 +825,7 @@ struct file { const struct file_operations *f_op; atomic_long_t f_count; unsigned int f_flags; - mode_t f_mode; + fmode_t f_mode; loff_t f_pos; struct fown_struct f_owner; unsigned int f_uid, f_gid; @@ -1714,7 +1714,7 @@ extern struct block_device *bdget(dev_t); extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); -extern struct block_device *open_by_devnum(dev_t, unsigned); +extern struct block_device *open_by_devnum(dev_t, fmode_t); #else static inline void bd_forget(struct inode *inode) {} #endif @@ -1729,7 +1729,7 @@ extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, struct gendisk *disk, unsigned cmd, unsigned long arg); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); -extern int blkdev_get(struct block_device *, mode_t, unsigned); +extern int blkdev_get(struct block_device *, fmode_t, unsigned); extern int blkdev_put(struct block_device *); extern int bd_claim(struct block_device *, void *); extern void bd_release(struct block_device *); diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index a89513188ce..00fbd5b245c 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h @@ -188,7 +188,7 @@ static inline void fsnotify_close(struct file *file) struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; const char *name = dentry->d_name.name; - mode_t mode = file->f_mode; + fmode_t mode = file->f_mode; u32 mask = (mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE; if (S_ISDIR(inode->i_mode)) diff --git a/include/linux/types.h b/include/linux/types.h index f24f7beb47d..1d98330b1f2 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -190,6 +190,7 @@ typedef __u32 __bitwise __wsum; #ifdef __KERNEL__ typedef unsigned __bitwise__ gfp_t; +typedef unsigned __bitwise__ fmode_t; #ifdef CONFIG_PHYS_ADDR_T_64BIT typedef u64 phys_addr_t; -- cgit v1.2.3 From 86d434dede14108dd917b25af0f29c0cb28b8d18 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 26 Aug 2007 19:50:05 -0400 Subject: [PATCH] eliminate use of ->f_flags in block methods store needed information in f_mode Signed-off-by: Al Viro --- include/linux/fs.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 60a7a581ba9..5ab5579a516 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -76,6 +76,10 @@ extern int dir_notify_enable; behavior for cross-node execution/opening_for_writing of files */ #define FMODE_EXEC ((__force fmode_t)16) +#define FMODE_NDELAY ((__force fmode_t)32) +#define FMODE_EXCL ((__force fmode_t)64) +#define FMODE_WRITE_IOCTL ((__force fmode_t)128) + #define RW_MASK 1 #define RWA_MASK 2 #define READ 0 -- cgit v1.2.3 From e915e872ed921d707bc32b3f2184d43abfa8c9e2 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Sep 2008 17:16:41 -0400 Subject: [PATCH] switch sg_scsi_ioctl() to passing fmode_t Signed-off-by: Al Viro --- include/linux/blkdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index a4413ec3cb3..8945c30e993 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -719,8 +719,8 @@ extern int blk_remove_plug(struct request_queue *); extern void blk_recount_segments(struct request_queue *, struct bio *); extern int scsi_cmd_ioctl(struct file *, struct request_queue *, struct gendisk *, unsigned int, void __user *); -extern int sg_scsi_ioctl(struct file *, struct request_queue *, - struct gendisk *, struct scsi_ioctl_command __user *); +extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, + struct scsi_ioctl_command __user *); /* * Temporary export, until SCSI gets fixed up. -- cgit v1.2.3 From 74f3c8aff36ad6552ea609c8b20bfd588fa16f38 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 27 Aug 2007 15:38:10 -0400 Subject: [PATCH] switch scsi_cmd_ioctl() to passing fmode_t Signed-off-by: Al Viro --- include/linux/blkdev.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 8945c30e993..48f41b991ad 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -717,8 +717,8 @@ extern void blk_plug_device(struct request_queue *); extern void blk_plug_device_unlocked(struct request_queue *); extern int blk_remove_plug(struct request_queue *); extern void blk_recount_segments(struct request_queue *, struct bio *); -extern int scsi_cmd_ioctl(struct file *, struct request_queue *, - struct gendisk *, unsigned int, void __user *); +extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t, + unsigned int, void __user *); extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t, struct scsi_ioctl_command __user *); -- cgit v1.2.3 From 1bddd9e6453ef1c7bc5b6f4ddbf7d31f4aee7a44 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 2 Sep 2008 17:19:43 -0400 Subject: [PATCH] lose the unused file argument in generic_ide_ioctl() Signed-off-by: Al Viro --- include/linux/ide.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 89e53cfbc78..0d03e83f719 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1158,8 +1158,7 @@ struct ide_ioctl_devset { int ide_setting_ioctl(ide_drive_t *, struct block_device *, unsigned int, unsigned long, const struct ide_ioctl_devset *); -int generic_ide_ioctl(ide_drive_t *, struct file *, struct block_device *, - unsigned, unsigned long); +int generic_ide_ioctl(ide_drive_t *, struct block_device *, unsigned, unsigned long); extern int ide_vlb_clk; extern int ide_pci_clk; -- cgit v1.2.3 From 647b3d0084158c47b1aea8f34d13cab9cd0a5b49 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 28 Aug 2007 22:15:59 -0400 Subject: [PATCH] lose unused arguments in dm ioctl callbacks Signed-off-by: Al Viro --- include/linux/device-mapper.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 3f8d4e76367..a567bbc5293 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -69,8 +69,7 @@ typedef int (*dm_status_fn) (struct dm_target *ti, status_type_t status_type, typedef int (*dm_message_fn) (struct dm_target *ti, unsigned argc, char **argv); -typedef int (*dm_ioctl_fn) (struct dm_target *ti, struct inode *inode, - struct file *filp, unsigned int cmd, +typedef int (*dm_ioctl_fn) (struct dm_target *ti, unsigned int cmd, unsigned long arg); typedef int (*dm_merge_fn) (struct dm_target *ti, struct bvec_merge_data *bvm, -- cgit v1.2.3 From 08f85851215100d0eebf026810955ee6ad456c38 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Oct 2007 13:26:20 -0400 Subject: [PATCH] move block_device_operations to blkdev.h Signed-off-by: Al Viro --- include/linux/blkdev.h | 17 +++++++++++++++++ include/linux/fs.h | 15 +-------------- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 48f41b991ad..48ec8862a11 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1057,6 +1057,23 @@ static inline int blk_integrity_rq(struct request *rq) #endif /* CONFIG_BLK_DEV_INTEGRITY */ +struct file; +struct inode; + +struct block_device_operations { + int (*open) (struct inode *, struct file *); + int (*release) (struct inode *, struct file *); + int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); + long (*unlocked_ioctl) (struct file *, unsigned, unsigned long); + long (*compat_ioctl) (struct file *, unsigned, unsigned long); + int (*direct_access) (struct block_device *, sector_t, + void **, unsigned long *); + int (*media_changed) (struct gendisk *); + int (*revalidate_disk) (struct gendisk *); + int (*getgeo)(struct block_device *, struct hd_geometry *); + struct module *owner; +}; + #else /* CONFIG_BLOCK */ /* * stubs for when the block layer is configured out diff --git a/include/linux/fs.h b/include/linux/fs.h index 5ab5579a516..58bbf689fef 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1270,20 +1270,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int); * to have different dirent layouts depending on the binary type. */ typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); - -struct block_device_operations { - int (*open) (struct inode *, struct file *); - int (*release) (struct inode *, struct file *); - int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); - long (*unlocked_ioctl) (struct file *, unsigned, unsigned long); - long (*compat_ioctl) (struct file *, unsigned, unsigned long); - int (*direct_access) (struct block_device *, sector_t, - void **, unsigned long *); - int (*media_changed) (struct gendisk *); - int (*revalidate_disk) (struct gendisk *); - int (*getgeo)(struct block_device *, struct hd_geometry *); - struct module *owner; -}; +struct block_device_operations; /* These macros are for out of kernel modules to test that * the kernel supports the unlocked_ioctl and compat_ioctl -- cgit v1.2.3 From bbc1cc978404105da23d505163ce9fd5598ed5b1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 7 Oct 2007 17:54:28 -0400 Subject: [PATCH] switch cdrom_{open,release,ioctl} to sane APIs ... convert to it in callers Signed-off-by: Al Viro --- include/linux/cdrom.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 5db265ea60f..0b49e08d3cb 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -987,11 +987,11 @@ struct cdrom_device_ops { }; /* the general block_device operations structure: */ -extern int cdrom_open(struct cdrom_device_info *cdi, struct inode *ip, - struct file *fp); -extern int cdrom_release(struct cdrom_device_info *cdi, struct file *fp); -extern int cdrom_ioctl(struct file *file, struct cdrom_device_info *cdi, - struct inode *ip, unsigned int cmd, unsigned long arg); +extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, + fmode_t mode); +extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode); +extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, + fmode_t mode, unsigned int cmd, unsigned long arg); extern int cdrom_media_changed(struct cdrom_device_info *); extern int register_cdrom(struct cdrom_device_info *cdi); -- cgit v1.2.3 From 633a08b81206122469365b4c72eaeb71f04f2cb4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 29 Aug 2007 20:34:12 -0400 Subject: [PATCH] introduce __blkdev_driver_ioctl() Analog of blkdev_driver_ioctl() with sane arguments. For now uses fake struct file, by the end of the series it won't and blkdev_driver_ioctl() will become a wrapper around it. Signed-off-by: Al Viro --- include/linux/blkdev.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 48ec8862a11..2bad616b994 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1074,6 +1074,8 @@ struct block_device_operations { struct module *owner; }; +extern int __blkdev_driver_ioctl(struct block_device *, fmode_t, unsigned int, + unsigned long); #else /* CONFIG_BLOCK */ /* * stubs for when the block layer is configured out -- cgit v1.2.3 From badf8082c33d18b118d3a6f1b32d5ea6b97d3839 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 16 Oct 2008 10:23:20 -0400 Subject: [PATCH] switch ide_disk_ops ->ioctl() to sane prototype Signed-off-by: Al Viro --- include/linux/ide.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ide.h b/include/linux/ide.h index 0d03e83f719..54525be4b5f 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -474,8 +474,8 @@ struct ide_disk_ops { ide_startstop_t (*do_request)(struct ide_drive_s *, struct request *, sector_t); int (*end_request)(struct ide_drive_s *, int, int); - int (*ioctl)(struct ide_drive_s *, struct inode *, - struct file *, unsigned int, unsigned long); + int (*ioctl)(struct ide_drive_s *, struct block_device *, + fmode_t, unsigned int, unsigned long); }; /* ATAPI device flags */ -- cgit v1.2.3 From d4430d62fa77208824a37fe6f85ab2831d274769 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 2 Mar 2008 09:09:22 -0500 Subject: [PATCH] beginning of methods conversion To keep the size of changesets sane we split the switch by drivers; to keep the damn thing bisectable we do the following: 1) rename the affected methods, add ones with correct prototypes, make (few) callers handle both. That's this changeset. 2) for each driver convert to new methods. *ALL* drivers are converted in this series. 3) kill the old (renamed) methods. Note that it _is_ a flagday; all in-tree drivers are converted and by the end of this series no trace of old methods remain. The only reason why we do that this way is to keep the damn thing bisectable and allow per-driver debugging if anything goes wrong. New methods: open(bdev, mode) release(disk, mode) ioctl(bdev, mode, cmd, arg) /* Called without BKL */ compat_ioctl(bdev, mode, cmd, arg) locked_ioctl(bdev, mode, cmd, arg) /* Called with BKL, legacy */ Signed-off-by: Al Viro --- include/linux/blkdev.h | 15 ++++++++++----- include/linux/fs.h | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 2bad616b994..b573186ff1a 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1061,11 +1061,16 @@ struct file; struct inode; struct block_device_operations { - int (*open) (struct inode *, struct file *); - int (*release) (struct inode *, struct file *); - int (*ioctl) (struct inode *, struct file *, unsigned, unsigned long); - long (*unlocked_ioctl) (struct file *, unsigned, unsigned long); - long (*compat_ioctl) (struct file *, unsigned, unsigned long); + int (*__open) (struct inode *, struct file *); + int (*__release) (struct inode *, struct file *); + int (*__ioctl) (struct inode *, struct file *, unsigned, unsigned long); + long (*__unlocked_ioctl) (struct file *, unsigned, unsigned long); + long (*__compat_ioctl) (struct file *, unsigned, unsigned long); + int (*open) (struct block_device *, fmode_t); + int (*release) (struct gendisk *, fmode_t); + int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); + int (*ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); + int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*direct_access) (struct block_device *, sector_t, void **, unsigned long *); int (*media_changed) (struct gendisk *); diff --git a/include/linux/fs.h b/include/linux/fs.h index 58bbf689fef..b5894604ba5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -79,6 +79,7 @@ extern int dir_notify_enable; #define FMODE_NDELAY ((__force fmode_t)32) #define FMODE_EXCL ((__force fmode_t)64) #define FMODE_WRITE_IOCTL ((__force fmode_t)128) +#define FMODE_NDELAY_NOW ((__force fmode_t)256) #define RW_MASK 1 #define RWA_MASK 2 -- cgit v1.2.3 From 90b8f2824ce68dd87d304641a1d5a048dfff39f5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 2 Mar 2008 10:43:36 -0500 Subject: [PATCH] end of methods switch: remove the old ones Signed-off-by: Al Viro --- include/linux/blkdev.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index b573186ff1a..a135256b272 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1057,15 +1057,7 @@ static inline int blk_integrity_rq(struct request *rq) #endif /* CONFIG_BLK_DEV_INTEGRITY */ -struct file; -struct inode; - struct block_device_operations { - int (*__open) (struct inode *, struct file *); - int (*__release) (struct inode *, struct file *); - int (*__ioctl) (struct inode *, struct file *, unsigned, unsigned long); - long (*__unlocked_ioctl) (struct file *, unsigned, unsigned long); - long (*__compat_ioctl) (struct file *, unsigned, unsigned long); int (*open) (struct block_device *, fmode_t); int (*release) (struct gendisk *, fmode_t); int (*locked_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); -- cgit v1.2.3 From 9a1c3542768b5a58e45a9216921cd10a3bae1205 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Feb 2008 20:40:24 -0500 Subject: [PATCH] pass fmode_t to blkdev_put() Signed-off-by: Al Viro --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index b5894604ba5..04c8dc41f45 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1722,7 +1722,7 @@ extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, unsigned long arg); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); extern int blkdev_get(struct block_device *, fmode_t, unsigned); -extern int blkdev_put(struct block_device *); +extern int blkdev_put(struct block_device *, fmode_t); extern int bd_claim(struct block_device *, void *); extern void bd_release(struct block_device *); #ifdef CONFIG_SYSFS -- cgit v1.2.3 From 30c40d2c01f68c7eb1a41ab3552bdaf5dbf300d4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 22 Feb 2008 19:50:45 -0500 Subject: [PATCH] propagate mode through open_bdev_excl/close_bdev_excl replace open_bdev_excl/close_bdev_excl with variants taking fmode_t. superblock gets the value used to mount it stored in sb->s_mode Signed-off-by: Al Viro --- include/linux/fs.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 04c8dc41f45..c6766314dc5 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1157,6 +1157,7 @@ struct super_block { char s_id[32]; /* Informational name */ void *s_fs_info; /* Filesystem private info */ + fmode_t s_mode; /* * The next field is for VFS *only*. No filesystems have any business @@ -1753,9 +1754,10 @@ extern void chrdev_show(struct seq_file *,off_t); extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); -extern struct block_device *open_bdev_excl(const char *, int, void *); -extern void close_bdev_excl(struct block_device *); +extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *); +extern void close_bdev_exclusive(struct block_device *, fmode_t); extern void blkdev_show(struct seq_file *,off_t); + #else #define BLKDEV_MAJOR_HASH_SIZE 0 #endif -- cgit v1.2.3 From e5eb8caa83a76191feb9705c1a0a689ca260b91e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Oct 2007 13:24:05 -0400 Subject: [PATCH] remember mode of reiserfs journal Signed-off-by: Al Viro --- include/linux/reiserfs_fs_sb.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 315517e8bfa..bda6b562a1e 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -178,6 +178,7 @@ struct reiserfs_journal { struct reiserfs_journal_cnode *j_first; /* oldest journal block. start here for traverse */ struct block_device *j_dev_bd; + fmode_t j_dev_mode; int j_1st_reserved_block; /* first block on s_dev of reserved area journal */ unsigned long j_state; -- cgit v1.2.3 From 572c48921574dbe6dceb958cf965aa962baefde4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 8 Oct 2007 13:24:05 -0400 Subject: [PATCH] sanitize blkdev_get() and friends * get rid of fake struct file/struct dentry in __blkdev_get() * merge __blkdev_get() and do_open() * get rid of flags argument of blkdev_get() Signed-off-by: Al Viro --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index c6766314dc5..cb78e389699 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1722,7 +1722,7 @@ extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, struct gendisk *disk, unsigned cmd, unsigned long arg); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); -extern int blkdev_get(struct block_device *, fmode_t, unsigned); +extern int blkdev_get(struct block_device *, fmode_t); extern int blkdev_put(struct block_device *, fmode_t); extern int bd_claim(struct block_device *, void *); extern void bd_release(struct block_device *); -- cgit v1.2.3 From e436fdae70a31102d2be32969b80fe8545edebd9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 18 Sep 2008 03:38:12 -0400 Subject: [PATCH] get rid of blkdev_driver_ioctl() convert remaining callers to __blkdev_driver_ioctl() Signed-off-by: Al Viro --- include/linux/fs.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index cb78e389699..11de682c65a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1718,9 +1718,6 @@ extern const struct file_operations def_fifo_fops; #ifdef CONFIG_BLOCK extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); -extern int blkdev_driver_ioctl(struct inode *inode, struct file *file, - struct gendisk *disk, unsigned cmd, - unsigned long arg); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); extern int blkdev_get(struct block_device *, fmode_t); extern int blkdev_put(struct block_device *, fmode_t); -- cgit v1.2.3 From 56b26add02b4bdea81d5e0ebda60db1fe3311ad4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 19 Sep 2008 03:17:36 -0400 Subject: [PATCH] kill the rest of struct file propagation in block ioctls Now we can switch blkdev_ioctl() block_device/mode Signed-off-by: Al Viro --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 11de682c65a..ff536e106b4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1717,7 +1717,7 @@ extern const struct file_operations bad_sock_fops; extern const struct file_operations def_fifo_fops; #ifdef CONFIG_BLOCK extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); -extern int blkdev_ioctl(struct inode *, struct file *, unsigned, unsigned long); +extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); extern int blkdev_get(struct block_device *, fmode_t); extern int blkdev_put(struct block_device *, fmode_t); -- cgit v1.2.3 From e9f95e637320efe1936b647308ddf4ec5b8e0311 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 21 Oct 2008 15:49:59 +0200 Subject: genirq: fix off by one and coding style Fix off-by-one in for_each_irq_desc_reverse(). Impact is near zero in practice, because nothing substantial wants to iterate down to IRQ#0 - but fix it nevertheless. Signed-off-by: Ingo Molnar Signed-off-by: Thomas Gleixner --- include/linux/irqnr.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h index 3171ddc3b39..452c280c811 100644 --- a/include/linux/irqnr.h +++ b/include/linux/irqnr.h @@ -13,9 +13,9 @@ 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--) +# define for_each_irq_desc_reverse(irq, desc) \ + for (irq = nr_irqs - 1, desc = irq_desc + (nr_irqs - 1); \ + irq >= 0; irq--, desc--) #endif #define for_each_irq_nr(irq) \ -- cgit v1.2.3 From 733d710b09748a79f70cbb58547d036d28ec566e Mon Sep 17 00:00:00 2001 From: Sergio Aguirre Date: Sat, 18 Oct 2008 12:26:47 -0300 Subject: V4L/DVB (9320): v4l2: Add 10-bit RAW Bayer formats Add 10-bit raw bayer format expanded to 16 bits. Adds also definition for 10-bit raw bayer format dpcm-compressed to 8 bits. Signed-off-by: Sergio Aguirre Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- include/linux/videodev2.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index d4b03034ee7..4669d7e72e7 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -315,6 +315,13 @@ struct v4l2_pix_format { /* see http://www.siliconimaging.com/RGB%20Bayer.htm */ #define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ #define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ +/* + * 10bit raw bayer, expanded to 16 bits + * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... + */ +#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') +/* 10bit raw bayer DPCM compressed to 8 bits */ +#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') #define V4L2_PIX_FMT_SBGGR16 v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */ /* compressed formats */ -- cgit v1.2.3 From d63a5ce3c0d25c96bdadc78792e5b48b846e899d Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Tue, 21 Oct 2008 17:44:57 +0100 Subject: dm: publish array_too_big Move array_too_big to include/linux/device-mapper.h because it is used by targets. Remove the test from dm-raid1 as the number of mirror legs is limited such that it can never fail. (Even for stripes it seems rather unlikely.) Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon --- include/linux/device-mapper.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h index 08d783592b7..dfb30db475e 100644 --- a/include/linux/device-mapper.h +++ b/include/linux/device-mapper.h @@ -354,6 +354,9 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size); */ #define dm_round_up(n, sz) (dm_div_up((n), (sz)) * (sz)) +#define dm_array_too_big(fixed, obj, num) \ + ((num) > (UINT_MAX - (fixed)) / (obj)) + static inline sector_t to_sector(unsigned long n) { return (n >> SECTOR_SHIFT); -- cgit v1.2.3 From 1f965b19437017cea6d3f3f46acdc5acae5fd011 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Tue, 21 Oct 2008 17:45:06 +0100 Subject: dm raid1: separate region_hash interface part1 Separate the region hash code from raid1 so it can be shared by forthcoming targets. Use BUG_ON() for failed async dm_io() calls. Signed-off-by: Heinz Mauelshagen Signed-off-by: Alasdair G Kergon --- include/linux/dm-region-hash.h | 104 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 include/linux/dm-region-hash.h (limited to 'include/linux') diff --git a/include/linux/dm-region-hash.h b/include/linux/dm-region-hash.h new file mode 100644 index 00000000000..a9e652a4137 --- /dev/null +++ b/include/linux/dm-region-hash.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. + * + * Device-Mapper dirty region hash interface. + * + * This file is released under the GPL. + */ + +#ifndef DM_REGION_HASH_H +#define DM_REGION_HASH_H + +#include + +/*----------------------------------------------------------------- + * Region hash + *----------------------------------------------------------------*/ +struct dm_region_hash; +struct dm_region; + +/* + * States a region can have. + */ +enum dm_rh_region_states { + DM_RH_CLEAN = 0x01, /* No writes in flight. */ + DM_RH_DIRTY = 0x02, /* Writes in flight. */ + DM_RH_NOSYNC = 0x04, /* Out of sync. */ + DM_RH_RECOVERING = 0x08, /* Under resynchronization. */ +}; + +/* + * Region hash create/destroy. + */ +struct bio_list; +struct dm_region_hash *dm_region_hash_create( + void *context, void (*dispatch_bios)(void *context, + struct bio_list *bios), + void (*wakeup_workers)(void *context), + void (*wakeup_all_recovery_waiters)(void *context), + sector_t target_begin, unsigned max_recovery, + struct dm_dirty_log *log, uint32_t region_size, + region_t nr_regions); +void dm_region_hash_destroy(struct dm_region_hash *rh); + +struct dm_dirty_log *dm_rh_dirty_log(struct dm_region_hash *rh); + +/* + * Conversion functions. + */ +region_t dm_rh_bio_to_region(struct dm_region_hash *rh, struct bio *bio); +sector_t dm_rh_region_to_sector(struct dm_region_hash *rh, region_t region); +void *dm_rh_region_context(struct dm_region *reg); + +/* + * Get region size and key (ie. number of the region). + */ +sector_t dm_rh_get_region_size(struct dm_region_hash *rh); +region_t dm_rh_get_region_key(struct dm_region *reg); + +/* + * Get/set/update region state (and dirty log). + * + */ +int dm_rh_get_state(struct dm_region_hash *rh, region_t region, int may_block); +void dm_rh_set_state(struct dm_region_hash *rh, region_t region, + enum dm_rh_region_states state, int may_block); + +/* Non-zero errors_handled leaves the state of the region NOSYNC */ +void dm_rh_update_states(struct dm_region_hash *rh, int errors_handled); + +/* Flush the region hash and dirty log. */ +int dm_rh_flush(struct dm_region_hash *rh); + +/* Inc/dec pending count on regions. */ +void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios); +void dm_rh_dec(struct dm_region_hash *rh, region_t region); + +/* Delay bios on regions. */ +void dm_rh_delay(struct dm_region_hash *rh, struct bio *bio); + +void dm_rh_mark_nosync(struct dm_region_hash *rh, + struct bio *bio, unsigned done, int error); + +/* + * Region recovery control. + */ + +/* Prepare some regions for recovery by starting to quiesce them. */ +void dm_rh_recovery_prepare(struct dm_region_hash *rh); + +/* Try fetching a quiesced region for recovery. */ +struct dm_region *dm_rh_recovery_start(struct dm_region_hash *rh); + +/* Report recovery end on a region. */ +void dm_rh_recovery_end(struct dm_region *reg, int error); + +/* Returns number of regions with recovery work outstanding. */ +int dm_rh_recovery_in_flight(struct dm_region_hash *rh); + +/* Start/stop recovery. */ +void dm_rh_start_recovery(struct dm_region_hash *rh); +void dm_rh_stop_recovery(struct dm_region_hash *rh); + +#endif /* DM_REGION_HASH_H */ -- cgit v1.2.3 From 5e458cc0f4770eea45d3c07110f01b3a94c72aa5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 22 Oct 2008 10:00:13 -0500 Subject: module: simplify load_module. Linus' recent catch of stack overflow in load_module lead me to look at the code. A couple of helpers to get a section address and get objects from a section can help clean things up a little. (And in case you're wondering, the stack size also dropped from 328 to 284 bytes). Signed-off-by: Rusty Russell --- include/linux/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 5d2970cdce9..eddf27db442 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -277,7 +277,7 @@ struct module /* Exception table */ unsigned int num_exentries; - const struct exception_table_entry *extable; + struct exception_table_entry *extable; /* Startup function. */ int (*init)(void); -- cgit v1.2.3 From 730b69d225259565c705f5f5a11cb1aba69568f1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 22 Oct 2008 10:00:22 -0500 Subject: module: check kernel param length at compile time, not runtime The kparam code tries to handle over-length parameter prefixes at runtime. Not only would I bet this has never been tested, it's not clear that truncating names is a good idea either. So let's check at compile time. We need to move the #define to moduleparam.h to do this, though. Signed-off-by: Rusty Russell --- include/linux/module.h | 2 +- include/linux/moduleparam.h | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index eddf27db442..196b499270d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -29,7 +29,7 @@ #define MODULE_SYMBOL_PREFIX "" #endif -#define MODULE_NAME_LEN (64 - sizeof(unsigned long)) +#define MODULE_NAME_LEN MAX_PARAM_PREFIX_LEN struct kernel_symbol { diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index ec624381c84..1eefe6d61b8 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -13,6 +13,9 @@ #define MODULE_PARAM_PREFIX KBUILD_MODNAME "." #endif +/* Chosen so that structs with an unsigned long line up. */ +#define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) + #ifdef MODULE #define ___module_cat(a,b) __mod_ ## a ## b #define __module_cat(a,b) ___module_cat(a,b) @@ -79,7 +82,8 @@ struct kparam_array #define __module_param_call(prefix, name, set, get, arg, perm) \ /* Default value instead of permissions? */ \ static int __param_perm_check_##name __attribute__((unused)) = \ - BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \ + BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)) \ + + BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN); \ static const char __param_str_##name[] = prefix #name; \ static struct kernel_param __moduleparam_const __param_##name \ __used \ -- cgit v1.2.3 From 9b473de87209fa86eb421b23386693b461612f30 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 22 Oct 2008 10:00:22 -0500 Subject: param: Fix duplicate module prefixes Instead of insisting each new module_param sysfs entry is unique, handle the case where it already exists (for builtin modules). The current code assumes that all identical prefixes are together in the section: true for normal uses, but not necessarily so if someone overrides MODULE_PARAM_PREFIX. More importantly, it's not true with the new "core_param()" code which uses "kernel" as a prefix. This simplifies the caller for the builtin case, at a slight loss of efficiency (we do the lookup every time to see if the directory exists). Signed-off-by: Rusty Russell Cc: Greg Kroah-Hartman --- include/linux/module.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index 196b499270d..3bfed013350 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -60,6 +60,7 @@ struct module_kobject struct kobject kobj; struct module *mod; struct kobject *drivers_dir; + struct module_param_attrs *mp; }; /* These are either module local, or the kernel's dummy ones. */ @@ -242,7 +243,6 @@ struct module /* Sysfs stuff. */ struct module_kobject mkobj; - struct module_param_attrs *param_attrs; struct module_attribute *modinfo_attrs; const char *version; const char *srcversion; -- cgit v1.2.3 From 67e67ceaac5bf55dbdceb704ff2d763d438b5373 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 22 Oct 2008 10:00:23 -0500 Subject: core_param() for genuinely core kernel parameters There are a lot of one-liner uses of __setup() in the kernel: they're cumbersome and not queryable (definitely not settable) via /sys. Yet it's ugly to simplify them to module_param(), because by default that inserts a prefix of the module name (usually filename). So, introduce a "core_param". The parameter gets no prefix, but appears in /sys/module/kernel/parameters/ (if non-zero perms arg). I thought about using the name "core", but that's more common than "kernel". And if you create a module called "kernel", you will die a horrible death. Signed-off-by: Rusty Russell --- include/linux/moduleparam.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/linux') diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 1eefe6d61b8..e4af3399ef4 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -104,6 +104,25 @@ struct kparam_array #define module_param(name, type, perm) \ module_param_named(name, name, type, perm) +#ifndef MODULE +/** + * core_param - define a historical core kernel parameter. + * @name: the name of the cmdline and sysfs parameter (often the same as var) + * @var: the variable + * @type: the type (for param_set_##type and param_get_##type) + * @perm: visibility in sysfs + * + * core_param is just like module_param(), but cannot be modular and + * doesn't add a prefix (such as "printk."). This is for compatibility + * with __setup(), and it makes sense as truly core parameters aren't + * tied to the particular file they're in. + */ +#define core_param(name, var, type, perm) \ + param_check_##type(name, &(var)); \ + __module_param_call("", name, param_set_##type, param_get_##type, \ + &var, perm) +#endif /* !MODULE */ + /* Actually copy string: maxlen param is usually sizeof(string). */ #define module_param_string(name, string, len, perm) \ static const struct kparam_string __param_string_##name \ -- cgit v1.2.3 From 0d557dc97f4bb501f086a03d0f00b99a7855d794 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Mon, 13 Oct 2008 23:50:09 +0200 Subject: workqueue: introduce create_rt_workqueue create_rt_workqueue will create a real time prioritized workqueue. This is needed for the conversion of stop_machine to a workqueue based implementation. This patch adds yet another parameter to __create_workqueue_key to tell it that we want an rt workqueue. However it looks like we rather should have something like "int type" instead of singlethread, freezable and rt. Signed-off-by: Heiko Carstens Signed-off-by: Rusty Russell Cc: Ingo Molnar --- include/linux/workqueue.h | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 5c158c477ac..89a5a1231ff 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -149,11 +149,11 @@ struct execute_work { extern struct workqueue_struct * __create_workqueue_key(const char *name, int singlethread, - int freezeable, struct lock_class_key *key, + int freezeable, int rt, struct lock_class_key *key, const char *lock_name); #ifdef CONFIG_LOCKDEP -#define __create_workqueue(name, singlethread, freezeable) \ +#define __create_workqueue(name, singlethread, freezeable, rt) \ ({ \ static struct lock_class_key __key; \ const char *__lock_name; \ @@ -164,17 +164,19 @@ __create_workqueue_key(const char *name, int singlethread, __lock_name = #name; \ \ __create_workqueue_key((name), (singlethread), \ - (freezeable), &__key, \ + (freezeable), (rt), &__key, \ __lock_name); \ }) #else -#define __create_workqueue(name, singlethread, freezeable) \ - __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL) +#define __create_workqueue(name, singlethread, freezeable, rt) \ + __create_workqueue_key((name), (singlethread), (freezeable), (rt), \ + NULL, NULL) #endif -#define create_workqueue(name) __create_workqueue((name), 0, 0) -#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1) -#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) +#define create_workqueue(name) __create_workqueue((name), 0, 0, 0) +#define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1) +#define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0) +#define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0) extern void destroy_workqueue(struct workqueue_struct *wq); -- cgit v1.2.3 From a30d46c042c8a17ef25de02f439fbd120ab8a8de Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 20 Oct 2008 23:46:28 +0200 Subject: mfd: twl4030 IRQ handling update - Move it into a separate file; clean and streamline it - Restructure the init code for reuse during secondary dispatch - Support both levels (primary, secondary) of IRQ dispatch - Use a workqueue for irq mask/unmask and trigger configuration Code for two subchips currently share that secondary handler code. One is the power subchip; its IRQs are now handled by this core, courtesy of this patch. The other is the GPIO module, which will be supported through a later patch. There are also minor changes to the header file, mostly related to GPIO support; nothing yet in mainline cares about those. A few references to OMAP-specific symbols are disabled; when they can all be removed, the TWL4030 support ceases being OMAP-specific. Signed-off-by: David Brownell Signed-off-by: Tony Lindgren Signed-off-by: Samuel Ortiz --- include/linux/i2c/twl4030.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i2c/twl4030.h b/include/linux/i2c/twl4030.h index cdb453162a9..fb604dcd38f 100644 --- a/include/linux/i2c/twl4030.h +++ b/include/linux/i2c/twl4030.h @@ -228,6 +228,12 @@ struct twl4030_gpio_platform_data { int gpio_base; unsigned irq_base, irq_end; + /* package the two LED signals as output-only GPIOs? */ + bool use_leds; + + /* gpio-n should control VMMC(n+1) if BIT(n) in mmc_cd is set */ + u8 mmc_cd; + /* For gpio-N, bit (1 << N) in "pullups" is set if that pullup * should be enabled. Else, if that bit is set in "pulldowns", * that pulldown is enabled. Don't waste power by letting any @@ -277,6 +283,8 @@ struct twl4030_platform_data { /*----------------------------------------------------------------------*/ +int twl4030_sih_setup(int module); + /* * FIXME completely stop using TWL4030_IRQ_BASE ... instead, pass the * IRQ data to subsidiary devices using platform device resources. @@ -291,16 +299,16 @@ struct twl4030_platform_data { #define TWL4030_MODIRQ_BCI (TWL4030_IRQ_BASE + 2) #define TWL4030_MODIRQ_MADC (TWL4030_IRQ_BASE + 3) /* #define TWL4030_MODIRQ_USB (TWL4030_IRQ_BASE + 4) */ -#define TWL4030_MODIRQ_PWR (TWL4030_IRQ_BASE + 5) +/* #define TWL4030_MODIRQ_PWR (TWL4030_IRQ_BASE + 5) */ #define TWL4030_PWRIRQ_PWRBTN (TWL4030_PWR_IRQ_BASE + 0) -#define TWL4030_PWRIRQ_CHG_PRES (TWL4030_PWR_IRQ_BASE + 1) -#define TWL4030_PWRIRQ_USB_PRES (TWL4030_PWR_IRQ_BASE + 2) -#define TWL4030_PWRIRQ_RTC (TWL4030_PWR_IRQ_BASE + 3) -#define TWL4030_PWRIRQ_HOT_DIE (TWL4030_PWR_IRQ_BASE + 4) -#define TWL4030_PWRIRQ_PWROK_TIMEOUT (TWL4030_PWR_IRQ_BASE + 5) -#define TWL4030_PWRIRQ_MBCHG (TWL4030_PWR_IRQ_BASE + 6) -#define TWL4030_PWRIRQ_SC_DETECT (TWL4030_PWR_IRQ_BASE + 7) +/* #define TWL4030_PWRIRQ_CHG_PRES (TWL4030_PWR_IRQ_BASE + 1) */ +/* #define TWL4030_PWRIRQ_USB_PRES (TWL4030_PWR_IRQ_BASE + 2) */ +/* #define TWL4030_PWRIRQ_RTC (TWL4030_PWR_IRQ_BASE + 3) */ +/* #define TWL4030_PWRIRQ_HOT_DIE (TWL4030_PWR_IRQ_BASE + 4) */ +/* #define TWL4030_PWRIRQ_PWROK_TIMEOUT (TWL4030_PWR_IRQ_BASE + 5) */ +/* #define TWL4030_PWRIRQ_MBCHG (TWL4030_PWR_IRQ_BASE + 6) */ +/* #define TWL4030_PWRIRQ_SC_DETECT (TWL4030_PWR_IRQ_BASE + 7) */ /* Rest are unsued currently*/ @@ -317,17 +325,13 @@ struct twl4030_platform_data { /* TWL4030 GPIO interrupt definitions */ #define TWL4030_GPIO_IRQ_NO(n) (TWL4030_GPIO_IRQ_BASE + (n)) -#define TWL4030_GPIO_IS_ENABLE 1 /* * Exported TWL4030 GPIO APIs * * WARNING -- use standard GPIO and IRQ calls instead; these will vanish. */ -int twl4030_get_gpio_datain(int gpio); -int twl4030_request_gpio(int gpio); int twl4030_set_gpio_debounce(int gpio, int enable); -int twl4030_free_gpio(int gpio); #if defined(CONFIG_TWL4030_BCI_BATTERY) || \ defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) -- cgit v1.2.3 From 27471fdb32e77ecb92f09d4ac5757785b4dc33bc Mon Sep 17 00:00:00 2001 From: Andy Henroid Date: Thu, 9 Oct 2008 11:45:22 -0700 Subject: i7300_idle driver v1.55 The Intel 7300 Memory Controller supports dynamic throttling of memory which can be used to save power when system is idle. This driver does the memory throttling when all CPUs are idle on such a system. Refer to "Intel 7300 Memory Controller Hub (MCH)" datasheet for the config space description. Signed-off-by: Andy Henroid Signed-off-by: Len Brown Signed-off-by: Venkatesh Pallipadi --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index f1624b39675..efb786d11f2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2422,6 +2422,7 @@ #define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a #define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e #define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b +#define PCI_DEVICE_ID_INTEL_FBD_CNB 0x360c #define PCI_DEVICE_ID_INTEL_ICH10_0 0x3a14 #define PCI_DEVICE_ID_INTEL_ICH10_1 0x3a16 #define PCI_DEVICE_ID_INTEL_ICH10_2 0x3a18 -- cgit v1.2.3 From 4ce72a2c063a7fa8e42a9435440ae3364115a58d Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 22 Oct 2008 15:25:26 +0800 Subject: sched: add CONFIG_SMP consistency a patch from Henrik Austad did this: >> Do not declare select_task_rq as part of sched_class when CONFIG_SMP is >> not set. Peter observed: > While a proper cleanup, could you do it by re-arranging the methods so > as to not create an additional ifdef? Do not declare select_task_rq and some other methods as part of sched_class when CONFIG_SMP is not set. Also gather those methods to avoid CONFIG_SMP mess. Idea-by: Henrik Austad Signed-off-by: Li Zefan Acked-by: Peter Zijlstra Acked-by: Henrik Austad Signed-off-by: Ingo Molnar --- include/linux/sched.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 4f59c8e8597..c05b45faef1 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -897,7 +897,6 @@ struct sched_class { void (*enqueue_task) (struct rq *rq, struct task_struct *p, int wakeup); void (*dequeue_task) (struct rq *rq, struct task_struct *p, int sleep); void (*yield_task) (struct rq *rq); - int (*select_task_rq)(struct task_struct *p, int sync); void (*check_preempt_curr) (struct rq *rq, struct task_struct *p, int sync); @@ -905,6 +904,8 @@ struct sched_class { void (*put_prev_task) (struct rq *rq, struct task_struct *p); #ifdef CONFIG_SMP + int (*select_task_rq)(struct task_struct *p, int sync); + unsigned long (*load_balance) (struct rq *this_rq, int this_cpu, struct rq *busiest, unsigned long max_load_move, struct sched_domain *sd, enum cpu_idle_type idle, @@ -916,16 +917,17 @@ struct sched_class { void (*pre_schedule) (struct rq *this_rq, struct task_struct *task); void (*post_schedule) (struct rq *this_rq); void (*task_wake_up) (struct rq *this_rq, struct task_struct *task); -#endif - void (*set_curr_task) (struct rq *rq); - void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); - void (*task_new) (struct rq *rq, struct task_struct *p); void (*set_cpus_allowed)(struct task_struct *p, const cpumask_t *newmask); void (*rq_online)(struct rq *rq); void (*rq_offline)(struct rq *rq); +#endif + + void (*set_curr_task) (struct rq *rq); + void (*task_tick) (struct rq *rq, struct task_struct *p, int queued); + void (*task_new) (struct rq *rq, struct task_struct *p); void (*switched_from) (struct rq *this_rq, struct task_struct *task, int running); -- cgit v1.2.3 From 319edafef64406c971035c56bd68480e5a82b581 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Mon, 20 Oct 2008 18:15:30 +0100 Subject: smc911x: Add IRQ polarity configuration Platforms like ARM Ltd's RealView require the IRQ polarity bit to be set for the SMC9118 chip. This patch allows the dynamic configuration via the smc911x_platdata structure. This patch also changes the smc91x_platdata structure name to the correct smc911x_platdata in the smc911x_drv_probe() function. Signed-off-by: Catalin Marinas Signed-off-by: Jeff Garzik --- include/linux/smc911x.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/smc911x.h b/include/linux/smc911x.h index b58f54c2418..521f37143fa 100644 --- a/include/linux/smc911x.h +++ b/include/linux/smc911x.h @@ -7,6 +7,7 @@ struct smc911x_platdata { unsigned long flags; unsigned long irq_flags; /* IRQF_... */ + int irq_polarity; }; #endif /* __SMC911X_H__ */ -- cgit v1.2.3 From a73a63701f8f23e70674b3c5e367a0a726c18468 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 22 Oct 2008 14:45:11 +0200 Subject: HID: add hid_type to general hid struct Add type to the hid structure to distinguish to which device type (now only mouse) we are talking to. Needed for per device type ignore list support. Note: this patch leaves the type as unknown for bluetooth devices, there is not support for this in the hidp code. Signed-off-by: Jiri Slaby Signed-off-by: Jiri Kosina --- include/linux/hid.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index f13bca2dd53..5355ca4b939 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -417,6 +417,11 @@ struct hid_input { struct input_dev *input; }; +enum hid_type { + HID_TYPE_OTHER = 0, + HID_TYPE_USBMOUSE +}; + struct hid_driver; struct hid_ll_driver; @@ -431,6 +436,7 @@ struct hid_device { /* device report descriptor */ __u32 vendor; /* Vendor ID */ __u32 product; /* Product ID */ __u32 version; /* HID version */ + enum hid_type type; /* device type (mouse, kbd, ...) */ unsigned country; /* HID country */ struct hid_report_enum report_enum[HID_REPORT_TYPES]; -- cgit v1.2.3 From 93fc9e1bb6507dde945c2eab68c93e1066ac3691 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Wed, 22 Oct 2008 10:25:29 -0700 Subject: mlx4_core: Support multiple pre-reserved QP regions For ethernet support, we need to reserve QPs for the ethernet and fibre channel driver. The QPs are reserved at the end of the QP table. (This way we assure that they are aligned to their size) We need to consider these reserved ranges in bitmap creation, so we extend the mlx4 bitmap utility functions to allow reserved ranges at both the bottom and the top of the range. Signed-off-by: Yevgeny Petrilin Signed-off-by: Roland Dreier --- include/linux/mlx4/device.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index d21e879f3c9..693f93cd29e 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -145,6 +145,18 @@ enum { MLX4_MTT_FLAG_PRESENT = 1 }; +enum mlx4_qp_region { + MLX4_QP_REGION_FW = 0, + MLX4_QP_REGION_ETH_ADDR, + MLX4_QP_REGION_FC_ADDR, + MLX4_QP_REGION_FC_EXCH, + MLX4_NUM_QP_REGION +}; + +enum { + MLX4_NUM_FEXCH = 64 * 1024, +}; + static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor) { return (major << 32) | (minor << 16) | subminor; @@ -169,7 +181,6 @@ struct mlx4_caps { int max_rq_desc_sz; int max_qp_init_rdma; int max_qp_dest_rdma; - int reserved_qps; int sqp_start; int num_srqs; int max_srq_wqes; @@ -201,6 +212,12 @@ struct mlx4_caps { u16 stat_rate_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; int max_gso_sz; + int reserved_qps_cnt[MLX4_NUM_QP_REGION]; + int reserved_qps; + int reserved_qps_base[MLX4_NUM_QP_REGION]; + int log_num_macs; + int log_num_vlans; + int log_num_prios; }; struct mlx4_buf_list { -- cgit v1.2.3 From b79acb49de6c2ab9ff0245f0f2b573d48b9a2d93 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Wed, 22 Oct 2008 10:56:48 -0700 Subject: mlx4_core: Get ethernet MTU and default address from firmware Get maximum ethernet MTU and default MAC address from the firmware QUERY_DEV_CAP command. Signed-off-by: Yevgeny Petrilin Signed-off-by: Roland Dreier --- include/linux/mlx4/device.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 693f93cd29e..f9e73cfc540 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -166,7 +166,9 @@ struct mlx4_caps { u64 fw_ver; int num_ports; int vl_cap[MLX4_MAX_PORTS + 1]; - int mtu_cap[MLX4_MAX_PORTS + 1]; + int ib_mtu_cap[MLX4_MAX_PORTS + 1]; + u64 def_mac[MLX4_MAX_PORTS + 1]; + int eth_mtu_cap[MLX4_MAX_PORTS + 1]; int gid_table_len[MLX4_MAX_PORTS + 1]; int pkey_table_len[MLX4_MAX_PORTS + 1]; int local_ca_ack_delay; -- cgit v1.2.3 From 08e5338d119daeb3c7746fa80fa916b8d3d48e89 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 22 Oct 2008 20:21:29 +0200 Subject: i2c-algo-pcf: Pass adapter data into ->waitforpin() method Pass adapter data into ->waitforpin() method. Signed-off-by: David S. Miller Signed-off-by: Jean Delvare --- include/linux/i2c-algo-pcf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 0177d280f73..5de8a319bf1 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -31,7 +31,7 @@ struct i2c_algo_pcf_data { int (*getpcf) (void *data, int ctl); int (*getown) (void *data); int (*getclock) (void *data); - void (*waitforpin) (void); + void (*waitforpin) (void *data); /* Multi-master lost arbitration back-off delay (msecs) * This should be set by the bus adapter or knowledgable client -- cgit v1.2.3 From 30091404af5a7cd515e7b565df76932e295d8f6f Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 22 Oct 2008 20:21:30 +0200 Subject: i2c-algo-pcf: Add adapter hooks around xfer begin and end Some I2C bus implementations need to synchronize with external entities, such as system firmware, which might also be programming the same I2C bus. In order to facilitate this add ->xfer_begin() and ->xfer_end() hooks which are invoked around pcf_xfer(). [JD: Make these hooks optional.] Signed-off-by: David S. Miller Signed-off-by: Jean Delvare --- include/linux/i2c-algo-pcf.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/i2c-algo-pcf.h b/include/linux/i2c-algo-pcf.h index 5de8a319bf1..0f91a957a69 100644 --- a/include/linux/i2c-algo-pcf.h +++ b/include/linux/i2c-algo-pcf.h @@ -33,6 +33,9 @@ struct i2c_algo_pcf_data { int (*getclock) (void *data); void (*waitforpin) (void *data); + void (*xfer_begin) (void *data); + void (*xfer_end) (void *data); + /* Multi-master lost arbitration back-off delay (msecs) * This should be set by the bus adapter or knowledgable client * if bus is multi-mastered, else zero -- cgit v1.2.3 From 14f55f7a033f86a4e8f0310dd4d54b5464322e6e Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 22 Oct 2008 20:21:30 +0200 Subject: i2c: Make clear what the class field of i2c_adapter is good for Make clear what the class field of i2c_adapter is good for. Signed-off-by: Wolfram Sang Signed-off-by: Jean Delvare --- include/linux/i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 06115128047..4ac8ec3c792 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -345,7 +345,7 @@ struct i2c_algorithm { struct i2c_adapter { struct module *owner; unsigned int id; - unsigned int class; + unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; -- cgit v1.2.3 From 7d1d8999b4bec0ba09f935e648a688bb25596d06 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 22 Oct 2008 20:21:31 +0200 Subject: i2c: Constify i2c_get_clientdata's parameter i2c_get_clientdata doesn't change the i2c_client it is passed as a parameter, so it can be constified. Same for i2c_get_adapdata. Signed-off-by: Jean Delvare --- include/linux/device.h | 2 +- include/linux/i2c.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index 987f5912720..1a3686d15f9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -450,7 +450,7 @@ static inline void set_dev_node(struct device *dev, int node) } #endif -static inline void *dev_get_drvdata(struct device *dev) +static inline void *dev_get_drvdata(const struct device *dev) { return dev->driver_data; } diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 4ac8ec3c792..a411f0b70e8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -224,7 +224,7 @@ static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) return to_i2c_client(dev); } -static inline void *i2c_get_clientdata (struct i2c_client *dev) +static inline void *i2c_get_clientdata(const struct i2c_client *dev) { return dev_get_drvdata (&dev->dev); } @@ -369,7 +369,7 @@ struct i2c_adapter { }; #define to_i2c_adapter(d) container_of(d, struct i2c_adapter, dev) -static inline void *i2c_get_adapdata (struct i2c_adapter *dev) +static inline void *i2c_get_adapdata(const struct i2c_adapter *dev) { return dev_get_drvdata (&dev->dev); } -- cgit v1.2.3 From c0589d4bc19294a49934af1be736eb6e9ad11673 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 22 Oct 2008 20:21:31 +0200 Subject: i2c: Drop 2-byte address block transfer defines We have no users and no implementers for these transfer types so it makes little sense to define functionality bits for them. Signed-off-by: Jean Delvare --- include/linux/i2c.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index a411f0b70e8..7d21aba819f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -541,8 +541,6 @@ struct i2c_msg { #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ -#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ -#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ I2C_FUNC_SMBUS_WRITE_BYTE) @@ -554,8 +552,6 @@ struct i2c_msg { I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) -#define I2C_FUNC_SMBUS_I2C_BLOCK_2 (I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2) #define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ I2C_FUNC_SMBUS_BYTE | \ -- cgit v1.2.3 From 3ae70deef0a5cc34a96aa1972697d01606bc7933 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 22 Oct 2008 20:21:32 +0200 Subject: i2c: Clean up Fix most checkpatch.pl errors and warnings. This includes replacing spaces with tabs in many places, adding and removing spaces, and folding long lines. Also complete a couple prototypes to make it clearer what the parameters represent. Signed-off-by: Jean Delvare --- include/linux/i2c.h | 149 ++++++++++++++++++++++++++-------------------------- 1 file changed, 75 insertions(+), 74 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7d21aba819f..12d7364ad3f 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -53,45 +53,44 @@ struct i2c_board_info; * transmit one message at a time, a more complex version can be used to * transmit an arbitrary number of messages without interruption. */ -extern int i2c_master_send(struct i2c_client *,const char* ,int); -extern int i2c_master_recv(struct i2c_client *,char* ,int); +extern int i2c_master_send(struct i2c_client *client, const char *buf, + int count); +extern int i2c_master_recv(struct i2c_client *client, char *buf, int count); /* Transfer num messages. */ -extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); - +extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); /* This is the very generalized SMBus access routine. You probably do not want to use this, though; one of the functions below may be much easier, and probably just as fast. Note that we use i2c_adapter here, because you do not need a specific smbus adapter to call this function. */ -extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr, - unsigned short flags, - char read_write, u8 command, int size, - union i2c_smbus_data * data); +extern s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char read_write, u8 command, + int size, union i2c_smbus_data *data); /* Now follow the 'nice' access routines. These also document the calling conventions of i2c_smbus_xfer. */ -extern s32 i2c_smbus_read_byte(struct i2c_client * client); -extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value); -extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command); -extern s32 i2c_smbus_write_byte_data(struct i2c_client * client, - u8 command, u8 value); -extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command); -extern s32 i2c_smbus_write_word_data(struct i2c_client * client, - u8 command, u16 value); +extern s32 i2c_smbus_read_byte(struct i2c_client *client); +extern s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value); +extern s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command); +extern s32 i2c_smbus_write_byte_data(struct i2c_client *client, + u8 command, u8 value); +extern s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command); +extern s32 i2c_smbus_write_word_data(struct i2c_client *client, + u8 command, u16 value); /* Returns the number of read bytes */ extern s32 i2c_smbus_read_block_data(struct i2c_client *client, u8 command, u8 *values); -extern s32 i2c_smbus_write_block_data(struct i2c_client * client, - u8 command, u8 length, - const u8 *values); +extern s32 i2c_smbus_write_block_data(struct i2c_client *client, + u8 command, u8 length, const u8 *values); /* Returns the number of read bytes */ -extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, +extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 length, u8 *values); -extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, +extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, u8 length, const u8 *values); @@ -169,7 +168,7 @@ struct i2c_driver { /* a ioctl like command that can be used to perform specific functions * with the device. */ - int (*command)(struct i2c_client *client,unsigned int cmd, void *arg); + int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); struct device_driver driver; const struct i2c_device_id *id_table; @@ -226,12 +225,12 @@ static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj) static inline void *i2c_get_clientdata(const struct i2c_client *dev) { - return dev_get_drvdata (&dev->dev); + return dev_get_drvdata(&dev->dev); } -static inline void i2c_set_clientdata (struct i2c_client *dev, void *data) +static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) { - dev_set_drvdata (&dev->dev, data); + dev_set_drvdata(&dev->dev, data); } /** @@ -272,7 +271,7 @@ struct i2c_board_info { * fields (such as associated irq, or device-specific platform_data) * are provided using conventional syntax. */ -#define I2C_BOARD_INFO(dev_type,dev_addr) \ +#define I2C_BOARD_INFO(dev_type, dev_addr) \ .type = (dev_type), .addr = (dev_addr) @@ -306,10 +305,12 @@ extern void i2c_unregister_device(struct i2c_client *); */ #ifdef CONFIG_I2C_BOARDINFO extern int -i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n); +i2c_register_board_info(int busnum, struct i2c_board_info const *info, + unsigned n); #else static inline int -i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n) +i2c_register_board_info(int busnum, struct i2c_board_info const *info, + unsigned n) { return 0; } @@ -328,11 +329,11 @@ struct i2c_algorithm { using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ - int (*master_xfer)(struct i2c_adapter *adap,struct i2c_msg *msgs, - int num); + int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, + int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, - unsigned short flags, char read_write, - u8 command, int size, union i2c_smbus_data * data); + unsigned short flags, char read_write, + u8 command, int size, union i2c_smbus_data *data); /* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); @@ -371,12 +372,12 @@ struct i2c_adapter { static inline void *i2c_get_adapdata(const struct i2c_adapter *dev) { - return dev_get_drvdata (&dev->dev); + return dev_get_drvdata(&dev->dev); } -static inline void i2c_set_adapdata (struct i2c_adapter *dev, void *data) +static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data) { - dev_set_drvdata (&dev->dev, data); + dev_set_drvdata(&dev->dev, data); } /*flags for the client struct: */ @@ -449,7 +450,7 @@ extern int i2c_probe(struct i2c_adapter *adapter, const struct i2c_client_address_data *address_data, int (*found_proc) (struct i2c_adapter *, int, int)); -extern struct i2c_adapter* i2c_get_adapter(int id); +extern struct i2c_adapter *i2c_get_adapter(int id); extern void i2c_put_adapter(struct i2c_adapter *adap); @@ -465,7 +466,7 @@ static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) return (func & i2c_get_functionality(adap)) == func; } -/* Return id number for a specific adapter */ +/* Return the adapter number for a specific adapter */ static inline int i2c_adapter_id(struct i2c_adapter *adap) { return adap->nr; @@ -526,7 +527,7 @@ struct i2c_msg { #define I2C_FUNC_I2C 0x00000001 #define I2C_FUNC_10BIT_ADDR 0x00000002 -#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ +#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_NOSTART etc. */ #define I2C_FUNC_SMBUS_PEC 0x00000008 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ #define I2C_FUNC_SMBUS_QUICK 0x00010000 @@ -542,25 +543,25 @@ struct i2c_msg { #define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ -#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ - I2C_FUNC_SMBUS_WRITE_BYTE) -#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ - I2C_FUNC_SMBUS_WRITE_BYTE_DATA) -#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA) -#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) -#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) - -#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ - I2C_FUNC_SMBUS_BYTE | \ - I2C_FUNC_SMBUS_BYTE_DATA | \ - I2C_FUNC_SMBUS_WORD_DATA | \ - I2C_FUNC_SMBUS_PROC_CALL | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ - I2C_FUNC_SMBUS_I2C_BLOCK | \ - I2C_FUNC_SMBUS_PEC) +#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ + I2C_FUNC_SMBUS_WRITE_BYTE) +#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ + I2C_FUNC_SMBUS_WRITE_BYTE_DATA) +#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ + I2C_FUNC_SMBUS_WRITE_WORD_DATA) +#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) +#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) + +#define I2C_FUNC_SMBUS_EMUL (I2C_FUNC_SMBUS_QUICK | \ + I2C_FUNC_SMBUS_BYTE | \ + I2C_FUNC_SMBUS_BYTE_DATA | \ + I2C_FUNC_SMBUS_WORD_DATA | \ + I2C_FUNC_SMBUS_PROC_CALL | \ + I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ + I2C_FUNC_SMBUS_I2C_BLOCK | \ + I2C_FUNC_SMBUS_PEC) /* * Data for SMBus Messages @@ -570,7 +571,7 @@ union i2c_smbus_data { __u8 byte; __u16 word; __u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */ - /* and one more for user-space compatibility */ + /* and one more for user-space compatibility */ }; /* i2c_smbus_xfer read or write markers */ @@ -598,21 +599,21 @@ union i2c_smbus_data { /* Default fill of many variables */ #define I2C_CLIENT_DEFAULTS {I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ - I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END} + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END, \ + I2C_CLIENT_END, I2C_CLIENT_END, I2C_CLIENT_END} /* I2C_CLIENT_MODULE_PARM creates a module parameter, and puts it in the module header */ @@ -621,7 +622,7 @@ union i2c_smbus_data { static unsigned short var[I2C_CLIENT_MAX_OPTS] = I2C_CLIENT_DEFAULTS; \ static unsigned int var##_num; \ module_param_array(var, short, &var##_num, 0); \ - MODULE_PARM_DESC(var,desc) + MODULE_PARM_DESC(var, desc) #define I2C_CLIENT_MODULE_PARM_FORCE(name) \ I2C_CLIENT_MODULE_PARM(force_##name, \ -- cgit v1.2.3 From 11f1f2afd6b07729b12aaba479344d7f12d88ff9 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 22 Oct 2008 20:21:33 +0200 Subject: i2c: Add info->archdata field If present the info->archdata is copied into the dev->archdata. Some (OpenFirmware) platforms need it. Signed-off-by: Anton Vorontsov Signed-off-by: Jean Delvare --- include/linux/i2c.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 12d7364ad3f..33a5992d493 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -239,6 +239,7 @@ static inline void i2c_set_clientdata(struct i2c_client *dev, void *data) * @flags: to initialize i2c_client.flags * @addr: stored in i2c_client.addr * @platform_data: stored in i2c_client.dev.platform_data + * @archdata: copied into i2c_client.dev.archdata * @irq: stored in i2c_client.irq * * I2C doesn't actually support hardware probing, although controllers and @@ -258,6 +259,7 @@ struct i2c_board_info { unsigned short flags; unsigned short addr; void *platform_data; + struct dev_archdata *archdata; int irq; }; -- cgit v1.2.3 From 2a2336f8228292b8197f4187e54b0748903e6645 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Wed, 22 Oct 2008 11:44:46 -0700 Subject: mlx4_core: Ethernet MAC/VLAN management Add support for managing MAC and VLAN filters for each port. Signed-off-by: Yevgeny Petrilin Signed-off-by: Oren Duer Signed-off-by: Roland Dreier --- include/linux/mlx4/cmd.h | 9 +++++++++ include/linux/mlx4/device.h | 12 ++++++++++++ 2 files changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 77323a72dd3..cf9c679ab38 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -132,6 +132,15 @@ enum { MLX4_MAILBOX_SIZE = 4096 }; +enum { + /* set port opcode modifiers */ + MLX4_SET_PORT_GENERAL = 0x0, + MLX4_SET_PORT_RQP_CALC = 0x1, + MLX4_SET_PORT_MAC_TABLE = 0x2, + MLX4_SET_PORT_VLAN_TABLE = 0x3, + MLX4_SET_PORT_PRIO_MAP = 0x4, +}; + struct mlx4_dev; struct mlx4_cmd_mailbox { diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index f9e73cfc540..1951fe70a25 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -153,6 +153,12 @@ enum mlx4_qp_region { MLX4_NUM_QP_REGION }; +enum mlx4_special_vlan_idx { + MLX4_NO_VLAN_IDX = 0, + MLX4_VLAN_MISS_IDX, + MLX4_VLAN_REGULAR +}; + enum { MLX4_NUM_FEXCH = 64 * 1024, }; @@ -438,6 +444,12 @@ int mlx4_multicast_attach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16], int block_mcast_loopback); int mlx4_multicast_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, u8 gid[16]); +int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac, int *index); +void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int index); + +int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index); +void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index); + int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list, int npages, u64 iova, u32 *lkey, u32 *rkey); int mlx4_fmr_alloc(struct mlx4_dev *dev, u32 pd, u32 access, int max_pages, -- cgit v1.2.3 From 7ff93f8b7ecbc36e7ffc5c11a61643821c1bfee5 Mon Sep 17 00:00:00 2001 From: Yevgeny Petrilin Date: Wed, 22 Oct 2008 15:38:42 -0700 Subject: mlx4_core: Multiple port type support Multi-protocol adapters support different port types. Each consumer of mlx4_core queries for supported port types; in particular mlx4_ib can no longer assume that all physical ports belong to it. Port type is configured through a sysfs interface. When the type of a port is changed, all mlx4 interfaces are unregistered, and then registered again with the new port types. Signed-off-by: Yevgeny Petrilin Signed-off-by: Roland Dreier --- include/linux/mlx4/device.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 1951fe70a25..bd9977b8949 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -60,6 +60,7 @@ enum { MLX4_DEV_CAP_FLAG_IPOIB_CSUM = 1 << 7, MLX4_DEV_CAP_FLAG_BAD_PKEY_CNTR = 1 << 8, MLX4_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1 << 9, + MLX4_DEV_CAP_FLAG_DPDP = 1 << 12, MLX4_DEV_CAP_FLAG_MEM_WINDOW = 1 << 16, MLX4_DEV_CAP_FLAG_APM = 1 << 17, MLX4_DEV_CAP_FLAG_ATOMIC = 1 << 18, @@ -153,6 +154,11 @@ enum mlx4_qp_region { MLX4_NUM_QP_REGION }; +enum mlx4_port_type { + MLX4_PORT_TYPE_IB = 1 << 0, + MLX4_PORT_TYPE_ETH = 1 << 1, +}; + enum mlx4_special_vlan_idx { MLX4_NO_VLAN_IDX = 0, MLX4_VLAN_MISS_IDX, @@ -226,6 +232,9 @@ struct mlx4_caps { int log_num_macs; int log_num_vlans; int log_num_prios; + enum mlx4_port_type port_type[MLX4_MAX_PORTS + 1]; + u8 supported_type[MLX4_MAX_PORTS + 1]; + u32 port_mask; }; struct mlx4_buf_list { @@ -380,6 +389,11 @@ struct mlx4_init_port_param { u64 si_guid; }; +#define mlx4_foreach_port(port, dev, type) \ + for ((port) = 1; (port) <= (dev)->caps.num_ports; (port)++) \ + if (((type) == MLX4_PORT_TYPE_IB ? (dev)->caps.port_mask : \ + ~(dev)->caps.port_mask) & 1 << ((port) - 1)) + int mlx4_buf_alloc(struct mlx4_dev *dev, int size, int max_direct, struct mlx4_buf *buf); void mlx4_buf_free(struct mlx4_dev *dev, int size, struct mlx4_buf *buf); -- cgit v1.2.3 From 8dd7f8036c123296fc4214f9d8810eb485570422 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Tue, 21 Oct 2008 17:38:25 +0800 Subject: PCI: add support for function level reset Sometimes, it's necessary to enable software's ability to quiesce and reset endpoint hardware with function-level granularity, so provide support for it. The patch implement Function Level Reset(FLR) feature following PCI-e spec. And this is the first step. We would add more generic method, like D0/D3, to allow more devices support this function. The patch contains two functions. pcie_reset_function() is the new driver API, and, contains some action to quiesce a device. The other function is a helper: pcie_execute_reset_function() just executes the reset for a particular device function. Current the usage model is in KVM. Function reset is necessary for assigning device to a guest, or moving it between partitions. For Function Level Reset(FLR), please refer to PCI Express spec chapter 6.6.2. Signed-off-by: Sheng Yang Signed-off-by: Matthew Wilcox Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 ++ include/linux/pci_regs.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 085187be29c..f6f6810296e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -626,6 +626,8 @@ int pcix_get_mmrbc(struct pci_dev *dev); int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc); int pcie_get_readrq(struct pci_dev *dev); int pcie_set_readrq(struct pci_dev *dev, int rq); +int pci_reset_function(struct pci_dev *dev); +int pci_execute_reset_function(struct pci_dev *dev); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); int pci_select_bars(struct pci_dev *dev, unsigned long flags); diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index eb6686b88f9..e5effd47ed7 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -377,6 +377,7 @@ #define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ #define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ #define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ +#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ #define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ @@ -389,6 +390,7 @@ #define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ #define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ #define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ +#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ #define PCI_EXP_DEVSTA 10 /* Device Status */ #define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ #define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ -- cgit v1.2.3 From 64c7f63c1b5c26f057c26f7920f397fed2f590d9 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Tue, 21 Oct 2008 10:09:05 -0700 Subject: PCI: include io.h in pci.h so that ioremap_nocache is defined Ingo pointed out that the m32r build was broken by pci_ioremap. It looks like some files include pci.h w/o including io.h. The latter defines ioremap_* if present, so it makes sense to include it in pci.h now that we have pci_ioremap there. Reported-by: Ingo Molnar Signed-off-by: Jesse Barnes --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index f6f6810296e..ee2fd6304e0 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -18,6 +18,7 @@ #define LINUX_PCI_H #include /* The pci register defines */ +#include /* * The PCI interface treats multi-function devices as independent -- cgit v1.2.3 From 1359f2701b96abd9bb69c1273fb995a093b6409a Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 20 Oct 2008 17:40:42 -0600 Subject: PCI Hotplug core: add 'name' param pci_hp_register interface Update pci_hp_register() to take a const char *name parameter. The motivation for this is to clean up the individual hotplug drivers so that each one does not have to manage its own name. The PCI core should be the place where we manage the name. We update the interface and all callsites first, in a "no functional change" manner, and clean up the drivers later. Cc: kristen.c.accardi@intel.com Acked-by: Kenji Kaneshige Reviewed-by: Matthew Wilcox Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- include/linux/pci_hotplug.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a08cd06b541..5efba667186 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -165,7 +165,8 @@ struct hotplug_slot { }; #define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj) -extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr); +extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr, + const char *name); extern int pci_hp_deregister(struct hotplug_slot *slot); extern int __must_check pci_hp_change_slot_info (struct hotplug_slot *slot, struct hotplug_slot_info *info); -- cgit v1.2.3 From d25b7c8d6ba2735602003d75a28894772fe8ad6a Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 20 Oct 2008 17:40:47 -0600 Subject: PCI: rename pci_update_slot_number to pci_renumber_slot The GPL exported symbol pci_update_slot_number has been renamed to pci_renumber_slot. Some of the safety checks were unnecessary and were removed. Cc: kristen.c.accardi@intel.com Cc: matthew@wil.cx Acked-by: Kenji Kaneshige Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index ee2fd6304e0..41717ae9807 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -512,7 +512,7 @@ struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, const char *name); void pci_destroy_slot(struct pci_slot *slot); -void pci_update_slot_number(struct pci_slot *slot, int slot_nr); +void pci_renumber_slot(struct pci_slot *slot, int slot_nr); int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn); void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); -- cgit v1.2.3 From 828f37683e6d3ab5912989df0d04201db7ad798e Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 20 Oct 2008 17:40:52 -0600 Subject: PCI: update pci_create_slot() to take a 'hotplug' param Slot detection drivers can co-exist with hotplug drivers. The names of the detected/claimed slots may be different depending on module load order. For legacy reasons, we need to allow hotplug drivers to override the slot name if a detection driver is loaded first (and they find the same slots). Creating and overriding slot names should be an atomic operation, otherwise you get a locking nightmare as various drivers race to call pci_create_slot(). pci_create_slot() is already serialized by grabbing the pci_bus_sem. We update the API and add a 'hotplug' param, which is: set if the caller is a hotplug driver NULL if the caller is a detection driver pci_create_slot() does not actually use the 'hotplug' parameter in this patch. A later patch will add the logic that uses it. Cc: kristen.c.accardi@intel.com Cc: matthew@wil.cx Acked-by: Kenji Kaneshige Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- include/linux/pci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 41717ae9807..9a8cee62330 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -510,7 +510,8 @@ struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, - const char *name); + const char *name, + struct hotplug_slot *hotplug); void pci_destroy_slot(struct pci_slot *slot); void pci_renumber_slot(struct pci_slot *slot, int slot_nr); int pci_scan_slot(struct pci_bus *bus, int devfn); -- cgit v1.2.3 From 0ad772ec464d3fcf9d210836b97e654f393606c4 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 20 Oct 2008 17:41:07 -0600 Subject: PCI, PCI Hotplug: introduce slot_name helpers In preparation for cleaning up the various hotplug drivers such that they don't have to manage their own 'name' parameters anymore, we provide the following convenience functions: pci_slot_name() hotplug_slot_name() These helpers will be used by individual hotplug drivers. Cc: kristen.c.accardi@intel.com Cc: matthew@wil.cx Acked-by: Kenji Kaneshige Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- include/linux/pci.h | 5 +++++ include/linux/pci_hotplug.h | 5 +++++ 2 files changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 9a8cee62330..955ab705c05 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -65,6 +65,11 @@ struct pci_slot { struct kobject kobj; }; +static inline const char *pci_slot_name(const struct pci_slot *slot) +{ + return kobject_name(&slot->kobj); +} + /* File state for mmap()s on /proc/bus/pci/X/Y */ enum pci_mmap_state { pci_mmap_io, diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index 5efba667186..a3a3245943b 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -165,6 +165,11 @@ struct hotplug_slot { }; #define to_hotplug_slot(n) container_of(n, struct hotplug_slot, kobj) +static inline const char *hotplug_slot_name(const struct hotplug_slot *slot) +{ + return pci_slot_name(slot->pci_slot); +} + extern int pci_hp_register(struct hotplug_slot *, struct pci_bus *, int nr, const char *name); extern int pci_hp_deregister(struct hotplug_slot *slot); -- cgit v1.2.3 From 58319b802a614f10f1b5238fbde7a4b2e9a60069 Mon Sep 17 00:00:00 2001 From: Alex Chiang Date: Mon, 20 Oct 2008 17:41:58 -0600 Subject: PCI: Hotplug core: remove 'name' Now that the PCI core manages the 'name' for each individual hotplug driver, and all drivers (except rpaphp) have been converted to use hotplug_slot_name(), there is no need for the PCI hotplug core to drag around its own copy of name either. Cc: kristen.c.accardi@intel.com Cc: matthew@wil.cx Acked-by: Kenji Kaneshige Signed-off-by: Alex Chiang Signed-off-by: Jesse Barnes --- include/linux/pci_hotplug.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/pci_hotplug.h b/include/linux/pci_hotplug.h index a3a3245943b..a00bd1a0f15 100644 --- a/include/linux/pci_hotplug.h +++ b/include/linux/pci_hotplug.h @@ -142,8 +142,6 @@ struct hotplug_slot_info { /** * struct hotplug_slot - used to register a physical slot with the hotplug pci core - * @name: the name of the slot being registered. This string must - * be unique amoung slots registered on this system. * @ops: pointer to the &struct hotplug_slot_ops to be used for this slot * @info: pointer to the &struct hotplug_slot_info for the initial values for * this slot. @@ -153,7 +151,6 @@ struct hotplug_slot_info { * needs. */ struct hotplug_slot { - char *name; struct hotplug_slot_ops *ops; struct hotplug_slot_info *info; void (*release) (struct hotplug_slot *slot); -- cgit v1.2.3 From 1388cc964e680c1086ca0edae35be094cb29d51e Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 22 Oct 2008 13:39:55 +1100 Subject: PCI: don't export linux/io.h from pci.h Move the include of io.h down into the #ifdef __KERNEL__ protected region. Signed-off-by: Stephen Rothwell Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 955ab705c05..752def8a2ef 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -18,7 +18,6 @@ #define LINUX_PCI_H #include /* The pci register defines */ -#include /* * The PCI interface treats multi-function devices as independent @@ -52,6 +51,7 @@ #include #include #include +#include /* Include the ID list */ #include -- cgit v1.2.3 From 848e4c68c4695beae563f9a3d59fce596b466a74 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 21 Oct 2008 14:26:39 +0900 Subject: libata: transfer EHI control flags to slave ehc.i ATA_EHI_NO_AUTOPSY and ATA_EHI_QUIET are used to control the behavior of EH. As only the master link is visible outside EH, these flags are set only for the master link although they should also apply to the slave link, which causes spurious EH messages during probe and suspend/resume. This patch transfers those two flags to slave ehc.i before performing slave autopsy and reporting. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 947cf84e555..c261aa0584b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -340,6 +340,9 @@ enum { ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET, + /* mask of flags to transfer *to* the slave link */ + ATA_EHI_TO_SLAVE_MASK = ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, + /* max tries if error condition is still set after ->error_handler */ ATA_EH_MAX_TRIES = 5, -- cgit v1.2.3 From d181146572c4fa9af2a068b967cb53dcac7da944 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 2 Aug 2008 00:49:18 -0400 Subject: [PATCH] new helper - kern_path() Analog of lookup_path(), takes struct path *. Signed-off-by: Al Viro --- include/linux/namei.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/namei.h b/include/linux/namei.h index 68f8c3203c8..221e8bc894b 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -61,6 +61,8 @@ extern int user_path_at(int, const char __user *, unsigned, struct path *); #define user_path_dir(name, path) \ user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path) +extern int kern_path(const char *, unsigned, struct path *); + extern int path_lookup(const char *, unsigned, struct nameidata *); extern int vfs_path_lookup(struct dentry *, struct vfsmount *, const char *, unsigned int, struct nameidata *); -- cgit v1.2.3 From b63365a2d60268a3988285d6c3c6003d7066f93a Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 23 Oct 2008 01:11:29 -0700 Subject: net: Fix disjunct computation of netdev features My change commit e2a6b85247aacc52d6ba0d9b37a99b8d1a3e0d83 net: Enable TSO if supported by at least one device didn't do what was intended because the netdev_compute_features function was designed for conjunctions. So what happened was that it would simply take the TSO status of the last constituent device. This patch extends it to support both conjunctions and disjunctions under the new name of netdev_increment_features. It also adds a new function netdev_fix_features which does the sanity checking that usually occurs upon registration. This ensures that the computation doesn't result in an illegal combination since this checking is absent when the change is initiated via ethtool. The two users of netdev_compute_features have been converted. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 64875859d65..c8bcb59adfd 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -541,6 +541,14 @@ struct net_device #define NETIF_F_V6_CSUM (NETIF_F_GEN_CSUM | NETIF_F_IPV6_CSUM) #define NETIF_F_ALL_CSUM (NETIF_F_V4_CSUM | NETIF_F_V6_CSUM) + /* + * If one device supports one of these features, then enable them + * for all in netdev_increment_features. + */ +#define NETIF_F_ONE_FOR_ALL (NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \ + NETIF_F_SG | NETIF_F_HIGHDMA | \ + NETIF_F_FRAGLIST) + /* Interface index. Unique device identifier */ int ifindex; int iflink; @@ -1698,7 +1706,9 @@ extern char *netdev_drivername(const struct net_device *dev, char *buffer, int l extern void linkwatch_run_queue(void); -extern int netdev_compute_features(unsigned long all, unsigned long one); +unsigned long netdev_increment_features(unsigned long all, unsigned long one, + unsigned long mask); +unsigned long netdev_fix_features(unsigned long features, const char *name); static inline int net_gso_ok(int features, int gso_type) { -- cgit v1.2.3 From 3516586a424ea5727be089da6541cbd5644f0497 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 5 Aug 2008 03:00:49 -0400 Subject: [PATCH] make O_EXCL in nd->intent.flags visible in nd->flags New flag: LOOKUP_EXCL. Set before doing the final step of pathname resolution on the paths that have LOOKUP_CREATE and O_EXCL. Signed-off-by: Al Viro --- include/linux/namei.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/namei.h b/include/linux/namei.h index 221e8bc894b..6b5627afd2e 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -51,8 +51,9 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; /* * Intent data */ -#define LOOKUP_OPEN (0x0100) -#define LOOKUP_CREATE (0x0200) +#define LOOKUP_OPEN 0x0100 +#define LOOKUP_CREATE 0x0200 +#define LOOKUP_EXCL 0x0400 extern int user_path_at(int, const char __user *, unsigned, struct path *); -- cgit v1.2.3 From 4ea3ada2955e4519befa98ff55dd62d6dfbd1705 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 11 Aug 2008 15:48:57 +0200 Subject: [PATCH] new helper: d_obtain_alias The calling conventions of d_alloc_anon are rather unfortunate for all users, and it's name is not very descriptive either. Add d_obtain_alias as a new exported helper that drops the inode reference in the failure case, too and allows to pass-through NULL pointers and inodes to allow for tail-calls in the export operations. Incidentally this helper already existed as a private function in libfs.c as exportfs_d_alloc so kill that one and switch the callers to d_obtain_alias. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- include/linux/dcache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index efba1de629a..2404257d6c6 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -231,6 +231,7 @@ extern struct dentry * d_alloc(struct dentry *, const struct qstr *); extern struct dentry * d_alloc_anon(struct inode *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); +extern struct dentry * d_obtain_alias(struct inode *); extern void shrink_dcache_sb(struct super_block *); extern void shrink_dcache_parent(struct dentry *); extern void shrink_dcache_for_umount(struct super_block *); -- cgit v1.2.3 From 9308a6128d9074e348d9f9b5822546fe12a794a9 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 11 Aug 2008 15:49:12 +0200 Subject: [PATCH] kill d_alloc_anon Remove d_alloc_anon now that no users are left. Signed-off-by: Christoph Hellwig Signed-off-by: Al Viro --- include/linux/dcache.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 2404257d6c6..74c64ae30cf 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -228,7 +228,6 @@ extern void d_delete(struct dentry *); /* allocate/de-allocate */ extern struct dentry * d_alloc(struct dentry *, const struct qstr *); -extern struct dentry * d_alloc_anon(struct inode *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *); extern struct dentry * d_obtain_alias(struct inode *); -- cgit v1.2.3 From 6de24f0ed08054b2a202902e4d63beff27654db8 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Thu, 28 Aug 2008 06:25:49 +0400 Subject: [PATCH 1/2] anondev: init IDR statically Signed-off-by: Alexey Dobriyan --- include/linux/fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index a6a625be13f..5f70aa62cf0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1593,7 +1593,6 @@ extern int get_sb_pseudo(struct file_system_type *, char *, struct vfsmount *mnt); extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); int __put_super_and_need_restart(struct super_block *sb); -void unnamed_dev_init(void); /* Alas, no aliases. Too much hassle with bringing module.h everywhere */ #define fops_get(fops) \ -- cgit v1.2.3 From e2761a1167633ed943fea29002f990194923d060 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 16 Oct 2008 07:50:28 +0900 Subject: [PATCH vfs-2.6 2/6] vfs: add d_ancestor() This adds d_ancestor() instead of d_isparent(), then use it. If new_dentry == old_dentry, is_subdir() returns 1, looks strange. "new_dentry == old_dentry" is not subdir obviously. But I'm not checking callers for now, so this keeps current behavior. Signed-off-by: OGAWA Hirofumi --- include/linux/dcache.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 74c64ae30cf..a37359d0bad 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -287,6 +287,7 @@ static inline struct dentry *d_add_unique(struct dentry *entry, struct inode *in /* used for rename() and baskets */ extern void d_move(struct dentry *, struct dentry *); +extern struct dentry *d_ancestor(struct dentry *, struct dentry *); /* appendix may either be NULL or be used for transname suffixes */ extern struct dentry * d_lookup(struct dentry *, struct qstr *); -- cgit v1.2.3 From 4e9ed2f85af7adfa7c3f0efa839a53186254fdcb Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 16 Oct 2008 07:50:29 +0900 Subject: [PATCH vfs-2.6 6/6] vfs: add LOOKUP_RENAME_TARGET intent This adds LOOKUP_RENAME_TARGET intent for lookup of rename destination. LOOKUP_RENAME_TARGET is going to be used like LOOKUP_CREATE. But since the destination of rename() can be existing directory entry, so it has a difference. Although that difference doesn't matter in my usage, this tells it to user of this intent. Signed-off-by: OGAWA Hirofumi --- include/linux/namei.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/namei.h b/include/linux/namei.h index 6b5627afd2e..99eb80306dc 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h @@ -54,6 +54,7 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND}; #define LOOKUP_OPEN 0x0100 #define LOOKUP_CREATE 0x0200 #define LOOKUP_EXCL 0x0400 +#define LOOKUP_RENAME_TARGET 0x0800 extern int user_path_at(int, const char __user *, unsigned, struct path *); -- cgit v1.2.3 From f696a3659fc4b3a3bf4bc83d9dbec5e5a2ffd929 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 31 Jul 2008 13:41:58 +0200 Subject: [PATCH] move executable checking into ->permission() For execute permission on a regular files we need to check if file has any execute bits at all, regardless of capabilites. This check is normally performed by generic_permission() but was also added to the case when the filesystem defines its own ->permission() method. In the latter case the filesystem should be responsible for performing this check. Move the check from inode_permission() inside filesystems which are not calling generic_permission(). Create a helper function execute_ok() that returns true if the inode is a directory or if any execute bits are present in i_mode. Also fix up the following code: - coda control file is never executable - sysctl files are never executable - hfs_permission seems broken on MAY_EXEC, remove - hfsplus_permission is eqivalent to generic_permission(), remove Signed-off-by: Miklos Szeredi --- include/linux/fs.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 5f70aa62cf0..025a4a251b6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1851,6 +1851,11 @@ extern int inode_permission(struct inode *, int); extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); +static inline bool execute_ok(struct inode *inode) +{ + return (inode->i_mode & S_IXUGO) || S_ISDIR(inode->i_mode); +} + extern int get_write_access(struct inode *); extern int deny_write_access(struct file *); static inline void put_write_access(struct inode * inode) -- cgit v1.2.3 From 08b9fe6b12d32324f311c46b88102b6b9067d434 Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Mon, 13 Oct 2008 00:09:50 -0400 Subject: [PATCH] i_version: remount support Add support for remounting a filesystem with the i_version option. Signed-off-by: Mimi Zohar --- include/linux/fs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 025a4a251b6..7d719c1a18e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -136,7 +136,7 @@ extern int dir_notify_enable; /* * Superblock flags that can be altered by MS_REMOUNT */ -#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK) +#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_I_VERSION) /* * Old magic mount flag and mask -- cgit v1.2.3 From e1759c215bee5abbcb6cb066590ab20905154ed5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Wed, 15 Oct 2008 23:50:22 +0400 Subject: proc: switch /proc/meminfo to seq_file and move it to fs/proc/meminfo.c while I'm at it. Signed-off-by: Alexey Dobriyan --- include/linux/hugetlb.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 32e0ef0f6e1..e1c8afc002c 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -27,7 +27,7 @@ void unmap_hugepage_range(struct vm_area_struct *, void __unmap_hugepage_range(struct vm_area_struct *, unsigned long, unsigned long, struct page *); int hugetlb_prefault(struct address_space *, struct vm_area_struct *); -int hugetlb_report_meminfo(char *); +void hugetlb_report_meminfo(struct seq_file *); int hugetlb_report_node_meminfo(int, char *); unsigned long hugetlb_total_pages(void); int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, @@ -79,7 +79,9 @@ static inline unsigned long hugetlb_total_pages(void) #define copy_hugetlb_page_range(src, dst, vma) ({ BUG(); 0; }) #define hugetlb_prefault(mapping, vma) ({ BUG(); 0; }) #define unmap_hugepage_range(vma, start, end, page) BUG() -#define hugetlb_report_meminfo(buf) 0 +static inline void hugetlb_report_meminfo(struct seq_file *m) +{ +} #define hugetlb_report_node_meminfo(n, buf) 0 #define follow_huge_pmd(mm, addr, pmd, write) NULL #define follow_huge_pud(mm, addr, pud, write) NULL -- cgit v1.2.3 From d8ba7a363393f803c93c8cffabd6d0362618bc2a Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 4 Oct 2008 22:34:18 +0400 Subject: proc: move rest of /proc/locks to fs/locks.c Signed-off-by: Alexey Dobriyan --- include/linux/fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index a6a625be13f..024049543ae 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1037,7 +1037,6 @@ extern int vfs_setlease(struct file *, long, struct file_lock **); extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); -extern struct seq_operations locks_seq_operations; #else /* !CONFIG_FILE_LOCKING */ #define fcntl_getlk(a, b) ({ -EINVAL; }) #define fcntl_setlk(a, b, c, d) ({ -EACCES; }) -- cgit v1.2.3 From f500975a3f3ecf3611d79f1d933906753460b9f2 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Sat, 4 Oct 2008 23:53:21 +0400 Subject: proc: move rest of /proc/partitions code to block/genhd.c Signed-off-by: Alexey Dobriyan Acked-by: Jens Axboe --- include/linux/genhd.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 206cdf96c3a..074a4fdf436 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -25,7 +25,6 @@ extern struct device_type part_type; extern struct kobject *block_depr; extern struct class block_class; -extern const struct seq_operations partitions_op; extern const struct seq_operations diskstats_op; enum { -- cgit v1.2.3 From 7b3c3a50a3e0ea46815150d420fa276ac254572b Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 02:42:17 +0400 Subject: proc: move /proc/slabinfo boilerplate to mm/slub.c, mm/slab.c Lose dummy ->write hook in case of SLUB, it's possible now. Signed-off-by: Alexey Dobriyan Acked-by: Pekka Enberg --- include/linux/slab.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/slab.h b/include/linux/slab.h index 5ff9676c1e2..ba965c84ae0 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -288,9 +288,4 @@ static inline void *kzalloc_node(size_t size, gfp_t flags, int node) return kmalloc_node(size, flags | __GFP_ZERO, node); } -#ifdef CONFIG_SLABINFO -extern const struct seq_operations slabinfo_op; -ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); -#endif - #endif /* _LINUX_SLAB_H */ -- cgit v1.2.3 From 5f6a6a9c4e4d790aae55cb412a7643329057c5e0 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 03:50:47 +0400 Subject: proc: move /proc/vmallocinfo to mm/vmalloc.c Signed-off-by: Alexey Dobriyan Acked-by: Christoph Lameter --- include/linux/vmalloc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 4c28c4d564e..307b88577ea 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -103,6 +103,4 @@ extern void free_vm_area(struct vm_struct *area); extern rwlock_t vmlist_lock; extern struct vm_struct *vmlist; -extern const struct seq_operations vmalloc_op; - #endif /* _LINUX_VMALLOC_H */ -- cgit v1.2.3 From 8f32f7e5ac2ed11b0659b6b55af926f3d58ffd9d Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 04:13:52 +0400 Subject: proc: move /proc/buddyinfo boilerplate to mm/vmstat.c Signed-off-by: Alexey Dobriyan --- include/linux/vmstat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 9cd3ab0f554..d4551f20640 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -54,7 +54,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, NR_VM_EVENT_ITEMS }; -extern const struct seq_operations fragmentation_op; extern const struct seq_operations pagetypeinfo_op; extern const struct seq_operations zoneinfo_op; extern const struct seq_operations vmstat_op; -- cgit v1.2.3 From 74e2e8e8ce7b3c0f878a349f9fa6cf2831548eef Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 04:15:36 +0400 Subject: proc: move /proc/pagetypeinfo boilerplate to mm/vmstat.c Signed-off-by: Alexey Dobriyan --- include/linux/vmstat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index d4551f20640..33ffd89a88a 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -54,7 +54,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, NR_VM_EVENT_ITEMS }; -extern const struct seq_operations pagetypeinfo_op; extern const struct seq_operations zoneinfo_op; extern const struct seq_operations vmstat_op; extern int sysctl_stat_interval; -- cgit v1.2.3 From b6aa44ab698c7df9d951d3eb45c4fcb8ba68fb25 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 04:17:48 +0400 Subject: proc: move /proc/vmstat boilerplate to mm/vmstat.c Signed-off-by: Alexey Dobriyan Acked-by: Christoph Lameter --- include/linux/vmstat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 33ffd89a88a..7b68c4c1e19 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -55,7 +55,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, }; extern const struct seq_operations zoneinfo_op; -extern const struct seq_operations vmstat_op; extern int sysctl_stat_interval; #ifdef CONFIG_VM_EVENT_COUNTERS -- cgit v1.2.3 From 5c9fe6281b75832e8d2555ec8700ea763d9a865e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 04:19:42 +0400 Subject: proc: move /proc/zoneinfo boilerplate to mm/vmstat.c Signed-off-by: Alexey Dobriyan Acked-by: Christoph Lameter --- include/linux/vmstat.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h index 7b68c4c1e19..524cd1b28ec 100644 --- a/include/linux/vmstat.h +++ b/include/linux/vmstat.h @@ -54,7 +54,6 @@ enum vm_event_item { PGPGIN, PGPGOUT, PSWPIN, PSWPOUT, NR_VM_EVENT_ITEMS }; -extern const struct seq_operations zoneinfo_op; extern int sysctl_stat_interval; #ifdef CONFIG_VM_EVENT_COUNTERS -- cgit v1.2.3 From 31d85ab28e71b0c938e0ef48af45747e80d99b53 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 12:55:38 +0400 Subject: proc: move /proc/diskstats boilerplate to block/genhd.c Signed-off-by: Alexey Dobriyan Acked-by: Jens Axboe --- include/linux/genhd.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 074a4fdf436..e439e6aed83 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -25,8 +25,6 @@ extern struct device_type part_type; extern struct kobject *block_depr; extern struct class block_class; -extern const struct seq_operations diskstats_op; - enum { /* These three have identical behaviour; use the second one if DOS FDISK gets confused about extended/logical partitions starting past cylinder 1023. */ -- cgit v1.2.3 From 593eb8a2d63e95772a5f22d746f18a997c5ee463 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:32:59 -0400 Subject: ftrace: return error on failed modified text. Have the ftrace_modify_code return error values: -EFAULT on error of reading the address -EINVAL if what is read does not match what it expected -EPERM if the write fails to update after a successful match. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 0e952958915..79fa10cbdcf 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -72,13 +72,33 @@ extern unsigned char *ftrace_nop_replace(void); extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); extern int ftrace_dyn_arch_init(void *data); extern int ftrace_mcount_set(unsigned long *data); -extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, - unsigned char *new_code); extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); extern void mcount_call(void); +/** + * ftrace_modify_code - modify code segment + * @ip: the address of the code segment + * @old_code: the contents of what is expected to be there + * @new_code: the code to patch in + * + * This is a very sensitive operation and great care needs + * to be taken by the arch. The operation should carefully + * read the location, check to see if what is read is indeed + * what we expect it to be, and then on success of the compare, + * it should write to the location. + * + * Return must be: + * 0 on success + * -EFAULT on error reading the location + * -EINVAL on a failed compare of the contents + * -EPERM on error writing to the location + * Any other value will be considered a failure. + */ +extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, + unsigned char *new_code); + extern int skip_trace(unsigned long ip); extern void ftrace_release(void *start, unsigned long size); -- cgit v1.2.3 From 81adbdc029ecc416d56563e7f159100181dd711d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:33:02 -0400 Subject: ftrace: only have ftrace_kill atomic When an anomaly is detected, we need a way to completely disable ftrace. Right now we have two functions: ftrace_kill and ftrace_kill_atomic. The ftrace_kill tries to do it in a "nice" way by converting everything back to a nop. The "nice" way is dangerous itself, so this patch removes it and only has the "atomic" version, which is all that is needed. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 79fa10cbdcf..ac58e94668b 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -40,7 +40,7 @@ extern void ftrace_stub(unsigned long a0, unsigned long a1); # define register_ftrace_function(ops) do { } while (0) # define unregister_ftrace_function(ops) do { } while (0) # define clear_ftrace_function(ops) do { } while (0) -static inline void ftrace_kill_atomic(void) { } +static inline void ftrace_kill(void) { } #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_DYNAMIC_FTRACE @@ -117,7 +117,6 @@ static inline void ftrace_release(void *start, unsigned long size) { } /* totally disable ftrace - can not re-enable after this */ void ftrace_kill(void); -void ftrace_kill_atomic(void); static inline void tracer_disable(void) { -- cgit v1.2.3 From 4d296c24326783bff1282ac72f310d8bac8df413 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:33:06 -0400 Subject: ftrace: remove mcount set The arch dependent function ftrace_mcount_set was only used by the daemon start up code. This patch removes it. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index ac58e94668b..1c4835f8691 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -71,7 +71,6 @@ extern int ftrace_ip_converted(unsigned long ip); extern unsigned char *ftrace_nop_replace(void); extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr); extern int ftrace_dyn_arch_init(void *data); -extern int ftrace_mcount_set(unsigned long *data); extern int ftrace_update_ftrace_func(ftrace_func_t func); extern void ftrace_caller(void); extern void ftrace_call(void); -- cgit v1.2.3 From 08f5ac906d2c0faf96d608c54a0b03177376da8d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 23 Oct 2008 09:33:07 -0400 Subject: ftrace: remove ftrace hash The ftrace hash was used by the ftrace_daemon code. The record ip function would place the calling address (ip) into the hash. The daemon would later read the hash and modify that code. The hash complicates the code. This patch removes it. Signed-off-by: Steven Rostedt Signed-off-by: Ingo Molnar --- include/linux/ftrace.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h index 1c4835f8691..703eb53cfa2 100644 --- a/include/linux/ftrace.h +++ b/include/linux/ftrace.h @@ -44,8 +44,6 @@ static inline void ftrace_kill(void) { } #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_DYNAMIC_FTRACE -# define FTRACE_HASHBITS 10 -# define FTRACE_HASHSIZE (1< Date: Mon, 6 Oct 2008 13:23:43 +0400 Subject: proc: move /proc/schedstat boilerplate to kernel/sched_stats.h Signed-off-by: Alexey Dobriyan --- include/linux/sched.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 5c38db536e0..7f60cb9b53c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -681,10 +681,6 @@ struct sched_info { }; #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ -#ifdef CONFIG_SCHEDSTATS -extern const struct file_operations proc_schedstat_operations; -#endif /* CONFIG_SCHEDSTATS */ - #ifdef CONFIG_TASK_DELAY_ACCT struct task_delay_info { spinlock_t lock; -- cgit v1.2.3 From 97ce5d6dcb07c403c0fc6001b755aacc38b5d7ff Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 14:14:19 +0400 Subject: proc: move all /proc/kcore stuff to fs/proc/kcore.c Signed-off-by: Alexey Dobriyan --- include/linux/proc_fs.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 27d534f4470..9d830890505 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -97,8 +97,6 @@ struct vmcore { #ifdef CONFIG_PROC_FS -extern struct proc_dir_entry *proc_root_kcore; - extern spinlock_t proc_subdir_lock; extern void proc_root_init(void); @@ -138,8 +136,6 @@ extern struct inode *proc_get_inode(struct super_block *, unsigned int, struct p extern int proc_readdir(struct file *, void *, filldir_t); extern struct dentry *proc_lookup(struct inode *, struct dentry *, struct nameidata *); -extern const struct file_operations proc_kcore_operations; - extern int pid_ns_prepare_proc(struct pid_namespace *ns); extern void pid_ns_release_proc(struct pid_namespace *ns); -- cgit v1.2.3 From 5aa140c2deca3701238d5acddf436ad7b02664c7 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 14:36:31 +0400 Subject: proc: move /proc/vmcore creation to fs/proc/vmcore.c Signed-off-by: Alexey Dobriyan --- include/linux/crash_dump.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/crash_dump.h b/include/linux/crash_dump.h index 0acf3b737e2..2dac064d835 100644 --- a/include/linux/crash_dump.h +++ b/include/linux/crash_dump.h @@ -14,8 +14,6 @@ extern unsigned long long elfcorehdr_addr; extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, unsigned long, int); -extern const struct file_operations proc_vmcore_operations; -extern struct proc_dir_entry *proc_vmcore; /* Architecture code defines this if there are other possible ELF * machine types, e.g. on bi-arch capable hardware. */ -- cgit v1.2.3 From 59c7572e82d69483a66eaa67b46548baeb69ecf4 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 6 Oct 2008 14:49:39 +0400 Subject: proc: remove fs/proc/proc_misc.c Now that everything was moved to their more or less expected places, apply rm(1). Signed-off-by: Alexey Dobriyan --- include/linux/proc_fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 9d830890505..b8bdb96eff7 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -100,7 +100,6 @@ struct vmcore { extern spinlock_t proc_subdir_lock; extern void proc_root_init(void); -extern void proc_misc_init(void); void proc_flush_task(struct task_struct *task); struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); -- cgit v1.2.3 From 66f50ee3cee4c9d98eea0add6f439e6e5e0ca4a5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 22 Oct 2008 14:14:59 -0700 Subject: profiling: fix up CONFIG_PROC_FS=n build In the case where procfs is disabled, create_proc_profile() does not exist. Stub it in with the others. Signed-off-by: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/profile.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/profile.h b/include/linux/profile.h index 570045053ce..a0fc32279fc 100644 --- a/include/linux/profile.h +++ b/include/linux/profile.h @@ -19,10 +19,16 @@ struct notifier_block; #if defined(CONFIG_PROFILING) && defined(CONFIG_PROC_FS) void create_prof_cpu_mask(struct proc_dir_entry *de); +int create_proc_profile(void); #else static inline void create_prof_cpu_mask(struct proc_dir_entry *de) { } + +static inline int create_proc_profile(void) +{ + return 0; +} #endif enum profile_type { @@ -37,7 +43,6 @@ extern int prof_on __read_mostly; /* init basic kernel profiler */ int profile_init(void); int profile_setup(char *str); -int create_proc_profile(void); void profile_tick(int type); /* -- cgit v1.2.3 From 4afe978530702c934dfdb11f54073136818b2119 Mon Sep 17 00:00:00 2001 From: Hidehiro Kawai Date: Wed, 22 Oct 2008 14:15:00 -0700 Subject: jbd: fix error handling for checkpoint io When a checkpointing IO fails, current JBD code doesn't check the error and continue journaling. This means latest metadata can be lost from both the journal and filesystem. This patch leaves the failed metadata blocks in the journal space and aborts journaling in the case of log_do_checkpoint(). To achieve this, we need to do: 1. don't remove the failed buffer from the checkpoint list where in the case of __try_to_free_cp_buf() because it may be released or overwritten by a later transaction 2. log_do_checkpoint() is the last chance, remove the failed buffer from the checkpoint list and abort the journal 3. when checkpointing fails, don't update the journal super block to prevent the journaled contents from being cleaned. For safety, don't update j_tail and j_tail_sequence either 4. when checkpointing fails, notify this error to the ext3 layer so that ext3 don't clear the needs_recovery flag, otherwise the journaled contents are ignored and cleaned in the recovery phase 5. if the recovery fails, keep the needs_recovery flag 6. prevent cleanup_journal_tail() from being called between __journal_drop_transaction() and journal_abort() (a race issue between journal_flush() and __log_wait_for_space() Signed-off-by: Hidehiro Kawai Acked-by: Jan Kara Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/jbd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 35d4f6342fa..346e2b80be7 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -911,7 +911,7 @@ extern int journal_set_features (journal_t *, unsigned long, unsigned long, unsigned long); extern int journal_create (journal_t *); extern int journal_load (journal_t *journal); -extern void journal_destroy (journal_t *); +extern int journal_destroy (journal_t *); extern int journal_recover (journal_t *journal); extern int journal_wipe (journal_t *, int); extern int journal_skip_recovery (journal_t *); -- cgit v1.2.3 From 94b6da5ab8293b04a300ba35c72eddfa94db8b02 Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Wed, 22 Oct 2008 14:15:05 -0700 Subject: memcg: fix page_cgroup allocation page_cgroup_init() is called from mem_cgroup_init(). But at this point, we cannot call alloc_bootmem(). (and this caused panic at boot.) This patch moves page_cgroup_init() to init/main.c. Time table is following: == parse_args(). # we can trust mem_cgroup_subsys.disabled bit after this. .... cgroup_init_early() # "early" init of cgroup. .... setup_arch() # memmap is allocated. ... page_cgroup_init(); mem_init(); # we cannot call alloc_bootmem after this. .... cgroup_init() # mem_cgroup is initialized. == Before page_cgroup_init(), mem_map must be initialized. So, I added page_cgroup_init() to init/main.c directly. (*) maybe this is not very clean but - cgroup_init_early() is too early - in cgroup_init(), we have to use vmalloc instead of alloc_bootmem(). use of vmalloc area in x86-32 is important and we should avoid very large vmalloc() in x86-32. So, we want to use alloc_bootmem() and added page_cgroup_init() directly to init/main.c [akpm@linux-foundation.org: remove unneeded/bad mem_cgroup_subsys declaration] [akpm@linux-foundation.org: fix build] Acked-by: Balbir Singh Tested-by: Balbir Singh Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page_cgroup.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/page_cgroup.h b/include/linux/page_cgroup.h index 0fd39f2231e..f546ad6fc02 100644 --- a/include/linux/page_cgroup.h +++ b/include/linux/page_cgroup.h @@ -99,5 +99,10 @@ static inline struct page_cgroup *lookup_page_cgroup(struct page *page) { return NULL; } + +static inline void page_cgroup_init(void) +{ +} + #endif #endif -- cgit v1.2.3 From 7106b4e333baeaf3c596e4d240438059b8a7616d Mon Sep 17 00:00:00 2001 From: Lee Howard Date: Tue, 21 Oct 2008 13:48:58 +0100 Subject: 8250: Oxford Semiconductor Devices Add support for the OxSemi 'Tornado' devices. Reformatted and reworked a bit by Alan Cox Signed-off-by: Lee Howard Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/pci_ids.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e5d344bfcb7..369f4428635 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1944,6 +1944,14 @@ #define PCI_VENDOR_ID_OXSEMI 0x1415 #define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403 +#define PCI_DEVICE_ID_OXSEMI_PCIe840 0xC000 +#define PCI_DEVICE_ID_OXSEMI_PCIe840_G 0xC004 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_0 0xC100 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_0_G 0xC104 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_1 0xC110 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_G 0xC114 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_U 0xC118 +#define PCI_DEVICE_ID_OXSEMI_PCIe952_1_GU 0xC11C #define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 #define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 #define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 -- cgit v1.2.3 From 388c8c16abafc2e74dff173b5de9ee519ea8d32f Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 3 Aug 2008 13:02:12 -0500 Subject: PCI: add routines for debugging and handling lost interrupts We're getting a lot of storage drivers blamed for interrupt misrouting issues. This patch provides a standard way of reporting the problem ... and, if possible, correcting it. Signed-off-by: James Bottomley Signed-off-by: Jesse Barnes --- include/linux/pci.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 752def8a2ef..c75b82bda32 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -546,6 +546,13 @@ struct pci_dev __deprecated *pci_find_slot(unsigned int bus, unsigned int devfn); #endif /* CONFIG_PCI_LEGACY */ +enum pci_lost_interrupt_reason { + PCI_LOST_IRQ_NO_INFORMATION = 0, + PCI_LOST_IRQ_DISABLE_MSI, + PCI_LOST_IRQ_DISABLE_MSIX, + PCI_LOST_IRQ_DISABLE_ACPI, +}; +enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *dev); int pci_find_capability(struct pci_dev *dev, int cap); int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap); int pci_find_ext_capability(struct pci_dev *dev, int cap); -- cgit v1.2.3 From 2fca5ccf97d2c28bcfce44f5b07d85e74e3cd18e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 22 Oct 2008 09:34:49 +0200 Subject: libata: switch to using block layer tagging support libata currently has a pretty dumb ATA_MAX_QUEUE loop for finding a free tag to use. Instead of fixing that up, convert libata to using block layer tagging - gets rid of code in libata, and is also much faster. Signed-off-by: Jens Axboe Acked-by: Tejun Heo Signed-off-by: Linus Torvalds --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c261aa0584b..507f53ef803 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -695,7 +695,6 @@ struct ata_port { unsigned int cbl; /* cable type; ATA_CBL_xxx */ struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; - unsigned long qc_allocated; unsigned int qc_active; int nr_active_links; /* #links with active qcs */ -- cgit v1.2.3 From 3ad0b02e4c1d5feba44b8ff48dccd1ba61a826b0 Mon Sep 17 00:00:00 2001 From: Venki Pallipadi Date: Wed, 22 Oct 2008 16:34:52 -0700 Subject: i7300_idle: Disable ioat channel only on platforms where ile driver can load Based on input from Andi Kleen: share the platform detection code with ioat_dma and disable the channel in dma engine only for specific platforms. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- include/linux/i7300_idle.h | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 include/linux/i7300_idle.h (limited to 'include/linux') diff --git a/include/linux/i7300_idle.h b/include/linux/i7300_idle.h new file mode 100644 index 00000000000..05a80c44513 --- /dev/null +++ b/include/linux/i7300_idle.h @@ -0,0 +1,83 @@ + +#ifndef I7300_IDLE_H +#define I7300_IDLE_H + +#include + +/* + * I/O AT controls (PCI bus 0 device 8 function 0) + * DIMM controls (PCI bus 0 device 16 function 1) + */ +#define IOAT_BUS 0 +#define IOAT_DEVFN PCI_DEVFN(8, 0) +#define MEMCTL_BUS 0 +#define MEMCTL_DEVFN PCI_DEVFN(16, 1) + +struct fbd_ioat { + unsigned int vendor; + unsigned int ioat_dev; +}; + +/* + * The i5000 chip-set has the same hooks as the i7300 + * but support is disabled by default because this driver + * has not been validated on that platform. + */ +#define SUPPORT_I5000 0 + +static const struct fbd_ioat fbd_ioat_list[] = { + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB}, +#if SUPPORT_I5000 + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT}, +#endif + {0, 0} +}; + +/* table of devices that work with this driver */ +static const struct pci_device_id pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) }, +#if SUPPORT_I5000 + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, +#endif + { } /* Terminating entry */ +}; + +/* Check for known platforms with I/O-AT */ +static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev, + struct pci_dev **ioat_dev) +{ + int i; + struct pci_dev *memdev, *dmadev; + + memdev = pci_get_bus_and_slot(MEMCTL_BUS, MEMCTL_DEVFN); + if (!memdev) + return -ENODEV; + + for (i = 0; pci_tbl[i].vendor != 0; i++) { + if (memdev->vendor == pci_tbl[i].vendor && + memdev->device == pci_tbl[i].device) { + break; + } + } + if (pci_tbl[i].vendor == 0) + return -ENODEV; + + dmadev = pci_get_bus_and_slot(IOAT_BUS, IOAT_DEVFN); + if (!dmadev) + return -ENODEV; + + for (i = 0; fbd_ioat_list[i].vendor != 0; i++) { + if (dmadev->vendor == fbd_ioat_list[i].vendor && + dmadev->device == fbd_ioat_list[i].ioat_dev) { + if (fbd_dev) + *fbd_dev = memdev; + if (ioat_dev) + *ioat_dev = dmadev; + + return 0; + } + } + return -ENODEV; +} + +#endif -- cgit v1.2.3 From c3a90c788b743303c4d824780a3a7271693fb64a Mon Sep 17 00:00:00 2001 From: Remi Denis-Courmont Date: Sun, 26 Oct 2008 23:07:25 -0700 Subject: Phonet: do not reply to indication reset packets This fixes a potential error packet loop. Signed-off-by: Remi Denis-Courmont Signed-off-by: David S. Miller --- include/linux/phonet.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/phonet.h b/include/linux/phonet.h index c9609f9aeda..4157faa857b 100644 --- a/include/linux/phonet.h +++ b/include/linux/phonet.h @@ -72,6 +72,7 @@ struct phonetmsg { } pn_msg_u; }; #define PN_COMMON_MESSAGE 0xF0 +#define PN_COMMGR 0x10 #define PN_PREFIX 0xE0 /* resource for extended messages */ #define pn_submsg_id pn_msg_u.base.pn_submsg_id #define pn_e_submsg_id pn_msg_u.ext.pn_e_submsg_id -- cgit v1.2.3 From 3d5afd324a4bf9f64f59599bf1e93cd7dd1dc97a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 27 Oct 2008 12:16:15 +0100 Subject: HID: fix oops during suspend of unbound HID devices Usbhid structure is allocated on start invoked only from probe of some driver. When there is no driver, the structure is null and causes null-dereference oopses. Fix it by allocating the structure on probe and disconnect of the device itself. Also make sure we won't race between start and resume or stop and suspend respectively. References: http://bugzilla.kernel.org/show_bug.cgi?id=11827 Signed-off-by: Jiri Slaby Cc: Johannes Berg Cc: Andreas Schwab Signed-off-by: Jiri Kosina --- include/linux/hid.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/hid.h b/include/linux/hid.h index 5355ca4b939..e5780f8c934 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -410,6 +410,7 @@ struct hid_output_fifo { #define HID_SUSPENDED 5 #define HID_CLEAR_HALT 6 #define HID_DISCONNECTED 7 +#define HID_STARTED 8 struct hid_input { struct list_head list; -- cgit v1.2.3 From 5550af4df179e52753d3a43a788a113ad8cd95cd Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Wed, 15 Oct 2008 20:15:06 +0800 Subject: KVM: Fix guest shared interrupt with in-kernel irqchip Every call of kvm_set_irq() should offer an irq_source_id, which is allocated by kvm_request_irq_source_id(). Based on irq_source_id, we identify the irq source and implement logical OR for shared level interrupts. The allocated irq_source_id can be freed by kvm_free_irq_source_id(). Currently, we support at most sizeof(unsigned long) different irq sources. [Amit: - rebase to kvm.git HEAD - move definition of KVM_USERSPACE_IRQ_SOURCE_ID to common file - move kvm_request_irq_source_id to the update_irq ioctl] [Xiantao: - Add kvm/ia64 stuff and make it work for kvm/ia64 guests] Signed-off-by: Sheng Yang Signed-off-by: Amit Shah Signed-off-by: Xiantao Zhang Signed-off-by: Avi Kivity --- include/linux/kvm_host.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 3833c48fae3..bb92be2153b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -37,6 +37,8 @@ #define KVM_REQ_UNHALT 6 #define KVM_REQ_MMU_SYNC 7 +#define KVM_USERSPACE_IRQ_SOURCE_ID 0 + struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; @@ -306,15 +308,18 @@ struct kvm_assigned_dev_kernel { int host_irq; int guest_irq; int irq_requested; + int irq_source_id; struct pci_dev *dev; struct kvm *kvm; }; -void kvm_set_irq(struct kvm *kvm, int irq, int level); +void kvm_set_irq(struct kvm *kvm, int irq_source_id, int irq, int level); void kvm_notify_acked_irq(struct kvm *kvm, unsigned gsi); void kvm_register_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); void kvm_unregister_irq_ack_notifier(struct kvm *kvm, struct kvm_irq_ack_notifier *kian); +int kvm_request_irq_source_id(struct kvm *kvm); +void kvm_free_irq_source_id(struct kvm *kvm, int irq_source_id); #ifdef CONFIG_DMAR int kvm_iommu_map_pages(struct kvm *kvm, gfn_t base_gfn, -- cgit v1.2.3 From bb45e202e695dea8657bb03a01d1522c37558672 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 19 Oct 2008 16:39:45 +0200 Subject: KVM: Future-proof device assignment ABI Reserve some space so we can add more data. Signed-off-by: Avi Kivity --- include/linux/kvm.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 797fcd78124..f18b86fa865 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -489,6 +489,9 @@ struct kvm_assigned_pci_dev { __u32 busnr; __u32 devfn; __u32 flags; + union { + __u32 reserved[12]; + }; }; struct kvm_assigned_irq { @@ -496,6 +499,9 @@ struct kvm_assigned_irq { __u32 host_irq; __u32 guest_irq; __u32 flags; + union { + __u32 reserved[12]; + }; }; #define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0) -- cgit v1.2.3 From 8175fe2dda1c93a9c596921c8ed4a0b4baccdefe Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 26 Oct 2008 00:30:18 +0200 Subject: HID: fix hid_device_id for cross compiling struct hid_device_id contains hidden padding which is bad for cross compiling. Make the padding explicit and consistent across architectures. Signed-off-by: Andreas Schwab Signed-off-by: Jiri Kosina --- include/linux/mod_devicetable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index eb71b45fdf5..97b91d1abb4 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -135,6 +135,7 @@ struct usb_device_id { struct hid_device_id { __u16 bus; + __u16 pad1; __u32 vendor; __u32 product; kernel_ulong_t driver_data -- cgit v1.2.3 From 3f5e26cee443eb4d3900cd3085664c3e51b72135 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Sat, 25 Oct 2008 15:02:51 -0700 Subject: adjust init section definitions Add rodata equivalents for assembly use, and fix the section attributes used by __REFCONST. Signed-off-by: Jan Beulich Signed-off-by: Andrew Morton Signed-off-by: Sam Ravnborg --- include/linux/init.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/init.h b/include/linux/init.h index 0c1264668be..68cb0265d00 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -112,21 +112,25 @@ #define __FINIT .previous #define __INITDATA .section ".init.data","aw" +#define __INITRODATA .section ".init.rodata","a" #define __FINITDATA .previous #define __DEVINIT .section ".devinit.text", "ax" #define __DEVINITDATA .section ".devinit.data", "aw" +#define __DEVINITRODATA .section ".devinit.rodata", "a" #define __CPUINIT .section ".cpuinit.text", "ax" #define __CPUINITDATA .section ".cpuinit.data", "aw" +#define __CPUINITRODATA .section ".cpuinit.rodata", "a" #define __MEMINIT .section ".meminit.text", "ax" #define __MEMINITDATA .section ".meminit.data", "aw" +#define __MEMINITRODATA .section ".meminit.rodata", "a" /* silence warnings when references are OK */ #define __REF .section ".ref.text", "ax" #define __REFDATA .section ".ref.data", "aw" -#define __REFCONST .section ".ref.rodata", "aw" +#define __REFCONST .section ".ref.rodata", "a" #ifndef __ASSEMBLY__ /* -- cgit v1.2.3 From 0833422274ff00729a603b020fac297e69a03e40 Mon Sep 17 00:00:00 2001 From: Kurt Garloff Date: Wed, 29 Oct 2008 14:00:48 -0700 Subject: mm: increase the default mlock limit from 32k to 64k By default, non-privileged tasks can only mlock() a small amount of memory to avoid a DoS attack by ordinary users. The Linux kernel defaulted to 32k (on a 4k page size system) to accommodate the needs of gpg. However, newer gpg2 needs 64k in various circumstances and otherwise fails miserably, see bnc#329675. Change the default to 64k, and make it more agnostic to PAGE_SIZE. Signed-off-by: Kurt Garloff Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/resource.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/resource.h b/include/linux/resource.h index aaa423a6f3d..40fc7e62608 100644 --- a/include/linux/resource.h +++ b/include/linux/resource.h @@ -59,10 +59,10 @@ struct rlimit { #define _STK_LIM (8*1024*1024) /* - * GPG wants 32kB of mlocked memory, to make sure pass phrases + * GPG2 wants 64kB of mlocked memory, to make sure pass phrases * and other sensitive information are never written to disk. */ -#define MLOCK_LIMIT (8 * PAGE_SIZE) +#define MLOCK_LIMIT ((PAGE_SIZE > 64*1024) ? PAGE_SIZE : 64*1024) /* * Due to binary compatibility, the actual resource numbers -- cgit v1.2.3 From 00c2e63c31d0f431952ff2a671c5c6997dd4f8b2 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 29 Oct 2008 14:00:53 -0700 Subject: freezer_cg: use thaw_process() in unfreeze_cgroup() Don't duplicate the implementation of thaw_process(). [akpm@linux-foundation.org: make __thaw_process() static] Signed-off-by: Li Zefan Cc: Cedric Le Goater Acked-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/freezer.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 8f225339eee..5a361f85cfe 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -44,11 +44,6 @@ static inline bool should_send_signal(struct task_struct *p) return !(p->flags & PF_FREEZER_NOSIG); } -/* - * Wake up a frozen process - */ -extern int __thaw_process(struct task_struct *p); - /* Takes and releases task alloc lock using task_lock() */ extern int thaw_process(struct task_struct *p); -- cgit v1.2.3 From 9b913735e53ab0da4a792bac0de8e178cc13dcfb Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Wed, 29 Oct 2008 14:00:54 -0700 Subject: cgroups: tiny cleanups - remove 'private' field from struct subsys - remove cgroup_init_smp() Signed-off-by: Li Zefan Acked-by: Paul Menage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cgroup.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 8b00f6643e9..1164963c3a8 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -25,7 +25,6 @@ struct cgroup; extern int cgroup_init_early(void); extern int cgroup_init(void); -extern void cgroup_init_smp(void); extern void cgroup_lock(void); extern bool cgroup_lock_live_group(struct cgroup *cgrp); extern void cgroup_unlock(void); @@ -348,8 +347,6 @@ struct cgroup_subsys { struct cgroupfs_root *root; struct list_head sibling; - - void *private; }; #define SUBSYS(_x) extern struct cgroup_subsys _x ## _subsys; @@ -410,7 +407,6 @@ void cgroup_mm_owner_callbacks(struct task_struct *old, static inline int cgroup_init_early(void) { return 0; } static inline int cgroup_init(void) { return 0; } -static inline void cgroup_init_smp(void) {} static inline void cgroup_fork(struct task_struct *p) {} static inline void cgroup_fork_callbacks(struct task_struct *p) {} static inline void cgroup_post_fork(struct task_struct *p) {} -- cgit v1.2.3 From 4e02ed4b4a2fae34aae766a5bb93ae235f60adb8 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Wed, 29 Oct 2008 14:00:55 -0700 Subject: fs: remove prepare_write/commit_write Nothing uses prepare_write or commit_write. Remove them from the tree completely. [akpm@linux-foundation.org: schedule simple_prepare_write() for unexporting] Signed-off-by: Nick Piggin Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 5b248d61430..0dcdd9458f4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -489,13 +489,6 @@ struct address_space_operations { int (*readpages)(struct file *filp, struct address_space *mapping, struct list_head *pages, unsigned nr_pages); - /* - * ext3 requires that a successful prepare_write() call be followed - * by a commit_write() call - they must be balanced - */ - int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); - int (*commit_write)(struct file *, struct page *, unsigned, unsigned); - int (*write_begin)(struct file *, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, struct page **pagep, void **fsdata); -- cgit v1.2.3 From 7106a27b52940085c2c3f6e42742d3a2a84d872a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 29 Oct 2008 14:01:15 -0700 Subject: kernel.h: fix might_sleep kernel-doc Put the kernel-doc for might_sleep() _immediately_ before the macro (no intervening lines). Otherwise kernel-doc complains like so: Warning(linux-2.6.27-rc3-git2//include/linux/kernel.h:129): No description found for parameter 'file' Warning(linux-2.6.27-rc3-git2//include/linux/kernel.h:129): No description found for parameter 'line' because kernel-doc is looking at the wrong function prototype (i.e., __might_sleep). [Yes, I have a todo note to myself to check/warn for that inconsistency in scripts/kernel-doc.] Signed-off-by: Randy Dunlap Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 396a350b87a..fba141d3ca0 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -116,6 +116,8 @@ extern int _cond_resched(void); # define might_resched() do { } while (0) #endif +#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP + void __might_sleep(char *file, int line); /** * might_sleep - annotation for functions that can sleep * @@ -126,8 +128,6 @@ extern int _cond_resched(void); * be bitten later when the calling function happens to sleep when it is not * supposed to. */ -#ifdef CONFIG_DEBUG_SPINLOCK_SLEEP - void __might_sleep(char *file, int line); # define might_sleep() \ do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0) #else -- cgit v1.2.3 From 731572d39fcd3498702eda4600db4c43d51e0b26 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 29 Oct 2008 14:01:20 -0700 Subject: nfsd: fix vm overcommit crash Junjiro R. Okajima reported a problem where knfsd crashes if you are using it to export shmemfs objects and run strict overcommit. In this situation the current->mm based modifier to the overcommit goes through a NULL pointer. We could simply check for NULL and skip the modifier but we've caught other real bugs in the past from mm being NULL here - cases where we did need a valid mm set up (eg the exec bug about a year ago). To preserve the checks and get the logic we want shuffle the checking around and add a new helper to the vm_ security wrappers Also fix a current->mm reference in nommu that should use the passed mm [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: fix build] Reported-by: Junjiro R. Okajima Acked-by: James Morris Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index f5c4a51eb42..c13f1cec9ab 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1585,6 +1585,7 @@ int security_syslog(int type); int security_settime(struct timespec *ts, struct timezone *tz); int security_vm_enough_memory(long pages); int security_vm_enough_memory_mm(struct mm_struct *mm, long pages); +int security_vm_enough_memory_kern(long pages); int security_bprm_alloc(struct linux_binprm *bprm); void security_bprm_free(struct linux_binprm *bprm); void security_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); @@ -1820,6 +1821,11 @@ static inline int security_vm_enough_memory(long pages) return cap_vm_enough_memory(current->mm, pages); } +static inline int security_vm_enough_memory_kern(long pages) +{ + return cap_vm_enough_memory(current->mm, pages); +} + static inline int security_vm_enough_memory_mm(struct mm_struct *mm, long pages) { return cap_vm_enough_memory(mm, pages); -- cgit v1.2.3 From effdb9492de01a51f8123e62e87e3330688f9bf1 Mon Sep 17 00:00:00 2001 From: Fernando Luis Vazquez Cao Date: Wed, 29 Oct 2008 14:01:21 -0700 Subject: spi: fix compile error Fix compile error below: LD drivers/spi/built-in.o CC [M] drivers/spi/spi_gpio.o In file included from drivers/spi/spi_gpio.c:26: include/linux/spi/spi_bitbang.h:23: error: field `work' has incomplete type make[2]: *** [drivers/spi/spi_gpio.o] Error 1 make[1]: *** [drivers/spi] Error 2 make: *** [drivers] Error 2 Signed-off-by: Fernando Luis Vazquez Cao Cc: David Brownell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/spi/spi_bitbang.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index b8db32cea1d..bf8de281b4e 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -18,6 +18,9 @@ * duplex (MicroWire) controllers. Provide chipslect() and txrx_bufs(), * and custom setup()/cleanup() methods. */ + +#include + struct spi_bitbang { struct workqueue_struct *workqueue; struct work_struct work; -- cgit v1.2.3 From c132419e560a2ecd3c8cf77f9c37e103e74b3754 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Thu, 30 Oct 2008 18:17:06 -0700 Subject: gianfar: Fix race in TBI/SerDes configuration The init_phy() function attaches to the PHY, then configures the SerDes<->TBI link (in SGMII mode). The TBI is on the MDIO bus with the PHY (sort of) and is accessed via the gianfar's MDIO registers, using the functions gfar_local_mdio_read/write(), which don't do any locking. The previously attached PHY will start a work-queue on a timer, and probably an irq handler as well, which will talk to the PHY and thus use the MDIO bus. This uses phy_read/write(), which have locking, but not against the gfar_local_mdio versions. The result is that PHY code will try to use the MDIO bus at the same time as the SerDes setup code, corrupting the transfers. Setting up the SerDes before attaching to the PHY will insure that there is no race between the SerDes code and *our* PHY, but doesn't fix everything. Typically the PHYs for all gianfar devices are on the same MDIO bus, which is associated with the first gianfar device. This means that the first gianfar's SerDes code could corrupt the MDIO transfers for a different gianfar's PHY. The lock used by phy_read/write() is contained in the mii_bus structure, which is pointed to by the PHY. This is difficult to access from the gianfar drivers, as there is no link between a gianfar device and the mii_bus which shares the same MDIO registers. As far as the device layer and drivers are concerned they are two unrelated devices (which happen to share registers). Generally all gianfar devices' PHYs will be on the bus associated with the first gianfar. But this might not be the case, so simply locking the gianfar's PHY's mii bus might not lock the mii bus that the SerDes setup code is going to use. We solve this by having the code that creates the gianfar platform device look in the device tree for an mdio device that shares the gianfar's registers. If one is found the ID of its platform device is saved in the gianfar's platform data. A new function in the gianfar mii code, gfar_get_miibus(), can use the bus ID to search through the platform devices for a gianfar_mdio device with the right ID. The platform device's driver data is the mii_bus structure, which the SerDes setup code can use to lock the current bus. Signed-off-by: Trent Piepho CC: Andy Fleming Signed-off-by: Jeff Garzik --- include/linux/fsl_devices.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h index 4e625e0094c..708bab58d8d 100644 --- a/include/linux/fsl_devices.h +++ b/include/linux/fsl_devices.h @@ -49,7 +49,8 @@ struct gianfar_platform_data { u32 device_flags; /* board specific information */ u32 board_flags; - char bus_id[MII_BUS_ID_SIZE]; + int mdio_bus; /* Bus controlled by us */ + char bus_id[MII_BUS_ID_SIZE]; /* Bus PHY is on */ u32 phy_id; u8 mac_addr[6]; phy_interface_t interface; -- cgit v1.2.3 From 9ce8e3073d9cfd6f859c22a25441db41b85cbf6e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 27 Aug 2008 15:23:18 +0200 Subject: libata: add whitelist for devices with known good pata-sata bridges libata currently imposes a UDMA5 max transfer rate and 200 sector max transfer size for SATA devices that sit behind a pata-sata bridge. Lots of devices have known good bridges that don't need this limit applied. The MTRON SSD disks are such devices. Transfer rates are increased by 20-30% with the restriction removed. So add a "blacklist" entry for the MTRON devices, with a flag indicating that the bridge is known good. Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 507f53ef803..f5441edee55 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -372,6 +372,7 @@ enum { ATA_HORKAGE_IPM = (1 << 7), /* Link PM problems */ ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ + ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v1.2.3 From ad1d967c88e349c7e822ad75dd3247a2a50d2ea3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 30 Oct 2008 23:54:35 -0700 Subject: net: delete excess kernel-doc notation Remove excess kernel-doc function parameters from networking header & driver files: Warning(include/net/sock.h:946): Excess function parameter or struct member 'sk' description in 'sk_filter_release' Warning(include/linux/netdevice.h:1545): Excess function parameter or struct member 'cpu' description in 'netif_tx_lock' Warning(drivers/net/wan/z85230.c:712): Excess function parameter or struct member 'regs' description in 'z8530_interrupt' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index c8bcb59adfd..9d77b1d7dca 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1537,7 +1537,6 @@ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq) /** * netif_tx_lock - grab network device transmit lock * @dev: network device - * @cpu: cpu number of lock owner * * Get network device transmit lock */ -- cgit v1.2.3 From 9663f2e6a6cf3f82b06d8fb699b11b80f92553ba Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Thu, 30 Oct 2008 19:38:18 -0700 Subject: resources: add io-mapping functions to dynamically map large device apertures Impact: add new generic io_map_*() APIs Graphics devices have large PCI apertures which would consume a significant fraction of a 32-bit address space if mapped during driver initialization. Using ioremap at runtime is impractical as it is too slow. This new set of interfaces uses atomic mappings on 32-bit processors and a large static mapping on 64-bit processors to provide reasonable 32-bit performance and optimal 64-bit performance. The current implementation sits atop the io_map_atomic fixmap-based mechanism for 32-bit processors. This includes some editorial suggestions from Randy Dunlap for Documentation/io-mapping.txt Signed-off-by: Keith Packard Signed-off-by: Eric Anholt Signed-off-by: Ingo Molnar --- include/linux/io-mapping.h | 118 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 include/linux/io-mapping.h (limited to 'include/linux') diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h new file mode 100644 index 00000000000..1b566993db6 --- /dev/null +++ b/include/linux/io-mapping.h @@ -0,0 +1,118 @@ +/* + * Copyright © 2008 Keith Packard + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _LINUX_IO_MAPPING_H +#define _LINUX_IO_MAPPING_H + +#include +#include +#include +#include + +/* + * The io_mapping mechanism provides an abstraction for mapping + * individual pages from an io device to the CPU in an efficient fashion. + * + * See Documentation/io_mapping.txt + */ + +/* this struct isn't actually defined anywhere */ +struct io_mapping; + +#ifdef CONFIG_X86_64 + +/* Create the io_mapping object*/ +static inline struct io_mapping * +io_mapping_create_wc(unsigned long base, unsigned long size) +{ + return (struct io_mapping *) ioremap_wc(base, size); +} + +static inline void +io_mapping_free(struct io_mapping *mapping) +{ + iounmap(mapping); +} + +/* Atomic map/unmap */ +static inline void * +io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) +{ + return ((char *) mapping) + offset; +} + +static inline void +io_mapping_unmap_atomic(void *vaddr) +{ +} + +/* Non-atomic map/unmap */ +static inline void * +io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) +{ + return ((char *) mapping) + offset; +} + +static inline void +io_mapping_unmap(void *vaddr) +{ +} + +#endif /* CONFIG_X86_64 */ + +#ifdef CONFIG_X86_32 +static inline struct io_mapping * +io_mapping_create_wc(unsigned long base, unsigned long size) +{ + return (struct io_mapping *) base; +} + +static inline void +io_mapping_free(struct io_mapping *mapping) +{ +} + +/* Atomic map/unmap */ +static inline void * +io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) +{ + offset += (unsigned long) mapping; + return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, + __pgprot(__PAGE_KERNEL_WC)); +} + +static inline void +io_mapping_unmap_atomic(void *vaddr) +{ + iounmap_atomic(vaddr, KM_USER0); +} + +static inline void * +io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) +{ + offset += (unsigned long) mapping; + return ioremap_wc(offset, PAGE_SIZE); +} + +static inline void +io_mapping_unmap(void *vaddr) +{ + iounmap(vaddr); +} +#endif /* CONFIG_X86_32 */ + +#endif /* _LINUX_IO_MAPPING_H */ -- cgit v1.2.3 From 4ac96572f1f6abe44b5e02e80fdfb5a990129613 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 2 Nov 2008 09:51:27 -0500 Subject: linux/string.h: fix comment typo s/user/used/ Signed-off-by: Jeff Garzik Signed-off-by: Linus Torvalds --- include/linux/string.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/string.h b/include/linux/string.h index 810d80df0a1..d18fc198aa2 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -1,7 +1,7 @@ #ifndef _LINUX_STRING_H_ #define _LINUX_STRING_H_ -/* We don't want strings.h stuff being user by user stuff by accident */ +/* We don't want strings.h stuff being used by user stuff by accident */ #ifndef __KERNEL__ #include -- cgit v1.2.3 From e5beae16901795223d677f15aa2fe192976278ee Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 3 Nov 2008 18:21:45 +0100 Subject: io mapping: clean up #ifdefs Impact: cleanup clean up ifdefs: change #ifdef CONFIG_X86_32/64 to CONFIG_HAVE_ATOMIC_IOMAP. flip around the #ifdef sections to clean up the structure. Signed-off-by: Keith Packard Signed-off-by: Ingo Molnar --- include/linux/io-mapping.h | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/io-mapping.h b/include/linux/io-mapping.h index 1b566993db6..82df31726a5 100644 --- a/include/linux/io-mapping.h +++ b/include/linux/io-mapping.h @@ -33,86 +33,93 @@ /* this struct isn't actually defined anywhere */ struct io_mapping; -#ifdef CONFIG_X86_64 +#ifdef CONFIG_HAVE_ATOMIC_IOMAP + +/* + * For small address space machines, mapping large objects + * into the kernel virtual space isn't practical. Where + * available, use fixmap support to dynamically map pages + * of the object at run time. + */ -/* Create the io_mapping object*/ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) { - return (struct io_mapping *) ioremap_wc(base, size); + return (struct io_mapping *) base; } static inline void io_mapping_free(struct io_mapping *mapping) { - iounmap(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { - return ((char *) mapping) + offset; + offset += (unsigned long) mapping; + return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, + __pgprot(__PAGE_KERNEL_WC)); } static inline void io_mapping_unmap_atomic(void *vaddr) { + iounmap_atomic(vaddr, KM_USER0); } -/* Non-atomic map/unmap */ static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { - return ((char *) mapping) + offset; + offset += (unsigned long) mapping; + return ioremap_wc(offset, PAGE_SIZE); } static inline void io_mapping_unmap(void *vaddr) { + iounmap(vaddr); } -#endif /* CONFIG_X86_64 */ +#else -#ifdef CONFIG_X86_32 +/* Create the io_mapping object*/ static inline struct io_mapping * io_mapping_create_wc(unsigned long base, unsigned long size) { - return (struct io_mapping *) base; + return (struct io_mapping *) ioremap_wc(base, size); } static inline void io_mapping_free(struct io_mapping *mapping) { + iounmap(mapping); } /* Atomic map/unmap */ static inline void * io_mapping_map_atomic_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return iomap_atomic_prot_pfn(offset >> PAGE_SHIFT, KM_USER0, - __pgprot(__PAGE_KERNEL_WC)); + return ((char *) mapping) + offset; } static inline void io_mapping_unmap_atomic(void *vaddr) { - iounmap_atomic(vaddr, KM_USER0); } +/* Non-atomic map/unmap */ static inline void * io_mapping_map_wc(struct io_mapping *mapping, unsigned long offset) { - offset += (unsigned long) mapping; - return ioremap_wc(offset, PAGE_SIZE); + return ((char *) mapping) + offset; } static inline void io_mapping_unmap(void *vaddr) { - iounmap(vaddr); } -#endif /* CONFIG_X86_32 */ + +#endif /* HAVE_ATOMIC_IOMAP */ #endif /* _LINUX_IO_MAPPING_H */ -- cgit v1.2.3 From a7b930cdf8ec790c85f81416c87f7c066679d373 Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Sun, 2 Nov 2008 13:32:43 -0800 Subject: PCI: annotate return value of pci_ioremap_bar with __iomem Was missing from the initial patch. Acked-by: Arjan van de Ven Signed-off-by: Harvey Harrison Signed-off-by: Jesse Barnes --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index c75b82bda32..feb4657bb04 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1136,7 +1136,7 @@ static inline void pci_mmcfg_late_init(void) { } #endif #ifdef CONFIG_HAS_IOMEM -static inline void * pci_ioremap_bar(struct pci_dev *pdev, int bar) +static inline void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) { /* * Make sure the BAR is actually a memory resource, not an IO resource -- cgit v1.2.3 From 6a87e42e955ff27e07a77f65f8f077dc7c4171e1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 3 Nov 2008 19:01:09 +0900 Subject: libata: implement ATA_HORKAGE_ATAPI_MOD16_DMA and apply it libata always uses PIO for ATAPI commands when the number of bytes to transfer isn't multiple of 16 but quantum DAT72 chokes on odd bytes PIO transfers. Implement a horkage to skip the mod16 check and apply it to the quantum device. This is reported by John Clark in the following thread. http://thread.gmane.org/gmane.linux.ide/34748 Signed-off-by: Tejun Heo Cc: John Clark Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index f5441edee55..c7665a4134c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -373,6 +373,8 @@ enum { ATA_HORKAGE_IVB = (1 << 8), /* cbl det validity bit bugs */ ATA_HORKAGE_STUCK_ERR = (1 << 9), /* stuck ERR on next PACKET */ ATA_HORKAGE_BRIDGE_OK = (1 << 10), /* no bridge limits */ + ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands + not multiple of 16 bytes */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ -- cgit v1.2.3 From 9b22ea560957de1484e6b3e8538f7eef202e3596 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 4 Nov 2008 14:49:57 -0800 Subject: net: fix packet socket delivery in rx irq handler The changes to deliver hardware accelerated VLAN packets to packet sockets (commit bc1d0411) caused a warning for non-NAPI drivers. The __vlan_hwaccel_rx() function is called directly from the drivers RX function, for non-NAPI drivers that means its still in RX IRQ context: [ 27.779463] ------------[ cut here ]------------ [ 27.779509] WARNING: at kernel/softirq.c:136 local_bh_enable+0x37/0x81() ... [ 27.782520] [] netif_nit_deliver+0x5b/0x75 [ 27.782590] [] __vlan_hwaccel_rx+0x79/0x162 [ 27.782664] [] atl1_intr+0x9a9/0xa7c [atl1] [ 27.782738] [] handle_IRQ_event+0x23/0x51 [ 27.782808] [] handle_edge_irq+0xc2/0x102 [ 27.782878] [] do_IRQ+0x4d/0x64 Split hardware accelerated VLAN reception into two parts to fix this: - __vlan_hwaccel_rx just stores the VLAN TCI and performs the VLAN device lookup, then calls netif_receive_skb()/netif_rx() - vlan_hwaccel_do_receive(), which is invoked by netif_receive_skb() in softirq context, performs the real reception and delivery to packet sockets. Reported-and-tested-by: Ramon Casellas Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/if_vlan.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 9e7b49b8062..a5cb0c3f6dc 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h @@ -114,6 +114,8 @@ extern u16 vlan_dev_vlan_id(const struct net_device *dev); extern int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, u16 vlan_tci, int polling); +extern int vlan_hwaccel_do_receive(struct sk_buff *skb); + #else static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev) { @@ -133,6 +135,11 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp, BUG(); return NET_XMIT_SUCCESS; } + +static inline int vlan_hwaccel_do_receive(struct sk_buff *skb) +{ + return 0; +} #endif /** -- cgit v1.2.3 From 467622ef2acb01986eab37ef96c3632b3ea35999 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 1 Nov 2008 04:19:11 -0700 Subject: [MTD] [NOR] Fix cfi_send_gen_cmd handling of x16 devices in x8 mode (v4) For "unlock" cycles to 16bit devices in 8bit compatibility mode we need to use the byte addresses 0xaaa and 0x555. These effectively match the word address 0x555 and 0x2aa, except the latter has its low bit set. Most chips don't care about the value of the 'A-1' pin in x8 mode, but some -- like the ST M29W320D -- do. So we need to be careful to set it where appropriate. cfi_send_gen_cmd is only ever passed addresses where the low byte is 0x00, 0x55 or 0xaa. Of those, only addresses ending 0xaa are affected by this patch, by masking in the extra low bit when the device is known to be in compatibility mode. [dwmw2: Do it only when (cmd_ofs & 0xff) == 0xaa] v4: Fix stupid typo in cfi_build_cmd_addr that failed to compile I'm writing this patch way to late at night. v3: Bring all of the work back into cfi_build_cmd_addr including calling of map_bankwidth(map) and cfi_interleave(cfi) So every caller doesn't need to. v2: Only modified the address if we our device_type is larger than our bus width. Cc: stable@kernel.org Signed-off-by: Eric W. Biederman Signed-off-by: David Woodhouse --- include/linux/mtd/cfi.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index ee5124ec319..00e2b575021 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -282,9 +282,25 @@ struct cfi_private { /* * Returns the command address according to the given geometry. */ -static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) +static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, + struct map_info *map, struct cfi_private *cfi) { - return (cmd_ofs * type) * interleave; + unsigned bankwidth = map_bankwidth(map); + unsigned interleave = cfi_interleave(cfi); + unsigned type = cfi->device_type; + uint32_t addr; + + addr = (cmd_ofs * type) * interleave; + + /* Modify the unlock address if we are in compatiblity mode. + * For 16bit devices on 8 bit busses + * and 32bit devices on 16 bit busses + * set the low bit of the alternating bit sequence of the address. + */ + if (((type * interleave) > bankwidth) && ((uint8_t)cmd_ofs == 0xaa)) + addr |= (type >> 1)*interleave; + + return addr; } /* @@ -430,7 +446,7 @@ static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t int type, map_word *prev_val) { map_word val; - uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); + uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi); val = cfi_build_cmd(cmd, map, cfi); if (prev_val) -- cgit v1.2.3 From 9fcd18c9e63e325dbd2b4c726623f760788d5aa8 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 5 Nov 2008 16:52:08 +0100 Subject: sched: re-tune balancing Impact: improve wakeup affinity on NUMA systems, tweak SMP systems Given the fixes+tweaks to the wakeup-buddy code, re-tweak the domain balancing defaults on NUMA and SMP systems. Turn on SD_WAKE_AFFINE which was off on x86 NUMA - there's no reason why we would not want to have wakeup affinity across nodes as well. (we already do this in the standard NUMA template.) lat_ctx on a NUMA box is particularly happy about this change: before: | phoenix:~/l> ./lat_ctx -s 0 2 | "size=0k ovr=2.60 | 2 5.70 after: | phoenix:~/l> ./lat_ctx -s 0 2 | "size=0k ovr=2.65 | 2 2.07 a 2.75x speedup. pipe-test is similarly happy about it too: | phoenix:~/sched-tests> ./pipe-test | 18.26 usecs/loop. | 14.70 usecs/loop. | 14.38 usecs/loop. | 10.55 usecs/loop. # +WAKE_AFFINE on domain0+domain1 | 8.63 usecs/loop. | 8.59 usecs/loop. | 9.03 usecs/loop. | 8.94 usecs/loop. | 8.96 usecs/loop. | 8.63 usecs/loop. Also: - disable SD_BALANCE_NEWIDLE on NUMA and SMP domains (keep it for siblings) - enable SD_WAKE_BALANCE on SMP domains Sysbench+postgresql improves all around the board, quite significantly: .28-rc3-11474e2c .28-rc3-11474e2c-tune ------------------------------------------------- 1: 571 688 +17.08% 2: 1236 1206 -2.55% 4: 2381 2642 +9.89% 8: 4958 5164 +3.99% 16: 9580 9574 -0.07% 32: 7128 8118 +12.20% 64: 7342 8266 +11.18% 128: 7342 8064 +8.95% 256: 7519 7884 +4.62% 512: 7350 7731 +4.93% ------------------------------------------------- SUM: 55412 59341 +6.62% So it's a win both for the runup portion, the peak area and the tail. Signed-off-by: Ingo Molnar --- include/linux/topology.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/topology.h b/include/linux/topology.h index 2158fc0d5a5..34a7ee0ebed 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -146,10 +146,10 @@ void arch_update_cpu_topology(void); .wake_idx = 1, \ .forkexec_idx = 1, \ .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_NEWIDLE \ - | SD_BALANCE_FORK \ | SD_BALANCE_EXEC \ + | SD_BALANCE_FORK \ | SD_WAKE_AFFINE \ + | SD_WAKE_BALANCE \ | BALANCE_FOR_PKG_POWER,\ .last_balance = jiffies, \ .balance_interval = 1, \ -- cgit v1.2.3 From f92131c3dd567fc6df18ce3f46fcf57ecbdefbe0 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 29 Oct 2008 14:10:51 +0100 Subject: bio: define __BIOVEC_PHYS_MERGEABLE Define __BIOVEC_PHYS_MERGEABLE as the default implementation of BIOVEC_PHYS_MERGEABLE, so that its available for reuse within an arch-specific definition of BIOVEC_PHYS_MERGEABLE. Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Jens Axboe --- include/linux/bio.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/bio.h b/include/linux/bio.h index 1c91a176b9a..6a642098e5c 100644 --- a/include/linux/bio.h +++ b/include/linux/bio.h @@ -236,12 +236,16 @@ static inline void *bio_data(struct bio *bio) #define __BVEC_END(bio) bio_iovec_idx((bio), (bio)->bi_vcnt - 1) #define __BVEC_START(bio) bio_iovec_idx((bio), (bio)->bi_idx) +/* Default implementation of BIOVEC_PHYS_MERGEABLE */ +#define __BIOVEC_PHYS_MERGEABLE(vec1, vec2) \ + ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) + /* * allow arch override, for eg virtualized architectures (put in asm/io.h) */ #ifndef BIOVEC_PHYS_MERGEABLE #define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \ - ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) + __BIOVEC_PHYS_MERGEABLE(vec1, vec2) #endif #define __BIO_SEG_BOUNDARY(addr1, addr2, mask) \ -- cgit v1.2.3 From 9c133c469d38043d5aadaa03f2fb840d88d1cf4f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 6 Nov 2008 08:42:48 +0100 Subject: Add round_jiffies_up and related routines This patch (as1158b) adds round_jiffies_up() and friends. These routines work like the analogous round_jiffies() functions, except that they will never round down. The new routines will be useful for timeouts where we don't care exactly when the timer expires, provided it doesn't expire too soon. Signed-off-by: Alan Stern Signed-off-by: Jens Axboe --- include/linux/timer.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/timer.h b/include/linux/timer.h index d4ba79248a2..daf9685b861 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h @@ -186,4 +186,9 @@ unsigned long __round_jiffies_relative(unsigned long j, int cpu); unsigned long round_jiffies(unsigned long j); unsigned long round_jiffies_relative(unsigned long j); +unsigned long __round_jiffies_up(unsigned long j, int cpu); +unsigned long __round_jiffies_up_relative(unsigned long j, int cpu); +unsigned long round_jiffies_up(unsigned long j); +unsigned long round_jiffies_up_relative(unsigned long j); + #endif -- cgit v1.2.3 From 2d3854a37e8b767a51aba38ed6d22817b0631e33 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 5 Nov 2008 13:39:10 +1100 Subject: cpumask: introduce new API, without changing anything Impact: introduce new APIs We want to deprecate cpumasks on the stack, as we are headed for gynormous numbers of CPUs. Eventually, we want to head towards an undefined 'struct cpumask' so they can never be declared on stack. 1) New cpumask functions which take pointers instead of copies. (cpus_* -> cpumask_*) 2) Several new helpers to reduce requirements for temporary cpumasks (cpumask_first_and, cpumask_next_and, cpumask_any_and) 3) Helpers for declaring cpumasks on or offstack for large NR_CPUS (cpumask_var_t, alloc_cpumask_var and free_cpumask_var) 4) 'struct cpumask' for explicitness and to mark new-style code. 5) Make iterator functions stop at nr_cpu_ids (a runtime constant), not NR_CPUS for time efficiency and for smaller dynamic allocations in future. 6) cpumask_copy() so we can allocate less than a full cpumask eventually (for alloc_cpumask_var), and so we can eliminate the 'struct cpumask' definition eventually. 7) work_on_cpu() helper for doing task on a CPU, rather than saving old cpumask for current thread and manipulating it. 8) smp_call_function_many() which is smp_call_function_mask() except taking a cpumask pointer. Note that this patch simply introduces the new functions and leaves the obsolescent ones in place. This is to simplify the transition patches. Signed-off-by: Rusty Russell Signed-off-by: Ingo Molnar --- include/linux/cpumask.h | 502 +++++++++++++++++++++++++++++++++++++++++++++- include/linux/smp.h | 9 + include/linux/workqueue.h | 8 + 3 files changed, 517 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index d3219d73f8e..c8e66619097 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -5,6 +5,9 @@ * Cpumasks provide a bitmap suitable for representing the * set of CPU's in a system, one bit position per CPU number. * + * The new cpumask_ ops take a "struct cpumask *"; the old ones + * use cpumask_t. + * * See detailed comments in the file linux/bitmap.h describing the * data type on which these cpumasks are based. * @@ -31,7 +34,7 @@ * will span the entire range of NR_CPUS. * . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . * - * The available cpumask operations are: + * The obsolescent cpumask operations are: * * void cpu_set(cpu, mask) turn on bit 'cpu' in mask * void cpu_clear(cpu, mask) turn off bit 'cpu' in mask @@ -138,7 +141,7 @@ #include #include -typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; +typedef struct cpumask { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; extern cpumask_t _unused_cpumask_arg_; #define cpu_set(cpu, dst) __cpu_set((cpu), &(dst)) @@ -527,4 +530,499 @@ extern cpumask_t cpu_active_map; #define for_each_online_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_online_map) #define for_each_present_cpu(cpu) for_each_cpu_mask_nr((cpu), cpu_present_map) +/* These are the new versions of the cpumask operators: passed by pointer. + * The older versions will be implemented in terms of these, then deleted. */ +#define cpumask_bits(maskp) ((maskp)->bits) + +#if NR_CPUS <= BITS_PER_LONG +#define CPU_BITS_ALL \ +{ \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} + +/* This produces more efficient code. */ +#define nr_cpumask_bits NR_CPUS + +#else /* NR_CPUS > BITS_PER_LONG */ + +#define CPU_BITS_ALL \ +{ \ + [0 ... BITS_TO_LONGS(NR_CPUS)-2] = ~0UL, \ + [BITS_TO_LONGS(NR_CPUS)-1] = CPU_MASK_LAST_WORD \ +} + +#define nr_cpumask_bits nr_cpu_ids +#endif /* NR_CPUS > BITS_PER_LONG */ + +/* verify cpu argument to cpumask_* operators */ +static inline unsigned int cpumask_check(unsigned int cpu) +{ +#ifdef CONFIG_DEBUG_PER_CPU_MAPS + WARN_ON_ONCE(cpu >= nr_cpumask_bits); +#endif /* CONFIG_DEBUG_PER_CPU_MAPS */ + return cpu; +} + +#if NR_CPUS == 1 +/* Uniprocesor. */ +#define cpumask_first(src) ({ (void)(src); 0; }) +#define cpumask_next(n, src) ({ (void)(src); 1; }) +#define cpumask_next_zero(n, src) ({ (void)(src); 1; }) +#define cpumask_next_and(n, srcp, andp) ({ (void)(srcp), (void)(andp); 1; }) +#define cpumask_any_but(mask, cpu) ({ (void)(mask); (void)(cpu); 0; }) + +#define for_each_cpu(cpu, mask) \ + for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) +#define for_each_cpu_and(cpu, mask, and) \ + for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask, (void)and) +#else +/** + * cpumask_first - get the first cpu in a cpumask + * @srcp: the cpumask pointer + * + * Returns >= nr_cpu_ids if no cpus set. + */ +static inline unsigned int cpumask_first(const struct cpumask *srcp) +{ + return find_first_bit(cpumask_bits(srcp), nr_cpumask_bits); +} + +/** + * cpumask_next - get the next cpu in a cpumask + * @n: the cpu prior to the place to search (ie. return will be > @n) + * @srcp: the cpumask pointer + * + * Returns >= nr_cpu_ids if no further cpus set. + */ +static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) +{ + /* -1 is a legal arg here. */ + if (n != -1) + cpumask_check(n); + return find_next_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); +} + +/** + * cpumask_next_zero - get the next unset cpu in a cpumask + * @n: the cpu prior to the place to search (ie. return will be > @n) + * @srcp: the cpumask pointer + * + * Returns >= nr_cpu_ids if no further cpus unset. + */ +static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) +{ + /* -1 is a legal arg here. */ + if (n != -1) + cpumask_check(n); + return find_next_zero_bit(cpumask_bits(srcp), nr_cpumask_bits, n+1); +} + +int cpumask_next_and(int n, const struct cpumask *, const struct cpumask *); +int cpumask_any_but(const struct cpumask *mask, unsigned int cpu); + +#define for_each_cpu(cpu, mask) \ + for ((cpu) = -1; \ + (cpu) = cpumask_next((cpu), (mask)), \ + (cpu) < nr_cpu_ids;) +#define for_each_cpu_and(cpu, mask, and) \ + for ((cpu) = -1; \ + (cpu) = cpumask_next_and((cpu), (mask), (and)), \ + (cpu) < nr_cpu_ids;) +#endif /* SMP */ + +#define CPU_BITS_NONE \ +{ \ + [0 ... BITS_TO_LONGS(NR_CPUS)-1] = 0UL \ +} + +#define CPU_BITS_CPU0 \ +{ \ + [0] = 1UL \ +} + +/** + * cpumask_set_cpu - set a cpu in a cpumask + * @cpu: cpu number (< nr_cpu_ids) + * @dstp: the cpumask pointer + */ +static inline void cpumask_set_cpu(unsigned int cpu, struct cpumask *dstp) +{ + set_bit(cpumask_check(cpu), cpumask_bits(dstp)); +} + +/** + * cpumask_clear_cpu - clear a cpu in a cpumask + * @cpu: cpu number (< nr_cpu_ids) + * @dstp: the cpumask pointer + */ +static inline void cpumask_clear_cpu(int cpu, struct cpumask *dstp) +{ + clear_bit(cpumask_check(cpu), cpumask_bits(dstp)); +} + +/** + * cpumask_test_cpu - test for a cpu in a cpumask + * @cpu: cpu number (< nr_cpu_ids) + * @cpumask: the cpumask pointer + * + * No static inline type checking - see Subtlety (1) above. + */ +#define cpumask_test_cpu(cpu, cpumask) \ + test_bit(cpumask_check(cpu), (cpumask)->bits) + +/** + * cpumask_test_and_set_cpu - atomically test and set a cpu in a cpumask + * @cpu: cpu number (< nr_cpu_ids) + * @cpumask: the cpumask pointer + * + * test_and_set_bit wrapper for cpumasks. + */ +static inline int cpumask_test_and_set_cpu(int cpu, struct cpumask *cpumask) +{ + return test_and_set_bit(cpumask_check(cpu), cpumask_bits(cpumask)); +} + +/** + * cpumask_setall - set all cpus (< nr_cpu_ids) in a cpumask + * @dstp: the cpumask pointer + */ +static inline void cpumask_setall(struct cpumask *dstp) +{ + bitmap_fill(cpumask_bits(dstp), nr_cpumask_bits); +} + +/** + * cpumask_clear - clear all cpus (< nr_cpu_ids) in a cpumask + * @dstp: the cpumask pointer + */ +static inline void cpumask_clear(struct cpumask *dstp) +{ + bitmap_zero(cpumask_bits(dstp), nr_cpumask_bits); +} + +/** + * cpumask_and - *dstp = *src1p & *src2p + * @dstp: the cpumask result + * @src1p: the first input + * @src2p: the second input + */ +static inline void cpumask_and(struct cpumask *dstp, + const struct cpumask *src1p, + const struct cpumask *src2p) +{ + bitmap_and(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); +} + +/** + * cpumask_or - *dstp = *src1p | *src2p + * @dstp: the cpumask result + * @src1p: the first input + * @src2p: the second input + */ +static inline void cpumask_or(struct cpumask *dstp, const struct cpumask *src1p, + const struct cpumask *src2p) +{ + bitmap_or(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); +} + +/** + * cpumask_xor - *dstp = *src1p ^ *src2p + * @dstp: the cpumask result + * @src1p: the first input + * @src2p: the second input + */ +static inline void cpumask_xor(struct cpumask *dstp, + const struct cpumask *src1p, + const struct cpumask *src2p) +{ + bitmap_xor(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); +} + +/** + * cpumask_andnot - *dstp = *src1p & ~*src2p + * @dstp: the cpumask result + * @src1p: the first input + * @src2p: the second input + */ +static inline void cpumask_andnot(struct cpumask *dstp, + const struct cpumask *src1p, + const struct cpumask *src2p) +{ + bitmap_andnot(cpumask_bits(dstp), cpumask_bits(src1p), + cpumask_bits(src2p), nr_cpumask_bits); +} + +/** + * cpumask_complement - *dstp = ~*srcp + * @dstp: the cpumask result + * @srcp: the input to invert + */ +static inline void cpumask_complement(struct cpumask *dstp, + const struct cpumask *srcp) +{ + bitmap_complement(cpumask_bits(dstp), cpumask_bits(srcp), + nr_cpumask_bits); +} + +/** + * cpumask_equal - *src1p == *src2p + * @src1p: the first input + * @src2p: the second input + */ +static inline bool cpumask_equal(const struct cpumask *src1p, + const struct cpumask *src2p) +{ + return bitmap_equal(cpumask_bits(src1p), cpumask_bits(src2p), + nr_cpumask_bits); +} + +/** + * cpumask_intersects - (*src1p & *src2p) != 0 + * @src1p: the first input + * @src2p: the second input + */ +static inline bool cpumask_intersects(const struct cpumask *src1p, + const struct cpumask *src2p) +{ + return bitmap_intersects(cpumask_bits(src1p), cpumask_bits(src2p), + nr_cpumask_bits); +} + +/** + * cpumask_subset - (*src1p & ~*src2p) == 0 + * @src1p: the first input + * @src2p: the second input + */ +static inline int cpumask_subset(const struct cpumask *src1p, + const struct cpumask *src2p) +{ + return bitmap_subset(cpumask_bits(src1p), cpumask_bits(src2p), + nr_cpumask_bits); +} + +/** + * cpumask_empty - *srcp == 0 + * @srcp: the cpumask to that all cpus < nr_cpu_ids are clear. + */ +static inline bool cpumask_empty(const struct cpumask *srcp) +{ + return bitmap_empty(cpumask_bits(srcp), nr_cpumask_bits); +} + +/** + * cpumask_full - *srcp == 0xFFFFFFFF... + * @srcp: the cpumask to that all cpus < nr_cpu_ids are set. + */ +static inline bool cpumask_full(const struct cpumask *srcp) +{ + return bitmap_full(cpumask_bits(srcp), nr_cpumask_bits); +} + +/** + * cpumask_weight - Count of bits in *srcp + * @srcp: the cpumask to count bits (< nr_cpu_ids) in. + */ +static inline unsigned int cpumask_weight(const struct cpumask *srcp) +{ + return bitmap_weight(cpumask_bits(srcp), nr_cpumask_bits); +} + +/** + * cpumask_shift_right - *dstp = *srcp >> n + * @dstp: the cpumask result + * @srcp: the input to shift + * @n: the number of bits to shift by + */ +static inline void cpumask_shift_right(struct cpumask *dstp, + const struct cpumask *srcp, int n) +{ + bitmap_shift_right(cpumask_bits(dstp), cpumask_bits(srcp), n, + nr_cpumask_bits); +} + +/** + * cpumask_shift_left - *dstp = *srcp << n + * @dstp: the cpumask result + * @srcp: the input to shift + * @n: the number of bits to shift by + */ +static inline void cpumask_shift_left(struct cpumask *dstp, + const struct cpumask *srcp, int n) +{ + bitmap_shift_left(cpumask_bits(dstp), cpumask_bits(srcp), n, + nr_cpumask_bits); +} + +/** + * cpumask_copy - *dstp = *srcp + * @dstp: the result + * @srcp: the input cpumask + */ +static inline void cpumask_copy(struct cpumask *dstp, + const struct cpumask *srcp) +{ + bitmap_copy(cpumask_bits(dstp), cpumask_bits(srcp), nr_cpumask_bits); +} + +/** + * cpumask_any - pick a "random" cpu from *srcp + * @srcp: the input cpumask + * + * Returns >= nr_cpu_ids if no cpus set. + */ +#define cpumask_any(srcp) cpumask_first(srcp) + +/** + * cpumask_first_and - return the first cpu from *srcp1 & *srcp2 + * @src1p: the first input + * @src2p: the second input + * + * Returns >= nr_cpu_ids if no cpus set in both. See also cpumask_next_and(). + */ +#define cpumask_first_and(src1p, src2p) cpumask_next_and(-1, (src1p), (src2p)) + +/** + * cpumask_any_and - pick a "random" cpu from *mask1 & *mask2 + * @mask1: the first input cpumask + * @mask2: the second input cpumask + * + * Returns >= nr_cpu_ids if no cpus set. + */ +#define cpumask_any_and(mask1, mask2) cpumask_first_and((mask1), (mask2)) + +/** + * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * + * @bitmap: the bitmap + * + * There are a few places where cpumask_var_t isn't appropriate and + * static cpumasks must be used (eg. very early boot), yet we don't + * expose the definition of 'struct cpumask'. + * + * This does the conversion, and can be used as a constant initializer. + */ +#define to_cpumask(bitmap) \ + ((struct cpumask *)(1 ? (bitmap) \ + : (void *)sizeof(__check_is_bitmap(bitmap)))) + +static inline int __check_is_bitmap(const unsigned long *bitmap) +{ + return 1; +} + +/** + * cpumask_size - size to allocate for a 'struct cpumask' in bytes + * + * This will eventually be a runtime variable, depending on nr_cpu_ids. + */ +static inline size_t cpumask_size(void) +{ + /* FIXME: Once all cpumask assignments are eliminated, this + * can be nr_cpumask_bits */ + return BITS_TO_LONGS(NR_CPUS) * sizeof(long); +} + +/* + * cpumask_var_t: struct cpumask for stack usage. + * + * Oh, the wicked games we play! In order to make kernel coding a + * little more difficult, we typedef cpumask_var_t to an array or a + * pointer: doing &mask on an array is a noop, so it still works. + * + * ie. + * cpumask_var_t tmpmask; + * if (!alloc_cpumask_var(&tmpmask, GFP_KERNEL)) + * return -ENOMEM; + * + * ... use 'tmpmask' like a normal struct cpumask * ... + * + * free_cpumask_var(tmpmask); + */ +#ifdef CONFIG_CPUMASK_OFFSTACK +typedef struct cpumask *cpumask_var_t; + +bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); +void alloc_bootmem_cpumask_var(cpumask_var_t *mask); +void free_cpumask_var(cpumask_var_t mask); + +#else +typedef struct cpumask cpumask_var_t[1]; + +static inline bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) +{ + return true; +} + +static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) +{ +} + +static inline void free_cpumask_var(cpumask_var_t mask) +{ +} +#endif /* CONFIG_CPUMASK_OFFSTACK */ + +/* The pointer versions of the maps, these will become the primary versions. */ +#define cpu_possible_mask ((const struct cpumask *)&cpu_possible_map) +#define cpu_online_mask ((const struct cpumask *)&cpu_online_map) +#define cpu_present_mask ((const struct cpumask *)&cpu_present_map) +#define cpu_active_mask ((const struct cpumask *)&cpu_active_map) + +/* It's common to want to use cpu_all_mask in struct member initializers, + * so it has to refer to an address rather than a pointer. */ +extern const DECLARE_BITMAP(cpu_all_bits, NR_CPUS); +#define cpu_all_mask to_cpumask(cpu_all_bits) + +/* First bits of cpu_bit_bitmap are in fact unset. */ +#define cpu_none_mask to_cpumask(cpu_bit_bitmap[0]) + +/* Wrappers for arch boot code to manipulate normally-constant masks */ +static inline void set_cpu_possible(unsigned int cpu, bool possible) +{ + if (possible) + cpumask_set_cpu(cpu, &cpu_possible_map); + else + cpumask_clear_cpu(cpu, &cpu_possible_map); +} + +static inline void set_cpu_present(unsigned int cpu, bool present) +{ + if (present) + cpumask_set_cpu(cpu, &cpu_present_map); + else + cpumask_clear_cpu(cpu, &cpu_present_map); +} + +static inline void set_cpu_online(unsigned int cpu, bool online) +{ + if (online) + cpumask_set_cpu(cpu, &cpu_online_map); + else + cpumask_clear_cpu(cpu, &cpu_online_map); +} + +static inline void set_cpu_active(unsigned int cpu, bool active) +{ + if (active) + cpumask_set_cpu(cpu, &cpu_active_map); + else + cpumask_clear_cpu(cpu, &cpu_active_map); +} + +static inline void init_cpu_present(const struct cpumask *src) +{ + cpumask_copy(&cpu_present_map, src); +} + +static inline void init_cpu_possible(const struct cpumask *src) +{ + cpumask_copy(&cpu_possible_map, src); +} + +static inline void init_cpu_online(const struct cpumask *src) +{ + cpumask_copy(&cpu_online_map, src); +} #endif /* __LINUX_CPUMASK_H */ diff --git a/include/linux/smp.h b/include/linux/smp.h index 2e4d58b26c0..3f9a60043a9 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -64,8 +64,17 @@ extern void smp_cpus_done(unsigned int max_cpus); * Call a function on all other processors */ int smp_call_function(void(*func)(void *info), void *info, int wait); +/* Deprecated: use smp_call_function_many() which uses a cpumask ptr. */ int smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info, int wait); + +static inline void smp_call_function_many(const struct cpumask *mask, + void (*func)(void *info), void *info, + int wait) +{ + smp_call_function_mask(*mask, func, info, wait); +} + int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, int wait); void __smp_call_function_single(int cpuid, struct call_single_data *data); diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 89a5a1231ff..b36291130f2 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -240,4 +240,12 @@ void cancel_rearming_delayed_work(struct delayed_work *work) cancel_delayed_work_sync(work); } +#ifndef CONFIG_SMP +static inline long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg) +{ + return fn(arg); +} +#else +long work_on_cpu(unsigned int cpu, long (*fn)(void *), void *arg); +#endif /* CONFIG_SMP */ #endif -- cgit v1.2.3 From 8950d89acaa8c353869e681772479d7955ae6f7a Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 5 Nov 2008 16:18:03 -0700 Subject: ACPI: remove CONFIG_ACPI_EC Remove CONFIG_ACPI_EC. It was always set the same as CONFIG_ACPI, and it had no menu label, so there was no way to set it to anything other than "y". Per section 6.5.4 of the ACPI 3.0b specification, OSPM must make Embedded Controller operation regions, accessed via the Embedded Controllers described in ECDT, available before executing any control method. The ECDT table is optional, but if it is present, the above text means that the EC it describes is a required part of the ACPI subsystem, so CONFIG_ACPI_EC=n wouldn't make sense. Signed-off-by: Bjorn Helgaas Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- include/linux/acpi.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fd6a452b0ce..d7846bdd272 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -163,8 +163,6 @@ struct acpi_pci_driver { int acpi_pci_register_driver(struct acpi_pci_driver *driver); void acpi_pci_unregister_driver(struct acpi_pci_driver *driver); -#ifdef CONFIG_ACPI_EC - extern int ec_read(u8 addr, u8 *val); extern int ec_write(u8 addr, u8 val); extern int ec_transaction(u8 command, @@ -172,8 +170,6 @@ extern int ec_transaction(u8 command, u8 *rdata, unsigned rdata_len, int force_poll); -#endif /*CONFIG_ACPI_EC*/ - #if defined(CONFIG_ACPI_WMI) || defined(CONFIG_ACPI_WMI_MODULE) typedef void (*wmi_notify_handler) (u32 value, void *context); -- cgit v1.2.3 From f8d570a4745835f2238a33b537218a1bb03fc671 Mon Sep 17 00:00:00 2001 From: David Miller Date: Thu, 6 Nov 2008 00:37:40 -0800 Subject: net: Fix recursive descent in __scm_destroy(). __scm_destroy() walks the list of file descriptors in the scm_fp_list pointed to by the scm_cookie argument. Those, in turn, can close sockets and invoke __scm_destroy() again. There is nothing which limits how deeply this can occur. The idea for how to fix this is from Linus. Basically, we do all of the fput()s at the top level by collecting all of the scm_fp_list objects hit by an fput(). Inside of the initial __scm_destroy() we keep running the list until it is empty. Signed-off-by: David S. Miller Signed-off-by: Linus Torvalds --- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b483f39a711..295b7c756ca 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1349,6 +1349,8 @@ struct task_struct { */ unsigned long timer_slack_ns; unsigned long default_timer_slack_ns; + + struct list_head *scm_work_list; }; /* -- cgit v1.2.3 From 9e975dae2970d22557662761c8505ce9fd165684 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 6 Nov 2008 12:53:46 -0800 Subject: fat: split include/msdos_fs.h This splits __KERNEL__ stuff in include/msdos_fs.h into fs/fat/fat.h. Signed-off-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/msdos_fs.h | 276 +---------------------------------------------- 1 file changed, 2 insertions(+), 274 deletions(-) (limited to 'include/linux') diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index ba63858056c..0982fb47a90 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -167,282 +167,10 @@ struct msdos_dir_slot { }; #ifdef __KERNEL__ - -#include -#include -#include -#include -#include - -/* - * vfat shortname flags - */ -#define VFAT_SFN_DISPLAY_LOWER 0x0001 /* convert to lowercase for display */ -#define VFAT_SFN_DISPLAY_WIN95 0x0002 /* emulate win95 rule for display */ -#define VFAT_SFN_DISPLAY_WINNT 0x0004 /* emulate winnt rule for display */ -#define VFAT_SFN_CREATE_WIN95 0x0100 /* emulate win95 rule for create */ -#define VFAT_SFN_CREATE_WINNT 0x0200 /* emulate winnt rule for create */ - -struct fat_mount_options { - uid_t fs_uid; - gid_t fs_gid; - unsigned short fs_fmask; - unsigned short fs_dmask; - unsigned short codepage; /* Codepage for shortname conversions */ - char *iocharset; /* Charset used for filename input/display */ - unsigned short shortname; /* flags for shortname display/create rule */ - unsigned char name_check; /* r = relaxed, n = normal, s = strict */ - unsigned short allow_utime;/* permission for setting the [am]time */ - unsigned quiet:1, /* set = fake successful chmods and chowns */ - showexec:1, /* set = only set x bit for com/exe/bat */ - sys_immutable:1, /* set = system files are immutable */ - dotsOK:1, /* set = hidden and system files are named '.filename' */ - isvfat:1, /* 0=no vfat long filename support, 1=vfat support */ - utf8:1, /* Use of UTF-8 character set (Default) */ - unicode_xlate:1, /* create escape sequences for unhandled Unicode */ - numtail:1, /* Does first alias have a numeric '~1' type tail? */ - flush:1, /* write things quickly */ - nocase:1, /* Does this need case conversion? 0=need case conversion*/ - usefree:1, /* Use free_clusters for FAT32 */ - tz_utc:1; /* Filesystem timestamps are in UTC */ -}; - -#define FAT_HASH_BITS 8 -#define FAT_HASH_SIZE (1UL << FAT_HASH_BITS) -#define FAT_HASH_MASK (FAT_HASH_SIZE-1) - -/* - * MS-DOS file system in-core superblock data - */ -struct msdos_sb_info { - unsigned short sec_per_clus; /* sectors/cluster */ - unsigned short cluster_bits; /* log2(cluster_size) */ - unsigned int cluster_size; /* cluster size */ - unsigned char fats,fat_bits; /* number of FATs, FAT bits (12 or 16) */ - unsigned short fat_start; - unsigned long fat_length; /* FAT start & length (sec.) */ - unsigned long dir_start; - unsigned short dir_entries; /* root dir start & entries */ - unsigned long data_start; /* first data sector */ - unsigned long max_cluster; /* maximum cluster number */ - unsigned long root_cluster; /* first cluster of the root directory */ - unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */ - struct mutex fat_lock; - unsigned int prev_free; /* previously allocated cluster number */ - unsigned int free_clusters; /* -1 if undefined */ - unsigned int free_clus_valid; /* is free_clusters valid? */ - struct fat_mount_options options; - struct nls_table *nls_disk; /* Codepage used on disk */ - struct nls_table *nls_io; /* Charset used for input and display */ - const void *dir_ops; /* Opaque; default directory operations */ - int dir_per_block; /* dir entries per block */ - int dir_per_block_bits; /* log2(dir_per_block) */ - - int fatent_shift; - struct fatent_operations *fatent_ops; - - spinlock_t inode_hash_lock; - struct hlist_head inode_hashtable[FAT_HASH_SIZE]; -}; - -#define FAT_CACHE_VALID 0 /* special case for valid cache */ - -/* - * MS-DOS file system inode data in memory - */ -struct msdos_inode_info { - spinlock_t cache_lru_lock; - struct list_head cache_lru; - int nr_caches; - /* for avoiding the race between fat_free() and fat_get_cluster() */ - unsigned int cache_valid_id; - - loff_t mmu_private; - int i_start; /* first cluster or 0 */ - int i_logstart; /* logical first cluster */ - int i_attrs; /* unused attribute bits */ - loff_t i_pos; /* on-disk position of directory entry or 0 */ - struct hlist_node i_fat_hash; /* hash by i_location */ - struct inode vfs_inode; -}; - -struct fat_slot_info { - loff_t i_pos; /* on-disk position of directory entry */ - loff_t slot_off; /* offset for slot or de start */ - int nr_slots; /* number of slots + 1(de) in filename */ - struct msdos_dir_entry *de; - struct buffer_head *bh; -}; - -static inline struct msdos_sb_info *MSDOS_SB(struct super_block *sb) -{ - return sb->s_fs_info; -} - -static inline struct msdos_inode_info *MSDOS_I(struct inode *inode) -{ - return container_of(inode, struct msdos_inode_info, vfs_inode); -} - -/* Return the FAT attribute byte for this inode */ -static inline u8 fat_attr(struct inode *inode) -{ - return ((inode->i_mode & S_IWUGO) ? ATTR_NONE : ATTR_RO) | - (S_ISDIR(inode->i_mode) ? ATTR_DIR : ATTR_NONE) | - MSDOS_I(inode)->i_attrs; -} - -static inline unsigned char fat_checksum(const __u8 *name) -{ - unsigned char s = name[0]; - s = (s<<7) + (s>>1) + name[1]; s = (s<<7) + (s>>1) + name[2]; - s = (s<<7) + (s>>1) + name[3]; s = (s<<7) + (s>>1) + name[4]; - s = (s<<7) + (s>>1) + name[5]; s = (s<<7) + (s>>1) + name[6]; - s = (s<<7) + (s>>1) + name[7]; s = (s<<7) + (s>>1) + name[8]; - s = (s<<7) + (s>>1) + name[9]; s = (s<<7) + (s>>1) + name[10]; - return s; -} - -static inline sector_t fat_clus_to_blknr(struct msdos_sb_info *sbi, int clus) -{ - return ((sector_t)clus - FAT_START_ENT) * sbi->sec_per_clus - + sbi->data_start; -} - -static inline void fat16_towchar(wchar_t *dst, const __u8 *src, size_t len) -{ -#ifdef __BIG_ENDIAN - while (len--) { - *dst++ = src[0] | (src[1] << 8); - src += 2; - } -#else - memcpy(dst, src, len * 2); -#endif -} - -static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) -{ -#ifdef __BIG_ENDIAN - while (len--) { - dst[0] = *src & 0x00FF; - dst[1] = (*src & 0xFF00) >> 8; - dst += 2; - src++; - } -#else - memcpy(dst, src, len * 2); -#endif -} - /* media of boot sector */ static inline int fat_valid_media(u8 media) { return 0xf8 <= media || media == 0xf0; } - -/* fat/cache.c */ -extern void fat_cache_inval_inode(struct inode *inode); -extern int fat_get_cluster(struct inode *inode, int cluster, - int *fclus, int *dclus); -extern int fat_bmap(struct inode *inode, sector_t sector, sector_t *phys, - unsigned long *mapped_blocks); - -/* fat/dir.c */ -extern const struct file_operations fat_dir_operations; -extern int fat_search_long(struct inode *inode, const unsigned char *name, - int name_len, struct fat_slot_info *sinfo); -extern int fat_dir_empty(struct inode *dir); -extern int fat_subdirs(struct inode *dir); -extern int fat_scan(struct inode *dir, const unsigned char *name, - struct fat_slot_info *sinfo); -extern int fat_get_dotdot_entry(struct inode *dir, struct buffer_head **bh, - struct msdos_dir_entry **de, loff_t *i_pos); -extern int fat_alloc_new_dir(struct inode *dir, struct timespec *ts); -extern int fat_add_entries(struct inode *dir, void *slots, int nr_slots, - struct fat_slot_info *sinfo); -extern int fat_remove_entries(struct inode *dir, struct fat_slot_info *sinfo); - -/* fat/fatent.c */ -struct fat_entry { - int entry; - union { - u8 *ent12_p[2]; - __le16 *ent16_p; - __le32 *ent32_p; - } u; - int nr_bhs; - struct buffer_head *bhs[2]; -}; - -static inline void fatent_init(struct fat_entry *fatent) -{ - fatent->nr_bhs = 0; - fatent->entry = 0; - fatent->u.ent32_p = NULL; - fatent->bhs[0] = fatent->bhs[1] = NULL; -} - -static inline void fatent_set_entry(struct fat_entry *fatent, int entry) -{ - fatent->entry = entry; - fatent->u.ent32_p = NULL; -} - -static inline void fatent_brelse(struct fat_entry *fatent) -{ - int i; - fatent->u.ent32_p = NULL; - for (i = 0; i < fatent->nr_bhs; i++) - brelse(fatent->bhs[i]); - fatent->nr_bhs = 0; - fatent->bhs[0] = fatent->bhs[1] = NULL; -} - -extern void fat_ent_access_init(struct super_block *sb); -extern int fat_ent_read(struct inode *inode, struct fat_entry *fatent, - int entry); -extern int fat_ent_write(struct inode *inode, struct fat_entry *fatent, - int new, int wait); -extern int fat_alloc_clusters(struct inode *inode, int *cluster, - int nr_cluster); -extern int fat_free_clusters(struct inode *inode, int cluster); -extern int fat_count_free_clusters(struct super_block *sb); - -/* fat/file.c */ -extern int fat_generic_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); -extern const struct file_operations fat_file_operations; -extern const struct inode_operations fat_file_inode_operations; -extern int fat_setattr(struct dentry * dentry, struct iattr * attr); -extern void fat_truncate(struct inode *inode); -extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, - struct kstat *stat); - -/* fat/inode.c */ -extern void fat_attach(struct inode *inode, loff_t i_pos); -extern void fat_detach(struct inode *inode); -extern struct inode *fat_iget(struct super_block *sb, loff_t i_pos); -extern struct inode *fat_build_inode(struct super_block *sb, - struct msdos_dir_entry *de, loff_t i_pos); -extern int fat_sync_inode(struct inode *inode); -extern int fat_fill_super(struct super_block *sb, void *data, int silent, - const struct inode_operations *fs_dir_inode_ops, int isvfat); - -extern int fat_flush_inodes(struct super_block *sb, struct inode *i1, - struct inode *i2); -/* fat/misc.c */ -extern void fat_fs_panic(struct super_block *s, const char *fmt, ...); -extern void fat_clusters_flush(struct super_block *sb); -extern int fat_chain_add(struct inode *inode, int new_dclus, int nr_cluster); -extern int date_dos2unix(unsigned short time, unsigned short date, int tz_utc); -extern void fat_date_unix2dos(int unix_date, __le16 *time, __le16 *date, - int tz_utc); -extern int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs); - -int fat_cache_init(void); -void fat_cache_destroy(void); - -#endif /* __KERNEL__ */ - -#endif +#endif /* !__KERNEL__ */ +#endif /* !_LINUX_MSDOS_FS_H */ -- cgit v1.2.3 From 9c0aa1b87bf541affef519eb4879ce7c5a5941ae Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Thu, 6 Nov 2008 12:53:54 -0800 Subject: fat: Cleanup FAT attribute stuff This adds three helpers: fat_make_attrs() - makes FAT attributes from inode. fat_make_mode() - makes mode_t from FAT attributes. fat_save_attrs() - saves FAT attributes to inode. Then this replaces: MSDOS_MKMODE() by fat_make_mode(), fat_attr() by fat_make_attrs(), ->i_attrs = attr & ATTR_UNUSED by fat_save_attrs(). And for root inode, those is used with ATTR_DIR instead of bogus ATTR_NONE. Signed-off-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/msdos_fs.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/msdos_fs.h b/include/linux/msdos_fs.h index 0982fb47a90..e0a9b207920 100644 --- a/include/linux/msdos_fs.h +++ b/include/linux/msdos_fs.h @@ -46,11 +46,6 @@ #define DELETED_FLAG 0xe5 /* marks file as deleted when in name[0] */ #define IS_FREE(n) (!*(n) || *(n) == DELETED_FLAG) -/* valid file mode bits */ -#define MSDOS_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO) -/* Convert attribute bits and a mask to the UNIX mode. */ -#define MSDOS_MKMODE(a, m) (m & (a & ATTR_RO ? S_IRUGO|S_IXUGO : S_IRWXUGO)) - #define MSDOS_NAME 11 /* maximum name length */ #define MSDOS_LONGNAME 256 /* maximum name length */ #define MSDOS_SLOTS 21 /* max # of slots for short and long names */ -- cgit v1.2.3 From 7597bc94d6f3bdccb086ac7f2ad91292fdaee2a4 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 5 Nov 2008 17:38:47 +0000 Subject: Fix accidental implicit cast in HR-timer conversion Fix the hrtimer_add_expires_ns() function. It should take a 'u64 ns' argument, but rather takes an 'unsigned long ns' argument - which might only be 32-bits. On FRV, this results in the kernel locking up because hrtimer_forward() passes the result of a 64-bit multiplication to this function, for which the compiler discards the top 32-bits - something that didn't happen when ktime_add_ns() was called directly. Signed-off-by: David Howells Acked-by: Arjan van de Ven Signed-off-by: Linus Torvalds --- include/linux/hrtimer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 2b3645b1acf..07e510a3b00 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -239,7 +239,7 @@ static inline void hrtimer_add_expires(struct hrtimer *timer, ktime_t time) timer->_softexpires = ktime_add_safe(timer->_softexpires, time); } -static inline void hrtimer_add_expires_ns(struct hrtimer *timer, unsigned long ns) +static inline void hrtimer_add_expires_ns(struct hrtimer *timer, u64 ns) { timer->_expires = ktime_add_ns(timer->_expires, ns); timer->_softexpires = ktime_add_ns(timer->_softexpires, ns); -- cgit v1.2.3 From 3b53fbf4314594fa04544b02b2fc6e607912da18 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 6 Nov 2008 15:45:32 -0800 Subject: net: Fix recursive descent in __scm_destroy(). __scm_destroy() walks the list of file descriptors in the scm_fp_list pointed to by the scm_cookie argument. Those, in turn, can close sockets and invoke __scm_destroy() again. There is nothing which limits how deeply this can occur. The idea for how to fix this is from Linus. Basically, we do all of the fput()s at the top level by collecting all of the scm_fp_list objects hit by an fput(). Inside of the initial __scm_destroy() we keep running the list until it is empty. Signed-off-by: David S. Miller --- include/linux/sched.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index b483f39a711..295b7c756ca 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1349,6 +1349,8 @@ struct task_struct { */ unsigned long timer_slack_ns; unsigned long default_timer_slack_ns; + + struct list_head *scm_work_list; }; /* -- cgit v1.2.3 From cd83e42c6b0413dcbb548c2ead799111ff7e6a13 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 7 Nov 2008 11:12:29 +1100 Subject: cpumask: new API, v2 - add cpumask_of() - add free_bootmem_cpumask_var() Signed-off-by: Rusty Russell Signed-off-by: Ingo Molnar --- include/linux/cpumask.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index c8e66619097..31caa1bc620 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -893,6 +893,12 @@ static inline void cpumask_copy(struct cpumask *dstp, */ #define cpumask_any_and(mask1, mask2) cpumask_first_and((mask1), (mask2)) +/** + * cpumask_of - the cpumask containing just a given cpu + * @cpu: the cpu (<= nr_cpu_ids) + */ +#define cpumask_of(cpu) (get_cpu_mask(cpu)) + /** * to_cpumask - convert an NR_CPUS bitmap to a struct cpumask * * @bitmap: the bitmap @@ -946,6 +952,7 @@ typedef struct cpumask *cpumask_var_t; bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); void alloc_bootmem_cpumask_var(cpumask_var_t *mask); void free_cpumask_var(cpumask_var_t mask); +void free_bootmem_cpumask_var(cpumask_var_t mask); #else typedef struct cpumask cpumask_var_t[1]; @@ -962,6 +969,10 @@ static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) static inline void free_cpumask_var(cpumask_var_t mask) { } + +static inline void free_bootmem_cpumask_var(cpumask_var_t mask) +{ +} #endif /* CONFIG_CPUMASK_OFFSTACK */ /* The pointer versions of the maps, these will become the primary versions. */ -- cgit v1.2.3 From 14800984706bf6936bbec5187f736e928be5c218 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Fri, 7 Nov 2008 15:26:50 +0100 Subject: sched: fine-tune SD_MC_INIT Tune SD_MC_INIT the same way as SD_CPU_INIT: unset SD_BALANCE_NEWIDLE, and set SD_WAKE_BALANCE. This improves vmark by 5%: vmark 132102 125968 125497 messages/sec avg 127855.66 .984 vmark 139404 131719 131272 messages/sec avg 134131.66 1.033 Signed-off-by: Mike Galbraith Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar # *DOCUMENTATION* --- include/linux/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/topology.h b/include/linux/topology.h index 34a7ee0ebed..a8d840595b7 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -120,10 +120,10 @@ void arch_update_cpu_topology(void); .wake_idx = 1, \ .forkexec_idx = 1, \ .flags = SD_LOAD_BALANCE \ - | SD_BALANCE_NEWIDLE \ | SD_BALANCE_FORK \ | SD_BALANCE_EXEC \ | SD_WAKE_AFFINE \ + | SD_WAKE_BALANCE \ | SD_SHARE_PKG_RESOURCES\ | BALANCE_FOR_MC_POWER, \ .last_balance = jiffies, \ -- cgit v1.2.3 From 52c642f33b14bfa1b00ef2b68296effb34a573f3 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Fri, 7 Nov 2008 16:09:23 +0100 Subject: sched: fine-tune SD_SIBLING_INIT fine-tune the HT sched-domains parameters as well. On a HT capable box, this increases lat_ctx performance from 23.87 usecs to 1.49 usecs: # before $ ./lat_ctx -s 0 2 "size=0k ovr=1.89 2 23.87 # after $ ./lat_ctx -s 0 2 "size=0k ovr=1.84 2 1.49 Signed-off-by: Ingo Molnar --- include/linux/topology.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/topology.h b/include/linux/topology.h index a8d840595b7..117f1b7405c 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -99,7 +99,7 @@ void arch_update_cpu_topology(void); | SD_BALANCE_FORK \ | SD_BALANCE_EXEC \ | SD_WAKE_AFFINE \ - | SD_WAKE_IDLE \ + | SD_WAKE_BALANCE \ | SD_SHARE_CPUPOWER, \ .last_balance = jiffies, \ .balance_interval = 1, \ -- cgit v1.2.3 From c3d6de698c84efdbdd3781b7058bcc339ab43da8 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 1 Aug 2008 17:37:55 +0200 Subject: ACPI video: if no ACPI backlight support, use vendor drivers If an ACPI graphics device supports backlight brightness functions (cmp. with latest ACPI spec Appendix B), let the ACPI video driver control backlight and switch backlight control off in vendor specific ACPI drivers (asus_acpi, thinkpad_acpi, eeepc, fujitsu_laptop, msi_laptop, sony_laptop, acer-wmi). Currently it is possible to load above drivers and let both poke on the brightness HW registers, the video and vendor specific ACPI drivers -> bad. This patch provides the basic support to check for BIOS capabilities before driver loading time. Driver specific modifications are in separate follow up patches. "acpi_backlight=vendor" Prever vendor driver over ACPI driver for backlight. "acpi_backlight=video" (default) Prever ACPI driver over vendor driver for backlight. Signed-off-by: Thomas Renninger Acked-by: Zhang Rui Signed-off-by: Andi Kleen Signed-off-by: Len Brown --- include/linux/acpi.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index fd6a452b0ce..7f23761ace3 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -194,6 +194,50 @@ extern bool wmi_has_guid(const char *guid); #endif /* CONFIG_ACPI_WMI */ +#define ACPI_VIDEO_OUTPUT_SWITCHING 0x0001 +#define ACPI_VIDEO_DEVICE_POSTING 0x0002 +#define ACPI_VIDEO_ROM_AVAILABLE 0x0004 +#define ACPI_VIDEO_BACKLIGHT 0x0008 +#define ACPI_VIDEO_BACKLIGHT_FORCE_VENDOR 0x0010 +#define ACPI_VIDEO_BACKLIGHT_FORCE_VIDEO 0x0020 +#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR 0x0040 +#define ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO 0x0080 +#define ACPI_VIDEO_BACKLIGHT_DMI_VENDOR 0x0100 +#define ACPI_VIDEO_BACKLIGHT_DMI_VIDEO 0x0200 +#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR 0x0400 +#define ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO 0x0800 + +#if defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) + +extern long acpi_video_get_capabilities(acpi_handle graphics_dev_handle); +extern long acpi_is_video_device(struct acpi_device *device); +extern int acpi_video_backlight_support(void); +extern int acpi_video_display_switch_support(void); + +#else + +static inline long acpi_video_get_capabilities(acpi_handle graphics_dev_handle) +{ + return 0; +} + +static inline long acpi_is_video_device(struct acpi_device *device) +{ + return 0; +} + +static inline int acpi_video_backlight_support(void) +{ + return 0; +} + +static inline int acpi_video_display_switch_support(void) +{ + return 0; +} + +#endif /* defined(CONFIG_ACPI_VIDEO) || defined(CONFIG_ACPI_VIDEO_MODULE) */ + extern int acpi_blacklisted(void); #ifdef CONFIG_DMI extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); -- cgit v1.2.3 From d1b268630875a7713b5d468a0c03403c5b721c8e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 8 Nov 2008 21:37:46 +0100 Subject: mmc: struct device - replace bus_id with dev_name(), dev_set_name() Acked-by: Greg Kroah-Hartman Signed-Off-By: Kay Sievers Signed-off-by: Pierre Ossman --- include/linux/mmc/card.h | 2 +- include/linux/mmc/host.h | 2 +- include/linux/mmc/sdio_func.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index ee6e822d599..403aa505f27 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -130,7 +130,7 @@ struct mmc_card { #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) #define mmc_card_name(c) ((c)->cid.prod_name) -#define mmc_card_id(c) ((c)->dev.bus_id) +#define mmc_card_id(c) (dev_name(&(c)->dev)) #define mmc_list_to_card(l) container_of(l, struct mmc_card, node) #define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index bde891f6459..f842f234e44 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -176,7 +176,7 @@ static inline void *mmc_priv(struct mmc_host *host) #define mmc_dev(x) ((x)->parent) #define mmc_classdev(x) (&(x)->class_dev) -#define mmc_hostname(x) ((x)->class_dev.bus_id) +#define mmc_hostname(x) (dev_name(&(x)->class_dev)) extern int mmc_suspend_host(struct mmc_host *, pm_message_t); extern int mmc_resume_host(struct mmc_host *); diff --git a/include/linux/mmc/sdio_func.h b/include/linux/mmc/sdio_func.h index 07bee4a0d45..451bdfc8583 100644 --- a/include/linux/mmc/sdio_func.h +++ b/include/linux/mmc/sdio_func.h @@ -63,7 +63,7 @@ struct sdio_func { #define sdio_func_set_present(f) ((f)->state |= SDIO_STATE_PRESENT) -#define sdio_func_id(f) ((f)->dev.bus_id) +#define sdio_func_id(f) (dev_name(&(f)->dev)) #define sdio_get_drvdata(f) dev_get_drvdata(&(f)->dev) #define sdio_set_drvdata(f,d) dev_set_drvdata(&(f)->dev, d) -- cgit v1.2.3 From 058e3739f6b0753696db1952378de9e8d2a11735 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Sun, 9 Nov 2008 00:27:53 -0500 Subject: clarify usage expectations for cnt32_to_63() Currently, all existing users of cnt32_to_63() are fine since the CPU architectures where it is used don't do read access reordering, and user mode preemption is disabled already. It is nevertheless a good idea to better elaborate usage requirements wrt preemption, and use an explicit memory barrier on SMP to avoid different CPUs accessing the counter value in the wrong order. On UP a simple compiler barrier is sufficient. Signed-off-by: Nicolas Pitre Acked-by: Mathieu Desnoyers Signed-off-by: Linus Torvalds --- include/linux/cnt32_to_63.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cnt32_to_63.h b/include/linux/cnt32_to_63.h index 8c0f9505b48..7605fdd1eb6 100644 --- a/include/linux/cnt32_to_63.h +++ b/include/linux/cnt32_to_63.h @@ -16,6 +16,7 @@ #include #include #include +#include /* this is used only to give gcc a clue about good code generation */ union cnt32_to_63 { @@ -53,11 +54,19 @@ union cnt32_to_63 { * needed increment. And any race in updating the value in memory is harmless * as the same value would simply be stored more than once. * - * The only restriction for the algorithm to work properly is that this - * code must be executed at least once per each half period of the 32-bit - * counter to properly update the state bit in memory. This is usually not a - * problem in practice, but if it is then a kernel timer could be scheduled - * to manage for this code to be executed often enough. + * The restrictions for the algorithm to work properly are: + * + * 1) this code must be called at least once per each half period of the + * 32-bit counter; + * + * 2) this code must not be preempted for a duration longer than the + * 32-bit counter half period minus the longest period between two + * calls to this code. + * + * Those requirements ensure proper update to the state bit in memory. + * This is usually not a problem in practice, but if it is then a kernel + * timer should be scheduled to manage for this code to be executed often + * enough. * * Note that the top bit (bit 63) in the returned value should be considered * as garbage. It is not cleared here because callers are likely to use a @@ -68,9 +77,10 @@ union cnt32_to_63 { */ #define cnt32_to_63(cnt_lo) \ ({ \ - static volatile u32 __m_cnt_hi; \ + static u32 __m_cnt_hi; \ union cnt32_to_63 __x; \ __x.hi = __m_cnt_hi; \ + smp_rmb(); \ __x.lo = (cnt_lo); \ if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \ __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \ -- cgit v1.2.3 From 984f2f377fdfd098f5ae58d09ee04d5e29e6112b Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 8 Nov 2008 20:24:19 +1100 Subject: cpumask: introduce new API, without changing anything, v3 Impact: cleanup Clean up based on feedback from Andrew Morton and others: - change to inline functions instead of macros - add __init to bootmem method - add a missing debug check Signed-off-by: Rusty Russell Signed-off-by: Ingo Molnar --- include/linux/cpumask.h | 58 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 31caa1bc620..21e1dd43e52 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h @@ -564,12 +564,36 @@ static inline unsigned int cpumask_check(unsigned int cpu) } #if NR_CPUS == 1 -/* Uniprocesor. */ -#define cpumask_first(src) ({ (void)(src); 0; }) -#define cpumask_next(n, src) ({ (void)(src); 1; }) -#define cpumask_next_zero(n, src) ({ (void)(src); 1; }) -#define cpumask_next_and(n, srcp, andp) ({ (void)(srcp), (void)(andp); 1; }) -#define cpumask_any_but(mask, cpu) ({ (void)(mask); (void)(cpu); 0; }) +/* Uniprocessor. Assume all masks are "1". */ +static inline unsigned int cpumask_first(const struct cpumask *srcp) +{ + return 0; +} + +/* Valid inputs for n are -1 and 0. */ +static inline unsigned int cpumask_next(int n, const struct cpumask *srcp) +{ + return n+1; +} + +static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) +{ + return n+1; +} + +static inline unsigned int cpumask_next_and(int n, + const struct cpumask *srcp, + const struct cpumask *andp) +{ + return n+1; +} + +/* cpu must be a valid cpu, ie 0, so there's no other choice. */ +static inline unsigned int cpumask_any_but(const struct cpumask *mask, + unsigned int cpu) +{ + return 1; +} #define for_each_cpu(cpu, mask) \ for ((cpu) = 0; (cpu) < 1; (cpu)++, (void)mask) @@ -620,10 +644,32 @@ static inline unsigned int cpumask_next_zero(int n, const struct cpumask *srcp) int cpumask_next_and(int n, const struct cpumask *, const struct cpumask *); int cpumask_any_but(const struct cpumask *mask, unsigned int cpu); +/** + * for_each_cpu - iterate over every cpu in a mask + * @cpu: the (optionally unsigned) integer iterator + * @mask: the cpumask pointer + * + * After the loop, cpu is >= nr_cpu_ids. + */ #define for_each_cpu(cpu, mask) \ for ((cpu) = -1; \ (cpu) = cpumask_next((cpu), (mask)), \ (cpu) < nr_cpu_ids;) + +/** + * for_each_cpu_and - iterate over every cpu in both masks + * @cpu: the (optionally unsigned) integer iterator + * @mask: the first cpumask pointer + * @and: the second cpumask pointer + * + * This saves a temporary CPU mask in many places. It is equivalent to: + * struct cpumask tmp; + * cpumask_and(&tmp, &mask, &and); + * for_each_cpu(cpu, &tmp) + * ... + * + * After the loop, cpu is >= nr_cpu_ids. + */ #define for_each_cpu_and(cpu, mask, and) \ for ((cpu) = -1; \ (cpu) = cpumask_next_and((cpu), (mask), (and)), \ -- cgit v1.2.3 From 8a8bc22332ee6ea49137508467a76aa7f4367719 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 10 Nov 2008 14:48:21 +0900 Subject: libata: revert convert-to-block-tagging patches This patch reverts the following three commits which convert libata to use block layer tagging. 43a49cbdf31e812c0d8f553d433b09b421f5d52c e013e13bf605b9e6b702adffbe2853cfc60e7806 2fca5ccf97d2c28bcfce44f5b07d85e74e3cd18e Although using block layer tagging is the right direction, due to the tight coupling among tag number, data structure allocation and hardware command slot allocation, libata doesn't work correctly with the current conversion. The biggest problem is guaranteeing that tag 0 is always used for non-NCQ commands. Due to the way blk-tag is implemented and how SCSI starts and finishes requests, such guarantee can't be made. I'm not sure whether this would actually break any low level driver but it doesn't look like a good idea to break such assumption given the frailty of ATA controllers. So, for the time being, keep using the old dumb in-libata qc allocation. Signed-off-by: Tejun Heo Cc: Jens Axobe Cc: Jeff Garzik Signed-off-by: Linus Torvalds --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c7665a4134c..59b0f1c807b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -698,6 +698,7 @@ struct ata_port { unsigned int cbl; /* cable type; ATA_CBL_xxx */ struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; + unsigned long qc_allocated; unsigned int qc_active; int nr_active_links; /* #links with active qcs */ -- cgit v1.2.3 From fd0fcf5c29dd0339c5f5d86eb2cbe9fdad5bcd73 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Thu, 6 Nov 2008 10:49:21 +0000 Subject: ssb: Fix DMA-API compilation for non-PCI systems This fixes compilation of the SSB DMA-API code on non-PCI platforms. Signed-off-by: Michael Buesch Signed-off-by: David S. Miller --- include/linux/ssb/ssb.h | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index e530026eedf..17d9b58f637 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -427,12 +427,16 @@ static inline int ssb_dma_mapping_error(struct ssb_device *dev, dma_addr_t addr) { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST return pci_dma_mapping_error(dev->bus->host_pci, addr); +#endif + break; case SSB_BUSTYPE_SSB: return dma_mapping_error(dev->dev, addr); default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); return -ENOSYS; } @@ -441,12 +445,16 @@ static inline dma_addr_t ssb_dma_map_single(struct ssb_device *dev, void *p, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST return pci_map_single(dev->bus->host_pci, p, size, dir); +#endif + break; case SSB_BUSTYPE_SSB: return dma_map_single(dev->dev, p, size, dir); default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); return 0; } @@ -455,14 +463,18 @@ static inline void ssb_dma_unmap_single(struct ssb_device *dev, dma_addr_t dma_a { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST pci_unmap_single(dev->bus->host_pci, dma_addr, size, dir); return; +#endif + break; case SSB_BUSTYPE_SSB: dma_unmap_single(dev->dev, dma_addr, size, dir); return; default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); } static inline void ssb_dma_sync_single_for_cpu(struct ssb_device *dev, @@ -472,15 +484,19 @@ static inline void ssb_dma_sync_single_for_cpu(struct ssb_device *dev, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr, size, dir); return; +#endif + break; case SSB_BUSTYPE_SSB: dma_sync_single_for_cpu(dev->dev, dma_addr, size, dir); return; default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); } static inline void ssb_dma_sync_single_for_device(struct ssb_device *dev, @@ -490,15 +506,19 @@ static inline void ssb_dma_sync_single_for_device(struct ssb_device *dev, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr, size, dir); return; +#endif + break; case SSB_BUSTYPE_SSB: dma_sync_single_for_device(dev->dev, dma_addr, size, dir); return; default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); } static inline void ssb_dma_sync_single_range_for_cpu(struct ssb_device *dev, @@ -509,17 +529,21 @@ static inline void ssb_dma_sync_single_range_for_cpu(struct ssb_device *dev, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST /* Just sync everything. That's all the PCI API can do. */ pci_dma_sync_single_for_cpu(dev->bus->host_pci, dma_addr, offset + size, dir); return; +#endif + break; case SSB_BUSTYPE_SSB: dma_sync_single_range_for_cpu(dev->dev, dma_addr, offset, size, dir); return; default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); } static inline void ssb_dma_sync_single_range_for_device(struct ssb_device *dev, @@ -530,17 +554,21 @@ static inline void ssb_dma_sync_single_range_for_device(struct ssb_device *dev, { switch (dev->bus->bustype) { case SSB_BUSTYPE_PCI: +#ifdef CONFIG_SSB_PCIHOST /* Just sync everything. That's all the PCI API can do. */ pci_dma_sync_single_for_device(dev->bus->host_pci, dma_addr, offset + size, dir); return; +#endif + break; case SSB_BUSTYPE_SSB: dma_sync_single_range_for_device(dev->dev, dma_addr, offset, size, dir); return; default: - __ssb_dma_not_implemented(dev); + break; } + __ssb_dma_not_implemented(dev); } -- cgit v1.2.3 From ad474caca3e2a0550b7ce0706527ad5ab389a4d4 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 10 Nov 2008 15:39:30 +0100 Subject: fix for account_group_exec_runtime(), make sure ->signal can't be freed under rq->lock Impact: fix hang/crash on ia64 under high load This is ugly, but the simplest patch by far. Unlike other similar routines, account_group_exec_runtime() could be called "implicitly" from within scheduler after exit_notify(). This means we can race with the parent doing release_task(), we can't just check ->signal != NULL. Change __exit_signal() to do spin_unlock_wait(&task_rq(tsk)->lock) before __cleanup_signal() to make sure ->signal can't be freed under task_rq(tsk)->lock. Note that task_rq_unlock_wait() doesn't care about the case when tsk changes cpu/rq under us, this should be OK. Thanks to Ingo who nacked my previous buggy patch. Signed-off-by: Oleg Nesterov Acked-by: Peter Zijlstra Signed-off-by: Ingo Molnar Reported-by: Doug Chapman --- include/linux/sched.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sched.h b/include/linux/sched.h index 295b7c756ca..644ffbda17c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -247,6 +247,7 @@ extern void init_idle(struct task_struct *idle, int cpu); extern void init_idle_bootup_task(struct task_struct *idle); extern int runqueue_is_locked(void); +extern void task_rq_unlock_wait(struct task_struct *p); extern cpumask_t nohz_cpu_mask; #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ) -- cgit v1.2.3 From 0906dd9df2f79042cfa82d8388895be7cbe7a51b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 11 Nov 2008 14:51:23 +0000 Subject: telephony: trivial: fix up email address Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- include/linux/telephony.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/telephony.h b/include/linux/telephony.h index 5b2b6261f19..f63afe330ad 100644 --- a/include/linux/telephony.h +++ b/include/linux/telephony.h @@ -14,7 +14,7 @@ * Authors: Ed Okerson, * Greg Herlein, * - * Contributors: Alan Cox, + * Contributors: Alan Cox, * David W. Erhart, * * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR -- cgit v1.2.3 From a358324466b171e145df20bdb74fe81759906de6 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 11 Nov 2008 15:01:42 -0500 Subject: ring-buffer: buffer record on/off switch Impact: enable/disable ring buffer recording API added Several kernel developers have requested that there be a way to stop recording into the ring buffers with a simple switch that can also be enabled from userspace. This patch addes a new kernel API to the ring buffers called: tracing_on() tracing_off() When tracing_off() is called, all ring buffers will not be able to record into their buffers. tracing_on() will enable the ring buffers again. These two act like an on/off switch. That is, there is no counting of the number of times tracing_off or tracing_on has been called. A new file is added to the debugfs/tracing directory called tracing_on This allows for userspace applications to also flip the switch. echo 0 > debugfs/tracing/tracing_on disables the tracing. echo 1 > /debugfs/tracing/tracing_on enables it. Note, this does not disable or enable any tracers. It only sets or clears a flag that needs to be set in order for the ring buffers to write to their buffers. It is a global flag, and affects all ring buffers. The buffers start out with tracing_on enabled. There are now three flags that control recording into the buffers: tracing_on: which affects all ring buffer tracers. buffer->record_disabled: which affects an allocated buffer, which may be set if an anomaly is detected, and tracing is disabled. cpu_buffer->record_disabled: which is set by tracing_stop() or if an anomaly is detected. tracing_start can not reenable this if an anomaly occurred. The userspace debugfs/tracing/tracing_enabled is implemented with tracing_stop() but the user space code can not enable it if the kernel called tracing_stop(). Userspace can enable the tracing_on even if the kernel disabled it. It is just a switch used to stop tracing if a condition was hit. tracing_on is not for protecting critical areas in the kernel nor is it for stopping tracing if an anomaly occurred. This is because userspace can reenable it at any time. Side effect: With this patch, I discovered a dead variable in ftrace.c called tracing_on. This patch removes it. Signed-off-by: Steven Rostedt --- include/linux/ring_buffer.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h index 536b0ca46a0..e097c2e6b6d 100644 --- a/include/linux/ring_buffer.h +++ b/include/linux/ring_buffer.h @@ -120,6 +120,9 @@ unsigned long ring_buffer_overruns(struct ring_buffer *buffer); u64 ring_buffer_time_stamp(int cpu); void ring_buffer_normalize_time_stamp(int cpu, u64 *ts); +void tracing_on(void); +void tracing_off(void); + enum ring_buffer_flags { RB_FL_OVERWRITE = 1 << 0, }; -- cgit v1.2.3 From 1a22f08dbd0e77c7cf45b5f527f93131d0b591b6 Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 11 Nov 2008 12:19:05 +0900 Subject: serial: sh-sci: fix cannot work SH7723 SCIFA SH7723 has SCIFA. This module is similer SCI register map, but it has FIFO. So this patch adds new type(PORT_SCIFA) and change some type checking. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Paul Mundt --- include/linux/serial_core.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index e27f216361f..4e4f1277f3b 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -155,6 +155,9 @@ #define PORT_SC26XX 82 +/* SH-SCI */ +#define PORT_SCIFA 83 + #ifdef __KERNEL__ #include -- cgit v1.2.3 From 621a0d5207c18012cb39932f2d9830a11a6cb03d Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 12 Nov 2008 09:36:35 +0100 Subject: hrtimer: clean up unused callback modes Impact: cleanup git grep HRTIMER_CB_IRQSAFE revealed half the callback modes are actually unused. Signed-off-by: Peter Zijlstra Signed-off-by: Ingo Molnar --- include/linux/hrtimer.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 07e510a3b00..3eba43878dc 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -46,9 +46,6 @@ enum hrtimer_restart { * hrtimer callback modes: * * HRTIMER_CB_SOFTIRQ: Callback must run in softirq context - * HRTIMER_CB_IRQSAFE: Callback may run in hardirq context - * HRTIMER_CB_IRQSAFE_NO_RESTART: Callback may run in hardirq context and - * does not restart the timer * HRTIMER_CB_IRQSAFE_PERCPU: Callback must run in hardirq context * Special mode for tick emulation and * scheduler timer. Such timers are per @@ -61,8 +58,6 @@ enum hrtimer_restart { */ enum hrtimer_cb_mode { HRTIMER_CB_SOFTIRQ, - HRTIMER_CB_IRQSAFE, - HRTIMER_CB_IRQSAFE_NO_RESTART, HRTIMER_CB_IRQSAFE_PERCPU, HRTIMER_CB_IRQSAFE_UNLOCKED, }; -- cgit v1.2.3 From b76f90b526737070302a127c710263e2ac707676 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 12 Nov 2008 13:26:55 -0800 Subject: remove ratelimt() It mistakenly assumes that a static local in an inlined function is a kernel-wide singleton. It also has no callers, so let's remove it. Cc: Dave Young Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ratelimit.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ratelimit.h b/include/linux/ratelimit.h index 18a5b9ba9d4..00044b85645 100644 --- a/include/linux/ratelimit.h +++ b/include/linux/ratelimit.h @@ -17,11 +17,4 @@ struct ratelimit_state { struct ratelimit_state name = {interval, burst,} extern int __ratelimit(struct ratelimit_state *rs); - -static inline int ratelimit(void) -{ - static DEFINE_RATELIMIT_STATE(rs, DEFAULT_RATELIMIT_INTERVAL, - DEFAULT_RATELIMIT_BURST); - return __ratelimit(&rs); -} #endif -- cgit v1.2.3 From 077eaf5b40ecb2c345d82f02275c20e965dfa3e5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 12 Nov 2008 13:27:04 -0800 Subject: rtc: rtc-wm8350: add support for WM8350 RTC This adds support for the RTC provided by the Wolfson Microelectronics WM8350. This driver was originally written by Graeme Gregory and Liam Girdwood, though it has been modified since then to update it to current mainline coding standards and for API completeness. [akpm@linux-foundation.org: s/schedule_timeout_interruptible/schedule_timeout_uninterruptible/ to prevent bogus timeout when signal_pending()] Signed-off-by: Mark Brown Cc: Alessandro Zummo Cc: David Brownell Cc: Liam Girdwood Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mfd/wm8350/rtc.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mfd/wm8350/rtc.h b/include/linux/mfd/wm8350/rtc.h index dfda69e9f44..24add2bef6c 100644 --- a/include/linux/mfd/wm8350/rtc.h +++ b/include/linux/mfd/wm8350/rtc.h @@ -261,6 +261,8 @@ struct wm8350_rtc { struct platform_device *pdev; + struct rtc_device *rtc; + int alarm_enabled; /* used over suspend/resume */ }; #endif -- cgit v1.2.3 From 4e17e1db96474af5620e3259754df4cb1c46521c Mon Sep 17 00:00:00 2001 From: Rodolfo Giometti Date: Wed, 12 Nov 2008 13:27:12 -0800 Subject: Add c2 port support C2port implements a two wire serial communication protocol (bit banging) designed to enable in-system programming, debugging, and boundary-scan testing on low pin-count Silicon Labs devices. Currently this code supports only flash programming through sysfs interface but extensions shoud be easy to add. Signed-off-by: Rodolfo Giometti Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/c2port.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 include/linux/c2port.h (limited to 'include/linux') diff --git a/include/linux/c2port.h b/include/linux/c2port.h new file mode 100644 index 00000000000..7b5a2388ba6 --- /dev/null +++ b/include/linux/c2port.h @@ -0,0 +1,65 @@ +/* + * Silicon Labs C2 port Linux support + * + * Copyright (c) 2007 Rodolfo Giometti + * Copyright (c) 2007 Eurotech S.p.A. + * + * 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 + */ + +#include + +#define C2PORT_NAME_LEN 32 + +/* + * C2 port basic structs + */ + +/* Main struct */ +struct c2port_ops; +struct c2port_device { + unsigned int access:1; + unsigned int flash_access:1; + + int id; + char name[C2PORT_NAME_LEN]; + struct c2port_ops *ops; + struct mutex mutex; /* prevent races during read/write */ + + struct device *dev; + + void *private_data; +}; + +/* Basic operations */ +struct c2port_ops { + /* Flash layout */ + unsigned short block_size; /* flash block size in bytes */ + unsigned short blocks_num; /* flash blocks number */ + + /* Enable or disable the access to C2 port */ + void (*access)(struct c2port_device *dev, int status); + + /* Set C2D data line as input/output */ + void (*c2d_dir)(struct c2port_device *dev, int dir); + + /* Read/write C2D data line */ + int (*c2d_get)(struct c2port_device *dev); + void (*c2d_set)(struct c2port_device *dev, int status); + + /* Write C2CK clock line */ + void (*c2ck_set)(struct c2port_device *dev, int status); +}; + +/* + * Exported functions + */ + +#define to_class_dev(obj) container_of((obj), struct class_device, kobj) +#define to_c2port_device(obj) container_of((obj), struct c2port_device, class) + +extern struct c2port_device *c2port_device_register(char *name, + struct c2port_ops *ops, void *devdata); +extern void c2port_device_unregister(struct c2port_device *dev); -- cgit v1.2.3 From 437184ae8bd1ef923a40b009e37801deae66ad55 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Tue, 4 Nov 2008 13:31:38 +0100 Subject: HID: map macbook keys for "Expose" and "Dashboard" On macbooks there are specific keys for the user-space functions Expose and Dashboard, which currently has no counterpart in input.h. This patch adds KEY_SCALE and KEY_DASHBOARD, and maps the keyboard accordingly. Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- include/linux/input.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/input.h b/include/linux/input.h index b86fb5581ce..5341e8251f8 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -238,6 +238,7 @@ struct input_absinfo { #define KEY_KPEQUAL 117 #define KEY_KPPLUSMINUS 118 #define KEY_PAUSE 119 +#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ #define KEY_KPCOMMA 121 #define KEY_HANGEUL 122 @@ -322,6 +323,7 @@ struct input_absinfo { #define KEY_PAUSECD 201 #define KEY_PROG3 202 #define KEY_PROG4 203 +#define KEY_DASHBOARD 204 /* AL Dashboard */ #define KEY_SUSPEND 205 #define KEY_CLOSE 206 /* AC Close */ #define KEY_PLAY 207 -- cgit v1.2.3 From d7de4c1dc3a2faca0bf05d9e342f885cb2696766 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Thu, 13 Nov 2008 20:40:12 +0200 Subject: slab: document SLAB_DESTROY_BY_RCU Explain this SLAB_DESTROY_BY_RCU thing... [hugh@veritas.com: add a pointer to comment in mm/slab.c] Signed-off-by: Peter Zijlstra Acked-by: Jens Axboe Acked-by: Paul E. McKenney Acked-by: Christoph Lameter Signed-off-by: Hugh Dickins Signed-off-by: Pekka Enberg --- include/linux/slab.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'include/linux') diff --git a/include/linux/slab.h b/include/linux/slab.h index ba965c84ae0..000da12b5cf 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -23,6 +23,34 @@ #define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */ #define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */ #define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ +/* + * SLAB_DESTROY_BY_RCU - **WARNING** READ THIS! + * + * This delays freeing the SLAB page by a grace period, it does _NOT_ + * delay object freeing. This means that if you do kmem_cache_free() + * that memory location is free to be reused at any time. Thus it may + * be possible to see another object there in the same RCU grace period. + * + * This feature only ensures the memory location backing the object + * stays valid, the trick to using this is relying on an independent + * object validation pass. Something like: + * + * rcu_read_lock() + * again: + * obj = lockless_lookup(key); + * if (obj) { + * if (!try_get_ref(obj)) // might fail for free objects + * goto again; + * + * if (obj->key != key) { // not the object we expected + * put_ref(obj); + * goto again; + * } + * } + * rcu_read_unlock(); + * + * See also the comment on struct slab_rcu in mm/slab.c. + */ #define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */ #define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ #define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ -- cgit v1.2.3 From 352d026338378b1f13f044e33c1047da6e470056 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 29 Oct 2008 15:16:58 -0400 Subject: USB: don't register endpoints for interfaces that are going away This patch (as1155) fixes a bug in usbcore. When interfaces are deleted, either because the device was disconnected or because of a configuration change, the extra attribute files and child endpoint devices may get left behind. This is because the core removes them before calling device_del(). But during device_del(), after the driver is unbound the core will reinstall altsetting 0 and recreate those extra attributes and children. The patch prevents this by adding a flag to record when the interface is in the midst of being unregistered. When the flag is set, the attribute files and child devices will not be created. Signed-off-by: Alan Stern Cc: stable [2.6.27, 2.6.26, 2.6.25] Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 8fa973bede5..f72aa51f7bc 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -108,6 +108,7 @@ enum usb_interface_condition { * (in probe()), bound to a driver, or unbinding (in disconnect()) * @is_active: flag set when the interface is bound and not suspended. * @sysfs_files_created: sysfs attributes exist + * @unregistering: flag set when the interface is being unregistered * @needs_remote_wakeup: flag set when the driver requires remote-wakeup * capability during autosuspend. * @needs_altsetting0: flag set when a set-interface request for altsetting 0 @@ -163,6 +164,7 @@ struct usb_interface { enum usb_interface_condition condition; /* state of binding */ unsigned is_active:1; /* the interface is not suspended */ unsigned sysfs_files_created:1; /* the sysfs attributes exist */ + unsigned unregistering:1; /* unregistration is in progress */ unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */ unsigned needs_altsetting0:1; /* switch to altsetting 0 is pending */ unsigned needs_binding:1; /* needs delayed unbind/rebind */ -- cgit v1.2.3 From e8f6fbf62de37cbc2e179176ac7010d5f4396b67 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 12 Nov 2008 01:38:36 +0000 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 Signed-off-by: David S. Miller --- include/linux/lockdep.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 331e5f1c2d8..29aec6e1002 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -331,10 +331,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) -- cgit v1.2.3 From d091c2f58ba32029495a933b721e8e02fbd12caa Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 12 Nov 2008 21:16:43 +0100 Subject: Add 'pr_fmt()' format modifier to pr_xyz macros. A common reason for device drivers to implement their own printk macros is the lack of a printk prefix with the standard pr_xyz macros. Introduce a pr_fmt() macro that is applied for every pr_xyz macro to the format string. The most common use of the pr_fmt macro would be to add the name of the device driver to all pr_xyz messages in a source file. Signed-off-by: Martin Schwidefsky Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index fba141d3ca0..dc7e0d0a647 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -318,32 +318,36 @@ static inline char *pack_hex_byte(char *buf, u8 byte) return buf; } -#define pr_emerg(fmt, arg...) \ - printk(KERN_EMERG fmt, ##arg) -#define pr_alert(fmt, arg...) \ - printk(KERN_ALERT fmt, ##arg) -#define pr_crit(fmt, arg...) \ - printk(KERN_CRIT fmt, ##arg) -#define pr_err(fmt, arg...) \ - printk(KERN_ERR fmt, ##arg) -#define pr_warning(fmt, arg...) \ - printk(KERN_WARNING fmt, ##arg) -#define pr_notice(fmt, arg...) \ - printk(KERN_NOTICE fmt, ##arg) -#define pr_info(fmt, arg...) \ - printk(KERN_INFO fmt, ##arg) +#ifndef pr_fmt +#define pr_fmt(fmt) fmt +#endif + +#define pr_emerg(fmt, ...) \ + printk(KERN_EMERG pr_fmt(fmt), ##__VA_ARGS__) +#define pr_alert(fmt, ...) \ + printk(KERN_ALERT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_crit(fmt, ...) \ + printk(KERN_CRIT pr_fmt(fmt), ##__VA_ARGS__) +#define pr_err(fmt, ...) \ + printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__) +#define pr_warning(fmt, ...) \ + printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__) +#define pr_notice(fmt, ...) \ + printk(KERN_NOTICE pr_fmt(fmt), ##__VA_ARGS__) +#define pr_info(fmt, ...) \ + printk(KERN_INFO pr_fmt(fmt), ##__VA_ARGS__) /* If you are writing a driver, please use dev_dbg instead */ #if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) #define pr_debug(fmt, ...) do { \ - dynamic_pr_debug(fmt, ##__VA_ARGS__); \ + dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ } while (0) #elif defined(DEBUG) -#define pr_debug(fmt, arg...) \ - printk(KERN_DEBUG fmt, ##arg) +#define pr_debug(fmt, ...) \ + printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) #else -#define pr_debug(fmt, arg...) \ - ({ if (0) printk(KERN_DEBUG fmt, ##arg); 0; }) +#define pr_debug(fmt, ...) \ + ({ if (0) printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); 0; }) #endif /* -- cgit v1.2.3 From 8f7b0ba1c853919b85b54774775f567f30006107 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 15 Nov 2008 01:15:43 +0000 Subject: Fix inotify watch removal/umount races Inotify watch removals suck violently. To kick the watch out we need (in this order) inode->inotify_mutex and ih->mutex. That's fine if we have a hold on inode; however, for all other cases we need to make damn sure we don't race with umount. We can *NOT* just grab a reference to a watch - inotify_unmount_inodes() will happily sail past it and we'll end with reference to inode potentially outliving its superblock. Ideally we just want to grab an active reference to superblock if we can; that will make sure we won't go into inotify_umount_inodes() until we are done. Cleanup is just deactivate_super(). However, that leaves a messy case - what if we *are* racing with umount() and active references to superblock can't be acquired anymore? We can bump ->s_count, grab ->s_umount, which will almost certainly wait until the superblock is shut down and the watch in question is pining for fjords. That's fine, but there is a problem - we might have hit the window between ->s_active getting to 0 / ->s_count - below S_BIAS (i.e. the moment when superblock is past the point of no return and is heading for shutdown) and the moment when deactivate_super() acquires ->s_umount. We could just do drop_super() yield() and retry, but that's rather antisocial and this stuff is luser-triggerable. OTOH, having grabbed ->s_umount and having found that we'd got there first (i.e. that ->s_root is non-NULL) we know that we won't race with inotify_umount_inodes(). So we could grab a reference to watch and do the rest as above, just with drop_super() instead of deactivate_super(), right? Wrong. We had to drop ih->mutex before we could grab ->s_umount. So the watch could've been gone already. That still can be dealt with - we need to save watch->wd, do idr_find() and compare its result with our pointer. If they match, we either have the damn thing still alive or we'd lost not one but two races at once, the watch had been killed and a new one got created with the same ->wd at the same address. That couldn't have happened in inotify_destroy(), but inotify_rm_wd() could run into that. Still, "new one got created" is not a problem - we have every right to kill it or leave it alone, whatever's more convenient. So we can use idr_find(...) == watch && watch->inode->i_sb == sb as "grab it and kill it" check. If it's been our original watch, we are fine, if it's a newcomer - nevermind, just pretend that we'd won the race and kill the fscker anyway; we are safe since we know that its superblock won't be going away. And yes, this is far beyond mere "not very pretty"; so's the entire concept of inotify to start with. Signed-off-by: Al Viro Acked-by: Greg KH Signed-off-by: Linus Torvalds --- include/linux/inotify.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/inotify.h b/include/linux/inotify.h index bd578578a8b..37ea2894b3c 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h @@ -134,6 +134,8 @@ extern void inotify_remove_watch_locked(struct inotify_handle *, struct inotify_watch *); extern void get_inotify_watch(struct inotify_watch *); extern void put_inotify_watch(struct inotify_watch *); +extern int pin_inotify_watch(struct inotify_watch *); +extern void unpin_inotify_watch(struct inotify_watch *); #else @@ -228,6 +230,15 @@ static inline void put_inotify_watch(struct inotify_watch *watch) { } +extern inline int pin_inotify_watch(struct inotify_watch *watch) +{ + return 0; +} + +extern inline void unpin_inotify_watch(struct inotify_watch *watch) +{ +} + #endif /* CONFIG_INOTIFY */ #endif /* __KERNEL __ */ -- cgit v1.2.3 From ba32929a91fe2c0628f5be62d1597b379c8d3062 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 10 Nov 2008 15:29:58 +0900 Subject: block: make add_partition() return pointer to hd_struct Make add_partition() return pointer to the new hd_struct on success and ERR_PTR() value on failure. This change will be used to fix md autodetection bug. Signed-off-by: Tejun Heo Cc: Neil Brown Signed-off-by: Jens Axboe --- include/linux/genhd.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/genhd.h b/include/linux/genhd.h index e439e6aed83..3df7742ce24 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -522,7 +522,9 @@ extern char *disk_name (struct gendisk *hd, int partno, char *buf); extern int disk_expand_part_tbl(struct gendisk *disk, int target); extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); -extern int __must_check add_partition(struct gendisk *, int, sector_t, sector_t, int); +extern struct hd_struct * __must_check add_partition(struct gendisk *disk, + int partno, sector_t start, + sector_t len, int flags); extern void delete_partition(struct gendisk *, int); extern void printk_all_partitions(void); -- cgit v1.2.3 From de11defebf00007677fb7ee91d9b089b78786fbb Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Wed, 19 Nov 2008 15:36:14 -0800 Subject: reintroduce accept4 Introduce a new accept4() system call. The addition of this system call matches analogous changes in 2.6.27 (dup3(), evenfd2(), signalfd4(), inotify_init1(), epoll_create1(), pipe2()) which added new system calls that differed from analogous traditional system calls in adding a flags argument that can be used to access additional functionality. The accept4() system call is exactly the same as accept(), except that it adds a flags bit-mask argument. Two flags are initially implemented. (Most of the new system calls in 2.6.27 also had both of these flags.) SOCK_CLOEXEC causes the close-on-exec (FD_CLOEXEC) flag to be enabled for the new file descriptor returned by accept4(). This is a useful security feature to avoid leaking information in a multithreaded program where one thread is doing an accept() at the same time as another thread is doing a fork() plus exec(). More details here: http://udrepper.livejournal.com/20407.html "Secure File Descriptor Handling", Ulrich Drepper). The other flag is SOCK_NONBLOCK, which causes the O_NONBLOCK flag to be enabled on the new open file description created by accept4(). (This flag is merely a convenience, saving the use of additional calls fcntl(F_GETFL) and fcntl (F_SETFL) to achieve the same result. Here's a test program. Works on x86-32. Should work on x86-64, but I (mtk) don't have a system to hand to test with. It tests accept4() with each of the four possible combinations of SOCK_CLOEXEC and SOCK_NONBLOCK set/clear in 'flags', and verifies that the appropriate flags are set on the file descriptor/open file description returned by accept4(). I tested Ulrich's patch in this thread by applying against 2.6.28-rc2, and it passes according to my test program. /* test_accept4.c Copyright (C) 2008, Linux Foundation, written by Michael Kerrisk Licensed under the GNU GPLv2 or later. */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #define PORT_NUM 33333 #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) /**********************************************************************/ /* The following is what we need until glibc gets a wrapper for accept4() */ /* Flags for socket(), socketpair(), accept4() */ #ifndef SOCK_CLOEXEC #define SOCK_CLOEXEC O_CLOEXEC #endif #ifndef SOCK_NONBLOCK #define SOCK_NONBLOCK O_NONBLOCK #endif #ifdef __x86_64__ #define SYS_accept4 288 #elif __i386__ #define USE_SOCKETCALL 1 #define SYS_ACCEPT4 18 #else #error "Sorry -- don't know the syscall # on this architecture" #endif static int accept4(int fd, struct sockaddr *sockaddr, socklen_t *addrlen, int flags) { printf("Calling accept4(): flags = %x", flags); if (flags != 0) { printf(" ("); if (flags & SOCK_CLOEXEC) printf("SOCK_CLOEXEC"); if ((flags & SOCK_CLOEXEC) && (flags & SOCK_NONBLOCK)) printf(" "); if (flags & SOCK_NONBLOCK) printf("SOCK_NONBLOCK"); printf(")"); } printf("\n"); #if USE_SOCKETCALL long args[6]; args[0] = fd; args[1] = (long) sockaddr; args[2] = (long) addrlen; args[3] = flags; return syscall(SYS_socketcall, SYS_ACCEPT4, args); #else return syscall(SYS_accept4, fd, sockaddr, addrlen, flags); #endif } /**********************************************************************/ static int do_test(int lfd, struct sockaddr_in *conn_addr, int closeonexec_flag, int nonblock_flag) { int connfd, acceptfd; int fdf, flf, fdf_pass, flf_pass; struct sockaddr_in claddr; socklen_t addrlen; printf("=======================================\n"); connfd = socket(AF_INET, SOCK_STREAM, 0); if (connfd == -1) die("socket"); if (connect(connfd, (struct sockaddr *) conn_addr, sizeof(struct sockaddr_in)) == -1) die("connect"); addrlen = sizeof(struct sockaddr_in); acceptfd = accept4(lfd, (struct sockaddr *) &claddr, &addrlen, closeonexec_flag | nonblock_flag); if (acceptfd == -1) { perror("accept4()"); close(connfd); return 0; } fdf = fcntl(acceptfd, F_GETFD); if (fdf == -1) die("fcntl:F_GETFD"); fdf_pass = ((fdf & FD_CLOEXEC) != 0) == ((closeonexec_flag & SOCK_CLOEXEC) != 0); printf("Close-on-exec flag is %sset (%s); ", (fdf & FD_CLOEXEC) ? "" : "not ", fdf_pass ? "OK" : "failed"); flf = fcntl(acceptfd, F_GETFL); if (flf == -1) die("fcntl:F_GETFD"); flf_pass = ((flf & O_NONBLOCK) != 0) == ((nonblock_flag & SOCK_NONBLOCK) !=0); printf("nonblock flag is %sset (%s)\n", (flf & O_NONBLOCK) ? "" : "not ", flf_pass ? "OK" : "failed"); close(acceptfd); close(connfd); printf("Test result: %s\n", (fdf_pass && flf_pass) ? "PASS" : "FAIL"); return fdf_pass && flf_pass; } static int create_listening_socket(int port_num) { struct sockaddr_in svaddr; int lfd; int optval; memset(&svaddr, 0, sizeof(struct sockaddr_in)); svaddr.sin_family = AF_INET; svaddr.sin_addr.s_addr = htonl(INADDR_ANY); svaddr.sin_port = htons(port_num); lfd = socket(AF_INET, SOCK_STREAM, 0); if (lfd == -1) die("socket"); optval = 1; if (setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) die("setsockopt"); if (bind(lfd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_in)) == -1) die("bind"); if (listen(lfd, 5) == -1) die("listen"); return lfd; } int main(int argc, char *argv[]) { struct sockaddr_in conn_addr; int lfd; int port_num; int passed; passed = 1; port_num = (argc > 1) ? atoi(argv[1]) : PORT_NUM; memset(&conn_addr, 0, sizeof(struct sockaddr_in)); conn_addr.sin_family = AF_INET; conn_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); conn_addr.sin_port = htons(port_num); lfd = create_listening_socket(port_num); if (!do_test(lfd, &conn_addr, 0, 0)) passed = 0; if (!do_test(lfd, &conn_addr, SOCK_CLOEXEC, 0)) passed = 0; if (!do_test(lfd, &conn_addr, 0, SOCK_NONBLOCK)) passed = 0; if (!do_test(lfd, &conn_addr, SOCK_CLOEXEC, SOCK_NONBLOCK)) passed = 0; close(lfd); exit(passed ? EXIT_SUCCESS : EXIT_FAILURE); } [mtk.manpages@gmail.com: rewrote changelog, updated test program] Signed-off-by: Ulrich Drepper Tested-by: Michael Kerrisk Acked-by: Michael Kerrisk Cc: Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/net.h | 6 ++---- include/linux/syscalls.h | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/net.h b/include/linux/net.h index 6dc14a24004..4515efae4c3 100644 --- a/include/linux/net.h +++ b/include/linux/net.h @@ -40,7 +40,7 @@ #define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ #define SYS_SENDMSG 16 /* sys_sendmsg(2) */ #define SYS_RECVMSG 17 /* sys_recvmsg(2) */ -#define SYS_PACCEPT 18 /* sys_paccept(2) */ +#define SYS_ACCEPT4 18 /* sys_accept4(2) */ typedef enum { SS_FREE = 0, /* not allocated */ @@ -100,7 +100,7 @@ enum sock_type { * remaining bits are used as flags. */ #define SOCK_TYPE_MASK 0xf -/* Flags for socket, socketpair, paccept */ +/* Flags for socket, socketpair, accept4 */ #define SOCK_CLOEXEC O_CLOEXEC #ifndef SOCK_NONBLOCK #define SOCK_NONBLOCK O_NONBLOCK @@ -223,8 +223,6 @@ extern int sock_map_fd(struct socket *sock, int flags); extern struct socket *sockfd_lookup(int fd, int *err); #define sockfd_put(sock) fput(sock->file) extern int net_ratelimit(void); -extern long do_accept(int fd, struct sockaddr __user *upeer_sockaddr, - int __user *upeer_addrlen, int flags); #define net_random() random32() #define net_srandom(seed) srandom32((__force u32)seed) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index d6ff145919c..04fb47bfb92 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -410,8 +410,7 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, asmlinkage long sys_bind(int, struct sockaddr __user *, int); asmlinkage long sys_connect(int, struct sockaddr __user *, int); asmlinkage long sys_accept(int, struct sockaddr __user *, int __user *); -asmlinkage long sys_paccept(int, struct sockaddr __user *, int __user *, - const __user sigset_t *, size_t, int); +asmlinkage long sys_accept4(int, struct sockaddr __user *, int __user *, int); asmlinkage long sys_getsockname(int, struct sockaddr __user *, int __user *); asmlinkage long sys_getpeername(int, struct sockaddr __user *, int __user *); asmlinkage long sys_send(int, void __user *, size_t, unsigned); -- cgit v1.2.3 From f481891fdc49d3d1b8a9674a1825d183069a805f Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Wed, 19 Nov 2008 15:36:30 -0800 Subject: cpuset: update top cpuset's mems after adding a node After adding a node into the machine, top cpuset's mems isn't updated. By reviewing the code, we found that the update function cpuset_track_online_nodes() was invoked after node_states[N_ONLINE] changes. It is wrong because N_ONLINE just means node has pgdat, and if node has/added memory, we use N_HIGH_MEMORY. So, We should invoke the update function after node_states[N_HIGH_MEMORY] changes, just like its commit says. This patch fixes it. And we use notifier of memory hotplug instead of direct calling of cpuset_track_online_nodes(). Signed-off-by: Miao Xie Acked-by: Yasunori Goto Cc: David Rientjes Cc: Paul Menage Signed-off-by: Linus Torvalds --- include/linux/cpuset.h | 4 ---- 1 file changed, 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h index 2691926fb50..8e540d32c9f 100644 --- a/include/linux/cpuset.h +++ b/include/linux/cpuset.h @@ -74,8 +74,6 @@ static inline int cpuset_do_slab_mem_spread(void) return current->flags & PF_SPREAD_SLAB; } -extern void cpuset_track_online_nodes(void); - extern int current_cpuset_is_being_rebound(void); extern void rebuild_sched_domains(void); @@ -151,8 +149,6 @@ static inline int cpuset_do_slab_mem_spread(void) return 0; } -static inline void cpuset_track_online_nodes(void) {} - static inline int current_cpuset_is_being_rebound(void) { return 0; -- cgit v1.2.3