From 225937bd5d69a40b886f47a7bc1f0837882586e3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Nov 2005 15:33:12 +0000 Subject: [ARM] Remove asm/hardware.h include from SA1100 io.h Unfortunately, we have a symbol clash between the SA-1100 header and some drivers. Since everywhere which needs SA1100 specifics includes asm/hardware.h, we don't need to include it in the SA1100 io.h header. In file included from drivers/net/wireless/wavelan_cs.p.h:459, from drivers/net/wireless/wavelan_cs.c:60: drivers/net/wireless/wavelan_cs.h:97:1: warning: "LCSR" redefined In file included from include/asm/arch/hardware.h:56, from include/asm/hardware.h:16, from include/asm/arch/io.h:13, from include/asm/io.h:71, from drivers/net/wireless/wavelan_cs.p.h:433, from drivers/net/wireless/wavelan_cs.c:60: include/asm/arch/SA-1100.h:1907:1: warning: this is the location of the previous definition Signed-off-by: Russell King diff --git a/include/asm-arm/arch-sa1100/io.h b/include/asm-arm/arch-sa1100/io.h index 9d4fe6c..040ccde 100644 --- a/include/asm-arm/arch-sa1100/io.h +++ b/include/asm-arm/arch-sa1100/io.h @@ -10,8 +10,6 @@ #ifndef __ASM_ARM_ARCH_IO_H #define __ASM_ARM_ARCH_IO_H -#include - #define IO_SPACE_LIMIT 0xffffffff /* -- cgit v0.10.2 From 3c0bdac3875505516eda1c6b6e68dd84eff3b231 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Nov 2005 15:43:22 +0000 Subject: [ARM] Remove mach-types.h from head.S We don't really need to check whether the machine type is Netwinder or CATS before setting up the PCI IO mapping for debugging. This allows us to eliminate asm/mach-types.h from head.S Signed-off-by: Russell King diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 8d87484..d7d69fd7 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -83,7 +82,7 @@ ENTRY(stext) @ and irqs disabled bl __lookup_processor_type @ r5=procinfo r9=cpuid movs r10, r5 @ invalid processor (r5=0)? - beq __error_p @ yes, error 'p' + beq __error_p @ yes, error 'p' bl __lookup_machine_type @ r5=machinfo movs r8, r5 @ invalid machine (r5=0)? beq __error_a @ yes, error 'a' @@ -343,16 +342,12 @@ __create_page_tables: bne 1b #if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_CATS) /* - * If we're using the NetWinder, we need to map in - * the 16550-type serial port for the debug messages + * If we're using the NetWinder or CATS, we also need to map + * in the 16550-type serial port for the debug messages */ - teq r1, #MACH_TYPE_NETWINDER - teqne r1, #MACH_TYPE_CATS - bne 1f add r0, r4, #0xff000000 >> 18 orr r3, r7, #0x7c000000 str r3, [r0] -1: #endif #ifdef CONFIG_ARCH_RPC /* -- cgit v0.10.2 From 5edf71ae129167ac276ebac18b25ccc7bec6ac3e Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Nov 2005 15:52:51 +0000 Subject: [ARM] Do not call flush_tlb_kernel_range() with IRQs disabled. We must not call TLB maintainence operations with interrupts disabled, otherwise we risk a lockup in the SMP IPI code. This means that consistent_free() can not be called from a context with IRQs disabled. In addition, we must not hold the lock in consistent_free when we call flush_tlb_kernel_range(). However, we must continue to prevent consistent_alloc() from re-using the memory region until we've finished tearing down the mapping and dealing with the TLB. Therefore, leave the vm_region entry in the list, but mark it inactive before dropping the lock and starting the tear-down process. After the mapping has been torn down, re-acquire the lock and remove the entry from the list. Signed-off-by: Russell King diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c index 47b0b76..dbfe9e8 100644 --- a/arch/arm/mm/consistent.c +++ b/arch/arm/mm/consistent.c @@ -66,6 +66,7 @@ struct vm_region { unsigned long vm_start; unsigned long vm_end; struct page *vm_pages; + int vm_active; }; static struct vm_region consistent_head = { @@ -104,6 +105,7 @@ vm_region_alloc(struct vm_region *head, size_t size, gfp_t gfp) list_add_tail(&new->vm_list, &c->vm_list); new->vm_start = addr; new->vm_end = addr + size; + new->vm_active = 1; spin_unlock_irqrestore(&consistent_lock, flags); return new; @@ -120,7 +122,7 @@ static struct vm_region *vm_region_find(struct vm_region *head, unsigned long ad struct vm_region *c; list_for_each_entry(c, &head->vm_list, vm_list) { - if (c->vm_start == addr) + if (c->vm_active && c->vm_start == addr) goto out; } c = NULL; @@ -319,6 +321,7 @@ EXPORT_SYMBOL(dma_mmap_writecombine); /* * free a page as defined by the above mapping. + * Must not be called with IRQs disabled. */ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) { @@ -326,14 +329,18 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr unsigned long flags, addr; pte_t *ptep; + WARN_ON(irqs_disabled()); + size = PAGE_ALIGN(size); spin_lock_irqsave(&consistent_lock, flags); - c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); if (!c) goto no_area; + c->vm_active = 0; + spin_unlock_irqrestore(&consistent_lock, flags); + if ((c->vm_end - c->vm_start) != size) { printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", __func__, c->vm_end - c->vm_start, size); @@ -372,8 +379,8 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr flush_tlb_kernel_range(c->vm_start, c->vm_end); + spin_lock_irqsave(&consistent_lock, flags); list_del(&c->vm_list); - spin_unlock_irqrestore(&consistent_lock, flags); kfree(c); -- cgit v0.10.2 From 9f2209078089e223a773a77518e53016173ead39 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Nov 2005 15:57:21 +0000 Subject: [ARM] Realview core.c does not need mach-types.h Signed-off-by: Russell King diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index e2c6fa2..af6580f 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include -- cgit v0.10.2 From 79a558ffba25ecefe21a5203077971a08dda598b Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 25 Nov 2005 15:59:01 +0000 Subject: [ARM] Update mach-types Signed-off-by: Russell King diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 048c9c1..4654874 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Fri Nov 11 21:55:04 2005 +# Last update: Fri Nov 25 14:43:04 2005 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -857,12 +857,12 @@ osiris MACH_OSIRIS OSIRIS 842 maestro MACH_MAESTRO MAESTRO 843 tunge2 MACH_TUNGE2 TUNGE2 844 ixbbm MACH_IXBBM IXBBM 845 -mx27 MACH_MX27 MX27 846 +mx27ads MACH_MX27 MX27 846 ax8004 MACH_AX8004 AX8004 847 at91sam9261ek MACH_AT91SAM9261EK AT91SAM9261EK 848 loft MACH_LOFT LOFT 849 magpie MACH_MAGPIE MAGPIE 850 -mx21 MACH_MX21 MX21 851 +mx21ads MACH_MX21 MX21 851 mb87m3400 MACH_MB87M3400 MB87M3400 852 mguard_delta MACH_MGUARD_DELTA MGUARD_DELTA 853 davinci_dvdp MACH_DAVINCI_DVDP DAVINCI_DVDP 854 @@ -897,10 +897,16 @@ omi_board MACH_OMI_BOARD OMI_BOARD 882 mx21civ MACH_MX21CIV MX21CIV 883 mahi_cdac MACH_MAHI_CDAC MAHI_CDAC 884 xscale_palmtx MACH_XSCALE_PALMTX XSCALE_PALMTX 885 -arch_s3c2413 MACH_ARCH_S3C2413 ARCH_S3C2413 886 s3c2413 MACH_S3C2413 S3C2413 887 samsys_ep0 MACH_SAMSYS_EP0 SAMSYS_EP0 888 wg302v1 MACH_WG302V1 WG302V1 889 wg302v2 MACH_WG302V2 WG302V2 890 eb42x MACH_EB42X EB42X 891 iq331es MACH_IQ331ES IQ331ES 892 +cosydsp MACH_COSYDSP COSYDSP 893 +uplat7d MACH_UPLAT7D UPLAT7D 894 +ptdavinci MACH_PTDAVINCI PTDAVINCI 895 +mbus MACH_MBUS MBUS 896 +nadia2vb MACH_NADIA2VB NADIA2VB 897 +r1000 MACH_R1000 R1000 898 +hw90250 MACH_HW90250 HW90250 899 -- cgit v0.10.2 From 192cdc5809f676841d16d58e1f249176e38d7dda Mon Sep 17 00:00:00 2001 From: Lucas Correia Villa Real Date: Mon, 28 Nov 2005 18:08:43 +0000 Subject: [ARM] 3178/1: S3C2400 - adds GPIO registers definitions to regs-gpio.h Patch from Lucas Correia Villa Real This patch adds definitions to GPIO registers for the S3C2400 into include/asm-arm/arch-s3c2410/regs-gpio.h. Signed-off-by: Lucas Correia Villa Real Signed-off-by: Russell King diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h index cb33d57..7f1be48 100644 --- a/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/include/asm-arm/arch-s3c2410/regs-gpio.h @@ -21,6 +21,7 @@ * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 28-Mar-2005 LCVR Fixed definition of GPB10 * 26-Oct-2005 BJD Added generic configuration types + * 27-Nov-2005 LCVR Added definitions to S3C2400 registers */ @@ -54,12 +55,16 @@ #define S3C2410_GPIOREG(x) ((x) + S3C24XX_VA_GPIO) -/* port A - 22bits, zero in bit X makes pin X output +/* port A - S3C2410: 22bits, zero in bit X makes pin X output + * S3C2400: 18bits, zero in bit X makes pin X output * 1 makes port special function, this is default */ #define S3C2410_GPACON S3C2410_GPIOREG(0x00) #define S3C2410_GPADAT S3C2410_GPIOREG(0x04) +#define S3C2400_GPACON S3C2410_GPIOREG(0x00) +#define S3C2400_GPADAT S3C2410_GPIOREG(0x04) + #define S3C2410_GPA0 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 0) #define S3C2410_GPA0_OUT (0<<0) #define S3C2410_GPA0_ADDR0 (1<<0) @@ -103,34 +108,42 @@ #define S3C2410_GPA10 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 10) #define S3C2410_GPA10_OUT (0<<10) #define S3C2410_GPA10_ADDR25 (1<<10) +#define S3C2400_GPA10_SCKE (1<<10) #define S3C2410_GPA11 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 11) #define S3C2410_GPA11_OUT (0<<11) #define S3C2410_GPA11_ADDR26 (1<<11) +#define S3C2400_GPA11_nCAS0 (1<<11) #define S3C2410_GPA12 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 12) #define S3C2410_GPA12_OUT (0<<12) #define S3C2410_GPA12_nGCS1 (1<<12) +#define S3C2400_GPA12_nCAS1 (1<<12) #define S3C2410_GPA13 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 13) #define S3C2410_GPA13_OUT (0<<13) #define S3C2410_GPA13_nGCS2 (1<<13) +#define S3C2400_GPA13_nGCS1 (1<<13) #define S3C2410_GPA14 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 14) #define S3C2410_GPA14_OUT (0<<14) #define S3C2410_GPA14_nGCS3 (1<<14) +#define S3C2400_GPA14_nGCS2 (1<<14) #define S3C2410_GPA15 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 15) #define S3C2410_GPA15_OUT (0<<15) #define S3C2410_GPA15_nGCS4 (1<<15) +#define S3C2400_GPA15_nGCS3 (1<<15) #define S3C2410_GPA16 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 16) #define S3C2410_GPA16_OUT (0<<16) #define S3C2410_GPA16_nGCS5 (1<<16) +#define S3C2400_GPA16_nGCS4 (1<<16) #define S3C2410_GPA17 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 17) #define S3C2410_GPA17_OUT (0<<17) #define S3C2410_GPA17_CLE (1<<17) +#define S3C2400_GPA17_nGCS5 (1<<17) #define S3C2410_GPA18 S3C2410_GPIONO(S3C2410_GPIO_BANKA, 18) #define S3C2410_GPA18_OUT (0<<18) @@ -152,10 +165,16 @@ #define S3C2410_GPA22_OUT (0<<22) #define S3C2410_GPA22_nFCE (1<<22) -/* 0x08 and 0x0c are reserved */ +/* 0x08 and 0x0c are reserved on S3C2410 */ -/* GPB is 10 IO pins, each configured by 2 bits each in GPBCON. +/* S3C2410: + * GPB is 10 IO pins, each configured by 2 bits each in GPBCON. * 00 = input, 01 = output, 10=special function, 11=reserved + + * S3C2400: + * GPB is 16 IO pins, each configured by 2 bits each in GPBCON. + * 00 = input, 01 = output, 10=data, 11=special function + * bit 0,1 = pin 0, 2,3= pin 1... * * CPBUP = pull up resistor control, 1=disabled, 0=enabled @@ -165,63 +184,113 @@ #define S3C2410_GPBDAT S3C2410_GPIOREG(0x14) #define S3C2410_GPBUP S3C2410_GPIOREG(0x18) +#define S3C2400_GPBCON S3C2410_GPIOREG(0x08) +#define S3C2400_GPBDAT S3C2410_GPIOREG(0x0C) +#define S3C2400_GPBUP S3C2410_GPIOREG(0x10) + /* no i/o pin in port b can have value 3! */ #define S3C2410_GPB0 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0) #define S3C2410_GPB0_INP (0x00 << 0) #define S3C2410_GPB0_OUTP (0x01 << 0) #define S3C2410_GPB0_TOUT0 (0x02 << 0) +#define S3C2400_GPB0_DATA16 (0x02 << 0) #define S3C2410_GPB1 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 1) #define S3C2410_GPB1_INP (0x00 << 2) #define S3C2410_GPB1_OUTP (0x01 << 2) #define S3C2410_GPB1_TOUT1 (0x02 << 2) +#define S3C2400_GPB1_DATA17 (0x02 << 2) #define S3C2410_GPB2 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 2) #define S3C2410_GPB2_INP (0x00 << 4) #define S3C2410_GPB2_OUTP (0x01 << 4) #define S3C2410_GPB2_TOUT2 (0x02 << 4) +#define S3C2400_GPB2_DATA18 (0x02 << 4) +#define S3C2400_GPB2_TCLK1 (0x03 << 4) #define S3C2410_GPB3 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 3) #define S3C2410_GPB3_INP (0x00 << 6) #define S3C2410_GPB3_OUTP (0x01 << 6) #define S3C2410_GPB3_TOUT3 (0x02 << 6) +#define S3C2400_GPB3_DATA19 (0x02 << 6) +#define S3C2400_GPB3_TXD1 (0x03 << 6) #define S3C2410_GPB4 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 4) #define S3C2410_GPB4_INP (0x00 << 8) #define S3C2410_GPB4_OUTP (0x01 << 8) #define S3C2410_GPB4_TCLK0 (0x02 << 8) +#define S3C2400_GPB4_DATA20 (0x02 << 8) #define S3C2410_GPB4_MASK (0x03 << 8) +#define S3C2400_GPB4_RXD1 (0x03 << 8) +#define S3C2400_GPB4_MASK (0x03 << 8) #define S3C2410_GPB5 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 5) #define S3C2410_GPB5_INP (0x00 << 10) #define S3C2410_GPB5_OUTP (0x01 << 10) #define S3C2410_GPB5_nXBACK (0x02 << 10) +#define S3C2400_GPB5_DATA21 (0x02 << 10) +#define S3C2400_GPB5_nCTS1 (0x03 << 10) #define S3C2410_GPB6 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 6) #define S3C2410_GPB6_INP (0x00 << 12) #define S3C2410_GPB6_OUTP (0x01 << 12) #define S3C2410_GPB6_nXBREQ (0x02 << 12) +#define S3C2400_GPB6_DATA22 (0x02 << 12) +#define S3C2400_GPB6_nRTS1 (0x03 << 12) #define S3C2410_GPB7 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 7) #define S3C2410_GPB7_INP (0x00 << 14) #define S3C2410_GPB7_OUTP (0x01 << 14) #define S3C2410_GPB7_nXDACK1 (0x02 << 14) +#define S3C2400_GPB7_DATA23 (0x02 << 14) #define S3C2410_GPB8 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8) #define S3C2410_GPB8_INP (0x00 << 16) #define S3C2410_GPB8_OUTP (0x01 << 16) #define S3C2410_GPB8_nXDREQ1 (0x02 << 16) +#define S3C2400_GPB8_DATA24 (0x02 << 16) #define S3C2410_GPB9 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 9) #define S3C2410_GPB9_INP (0x00 << 18) #define S3C2410_GPB9_OUTP (0x01 << 18) #define S3C2410_GPB9_nXDACK0 (0x02 << 18) +#define S3C2400_GPB9_DATA25 (0x02 << 18) +#define S3C2400_GPB9_I2SSDI (0x03 << 18) #define S3C2410_GPB10 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 10) #define S3C2410_GPB10_INP (0x00 << 20) #define S3C2410_GPB10_OUTP (0x01 << 20) #define S3C2410_GPB10_nXDRE0 (0x02 << 20) +#define S3C2400_GPB10_DATA26 (0x02 << 20) +#define S3C2400_GPB10_nSS (0x03 << 20) + +#define S3C2400_GPB11 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 11) +#define S3C2400_GPB11_INP (0x00 << 22) +#define S3C2400_GPB11_OUTP (0x01 << 22) +#define S3C2400_GPB11_DATA27 (0x02 << 22) + +#define S3C2400_GPB12 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 12) +#define S3C2400_GPB12_INP (0x00 << 24) +#define S3C2400_GPB12_OUTP (0x01 << 24) +#define S3C2400_GPB12_DATA28 (0x02 << 24) + +#define S3C2400_GPB13 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 13) +#define S3C2400_GPB13_INP (0x00 << 26) +#define S3C2400_GPB13_OUTP (0x01 << 26) +#define S3C2400_GPB13_DATA29 (0x02 << 26) + +#define S3C2400_GPB14 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 14) +#define S3C2400_GPB14_INP (0x00 << 28) +#define S3C2400_GPB14_OUTP (0x01 << 28) +#define S3C2400_GPB14_DATA30 (0x02 << 28) + +#define S3C2400_GPB15 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 15) +#define S3C2400_GPB15_INP (0x00 << 30) +#define S3C2400_GPB15_OUTP (0x01 << 30) +#define S3C2400_GPB15_DATA31 (0x02 << 30) + +#define S3C2410_GPB_PUPDIS(x) (1<<(x)) /* Port C consits of 16 GPIO/Special function * @@ -233,150 +302,193 @@ #define S3C2410_GPCDAT S3C2410_GPIOREG(0x24) #define S3C2410_GPCUP S3C2410_GPIOREG(0x28) +#define S3C2400_GPCCON S3C2410_GPIOREG(0x14) +#define S3C2400_GPCDAT S3C2410_GPIOREG(0x18) +#define S3C2400_GPCUP S3C2410_GPIOREG(0x1C) + #define S3C2410_GPC0 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 0) #define S3C2410_GPC0_INP (0x00 << 0) #define S3C2410_GPC0_OUTP (0x01 << 0) #define S3C2410_GPC0_LEND (0x02 << 0) +#define S3C2400_GPC0_VD0 (0x02 << 0) #define S3C2410_GPC1 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 1) #define S3C2410_GPC1_INP (0x00 << 2) #define S3C2410_GPC1_OUTP (0x01 << 2) #define S3C2410_GPC1_VCLK (0x02 << 2) +#define S3C2400_GPC1_VD1 (0x02 << 2) #define S3C2410_GPC2 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 2) #define S3C2410_GPC2_INP (0x00 << 4) #define S3C2410_GPC2_OUTP (0x01 << 4) #define S3C2410_GPC2_VLINE (0x02 << 4) +#define S3C2400_GPC2_VD2 (0x02 << 4) #define S3C2410_GPC3 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 3) #define S3C2410_GPC3_INP (0x00 << 6) #define S3C2410_GPC3_OUTP (0x01 << 6) #define S3C2410_GPC3_VFRAME (0x02 << 6) +#define S3C2400_GPC3_VD3 (0x02 << 6) #define S3C2410_GPC4 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 4) #define S3C2410_GPC4_INP (0x00 << 8) #define S3C2410_GPC4_OUTP (0x01 << 8) #define S3C2410_GPC4_VM (0x02 << 8) +#define S3C2400_GPC4_VD4 (0x02 << 8) #define S3C2410_GPC5 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 5) #define S3C2410_GPC5_INP (0x00 << 10) #define S3C2410_GPC5_OUTP (0x01 << 10) #define S3C2410_GPC5_LCDVF0 (0x02 << 10) +#define S3C2400_GPC5_VD5 (0x02 << 10) #define S3C2410_GPC6 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 6) #define S3C2410_GPC6_INP (0x00 << 12) #define S3C2410_GPC6_OUTP (0x01 << 12) #define S3C2410_GPC6_LCDVF1 (0x02 << 12) +#define S3C2400_GPC6_VD6 (0x02 << 12) #define S3C2410_GPC7 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 7) #define S3C2410_GPC7_INP (0x00 << 14) #define S3C2410_GPC7_OUTP (0x01 << 14) #define S3C2410_GPC7_LCDVF2 (0x02 << 14) +#define S3C2400_GPC7_VD7 (0x02 << 14) #define S3C2410_GPC8 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 8) #define S3C2410_GPC8_INP (0x00 << 16) #define S3C2410_GPC8_OUTP (0x01 << 16) #define S3C2410_GPC8_VD0 (0x02 << 16) +#define S3C2400_GPC8_VD8 (0x02 << 16) #define S3C2410_GPC9 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 9) #define S3C2410_GPC9_INP (0x00 << 18) #define S3C2410_GPC9_OUTP (0x01 << 18) #define S3C2410_GPC9_VD1 (0x02 << 18) +#define S3C2400_GPC9_VD9 (0x02 << 18) #define S3C2410_GPC10 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 10) #define S3C2410_GPC10_INP (0x00 << 20) #define S3C2410_GPC10_OUTP (0x01 << 20) #define S3C2410_GPC10_VD2 (0x02 << 20) +#define S3C2400_GPC10_VD10 (0x02 << 20) #define S3C2410_GPC11 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 11) #define S3C2410_GPC11_INP (0x00 << 22) #define S3C2410_GPC11_OUTP (0x01 << 22) #define S3C2410_GPC11_VD3 (0x02 << 22) +#define S3C2400_GPC11_VD11 (0x02 << 22) #define S3C2410_GPC12 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 12) #define S3C2410_GPC12_INP (0x00 << 24) #define S3C2410_GPC12_OUTP (0x01 << 24) #define S3C2410_GPC12_VD4 (0x02 << 24) +#define S3C2400_GPC12_VD12 (0x02 << 24) #define S3C2410_GPC13 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 13) #define S3C2410_GPC13_INP (0x00 << 26) #define S3C2410_GPC13_OUTP (0x01 << 26) #define S3C2410_GPC13_VD5 (0x02 << 26) +#define S3C2400_GPC13_VD13 (0x02 << 26) #define S3C2410_GPC14 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 14) #define S3C2410_GPC14_INP (0x00 << 28) #define S3C2410_GPC14_OUTP (0x01 << 28) #define S3C2410_GPC14_VD6 (0x02 << 28) +#define S3C2400_GPC14_VD14 (0x02 << 28) #define S3C2410_GPC15 S3C2410_GPIONO(S3C2410_GPIO_BANKC, 15) #define S3C2410_GPC15_INP (0x00 << 30) #define S3C2410_GPC15_OUTP (0x01 << 30) #define S3C2410_GPC15_VD7 (0x02 << 30) +#define S3C2400_GPC15_VD15 (0x02 << 30) + +#define S3C2410_GPC_PUPDIS(x) (1<<(x)) -/* Port D consists of 16 GPIO/Special function +/* + * S3C2410: Port D consists of 16 GPIO/Special function * * almost identical setup to port b, but the special functions are mostly * to do with the video system's data. + * + * S3C2400: Port D consists of 11 GPIO/Special function + * + * almost identical setup to port c */ #define S3C2410_GPDCON S3C2410_GPIOREG(0x30) #define S3C2410_GPDDAT S3C2410_GPIOREG(0x34) #define S3C2410_GPDUP S3C2410_GPIOREG(0x38) +#define S3C2400_GPDCON S3C2410_GPIOREG(0x20) +#define S3C2400_GPDDAT S3C2410_GPIOREG(0x24) +#define S3C2400_GPDUP S3C2410_GPIOREG(0x28) + #define S3C2410_GPD0 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 0) #define S3C2410_GPD0_INP (0x00 << 0) #define S3C2410_GPD0_OUTP (0x01 << 0) #define S3C2410_GPD0_VD8 (0x02 << 0) +#define S3C2400_GPD0_VFRAME (0x02 << 0) #define S3C2410_GPD1 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 1) #define S3C2410_GPD1_INP (0x00 << 2) #define S3C2410_GPD1_OUTP (0x01 << 2) #define S3C2410_GPD1_VD9 (0x02 << 2) +#define S3C2400_GPD1_VM (0x02 << 2) #define S3C2410_GPD2 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 2) #define S3C2410_GPD2_INP (0x00 << 4) #define S3C2410_GPD2_OUTP (0x01 << 4) #define S3C2410_GPD2_VD10 (0x02 << 4) +#define S3C2400_GPD2_VLINE (0x02 << 4) #define S3C2410_GPD3 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 3) #define S3C2410_GPD3_INP (0x00 << 6) #define S3C2410_GPD3_OUTP (0x01 << 6) #define S3C2410_GPD3_VD11 (0x02 << 6) +#define S3C2400_GPD3_VCLK (0x02 << 6) #define S3C2410_GPD4 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 4) #define S3C2410_GPD4_INP (0x00 << 8) #define S3C2410_GPD4_OUTP (0x01 << 8) #define S3C2410_GPD4_VD12 (0x02 << 8) +#define S3C2400_GPD4_LEND (0x02 << 8) #define S3C2410_GPD5 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 5) #define S3C2410_GPD5_INP (0x00 << 10) #define S3C2410_GPD5_OUTP (0x01 << 10) #define S3C2410_GPD5_VD13 (0x02 << 10) +#define S3C2400_GPD5_TOUT0 (0x02 << 10) #define S3C2410_GPD6 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 6) #define S3C2410_GPD6_INP (0x00 << 12) #define S3C2410_GPD6_OUTP (0x01 << 12) #define S3C2410_GPD6_VD14 (0x02 << 12) +#define S3C2400_GPD6_TOUT1 (0x02 << 12) #define S3C2410_GPD7 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 7) #define S3C2410_GPD7_INP (0x00 << 14) #define S3C2410_GPD7_OUTP (0x01 << 14) #define S3C2410_GPD7_VD15 (0x02 << 14) +#define S3C2400_GPD7_TOUT2 (0x02 << 14) #define S3C2410_GPD8 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 8) #define S3C2410_GPD8_INP (0x00 << 16) #define S3C2410_GPD8_OUTP (0x01 << 16) #define S3C2410_GPD8_VD16 (0x02 << 16) +#define S3C2400_GPD8_TOUT3 (0x02 << 16) #define S3C2410_GPD9 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 9) #define S3C2410_GPD9_INP (0x00 << 18) #define S3C2410_GPD9_OUTP (0x01 << 18) #define S3C2410_GPD9_VD17 (0x02 << 18) +#define S3C2400_GPD9_TCLK0 (0x02 << 18) +#define S3C2410_GPD9_MASK (0x03 << 18) #define S3C2410_GPD10 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 10) #define S3C2410_GPD10_INP (0x00 << 20) #define S3C2410_GPD10_OUTP (0x01 << 20) #define S3C2410_GPD10_VD18 (0x02 << 20) +#define S3C2400_GPD10_nWAIT (0x02 << 20) #define S3C2410_GPD11 S3C2410_GPIONO(S3C2410_GPIO_BANKD, 11) #define S3C2410_GPD11_INP (0x00 << 22) @@ -403,37 +515,56 @@ #define S3C2410_GPD15_OUTP (0x01 << 30) #define S3C2410_GPD15_VD23 (0x02 << 30) -/* Port E consists of 16 GPIO/Special function +#define S3C2410_GPD_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port E consists of 16 GPIO/Special function * * again, the same as port B, but dealing with I2S, SDI, and * more miscellaneous functions + * + * S3C2400: + * Port E consists of 12 GPIO/Special function + * + * GPIO / interrupt inputs */ #define S3C2410_GPECON S3C2410_GPIOREG(0x40) #define S3C2410_GPEDAT S3C2410_GPIOREG(0x44) #define S3C2410_GPEUP S3C2410_GPIOREG(0x48) +#define S3C2400_GPECON S3C2410_GPIOREG(0x2C) +#define S3C2400_GPEDAT S3C2410_GPIOREG(0x30) +#define S3C2400_GPEUP S3C2410_GPIOREG(0x34) + #define S3C2410_GPE0 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 0) #define S3C2410_GPE0_INP (0x00 << 0) #define S3C2410_GPE0_OUTP (0x01 << 0) #define S3C2410_GPE0_I2SLRCK (0x02 << 0) +#define S3C2400_GPE0_EINT0 (0x02 << 0) #define S3C2410_GPE0_MASK (0x03 << 0) #define S3C2410_GPE1 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 1) #define S3C2410_GPE1_INP (0x00 << 2) #define S3C2410_GPE1_OUTP (0x01 << 2) #define S3C2410_GPE1_I2SSCLK (0x02 << 2) +#define S3C2400_GPE1_EINT1 (0x02 << 2) +#define S3C2400_GPE1_nSS (0x03 << 2) #define S3C2410_GPE1_MASK (0x03 << 2) #define S3C2410_GPE2 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 2) #define S3C2410_GPE2_INP (0x00 << 4) #define S3C2410_GPE2_OUTP (0x01 << 4) #define S3C2410_GPE2_CDCLK (0x02 << 4) +#define S3C2400_GPE2_EINT2 (0x02 << 4) +#define S3C2400_GPE2_I2SSDI (0x03 << 4) #define S3C2410_GPE3 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 3) #define S3C2410_GPE3_INP (0x00 << 6) #define S3C2410_GPE3_OUTP (0x01 << 6) #define S3C2410_GPE3_I2SSDI (0x02 << 6) +#define S3C2400_GPE3_EINT3 (0x02 << 6) +#define S3C2400_GPE3_nCTS1 (0x03 << 6) #define S3C2410_GPE3_nSS0 (0x03 << 6) #define S3C2410_GPE3_MASK (0x03 << 6) @@ -441,6 +572,8 @@ #define S3C2410_GPE4_INP (0x00 << 8) #define S3C2410_GPE4_OUTP (0x01 << 8) #define S3C2410_GPE4_I2SSDO (0x02 << 8) +#define S3C2400_GPE4_EINT4 (0x02 << 8) +#define S3C2400_GPE4_nRTS1 (0x03 << 8) #define S3C2410_GPE4_I2SSDI (0x03 << 8) #define S3C2410_GPE4_MASK (0x03 << 8) @@ -448,36 +581,46 @@ #define S3C2410_GPE5_INP (0x00 << 10) #define S3C2410_GPE5_OUTP (0x01 << 10) #define S3C2410_GPE5_SDCLK (0x02 << 10) +#define S3C2400_GPE5_EINT5 (0x02 << 10) +#define S3C2400_GPE5_TCLK1 (0x03 << 10) #define S3C2410_GPE6 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 6) #define S3C2410_GPE6_INP (0x00 << 12) #define S3C2410_GPE6_OUTP (0x01 << 12) #define S3C2410_GPE6_SDCMD (0x02 << 12) +#define S3C2400_GPE6_EINT6 (0x02 << 12) #define S3C2410_GPE7 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7) #define S3C2410_GPE7_INP (0x00 << 14) #define S3C2410_GPE7_OUTP (0x01 << 14) #define S3C2410_GPE7_SDDAT0 (0x02 << 14) +#define S3C2400_GPE7_EINT7 (0x02 << 14) #define S3C2410_GPE8 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8) #define S3C2410_GPE8_INP (0x00 << 16) #define S3C2410_GPE8_OUTP (0x01 << 16) #define S3C2410_GPE8_SDDAT1 (0x02 << 16) +#define S3C2400_GPE8_nXDACK0 (0x02 << 16) #define S3C2410_GPE9 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9) #define S3C2410_GPE9_INP (0x00 << 18) #define S3C2410_GPE9_OUTP (0x01 << 18) #define S3C2410_GPE9_SDDAT2 (0x02 << 18) +#define S3C2400_GPE9_nXDACK1 (0x02 << 18) +#define S3C2400_GPE9_nXBACK (0x03 << 18) #define S3C2410_GPE10 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 10) #define S3C2410_GPE10_INP (0x00 << 20) #define S3C2410_GPE10_OUTP (0x01 << 20) #define S3C2410_GPE10_SDDAT3 (0x02 << 20) +#define S3C2400_GPE10_nXDREQ0 (0x02 << 20) #define S3C2410_GPE11 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11) #define S3C2410_GPE11_INP (0x00 << 22) #define S3C2410_GPE11_OUTP (0x01 << 22) #define S3C2410_GPE11_SPIMISO0 (0x02 << 22) +#define S3C2400_GPE11_nXDREQ1 (0x02 << 22) +#define S3C2400_GPE11_nXBREQ (0x03 << 22) #define S3C2410_GPE12 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 12) #define S3C2410_GPE12_INP (0x00 << 24) @@ -509,7 +652,8 @@ #define S3C2410_GPE_PUPDIS(x) (1<<(x)) -/* Port F consists of 8 GPIO/Special function +/* S3C2410: + * Port F consists of 8 GPIO/Special function * * GPIO / interrupt inputs * @@ -517,100 +661,141 @@ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined * * pull up works like all other ports. + * + * S3C2400: + * Port F consists of 7 GPIO/Special function + * + * GPIO/serial/misc pins */ #define S3C2410_GPFCON S3C2410_GPIOREG(0x50) #define S3C2410_GPFDAT S3C2410_GPIOREG(0x54) #define S3C2410_GPFUP S3C2410_GPIOREG(0x58) +#define S3C2400_GPFCON S3C2410_GPIOREG(0x38) +#define S3C2400_GPFDAT S3C2410_GPIOREG(0x3C) +#define S3C2400_GPFUP S3C2410_GPIOREG(0x40) + #define S3C2410_GPF0 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 0) #define S3C2410_GPF0_INP (0x00 << 0) #define S3C2410_GPF0_OUTP (0x01 << 0) #define S3C2410_GPF0_EINT0 (0x02 << 0) +#define S3C2400_GPF0_RXD0 (0x02 << 0) #define S3C2410_GPF1 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 1) #define S3C2410_GPF1_INP (0x00 << 2) #define S3C2410_GPF1_OUTP (0x01 << 2) #define S3C2410_GPF1_EINT1 (0x02 << 2) +#define S3C2400_GPF1_RXD1 (0x02 << 2) +#define S3C2400_GPF1_IICSDA (0x03 << 2) #define S3C2410_GPF2 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 2) #define S3C2410_GPF2_INP (0x00 << 4) #define S3C2410_GPF2_OUTP (0x01 << 4) #define S3C2410_GPF2_EINT2 (0x02 << 4) +#define S3C2400_GPF2_TXD0 (0x02 << 4) #define S3C2410_GPF3 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 3) #define S3C2410_GPF3_INP (0x00 << 6) #define S3C2410_GPF3_OUTP (0x01 << 6) #define S3C2410_GPF3_EINT3 (0x02 << 6) +#define S3C2400_GPF3_TXD1 (0x02 << 6) +#define S3C2400_GPF3_IICSCL (0x03 << 6) #define S3C2410_GPF4 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 4) #define S3C2410_GPF4_INP (0x00 << 8) #define S3C2410_GPF4_OUTP (0x01 << 8) #define S3C2410_GPF4_EINT4 (0x02 << 8) +#define S3C2400_GPF4_nRTS0 (0x02 << 8) +#define S3C2400_GPF4_nXBACK (0x03 << 8) #define S3C2410_GPF5 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 5) #define S3C2410_GPF5_INP (0x00 << 10) #define S3C2410_GPF5_OUTP (0x01 << 10) #define S3C2410_GPF5_EINT5 (0x02 << 10) +#define S3C2400_GPF5_nCTS0 (0x02 << 10) +#define S3C2400_GPF5_nXBREQ (0x03 << 10) #define S3C2410_GPF6 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 6) #define S3C2410_GPF6_INP (0x00 << 12) #define S3C2410_GPF6_OUTP (0x01 << 12) #define S3C2410_GPF6_EINT6 (0x02 << 12) +#define S3C2400_GPF6_CLKOUT (0x02 << 12) #define S3C2410_GPF7 S3C2410_GPIONO(S3C2410_GPIO_BANKF, 7) #define S3C2410_GPF7_INP (0x00 << 14) #define S3C2410_GPF7_OUTP (0x01 << 14) #define S3C2410_GPF7_EINT7 (0x02 << 14) -/* Port G consists of 8 GPIO/IRQ/Special function +#define S3C2410_GPF_PUPDIS(x) (1<<(x)) + +/* S3C2410: + * Port G consists of 8 GPIO/IRQ/Special function * * GPGCON has 2 bits for each of the input pins on port F * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func * * pull up works like all other ports. + * + * S3C2400: + * Port G consists of 10 GPIO/Special function */ #define S3C2410_GPGCON S3C2410_GPIOREG(0x60) #define S3C2410_GPGDAT S3C2410_GPIOREG(0x64) #define S3C2410_GPGUP S3C2410_GPIOREG(0x68) +#define S3C2400_GPGCON S3C2410_GPIOREG(0x44) +#define S3C2400_GPGDAT S3C2410_GPIOREG(0x48) +#define S3C2400_GPGUP S3C2410_GPIOREG(0x4C) + #define S3C2410_GPG0 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 0) #define S3C2410_GPG0_INP (0x00 << 0) #define S3C2410_GPG0_OUTP (0x01 << 0) #define S3C2410_GPG0_EINT8 (0x02 << 0) +#define S3C2400_GPG0_I2SLRCK (0x02 << 0) #define S3C2410_GPG1 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 1) #define S3C2410_GPG1_INP (0x00 << 2) #define S3C2410_GPG1_OUTP (0x01 << 2) #define S3C2410_GPG1_EINT9 (0x02 << 2) +#define S3C2400_GPG1_I2SSCLK (0x02 << 2) #define S3C2410_GPG2 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 2) #define S3C2410_GPG2_INP (0x00 << 4) #define S3C2410_GPG2_OUTP (0x01 << 4) #define S3C2410_GPG2_EINT10 (0x02 << 4) +#define S3C2400_GPG2_CDCLK (0x02 << 4) #define S3C2410_GPG3 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 3) #define S3C2410_GPG3_INP (0x00 << 6) #define S3C2410_GPG3_OUTP (0x01 << 6) #define S3C2410_GPG3_EINT11 (0x02 << 6) +#define S3C2400_GPG3_I2SSDO (0x02 << 6) +#define S3C2400_GPG3_I2SSDI (0x03 << 6) #define S3C2410_GPG4 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 4) #define S3C2410_GPG4_INP (0x00 << 8) #define S3C2410_GPG4_OUTP (0x01 << 8) #define S3C2410_GPG4_EINT12 (0x02 << 8) +#define S3C2400_GPG4_MMCCLK (0x02 << 8) +#define S3C2400_GPG4_I2SSDI (0x03 << 8) #define S3C2410_GPG4_LCDPWREN (0x03 << 8) #define S3C2410_GPG5 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5) #define S3C2410_GPG5_INP (0x00 << 10) #define S3C2410_GPG5_OUTP (0x01 << 10) #define S3C2410_GPG5_EINT13 (0x02 << 10) +#define S3C2400_GPG5_MMCCMD (0x02 << 10) +#define S3C2400_GPG5_IICSDA (0x03 << 10) #define S3C2410_GPG5_SPIMISO1 (0x03 << 10) #define S3C2410_GPG6 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6) #define S3C2410_GPG6_INP (0x00 << 12) #define S3C2410_GPG6_OUTP (0x01 << 12) #define S3C2410_GPG6_EINT14 (0x02 << 12) +#define S3C2400_GPG6_MMCDAT (0x02 << 12) +#define S3C2400_GPG6_IICSCL (0x03 << 12) #define S3C2410_GPG6_SPIMOSI1 (0x03 << 12) #define S3C2410_GPG7 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 7) @@ -618,16 +803,22 @@ #define S3C2410_GPG7_OUTP (0x01 << 14) #define S3C2410_GPG7_EINT15 (0x02 << 14) #define S3C2410_GPG7_SPICLK1 (0x03 << 14) +#define S3C2400_GPG7_SPIMISO (0x02 << 14) +#define S3C2400_GPG7_IICSDA (0x03 << 14) #define S3C2410_GPG8 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 8) #define S3C2410_GPG8_INP (0x00 << 16) #define S3C2410_GPG8_OUTP (0x01 << 16) #define S3C2410_GPG8_EINT16 (0x02 << 16) +#define S3C2400_GPG8_SPIMOSI (0x02 << 16) +#define S3C2400_GPG8_IICSCL (0x03 << 16) #define S3C2410_GPG9 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 9) #define S3C2410_GPG9_INP (0x00 << 18) #define S3C2410_GPG9_OUTP (0x01 << 18) #define S3C2410_GPG9_EINT17 (0x02 << 18) +#define S3C2400_GPG9_SPICLK (0x02 << 18) +#define S3C2400_GPG9_MMCCLK (0x03 << 18) #define S3C2410_GPG10 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 10) #define S3C2410_GPG10_INP (0x00 << 20) @@ -737,19 +928,27 @@ #define S3C2410_GPH10_CLKOUT1 (0x02 << 20) /* miscellaneous control */ - +#define S3C2400_MISCCR S3C2410_GPIOREG(0x54) #define S3C2410_MISCCR S3C2410_GPIOREG(0x80) #define S3C2410_DCLKCON S3C2410_GPIOREG(0x84) /* see clock.h for dclk definitions */ /* pullup control on databus */ -#define S3C2410_MISCCR_SPUCR_HEN (0) +#define S3C2410_MISCCR_SPUCR_HEN (0<<0) #define S3C2410_MISCCR_SPUCR_HDIS (1<<0) -#define S3C2410_MISCCR_SPUCR_LEN (0) +#define S3C2410_MISCCR_SPUCR_LEN (0<<1) #define S3C2410_MISCCR_SPUCR_LDIS (1<<1) -#define S3C2410_MISCCR_USBDEV (0) +#define S3C2400_MISCCR_SPUCR_LEN (0<<0) +#define S3C2400_MISCCR_SPUCR_LDIS (1<<0) +#define S3C2400_MISCCR_SPUCR_HEN (0<<1) +#define S3C2400_MISCCR_SPUCR_HDIS (1<<1) + +#define S3C2400_MISCCR_HZ_STOPEN (0<<2) +#define S3C2400_MISCCR_HZ_STOPPREV (1<<2) + +#define S3C2410_MISCCR_USBDEV (0<<3) #define S3C2410_MISCCR_USBHOST (1<<3) #define S3C2410_MISCCR_CLK0_MPLL (0<<4) @@ -785,7 +984,7 @@ * * Samsung datasheet p9-25 */ - +#define S3C2400_EXTINT0 S3C2410_GPIOREG(0x58) #define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88) #define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C) #define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90) @@ -833,5 +1032,21 @@ #define S3C2410_GSTATUS2_OFFRESET (1<<1) #define S3C2410_GSTATUS2_PONRESET (1<<0) +/* open drain control register */ +#define S3C2400_OPENCR S3C2410_GPIOREG(0x50) + +#define S3C2400_OPENCR_OPC_RXD1DIS (0<<0) +#define S3C2400_OPENCR_OPC_RXD1EN (1<<0) +#define S3C2400_OPENCR_OPC_TXD1DIS (0<<1) +#define S3C2400_OPENCR_OPC_TXD1EN (1<<1) +#define S3C2400_OPENCR_OPC_CMDDIS (0<<2) +#define S3C2400_OPENCR_OPC_CMDEN (1<<2) +#define S3C2400_OPENCR_OPC_DATDIS (0<<3) +#define S3C2400_OPENCR_OPC_DATEN (1<<3) +#define S3C2400_OPENCR_OPC_MISODIS (0<<4) +#define S3C2400_OPENCR_OPC_MISOEN (1<<4) +#define S3C2400_OPENCR_OPC_MOSIDIS (0<<5) +#define S3C2400_OPENCR_OPC_MOSIEN (1<<5) + #endif /* __ASM_ARCH_REGS_GPIO_H */ -- cgit v0.10.2 From 243077f58f2ae2540e35d8ea01a15f13586d9e9e Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 28 Nov 2005 18:08:44 +0000 Subject: [ARM] 3179/1: Update/correct Zaurus Kconfig entries Patch from Richard Purdie Add iWMMX Extentions for the pxa27x based Zaurus models and fix a couple of minor mistakes in the PXA Kconfig file. Signed-off-by: Richard Purdie Signed-off-by: Russell King diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index cd50664..526acbc 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -44,6 +44,7 @@ config PXA_SHARPSL_25x config PXA_SHARPSL_27x bool "Sharp PXA270 models (SL-Cxx00)" select PXA27x + select IWMMXT endchoice @@ -60,7 +61,6 @@ config MACH_CORGI bool "Enable Sharp SL-C700 (Corgi) Support" depends PXA_SHARPSL_25x select PXA_SHARP_C7xx - select PXA_SSP config MACH_SHEPHERD bool "Enable Sharp SL-C750 (Shepherd) Support" @@ -90,7 +90,7 @@ config MACH_BORZOI config MACH_TOSA bool "Enable Sharp SL-6000x (Tosa) Support" - depends PXA_SHARPSL + depends PXA_SHARPSL_25x config PXA25x bool -- cgit v0.10.2 From 0e1637420e94d501eb80763cce0c498f00d65b0a Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Mon, 28 Nov 2005 18:08:45 +0000 Subject: [ARM] 3180/1: Update Zaurus defconfigs Patch from Richard Purdie This updates the Zaurus defconfigs. Poodle gets merged into corgi_defconfig and support for tosa and akita is enabled. Signed-off-by: Richard Purdie Signed-off-by: Russell King diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 24987c8..0622902 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-rc3 -# Sun Oct 9 15:46:42 2005 +# Linux kernel version: 2.6.15-rc2 +# Mon Nov 28 10:30:09 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -64,6 +64,23 @@ CONFIG_OBSOLETE_MODPARM=y CONFIG_KMOD=y # +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# # System Type # # CONFIG_ARCH_CLPS7500 is not set @@ -85,6 +102,7 @@ CONFIG_ARCH_PXA=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set @@ -98,12 +116,14 @@ CONFIG_ARCH_PXA=y CONFIG_PXA_SHARPSL=y CONFIG_PXA_SHARPSL_25x=y # CONFIG_PXA_SHARPSL_27x is not set -# CONFIG_MACH_POODLE is not set +CONFIG_MACH_POODLE=y CONFIG_MACH_CORGI=y CONFIG_MACH_SHEPHERD=y CONFIG_MACH_HUSKY=y +CONFIG_MACH_TOSA=y CONFIG_PXA25x=y CONFIG_PXA_SHARP_C7xx=y +CONFIG_PXA_SSP=y # # Processor Type @@ -155,6 +175,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_ALIGNMENT_TRAP=y # @@ -235,6 +256,10 @@ CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# # CONFIG_NETFILTER_NETLINK is not set # @@ -356,6 +381,10 @@ CONFIG_IP6_NF_RAW=m # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set CONFIG_NET_CLS_ROUTE=y @@ -413,6 +442,7 @@ CONFIG_IRCOMM=m # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VIA_FIR is not set +CONFIG_PXA_FICP=m CONFIG_BT=m CONFIG_BT_L2CAP=m CONFIG_BT_SCO=m @@ -431,7 +461,6 @@ CONFIG_BT_HCIUSB=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_BCSP_TXCRC=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -459,6 +488,11 @@ CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -477,6 +511,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -532,6 +567,11 @@ CONFIG_MTD_NAND_SHARPSL=y # CONFIG_MTD_NAND_NANDSIM is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -551,14 +591,6 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -625,6 +657,7 @@ CONFIG_SCSI_MULTI_LUN=y # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set @@ -748,6 +781,7 @@ CONFIG_PPP_ASYNC=m # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set CONFIG_PPP_BSDCOMP=m +# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -850,11 +884,15 @@ CONFIG_UNIX98_PTYS=y # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -889,6 +927,7 @@ CONFIG_I2C_PXA=y # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set # CONFIG_SENSORS_MAX6875 is not set +# CONFIG_RTC_X1205_I2C is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -957,7 +996,10 @@ CONFIG_VIDEO_DEV=m # CONFIG_VIDEO_SAA5246A is not set # CONFIG_VIDEO_SAA5249 is not set # CONFIG_TUNER_3036 is not set +# CONFIG_VIDEO_EM28XX is not set # CONFIG_VIDEO_OVCAMCHIP is not set +# CONFIG_VIDEO_AUDIO_DECODER is not set +# CONFIG_VIDEO_DECODER is not set # # Radio Adapters @@ -976,13 +1018,12 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_PXA is not set CONFIG_FB_W100=y -# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -991,6 +1032,7 @@ CONFIG_FB_W100=y # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -1087,15 +1129,15 @@ CONFIG_USB_SL811_CS=m # USB Device Class drivers # # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m # -# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# may also be needed; see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -1107,7 +1149,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set # # USB Input Devices @@ -1185,6 +1226,7 @@ CONFIG_USB_MON=y CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ANYDATA is not set CONFIG_USB_SERIAL_BELKIN=m # CONFIG_USB_SERIAL_WHITEHEAT is not set CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -1340,6 +1382,7 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1466,7 +1509,9 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y diff --git a/arch/arm/configs/poodle_defconfig b/arch/arm/configs/poodle_defconfig deleted file mode 100644 index 7282290..0000000 --- a/arch/arm/configs/poodle_defconfig +++ /dev/null @@ -1,1015 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-rc3 -# Sun Oct 9 17:04:29 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y -CONFIG_INIT_ENV_ARG_LIMIT=32 - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -CONFIG_INITRAMFS_SOURCE="" -CONFIG_EMBEDDED=y -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_ALL is not set -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y -CONFIG_MODVERSIONS=y -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -CONFIG_ARCH_PXA=y -# CONFIG_ARCH_RPC is not set -# CONFIG_ARCH_SA1100 is not set -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set -# CONFIG_ARCH_AAEC2000 is not set - -# -# Intel PXA2xx Implementations -# -# CONFIG_ARCH_LUBBOCK is not set -# CONFIG_MACH_MAINSTONE is not set -# CONFIG_ARCH_PXA_IDP is not set -CONFIG_PXA_SHARPSL=y -CONFIG_PXA_SHARPSL_25x=y -# CONFIG_PXA_SHARPSL_27x is not set -CONFIG_MACH_POODLE=y -# CONFIG_MACH_CORGI is not set -# CONFIG_MACH_SHEPHERD is not set -# CONFIG_MACH_HUSKY is not set -CONFIG_PXA25x=y - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_XSCALE=y -CONFIG_CPU_32v5=y -CONFIG_CPU_ABRT_EV5T=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WBI=y - -# -# Processor Features -# -CONFIG_ARM_THUMB=y -CONFIG_XSCALE_PMU=y -CONFIG_SHARP_LOCOMO=y -CONFIG_SHARP_PARAM=y -CONFIG_SHARP_SCOOP=y - -# -# Bus support -# -CONFIG_ISA_DMA_API=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y -CONFIG_PCMCIA_LOAD_CIS=y -CONFIG_PCMCIA_IOCTL=y - -# -# PC-card bridges -# -CONFIG_PCMCIA_PXA2XX=y - -# -# Kernel Features -# -CONFIG_PREEMPT=y -# CONFIG_NO_IDLE_HZ is not set -# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -# CONFIG_SPARSEMEM_STATIC is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty1 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 debug" -# CONFIG_XIP_KERNEL is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -CONFIG_FPE_NWFPE=y -# CONFIG_FPE_NWFPE_XP is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_MISC=m -# CONFIG_ARTHUR is not set - -# -# Power management options -# -CONFIG_PM=y -CONFIG_APM=y - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_SYN_COOKIES=y -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_INET_DIAG=y -CONFIG_INET_TCP_DIAG=y -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_BIC=y -# CONFIG_IPV6 is not set -# CONFIG_NETFILTER is not set - -# -# DCCP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_DCCP is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_IEEE80211 is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -CONFIG_FW_LOADER=y -# CONFIG_DEBUG_DRIVER is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AFS_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -CONFIG_MTD_COMPLEX_MAPPINGS=y -CONFIG_MTD_SHARP_SL=y -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set - -# -# NAND Flash Device Drivers -# -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_VERIFY_WRITE=y -# CONFIG_MTD_NAND_H1900 is not set -CONFIG_MTD_NAND_IDS=y -# CONFIG_MTD_NAND_DISKONCHIP is not set -CONFIG_MTD_NAND_SHARPSL=y -# CONFIG_MTD_NAND_NANDSIM is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# - -# -# Block devices -# -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -CONFIG_BLK_DEV_IDECS=y -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Network device support -# -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# PHY device support -# -# CONFIG_PHYLIB is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_SMC91X is not set -# CONFIG_DM9000 is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_PCMCIA_WAVELAN is not set -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -# CONFIG_AIRO_CS is not set -# CONFIG_PCMCIA_WL3501 is not set -# CONFIG_HOSTAP is not set -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -# CONFIG_PCMCIA_3C589 is not set -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -CONFIG_PCMCIA_PCNET=y -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=m -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -CONFIG_PPP_BSDCOMP=m -# CONFIG_PPPOE is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -CONFIG_INPUT_TSDEV=y -CONFIG_INPUT_TSDEV_SCREEN_X=240 -CONFIG_INPUT_TSDEV_SCREEN_Y=320 -CONFIG_INPUT_EVDEV=y -CONFIG_INPUT_EVBUG=y - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -# CONFIG_KEYBOARD_ATKBD is not set -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -CONFIG_KEYBOARD_LOCOMO=y -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -# CONFIG_KEYBOARD_CORGI is not set -CONFIG_KEYBOARD_SPITZ=y -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_PXA=y -CONFIG_SERIAL_PXA_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -# CONFIG_LEGACY_PTYS is not set - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_CHARDEV is not set - -# -# I2C Algorithms -# -CONFIG_I2C_ALGOBIT=y -# CONFIG_I2C_ALGOPCF is not set -# CONFIG_I2C_ALGOPCA is not set - -# -# I2C Hardware Bus support -# -# CONFIG_I2C_PXA is not set -# CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_STUB is not set -# CONFIG_I2C_PCA_ISA is not set - -# -# Miscellaneous I2C Chip support -# -# CONFIG_SENSORS_DS1337 is not set -# CONFIG_SENSORS_DS1374 is not set -# CONFIG_SENSORS_EEPROM is not set -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCA9539 is not set -# CONFIG_SENSORS_PCF8591 is not set -# CONFIG_SENSORS_RTC8564 is not set -# CONFIG_SENSORS_MAX6875 is not set -CONFIG_I2C_DEBUG_CORE=y -CONFIG_I2C_DEBUG_ALGO=y -CONFIG_I2C_DEBUG_BUS=y -# CONFIG_I2C_DEBUG_CHIP is not set - -# -# Hardware Monitoring support -# -CONFIG_HWMON=y -# CONFIG_HWMON_VID is not set -# CONFIG_SENSORS_ADM1021 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM1026 is not set -# CONFIG_SENSORS_ADM1031 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_ASB100 is not set -# CONFIG_SENSORS_ATXP1 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCHER is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_LM63 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM77 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -# CONFIG_SENSORS_LM83 is not set -# CONFIG_SENSORS_LM85 is not set -# CONFIG_SENSORS_LM87 is not set -# CONFIG_SENSORS_LM90 is not set -# CONFIG_SENSORS_LM92 is not set -# CONFIG_SENSORS_MAX1619 is not set -# CONFIG_SENSORS_PC87360 is not set -# CONFIG_SENSORS_SMSC47M1 is not set -# CONFIG_SENSORS_SMSC47B397 is not set -# CONFIG_SENSORS_W83781D is not set -# CONFIG_SENSORS_W83792D is not set -# CONFIG_SENSORS_W83L785TS is not set -# CONFIG_SENSORS_W83627HF is not set -# CONFIG_SENSORS_W83627EHF is not set -# CONFIG_HWMON_DEBUG_CHIP is not set - -# -# Misc devices -# - -# -# Multimedia Capabilities Port drivers -# - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# - -# -# Video Adapters -# -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_SAA5246A is not set -# CONFIG_VIDEO_SAA5249 is not set -# CONFIG_TUNER_3036 is not set -# CONFIG_VIDEO_OVCAMCHIP is not set - -# -# Radio Adapters -# -# CONFIG_RADIO_MAESTRO is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y -# CONFIG_FB_MACMODES is not set -CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_PXA=y -# CONFIG_FB_W100 is not set -# CONFIG_FB_PXA_PARAMETERS is not set -# CONFIG_FB_S1D13XXX is not set -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_7x14 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_10x18 is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -CONFIG_USB_GADGET=y -# CONFIG_USB_GADGET_DEBUG_FILES is not set -CONFIG_USB_GADGET_SELECTED=y -# CONFIG_USB_GADGET_NET2280 is not set -CONFIG_USB_GADGET_PXA2XX=y -CONFIG_USB_PXA2XX=y -# CONFIG_USB_PXA2XX_SMALL is not set -# CONFIG_USB_GADGET_GOKU is not set -# CONFIG_USB_GADGET_LH7A40X is not set -# CONFIG_USB_GADGET_OMAP is not set -# CONFIG_USB_GADGET_DUMMY_HCD is not set -# CONFIG_USB_GADGET_DUALSPEED is not set -# CONFIG_USB_ZERO is not set -CONFIG_USB_ETH=y -CONFIG_USB_ETH_RNDIS=y -# CONFIG_USB_GADGETFS is not set -# CONFIG_USB_FILE_STORAGE is not set -# CONFIG_USB_G_SERIAL is not set - -# -# MMC/SD Card support -# -CONFIG_MMC=y -CONFIG_MMC_DEBUG=y -CONFIG_MMC_BLOCK=y -CONFIG_MMC_PXA=y -# CONFIG_MMC_WBSD is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_EXT2_FS_SECURITY=y -# CONFIG_EXT2_FS_XIP is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -CONFIG_FS_POSIX_ACL=y -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -CONFIG_INOTIFY=y -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -CONFIG_VFAT_FS=y -CONFIG_FAT_DEFAULT_CODEPAGE=437 -CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_JFFS2_FS_WRITEBUFFER=y -CONFIG_JFFS2_COMPRESSION_OPTIONS=y -CONFIG_JFFS2_ZLIB=y -CONFIG_JFFS2_RTIME=y -CONFIG_JFFS2_RUBIN=y -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -CONFIG_CRAMFS=m -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_9P_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="cp437" -CONFIG_NLS_CODEPAGE_437=y -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ASCII=y -CONFIG_NLS_ISO8859_1=y -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -CONFIG_NLS_UTF8=y - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_MAGIC_SYSRQ=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DETECT_SOFTLOCKUP=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_DEBUG_SLAB is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_DEBUG_SPINLOCK_SLEEP is not set -# CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_BUGVERBOSE is not set -# CONFIG_DEBUG_INFO is not set -# CONFIG_DEBUG_FS is not set -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set -# CONFIG_DEBUG_WAITQ is not set -CONFIG_DEBUG_ERRORS=y -# CONFIG_DEBUG_LL is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -CONFIG_CRC_CCITT=y -# CONFIG_CRC16 is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 900e04f..18e9bea 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.14-rc3 -# Sun Oct 9 17:11:19 2005 +# Linux kernel version: 2.6.15-rc2 +# Mon Nov 28 10:26:52 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -64,6 +64,23 @@ CONFIG_OBSOLETE_MODPARM=y CONFIG_KMOD=y # +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# # System Type # # CONFIG_ARCH_CLPS7500 is not set @@ -85,6 +102,7 @@ CONFIG_ARCH_PXA=y # CONFIG_ARCH_LH7A40X is not set # CONFIG_ARCH_OMAP is not set # CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set # CONFIG_ARCH_IMX is not set # CONFIG_ARCH_H720X is not set # CONFIG_ARCH_AAEC2000 is not set @@ -98,10 +116,13 @@ CONFIG_ARCH_PXA=y CONFIG_PXA_SHARPSL=y # CONFIG_PXA_SHARPSL_25x is not set CONFIG_PXA_SHARPSL_27x=y +CONFIG_MACH_AKITA=y CONFIG_MACH_SPITZ=y CONFIG_MACH_BORZOI=y CONFIG_PXA27x=y +CONFIG_IWMMXT=y CONFIG_PXA_SHARP_Cxx00=y +CONFIG_PXA_SSP=y # # Processor Type @@ -153,6 +174,7 @@ CONFIG_FLATMEM_MANUAL=y CONFIG_FLATMEM=y CONFIG_FLAT_NODE_MEM_MAP=y # CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_ALIGNMENT_TRAP=y # @@ -233,6 +255,10 @@ CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set + +# +# Core Netfilter Configuration +# # CONFIG_NETFILTER_NETLINK is not set # @@ -354,6 +380,10 @@ CONFIG_IP6_NF_RAW=m # CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set CONFIG_NET_CLS_ROUTE=y @@ -411,6 +441,7 @@ CONFIG_IRCOMM=m # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set # CONFIG_VIA_FIR is not set +CONFIG_PXA_FICP=m CONFIG_BT=m CONFIG_BT_L2CAP=m CONFIG_BT_SCO=m @@ -429,7 +460,6 @@ CONFIG_BT_HCIUSB=m CONFIG_BT_HCIUART=m CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y -CONFIG_BT_HCIUART_BCSP_TXCRC=y CONFIG_BT_HCIBCM203X=m CONFIG_BT_HCIBPA10X=m CONFIG_BT_HCIBFUSB=m @@ -457,6 +487,11 @@ CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set # +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# # Memory Technology Devices (MTD) # CONFIG_MTD=y @@ -475,6 +510,7 @@ CONFIG_MTD_BLOCK=y # CONFIG_FTL is not set # CONFIG_NFTL is not set # CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set # # RAM/ROM/Flash chip drivers @@ -530,6 +566,11 @@ CONFIG_MTD_NAND_SHARPSL=y # CONFIG_MTD_NAND_NANDSIM is not set # +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# # Parallel port support # # CONFIG_PARPORT is not set @@ -549,14 +590,6 @@ CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_RAM is not set CONFIG_BLK_DEV_RAM_COUNT=16 # CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y # CONFIG_ATA_OVER_ETH is not set # @@ -623,6 +656,7 @@ CONFIG_SCSI_MULTI_LUN=y # # SCSI low-level drivers # +# CONFIG_ISCSI_TCP is not set # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set @@ -746,6 +780,7 @@ CONFIG_PPP_ASYNC=m # CONFIG_PPP_SYNC_TTY is not set # CONFIG_PPP_DEFLATE is not set CONFIG_PPP_BSDCOMP=m +# CONFIG_PPP_MPPE is not set # CONFIG_PPPOE is not set # CONFIG_SLIP is not set # CONFIG_SHAPER is not set @@ -771,6 +806,7 @@ CONFIG_INPUT=y # CONFIG_INPUT_TSDEV is not set CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set +# CONFIG_INPUT_POWER is not set # # Input Device Drivers @@ -848,11 +884,15 @@ CONFIG_UNIX98_PTYS=y # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set +# CONFIG_CARDMAN_4000 is not set +# CONFIG_CARDMAN_4040 is not set # CONFIG_RAW_DRIVER is not set # # TPM devices # +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set # # I2C support @@ -891,14 +931,13 @@ CONFIG_FB=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y # CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set +# CONFIG_FB_S1D13XXX is not set CONFIG_FB_PXA=y -# CONFIG_FB_W100 is not set # CONFIG_FB_PXA_PARAMETERS is not set -# CONFIG_FB_S1D13XXX is not set +# CONFIG_FB_W100 is not set # CONFIG_FB_VIRTUAL is not set # @@ -907,6 +946,7 @@ CONFIG_FB_PXA=y # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y @@ -965,15 +1005,15 @@ CONFIG_USB_SL811_CS=m # # USB Device Class drivers # +CONFIG_USB_ACM=m +CONFIG_USB_PRINTER=m # -# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information +# may also be needed; see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set @@ -985,7 +1025,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set # # USB Input Devices @@ -1058,6 +1097,7 @@ CONFIG_USB_MON=y CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_AIRPRIME is not set +# CONFIG_USB_SERIAL_ANYDATA is not set CONFIG_USB_SERIAL_BELKIN=m # CONFIG_USB_SERIAL_WHITEHEAT is not set CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -1218,6 +1258,7 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y +CONFIG_JFFS2_SUMMARY=y CONFIG_JFFS2_COMPRESSION_OPTIONS=y CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y @@ -1344,7 +1385,9 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_USER is not set # CONFIG_DEBUG_WAITQ is not set CONFIG_DEBUG_ERRORS=y -- cgit v0.10.2 From f5417612d787e6b619fd69616bbf95f1b895e900 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 28 Nov 2005 18:09:44 +0000 Subject: [ARM] 3181/1: add PORT_ identifier for Hilscher netx uart Patch from Sascha Hauer This patch adds PORT_NETX for supporting the Hilscher netx embedded UARTs. Signed-off-by: Sascha Hauer Signed-off-by: Russell King diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index a3ac92b..e3710d7 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -121,6 +121,9 @@ #define PORT_IP3106 70 +/* Hilscher netx */ +#define PORT_NETX 71 + #ifdef __KERNEL__ #include -- cgit v0.10.2 From 24117defabc849a6ad5081ad0fafd0664bf55f13 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 28 Nov 2005 21:00:29 +0000 Subject: [MMC] Fix protocol errors A review against MMC/SD specifications found some errors in the current implementation. Signed-off-by: Pierre Ossman Signed-off-by: Russell King diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index da52839..d336a1d 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -816,7 +816,7 @@ static void mmc_discover_cards(struct mmc_host *host) cmd.opcode = SD_SEND_RELATIVE_ADDR; cmd.arg = 0; - cmd.flags = MMC_RSP_R1; + cmd.flags = MMC_RSP_R6; err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); if (err != MMC_ERR_NONE) diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index f819cae..a14dc30 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h @@ -63,7 +63,7 @@ /* class 5 */ #define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */ #define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */ -#define MMC_ERASE 37 /* ac R1b */ +#define MMC_ERASE 38 /* ac R1b */ /* class 9 */ #define MMC_FAST_IO 39 /* ac R4 */ @@ -74,7 +74,7 @@ /* class 8 */ #define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */ -#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */ +#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1 */ /* SD commands type argument response */ /* class 8 */ -- cgit v0.10.2 From cb3592be272d83011051dc49f4326355c01f1e1f Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 28 Nov 2005 21:04:11 +0000 Subject: [SERIAL] mark several serial tables const This patch marks a few serial data structures const, moving them to .rodata where they won't false-share cachelines with things that get written to. Signed-off-by: Arjan van de Ven Signed-off-by: Russell King diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index e08510d..d2bcd1f 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -102,7 +102,7 @@ static unsigned int share_irqs = SERIAL8250_SHARE_IRQS; #define SERIAL_PORT_DFNS #endif -static struct old_serial_port old_serial_port[] = { +static const struct old_serial_port old_serial_port[] = { SERIAL_PORT_DFNS /* defined in asm/serial.h */ }; diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5c3c039..8d92adf 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -468,7 +468,7 @@ static unsigned short timedia_eight_port[] = { 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 }; -static struct timedia_struct { +static const struct timedia_struct { int num; unsigned short *ids; } timedia_data[] = { diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 2331296..c17d680 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1779,7 +1779,7 @@ struct baud_rates { unsigned int cflag; }; -static struct baud_rates baud_rates[] = { +static const struct baud_rates baud_rates[] = { { 921600, B921600 }, { 460800, B460800 }, { 230400, B230400 }, diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 2c7d3ef..7ce0c7e 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -85,7 +85,7 @@ struct multi_id { int multi; /* 1 = multifunction, > 1 = # ports */ }; -static struct multi_id multi_id[] = { +static const struct multi_id multi_id[] = { { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 }, { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 }, { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 }, @@ -354,8 +354,8 @@ next_tuple(client_handle_t handle, tuple_t * tuple, cisparse_t * parse) static int simple_config(dev_link_t *link) { - static kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; - static int size_table[2] = { 8, 16 }; + static const kio_addr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 }; + static const int size_table[2] = { 8, 16 }; client_handle_t handle = link->handle; struct serial_info *info = link->priv; struct serial_cfg_mem *cfg_mem; -- cgit v0.10.2 From 6aab341e0a28aff100a09831c5300a2994b8b986 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 28 Nov 2005 14:34:23 -0800 Subject: mm: re-architect the VM_UNPAGED logic This replaces the (in my opinion horrible) VM_UNMAPPED logic with very explicit support for a "remapped page range" aka VM_PFNMAP. It allows a VM area to contain an arbitrary range of page table entries that the VM never touches, and never considers to be normal pages. Any user of "remap_pfn_range()" automatically gets this new functionality, and doesn't even have to mark the pages reserved or indeed mark them any other way. It just works. As a side effect, doing mmap() on /dev/mem works for arbitrary ranges. Sparc update from David in the next commit. Signed-off-by: Linus Torvalds diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c index b44b36e..f0c47da 100644 --- a/arch/powerpc/kernel/vdso.c +++ b/arch/powerpc/kernel/vdso.c @@ -145,8 +145,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma) struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE); struct page *upg = (vma && vma->vm_mm) ? - follow_page(vma->vm_mm, vma->vm_start + - i*PAGE_SIZE, 0) + follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0) : NULL; dump_one_vdso_page(pg, upg); } @@ -157,8 +156,7 @@ static void dump_vdso_pages(struct vm_area_struct * vma) struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE); struct page *upg = (vma && vma->vm_mm) ? - follow_page(vma->vm_mm, vma->vm_start + - i*PAGE_SIZE, 0) + follow_page(vma, vma->vm_start + i*PAGE_SIZE, 0) : NULL; dump_one_vdso_page(pg, upg); } diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 29c3b63..91dd669 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -591,7 +591,7 @@ static inline size_t read_zero_pagealigned(char __user * buf, size_t size) if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0) goto out_up; - if (vma->vm_flags & (VM_SHARED | VM_HUGETLB | VM_UNPAGED)) + if (vma->vm_flags & (VM_SHARED | VM_HUGETLB)) break; count = vma->vm_end - addr; if (count > size) diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 9ab97ce..50bd5a8f 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -402,12 +402,11 @@ struct numa_maps { /* * Calculate numa node maps for a vma */ -static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) +static struct numa_maps *get_numa_maps(struct vm_area_struct *vma) { + int i; struct page *page; unsigned long vaddr; - struct mm_struct *mm = vma->vm_mm; - int i; struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL); if (!md) @@ -420,7 +419,7 @@ static struct numa_maps *get_numa_maps(const struct vm_area_struct *vma) md->node[i] =0; for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { - page = follow_page(mm, vaddr, 0); + page = follow_page(vma, vaddr, 0); if (page) { int count = page_mapcount(page); diff --git a/include/linux/mm.h b/include/linux/mm.h index f0cdfd1..6a75a7a 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -145,7 +145,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_GROWSDOWN 0x00000100 /* general info on the segment */ #define VM_GROWSUP 0x00000200 #define VM_SHM 0x00000000 /* Means nothing: delete it later */ -#define VM_UNPAGED 0x00000400 /* Pages managed without map count */ +#define VM_PFNMAP 0x00000400 /* Page-ranges managed without "struct page", just pure PFN */ #define VM_DENYWRITE 0x00000800 /* ETXTBSY on write attempts.. */ #define VM_EXECUTABLE 0x00001000 @@ -664,6 +664,7 @@ struct zap_details { unsigned long truncate_count; /* Compare vm_truncate_count */ }; +struct page *vm_normal_page(struct vm_area_struct *, unsigned long, pte_t); unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, unsigned long size, struct zap_details *); unsigned long unmap_vmas(struct mmu_gather **tlb, @@ -953,7 +954,7 @@ unsigned long vmalloc_to_pfn(void *addr); int remap_pfn_range(struct vm_area_struct *, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t); -struct page *follow_page(struct mm_struct *, unsigned long address, +struct page *follow_page(struct vm_area_struct *, unsigned long address, unsigned int foll_flags); #define FOLL_WRITE 0x01 /* check pte is writable */ #define FOLL_TOUCH 0x02 /* mark page accessed */ diff --git a/mm/fremap.c b/mm/fremap.c index 007cbad..f851775 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -27,24 +27,20 @@ static int zap_pte(struct mm_struct *mm, struct vm_area_struct *vma, struct page *page = NULL; if (pte_present(pte)) { - unsigned long pfn = pte_pfn(pte); - flush_cache_page(vma, addr, pfn); + flush_cache_page(vma, addr, pte_pfn(pte)); pte = ptep_clear_flush(vma, addr, ptep); - if (unlikely(!pfn_valid(pfn))) { - print_bad_pte(vma, pte, addr); - goto out; + page = vm_normal_page(vma, addr, pte); + if (page) { + if (pte_dirty(pte)) + set_page_dirty(page); + page_remove_rmap(page); + page_cache_release(page); } - page = pfn_to_page(pfn); - if (pte_dirty(pte)) - set_page_dirty(page); - page_remove_rmap(page); - page_cache_release(page); } else { if (!pte_file(pte)) free_swap_and_cache(pte_to_swp_entry(pte)); pte_clear(mm, addr, ptep); } -out: return !!page; } @@ -65,8 +61,6 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma, pte_t pte_val; spinlock_t *ptl; - BUG_ON(vma->vm_flags & VM_UNPAGED); - pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); if (!pud) @@ -122,8 +116,6 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, pte_t pte_val; spinlock_t *ptl; - BUG_ON(vma->vm_flags & VM_UNPAGED); - pgd = pgd_offset(mm, addr); pud = pud_alloc(mm, pgd, addr); if (!pud) diff --git a/mm/madvise.c b/mm/madvise.c index 328a3bc..2b7cf04 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -126,7 +126,7 @@ static long madvise_dontneed(struct vm_area_struct * vma, unsigned long start, unsigned long end) { *prev = vma; - if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_UNPAGED)) + if (vma->vm_flags & (VM_LOCKED|VM_HUGETLB|VM_PFNMAP)) return -EINVAL; if (unlikely(vma->vm_flags & VM_NONLINEAR)) { diff --git a/mm/memory.c b/mm/memory.c index d1f46f4..b57fbc6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -333,9 +333,9 @@ static inline void add_mm_rss(struct mm_struct *mm, int file_rss, int anon_rss) } /* - * This function is called to print an error when a pte in a - * !VM_UNPAGED region is found pointing to an invalid pfn (which - * is an error. + * This function is called to print an error when a bad pte + * is found. For example, we might have a PFN-mapped pte in + * a region that doesn't allow it. * * The calling function must still handle the error. */ @@ -350,19 +350,56 @@ void print_bad_pte(struct vm_area_struct *vma, pte_t pte, unsigned long vaddr) } /* - * page_is_anon applies strict checks for an anonymous page belonging to - * this vma at this address. It is used on VM_UNPAGED vmas, which are - * usually populated with shared originals (which must not be counted), - * but occasionally contain private COWed copies (when !VM_SHARED, or - * perhaps via ptrace when VM_SHARED). An mmap of /dev/mem might window - * free pages, pages from other processes, or from other parts of this: - * it's tricky, but try not to be deceived by foreign anonymous pages. + * This function gets the "struct page" associated with a pte. + * + * NOTE! Some mappings do not have "struct pages". A raw PFN mapping + * will have each page table entry just pointing to a raw page frame + * number, and as far as the VM layer is concerned, those do not have + * pages associated with them - even if the PFN might point to memory + * that otherwise is perfectly fine and has a "struct page". + * + * The way we recognize those mappings is through the rules set up + * by "remap_pfn_range()": the vma will have the VM_PFNMAP bit set, + * and the vm_pgoff will point to the first PFN mapped: thus every + * page that is a raw mapping will always honor the rule + * + * pfn_of_page == vma->vm_pgoff + ((addr - vma->vm_start) >> PAGE_SHIFT) + * + * and if that isn't true, the page has been COW'ed (in which case it + * _does_ have a "struct page" associated with it even if it is in a + * VM_PFNMAP range). */ -static inline int page_is_anon(struct page *page, - struct vm_area_struct *vma, unsigned long addr) +struct page *vm_normal_page(struct vm_area_struct *vma, unsigned long addr, pte_t pte) { - return page && PageAnon(page) && page_mapped(page) && - page_address_in_vma(page, vma) == addr; + unsigned long pfn = pte_pfn(pte); + + if (vma->vm_flags & VM_PFNMAP) { + unsigned long off = (addr - vma->vm_start) >> PAGE_SHIFT; + if (pfn == vma->vm_pgoff + off) + return NULL; + } + + /* + * Add some anal sanity checks for now. Eventually, + * we should just do "return pfn_to_page(pfn)", but + * in the meantime we check that we get a valid pfn, + * and that the resulting page looks ok. + * + * Remove this test eventually! + */ + if (unlikely(!pfn_valid(pfn))) { + print_bad_pte(vma, pte, addr); + return NULL; + } + + /* + * NOTE! We still have PageReserved() pages in the page + * tables. + * + * The PAGE_ZERO() pages and various VDSO mappings can + * cause them to exist. + */ + return pfn_to_page(pfn); } /* @@ -379,7 +416,6 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, unsigned long vm_flags = vma->vm_flags; pte_t pte = *src_pte; struct page *page; - unsigned long pfn; /* pte contains position in swap or file, so copy. */ if (unlikely(!pte_present(pte))) { @@ -397,22 +433,6 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, goto out_set_pte; } - pfn = pte_pfn(pte); - page = pfn_valid(pfn)? pfn_to_page(pfn): NULL; - - if (unlikely(vm_flags & VM_UNPAGED)) - if (!page_is_anon(page, vma, addr)) - goto out_set_pte; - - /* - * If the pte points outside of valid memory but - * the region is not VM_UNPAGED, we have a problem. - */ - if (unlikely(!page)) { - print_bad_pte(vma, pte, addr); - goto out_set_pte; /* try to do something sane */ - } - /* * If it's a COW mapping, write protect it both * in the parent and the child @@ -429,9 +449,13 @@ copy_one_pte(struct mm_struct *dst_mm, struct mm_struct *src_mm, if (vm_flags & VM_SHARED) pte = pte_mkclean(pte); pte = pte_mkold(pte); - get_page(page); - page_dup_rmap(page); - rss[!!PageAnon(page)]++; + + page = vm_normal_page(vma, addr, pte); + if (page) { + get_page(page); + page_dup_rmap(page); + rss[!!PageAnon(page)]++; + } out_set_pte: set_pte_at(dst_mm, addr, dst_pte, pte); @@ -543,7 +567,7 @@ int copy_page_range(struct mm_struct *dst_mm, struct mm_struct *src_mm, * readonly mappings. The tradeoff is that copy_page_range is more * efficient than faulting. */ - if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_UNPAGED))) { + if (!(vma->vm_flags & (VM_HUGETLB|VM_NONLINEAR|VM_PFNMAP))) { if (!vma->anon_vma) return 0; } @@ -584,19 +608,10 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb, } if (pte_present(ptent)) { struct page *page; - unsigned long pfn; (*zap_work) -= PAGE_SIZE; - pfn = pte_pfn(ptent); - page = pfn_valid(pfn)? pfn_to_page(pfn): NULL; - - if (unlikely(vma->vm_flags & VM_UNPAGED)) { - if (!page_is_anon(page, vma, addr)) - page = NULL; - } else if (unlikely(!page)) - print_bad_pte(vma, ptent, addr); - + page = vm_normal_page(vma, addr, ptent); if (unlikely(details) && page) { /* * unmap_shared_mapping_pages() wants to @@ -852,7 +867,7 @@ unsigned long zap_page_range(struct vm_area_struct *vma, unsigned long address, /* * Do a quick page-table lookup for a single page. */ -struct page *follow_page(struct mm_struct *mm, unsigned long address, +struct page *follow_page(struct vm_area_struct *vma, unsigned long address, unsigned int flags) { pgd_t *pgd; @@ -860,8 +875,8 @@ struct page *follow_page(struct mm_struct *mm, unsigned long address, pmd_t *pmd; pte_t *ptep, pte; spinlock_t *ptl; - unsigned long pfn; struct page *page; + struct mm_struct *mm = vma->vm_mm; page = follow_huge_addr(mm, address, flags & FOLL_WRITE); if (!IS_ERR(page)) { @@ -897,11 +912,10 @@ struct page *follow_page(struct mm_struct *mm, unsigned long address, goto unlock; if ((flags & FOLL_WRITE) && !pte_write(pte)) goto unlock; - pfn = pte_pfn(pte); - if (!pfn_valid(pfn)) + page = vm_normal_page(vma, address, pte); + if (unlikely(!page)) goto unlock; - page = pfn_to_page(pfn); if (flags & FOLL_GET) get_page(page); if (flags & FOLL_TOUCH) { @@ -974,8 +988,10 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, return i ? : -EFAULT; } if (pages) { - pages[i] = pte_page(*pte); - get_page(pages[i]); + struct page *page = vm_normal_page(vma, start, *pte); + pages[i] = page; + if (page) + get_page(page); } pte_unmap(pte); if (vmas) @@ -1010,7 +1026,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, foll_flags |= FOLL_WRITE; cond_resched(); - while (!(page = follow_page(mm, start, foll_flags))) { + while (!(page = follow_page(vma, start, foll_flags))) { int ret; ret = __handle_mm_fault(mm, vma, start, foll_flags & FOLL_WRITE); @@ -1214,11 +1230,12 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, * in 2.6 the LRU scan won't even find its pages, so this * flag means no more than count its pages in reserved_vm, * and omit it from core dump, even when VM_IO turned off. - * VM_UNPAGED tells the core MM not to "manage" these pages - * (e.g. refcount, mapcount, try to swap them out): in - * particular, zap_pte_range does not try to free them. + * VM_PFNMAP tells the core MM that the base pages are just + * raw PFN mappings, and do not have a "struct page" associated + * with them. */ - vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED; + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + vma->vm_pgoff = pfn; BUG_ON(addr >= end); pfn -= addr >> PAGE_SHIFT; @@ -1273,6 +1290,26 @@ static inline pte_t maybe_mkwrite(pte_t pte, struct vm_area_struct *vma) return pte; } +static inline void cow_user_page(struct page *dst, struct page *src, unsigned long va) +{ + /* + * If the source page was a PFN mapping, we don't have + * a "struct page" for it. We do a best-effort copy by + * just copying from the original user address. If that + * fails, we just zero-fill it. Live with it. + */ + if (unlikely(!src)) { + void *kaddr = kmap_atomic(dst, KM_USER0); + unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE); + if (left) + memset(kaddr, 0, PAGE_SIZE); + kunmap_atomic(kaddr, KM_USER0); + return; + + } + copy_user_highpage(dst, src, va); +} + /* * This routine handles present pages, when users try to write * to a shared page. It is done by copying the page to a new address @@ -1296,28 +1333,13 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, spinlock_t *ptl, pte_t orig_pte) { struct page *old_page, *src_page, *new_page; - unsigned long pfn = pte_pfn(orig_pte); pte_t entry; int ret = VM_FAULT_MINOR; - if (unlikely(!pfn_valid(pfn))) { - /* - * Page table corrupted: show pte and kill process. - * Or it's an attempt to COW an out-of-map VM_UNPAGED - * entry, which copy_user_highpage does not support. - */ - print_bad_pte(vma, orig_pte, address); - ret = VM_FAULT_OOM; - goto unlock; - } - old_page = pfn_to_page(pfn); + old_page = vm_normal_page(vma, address, orig_pte); src_page = old_page; - - if (unlikely(vma->vm_flags & VM_UNPAGED)) - if (!page_is_anon(old_page, vma, address)) { - old_page = NULL; - goto gotten; - } + if (!old_page) + goto gotten; if (PageAnon(old_page) && !TestSetPageLocked(old_page)) { int reuse = can_share_swap_page(old_page); @@ -1351,7 +1373,7 @@ gotten: new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!new_page) goto oom; - copy_user_highpage(new_page, src_page, address); + cow_user_page(new_page, src_page, address); } /* @@ -1812,16 +1834,7 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, spinlock_t *ptl; pte_t entry; - /* - * A VM_UNPAGED vma will normally be filled with present ptes - * by remap_pfn_range, and never arrive here; but it might have - * holes, or if !VM_DONTEXPAND, mremap might have expanded it. - * It's weird enough handling anon pages in unpaged vmas, we do - * not want to worry about ZERO_PAGEs too (it may or may not - * matter if their counts wrap): just give them anon pages. - */ - - if (write_access || (vma->vm_flags & VM_UNPAGED)) { + if (write_access) { /* Allocate our own private page. */ pte_unmap(page_table); @@ -1896,8 +1909,6 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, int anon = 0; pte_unmap(page_table); - BUG_ON(vma->vm_flags & VM_UNPAGED); - if (vma->vm_file) { mapping = vma->vm_file->f_mapping; sequence = mapping->truncate_count; @@ -1930,7 +1941,7 @@ retry: page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!page) goto oom; - copy_user_highpage(page, new_page, address); + cow_user_page(page, new_page, address); page_cache_release(new_page); new_page = page; anon = 1; diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 5609a31..bec88c8 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -189,17 +189,15 @@ static int check_pte_range(struct vm_area_struct *vma, pmd_t *pmd, orig_pte = pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); do { - unsigned long pfn; + struct page *page; unsigned int nid; if (!pte_present(*pte)) continue; - pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) { - print_bad_pte(vma, *pte, addr); + page = vm_normal_page(vma, addr, *pte); + if (!page) continue; - } - nid = pfn_to_nid(pfn); + nid = page_to_nid(page); if (!node_isset(nid, *nodes)) break; } while (pte++, addr += PAGE_SIZE, addr != end); @@ -269,8 +267,6 @@ check_range(struct mm_struct *mm, unsigned long start, unsigned long end, first = find_vma(mm, start); if (!first) return ERR_PTR(-EFAULT); - if (first->vm_flags & VM_UNPAGED) - return ERR_PTR(-EACCES); prev = NULL; for (vma = first; vma && vma->vm_start < end; vma = vma->vm_next) { if (!vma->vm_next && vma->vm_end < end) diff --git a/mm/msync.c b/mm/msync.c index b3f4caf..1b5b6f6 100644 --- a/mm/msync.c +++ b/mm/msync.c @@ -27,7 +27,6 @@ static void msync_pte_range(struct vm_area_struct *vma, pmd_t *pmd, again: pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl); do { - unsigned long pfn; struct page *page; if (progress >= 64) { @@ -40,13 +39,9 @@ again: continue; if (!pte_maybe_dirty(*pte)) continue; - pfn = pte_pfn(*pte); - if (unlikely(!pfn_valid(pfn))) { - print_bad_pte(vma, *pte, addr); + page = vm_normal_page(vma, addr, *pte); + if (!page) continue; - } - page = pfn_to_page(pfn); - if (ptep_clear_flush_dirty(vma, addr, pte) || page_test_and_clear_dirty(page)) set_page_dirty(page); @@ -97,9 +92,8 @@ static void msync_page_range(struct vm_area_struct *vma, /* For hugepages we can't go walking the page table normally, * but that's ok, hugetlbfs is memory based, so we don't need * to do anything more on an msync(). - * Can't do anything with VM_UNPAGED regions either. */ - if (vma->vm_flags & (VM_HUGETLB|VM_UNPAGED)) + if (vma->vm_flags & VM_HUGETLB) return; BUG_ON(addr >= end); diff --git a/mm/nommu.c b/mm/nommu.c index 6deb6ab..c119681 100644 --- a/mm/nommu.c +++ b/mm/nommu.c @@ -1045,7 +1045,7 @@ struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr) EXPORT_SYMBOL(find_vma); -struct page *follow_page(struct mm_struct *mm, unsigned long address, +struct page *follow_page(struct vm_area_struct *vma, unsigned long address, unsigned int foll_flags) { return NULL; diff --git a/mm/rmap.c b/mm/rmap.c index 2e034a0..6389cda 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -226,8 +226,6 @@ vma_address(struct page *page, struct vm_area_struct *vma) /* * At what user virtual address is page expected in vma? checking that the * page matches the vma: currently only used on anon pages, by unuse_vma; - * and by extraordinary checks on anon pages in VM_UNPAGED vmas, taking - * care that an mmap of /dev/mem might window free and foreign pages. */ unsigned long page_address_in_vma(struct page *page, struct vm_area_struct *vma) { @@ -614,7 +612,6 @@ static void try_to_unmap_cluster(unsigned long cursor, struct page *page; unsigned long address; unsigned long end; - unsigned long pfn; address = (vma->vm_start + cursor) & CLUSTER_MASK; end = address + CLUSTER_SIZE; @@ -643,15 +640,8 @@ static void try_to_unmap_cluster(unsigned long cursor, for (; address < end; pte++, address += PAGE_SIZE) { if (!pte_present(*pte)) continue; - - pfn = pte_pfn(*pte); - if (unlikely(!pfn_valid(pfn))) { - print_bad_pte(vma, *pte, address); - continue; - } - - page = pfn_to_page(pfn); - BUG_ON(PageAnon(page)); + page = vm_normal_page(vma, address, *pte); + BUG_ON(!page || PageAnon(page)); if (ptep_clear_flush_young(vma, address, pte)) continue; -- cgit v0.10.2 From 5cd9194a1b0b0fa219c31421ac64dfd38670ed49 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 28 Nov 2005 14:02:10 -0800 Subject: [PATCH] sparc: convert IO remapping to VM_PFNMAP Here are the Sparc bits. Signed-off-by: Linus Torvalds diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c index 0410bae..2cb0728 100644 --- a/arch/sparc/mm/generic.c +++ b/arch/sparc/mm/generic.c @@ -32,9 +32,7 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, unsigne if (end > PMD_SIZE) end = PMD_SIZE; do { - pte_t oldpage = *pte; - pte_clear(mm, address, pte); - set_pte(pte, mk_pte_io(offset, prot, space)); + set_pte_at(mm, address, pte, mk_pte_io(offset, prot, space)); address += PAGE_SIZE; offset += PAGE_SIZE; pte++; @@ -63,7 +61,7 @@ static inline int io_remap_pmd_range(struct mm_struct *mm, pmd_t * pmd, unsigned } int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, - unsigned long pfn, unsigned long size, pgprot_t prot) + unsigned long pfn, unsigned long size, pgprot_t prot) { int error = 0; pgd_t * dir; @@ -74,7 +72,9 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; /* See comment in mm/memory.c remap_pfn_range */ - vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED; + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + vma->vm_pgoff = (offset >> PAGE_SHIFT) | + ((unsigned long)space << 28UL); prot = __pgprot(pg_iobits); offset -= from; diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index 8fd4cb1..d9396c1 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -15,6 +15,15 @@ #include #include +static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) +{ + pte_t pte; + pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) & + ~(unsigned long)_PAGE_CACHE); + pte_val(pte) |= (((unsigned long)space) << 32); + return pte; +} + /* Remap IO memory, the same way as remap_pfn_range(), but use * the obio memory space. * @@ -126,9 +135,13 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from, struct mm_struct *mm = vma->vm_mm; int space = GET_IOSPACE(pfn); unsigned long offset = GET_PFN(pfn) << PAGE_SHIFT; + unsigned long phys_base; + + phys_base = offset | (((unsigned long) space) << 32UL); /* See comment in mm/memory.c remap_pfn_range */ - vma->vm_flags |= VM_IO | VM_RESERVED | VM_UNPAGED; + vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; + vma->vm_pgoff = phys_base >> PAGE_SHIFT; prot = __pgprot(pg_iobits); offset -= from; diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 9a02879..f0a9b44 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -348,16 +348,6 @@ extern unsigned long find_ecache_flush_span(unsigned long size); struct vm_area_struct; extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); -/* Make a non-present pseudo-TTE. */ -static inline pte_t mk_pte_io(unsigned long page, pgprot_t prot, int space) -{ - pte_t pte; - pte_val(pte) = (((page) | pgprot_val(prot) | _PAGE_E) & - ~(unsigned long)_PAGE_CACHE); - pte_val(pte) |= (((unsigned long)space) << 32); - return pte; -} - /* Encode and de-code a swap entry */ #define __swp_type(entry) (((entry).val >> PAGE_SHIFT) & 0xffUL) #define __swp_offset(entry) ((entry).val >> (PAGE_SHIFT + 8UL)) -- cgit v0.10.2 From e0f39591cc178026607fcbbe9a53be435fe8285d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 28 Nov 2005 13:43:44 -0800 Subject: [PATCH] Workaround for gcc 2.96 (undefined references) LD .tmp_vmlinux1 mm/built-in.o(.text+0x100d6): In function `copy_page_range': : undefined reference to `__pud_alloc' mm/built-in.o(.text+0x1010b): In function `copy_page_range': : undefined reference to `__pmd_alloc' mm/built-in.o(.text+0x11ef4): In function `__handle_mm_fault': : undefined reference to `__pud_alloc' fs/built-in.o(.text+0xc930): In function `install_arg_page': : undefined reference to `__pud_alloc' make: *** [.tmp_vmlinux1] Error 1 Those missing references in mm/memory.c arise from this code in include/linux/mm.h, combined with the fact that __PGTABLE_PMD_FOLDED and __PGTABLE_PUD_FOLDED are both set and __ARCH_HAS_4LEVEL_HACK is not: /* * The following ifdef needed to get the 4level-fixup.h header to work. * Remove it when 4level-fixup.h has been removed. */ #if defined(CONFIG_MMU) && !defined(__ARCH_HAS_4LEVEL_HACK) static inline pud_t *pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) { return (unlikely(pgd_none(*pgd)) && __pud_alloc(mm, pgd, address))? NULL: pud_offset(pgd, address); } static inline pmd_t *pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) { return (unlikely(pud_none(*pud)) && __pmd_alloc(mm, pud, address))? NULL: pmd_offset(pud, address); } #endif /* CONFIG_MMU && !__ARCH_HAS_4LEVEL_HACK */ With my configuration the pgd_none and pud_none routines are inlines returning a constant 0. Apparently the old compiler avoids generating calls to __pud_alloc and __pmd_alloc but still lists them as undefined references in the module's symbol table. I don't know which change caused this problem. I think it was added somewhere between 2.6.14 and 2.6.15-rc1, because I remember building several 2.6.14-rc kernels without difficulty. However I can't point to an individual culprit. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index b57fbc6..9ab206b 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2160,6 +2160,12 @@ int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) spin_unlock(&mm->page_table_lock); return 0; } +#else +/* Workaround for gcc 2.96 */ +int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address) +{ + return 0; +} #endif /* __PAGETABLE_PUD_FOLDED */ #ifndef __PAGETABLE_PMD_FOLDED @@ -2188,6 +2194,12 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) spin_unlock(&mm->page_table_lock); return 0; } +#else +/* Workaround for gcc 2.96 */ +int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) +{ + return 0; +} #endif /* __PAGETABLE_PMD_FOLDED */ int make_pages_present(unsigned long addr, unsigned long end) -- cgit v0.10.2 From a9d9baa1e819b2f92f9cfa5240f766c535e636a6 Mon Sep 17 00:00:00 2001 From: Ashok Raj Date: Mon, 28 Nov 2005 13:43:46 -0800 Subject: [PATCH] clean up lock_cpu_hotplug() in cpufreq There are some callers in cpufreq hotplug notify path that the lowest function calls lock_cpu_hotplug(). The lock is already held during cpu_up() and cpu_down() calls when the notify calls are broadcast to registered clients. Ideally if possible, we could disable_preempt() at the highest caller and make sure we dont sleep in the path down in cpufreq->driver_target() calls but the calls are so intertwined and cumbersome to cleanup. Hence we consistently use lock_cpu_hotplug() and unlock_cpu_hotplug() in all places. - Removed export of cpucontrol semaphore and made it static. - removed explicit uses of up/down with lock_cpu_hotplug() so we can keep track of the the callers in same thread context and just keep refcounts without calling a down() that causes a deadlock. - Removed current_in_hotplug() uses - Removed PF_HOTPLUG_CPU in sched.h introduced for the current_in_hotplug() temporary workaround. Tested with insmod of cpufreq_stat.ko, and logical online/offline to make sure we dont have any hang situations. Signed-off-by: Ashok Raj Cc: Zwane Mwaikambo Cc: Shaohua Li Cc: "Siddha, Suresh B" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 1c0f62d..815902c 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1113,21 +1113,13 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy, { int retval = -EINVAL; - /* - * If we are already in context of hotplug thread, we dont need to - * acquire the hotplug lock. Otherwise acquire cpucontrol to prevent - * hotplug from removing this cpu that we are working on. - */ - if (!current_in_cpu_hotplug()) - lock_cpu_hotplug(); - + lock_cpu_hotplug(); dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, target_freq, relation); if (cpu_online(policy->cpu) && cpufreq_driver->target) retval = cpufreq_driver->target(policy, target_freq, relation); - if (!current_in_cpu_hotplug()) - unlock_cpu_hotplug(); + unlock_cpu_hotplug(); return retval; } diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 43c4453..0ed1d48 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -65,10 +65,9 @@ extern struct sysdev_class cpu_sysdev_class; #ifdef CONFIG_HOTPLUG_CPU /* Stop CPUs going up and down. */ -extern struct semaphore cpucontrol; -#define lock_cpu_hotplug() down(&cpucontrol) -#define unlock_cpu_hotplug() up(&cpucontrol) -#define lock_cpu_hotplug_interruptible() down_interruptible(&cpucontrol) +extern void lock_cpu_hotplug(void); +extern void unlock_cpu_hotplug(void); +extern int lock_cpu_hotplug_interruptible(void); #define hotcpu_notifier(fn, pri) { \ static struct notifier_block fn##_nb = \ { .notifier_call = fn, .priority = pri }; \ diff --git a/include/linux/sched.h b/include/linux/sched.h index 2038bd2..b0ad6f3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -908,7 +908,6 @@ do { if (atomic_dec_and_test(&(tsk)->usage)) __put_task_struct(tsk); } while(0) #define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ #define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ #define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ -#define PF_HOTPLUG_CPU 0x01000000 /* Currently performing CPU hotplug */ /* * Only the _current_ task can read/write to tsk->flags, but other diff --git a/kernel/cpu.c b/kernel/cpu.c index d61ba88..e882c6b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -16,47 +16,76 @@ #include /* This protects CPUs going up and down... */ -DECLARE_MUTEX(cpucontrol); -EXPORT_SYMBOL_GPL(cpucontrol); +static DECLARE_MUTEX(cpucontrol); static struct notifier_block *cpu_chain; -/* - * Used to check by callers if they need to acquire the cpucontrol - * or not to protect a cpu from being removed. Its sometimes required to - * call these functions both for normal operations, and in response to - * a cpu being added/removed. If the context of the call is in the same - * thread context as a CPU hotplug thread, we dont need to take the lock - * since its already protected - * check drivers/cpufreq/cpufreq.c for its usage - Ashok Raj - */ +#ifdef CONFIG_HOTPLUG_CPU +static struct task_struct *lock_cpu_hotplug_owner; +static int lock_cpu_hotplug_depth; -int current_in_cpu_hotplug(void) +static int __lock_cpu_hotplug(int interruptible) { - return (current->flags & PF_HOTPLUG_CPU); + int ret = 0; + + if (lock_cpu_hotplug_owner != current) { + if (interruptible) + ret = down_interruptible(&cpucontrol); + else + down(&cpucontrol); + } + + /* + * Set only if we succeed in locking + */ + if (!ret) { + lock_cpu_hotplug_depth++; + lock_cpu_hotplug_owner = current; + } + + return ret; } -EXPORT_SYMBOL_GPL(current_in_cpu_hotplug); +void lock_cpu_hotplug(void) +{ + __lock_cpu_hotplug(0); +} +EXPORT_SYMBOL_GPL(lock_cpu_hotplug); +void unlock_cpu_hotplug(void) +{ + if (--lock_cpu_hotplug_depth == 0) { + lock_cpu_hotplug_owner = NULL; + up(&cpucontrol); + } +} +EXPORT_SYMBOL_GPL(unlock_cpu_hotplug); + +int lock_cpu_hotplug_interruptible(void) +{ + return __lock_cpu_hotplug(1); +} +EXPORT_SYMBOL_GPL(lock_cpu_hotplug_interruptible); +#endif /* CONFIG_HOTPLUG_CPU */ /* Need to know about CPUs going up/down? */ int register_cpu_notifier(struct notifier_block *nb) { int ret; - if ((ret = down_interruptible(&cpucontrol)) != 0) + if ((ret = lock_cpu_hotplug_interruptible()) != 0) return ret; ret = notifier_chain_register(&cpu_chain, nb); - up(&cpucontrol); + unlock_cpu_hotplug(); return ret; } EXPORT_SYMBOL(register_cpu_notifier); void unregister_cpu_notifier(struct notifier_block *nb) { - down(&cpucontrol); + lock_cpu_hotplug(); notifier_chain_unregister(&cpu_chain, nb); - up(&cpucontrol); + unlock_cpu_hotplug(); } EXPORT_SYMBOL(unregister_cpu_notifier); @@ -112,13 +141,6 @@ int cpu_down(unsigned int cpu) goto out; } - /* - * Leave a trace in current->flags indicating we are already in - * process of performing CPU hotplug. Callers can check if cpucontrol - * is already acquired by current thread, and if so not cause - * a dead lock by not acquiring the lock - */ - current->flags |= PF_HOTPLUG_CPU; err = notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, (void *)(long)cpu); if (err == NOTIFY_BAD) { @@ -171,7 +193,6 @@ out_thread: out_allowed: set_cpus_allowed(current, old_allowed); out: - current->flags &= ~PF_HOTPLUG_CPU; unlock_cpu_hotplug(); return err; } @@ -182,7 +203,7 @@ int __devinit cpu_up(unsigned int cpu) int ret; void *hcpu = (void *)(long)cpu; - if ((ret = down_interruptible(&cpucontrol)) != 0) + if ((ret = lock_cpu_hotplug_interruptible()) != 0) return ret; if (cpu_online(cpu) || !cpu_present(cpu)) { @@ -190,11 +211,6 @@ int __devinit cpu_up(unsigned int cpu) goto out; } - /* - * Leave a trace in current->flags indicating we are already in - * process of performing CPU hotplug. - */ - current->flags |= PF_HOTPLUG_CPU; ret = notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu); if (ret == NOTIFY_BAD) { printk("%s: attempt to bring up CPU %u failed\n", @@ -217,7 +233,6 @@ out_notify: if (ret != 0) notifier_call_chain(&cpu_chain, CPU_UP_CANCELED, hcpu); out: - current->flags &= ~PF_HOTPLUG_CPU; - up(&cpucontrol); + unlock_cpu_hotplug(); return ret; } -- cgit v0.10.2 From ff88a3b2f56ae4f3296ea957ea38f99f8bd0e5a8 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 28 Nov 2005 13:43:47 -0800 Subject: [PATCH] memory_sysdev_class is static So don't define it as extern in the header file. drivers/base/memory.c:28: error: static declaration of 'memory_sysdev_class' follows non-static declaration include/linux/memory.h:88: error: previous declaration of 'memory_sysdev_class' was here Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/memory.h b/include/linux/memory.h index 9a42438..dc4081b 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -85,7 +85,6 @@ struct notifier_block; extern int register_memory_notifier(struct notifier_block *nb); extern void unregister_memory_notifier(struct notifier_block *nb); -extern struct sysdev_class memory_sysdev_class; #endif /* CONFIG_MEMORY_HOTPLUG */ #define hotplug_memory_notifier(fn, pri) { \ -- cgit v0.10.2 From c13cf856cbe16aec3007604dc013cbf3a16c6686 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 28 Nov 2005 13:43:48 -0800 Subject: [PATCH] fork.c: proc_fork_connector() called under write_lock() Don't do that - it does GFP_KERNEL allocations, for a start. (Reported by Guillaume Thouvenin ) Acked-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/fork.c b/kernel/fork.c index 1c1cf8d..d0d4987 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1135,13 +1135,13 @@ static task_t *copy_process(unsigned long clone_flags, __get_cpu_var(process_counts)++; } - proc_fork_connector(p); if (!current->signal->tty && p->signal->tty) p->signal->tty = NULL; nr_threads++; total_forks++; write_unlock_irq(&tasklist_lock); + proc_fork_connector(p); retval = 0; fork_out: -- cgit v0.10.2 From 8080f231224ccd3169f39e73fd750ba98d5b98a7 Mon Sep 17 00:00:00 2001 From: David Howells Date: Mon, 28 Nov 2005 13:43:51 -0800 Subject: [PATCH] FRV: Make the FRV arch work again The attached patch implements a bunch of small changes to the FRV arch to make it work again. It deals with the following problems: (1) SEM_DEBUG should be SEMAPHORE_DEBUG. (2) The argument list to pcibios_penalize_isa_irq() has changed. (3) CONFIG_HIGHMEM can't be used directly in #if as it may not be defined. (4) page->private is no longer directly accessible. (5) linux/hardirq.h assumes asm/hardirq.h will include linux/irq.h (6) The IDE MMIO access functions are given pointers, not integers, and so get type casting errors. (7) __pa() is passed an explicit u64 type in drivers/char/mem.c, but that can't be cast directly to a pointer on a 32-bit platform. (8) SEMAPHORE_DEBUG should not be contingent on WAITQUEUE_DEBUG as that no longer exists. (9) PREEMPT_ACTIVE is too low a value. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/frv/kernel/semaphore.c b/arch/frv/kernel/semaphore.c index 5cba9c1..7971d68 100644 --- a/arch/frv/kernel/semaphore.c +++ b/arch/frv/kernel/semaphore.c @@ -20,7 +20,7 @@ struct sem_waiter { struct task_struct *task; }; -#if SEM_DEBUG +#if SEMAPHORE_DEBUG void semtrace(struct semaphore *sem, const char *str) { if (sem->debug) diff --git a/arch/frv/mb93090-mb00/pci-irq.c b/arch/frv/mb93090-mb00/pci-irq.c index af981bd..24622d8 100644 --- a/arch/frv/mb93090-mb00/pci-irq.c +++ b/arch/frv/mb93090-mb00/pci-irq.c @@ -60,7 +60,7 @@ void __init pcibios_fixup_irqs(void) } } -void __init pcibios_penalize_isa_irq(int irq, int active) +void __init pcibios_penalize_isa_irq(int irq) { } diff --git a/arch/frv/mm/init.c b/arch/frv/mm/init.c index 7943315..765088e 100644 --- a/arch/frv/mm/init.c +++ b/arch/frv/mm/init.c @@ -108,7 +108,7 @@ void __init paging_init(void) memset((void *) empty_zero_page, 0, PAGE_SIZE); -#if CONFIG_HIGHMEM +#ifdef CONFIG_HIGHMEM if (num_physpages - num_mappedpages) { pgd_t *pge; pud_t *pue; diff --git a/arch/frv/mm/pgalloc.c b/arch/frv/mm/pgalloc.c index 2c67dfe..f76dd03 100644 --- a/arch/frv/mm/pgalloc.c +++ b/arch/frv/mm/pgalloc.c @@ -85,7 +85,7 @@ static inline void pgd_list_add(pgd_t *pgd) struct page *page = virt_to_page(pgd); page->index = (unsigned long) pgd_list; if (pgd_list) - pgd_list->private = (unsigned long) &page->index; + set_page_private(pgd_list, (unsigned long) &page->index); pgd_list = page; set_page_private(page, (unsigned long)&pgd_list); } @@ -94,10 +94,10 @@ static inline void pgd_list_del(pgd_t *pgd) { struct page *next, **pprev, *page = virt_to_page(pgd); next = (struct page *) page->index; - pprev = (struct page **)page_private(page); + pprev = (struct page **) page_private(page); *pprev = next; if (next) - next->private = (unsigned long) pprev; + set_page_private(next, (unsigned long) pprev); } void pgd_ctor(void *pgd, kmem_cache_t *cache, unsigned long unused) diff --git a/include/asm-frv/hardirq.h b/include/asm-frv/hardirq.h index 5248ca0..6851239 100644 --- a/include/asm-frv/hardirq.h +++ b/include/asm-frv/hardirq.h @@ -14,6 +14,7 @@ #include #include +#include typedef struct { unsigned int __softirq_pending; diff --git a/include/asm-frv/ide.h b/include/asm-frv/ide.h index f9caecf..ae031ea 100644 --- a/include/asm-frv/ide.h +++ b/include/asm-frv/ide.h @@ -33,10 +33,10 @@ /* * some bits needed for parts of the IDE subsystem to compile */ -#define __ide_mm_insw(port, addr, n) insw(port, addr, n) -#define __ide_mm_insl(port, addr, n) insl(port, addr, n) -#define __ide_mm_outsw(port, addr, n) outsw(port, addr, n) -#define __ide_mm_outsl(port, addr, n) outsl(port, addr, n) +#define __ide_mm_insw(port, addr, n) insw((unsigned long) (port), addr, n) +#define __ide_mm_insl(port, addr, n) insl((unsigned long) (port), addr, n) +#define __ide_mm_outsw(port, addr, n) outsw((unsigned long) (port), addr, n) +#define __ide_mm_outsl(port, addr, n) outsl((unsigned long) (port), addr, n) #endif /* __KERNEL__ */ diff --git a/include/asm-frv/page.h b/include/asm-frv/page.h index 4feba56..b8221b6 100644 --- a/include/asm-frv/page.h +++ b/include/asm-frv/page.h @@ -47,8 +47,8 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define devmem_is_allowed(pfn) 1 -#define __pa(vaddr) virt_to_phys((void *) vaddr) -#define __va(paddr) phys_to_virt((unsigned long) paddr) +#define __pa(vaddr) virt_to_phys((void *) (unsigned long) (vaddr)) +#define __va(paddr) phys_to_virt((unsigned long) (paddr)) #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) diff --git a/include/asm-frv/semaphore.h b/include/asm-frv/semaphore.h index b183962..907c5c3 100644 --- a/include/asm-frv/semaphore.h +++ b/include/asm-frv/semaphore.h @@ -20,7 +20,7 @@ #include #include -#define SEMAPHORE_DEBUG WAITQUEUE_DEBUG +#define SEMAPHORE_DEBUG 0 /* * the semaphore definition diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h index c8cba78..60f6b2a 100644 --- a/include/asm-frv/thread_info.h +++ b/include/asm-frv/thread_info.h @@ -58,7 +58,7 @@ struct thread_info { #endif -#define PREEMPT_ACTIVE 0x4000000 +#define PREEMPT_ACTIVE 0x10000000 /* * macros/functions for gaining access to the thread information structure -- cgit v0.10.2 From 1a9c3f78a32ddc4ec50f5da2cf2db5db6f442986 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 28 Nov 2005 13:43:52 -0800 Subject: [PATCH] Console rotation fixes Remove bogus usage of test/set_bit() from fbcon rotation code and just manipulate the bits directly. This fixes an oops on powerpc among others and should be faster. Seems to work fine on the G5 here. Signed-off-by: Benjamin Herrenschmidt Acked-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 3afd1ee..4952b66 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c @@ -34,7 +34,7 @@ static inline void ccw_update_attr(u8 *dst, u8 *src, int attribute, msk <<= (8 - mod); if (offset > mod) - set_bit(FBCON_BIT(7), (void *)&msk1); + msk1 |= 0x01; for (i = 0; i < vc->vc_font.width; i++) { for (j = 0; j < width; j++) { diff --git a/drivers/video/console/fbcon_rotate.h b/drivers/video/console/fbcon_rotate.h index e504fbf..1b8f92f 100644 --- a/drivers/video/console/fbcon_rotate.h +++ b/drivers/video/console/fbcon_rotate.h @@ -21,21 +21,13 @@ (s == SCROLL_REDRAW || s == SCROLL_MOVE || !(i)->fix.xpanstep) ? \ (i)->var.xres : (i)->var.xres_virtual; }) -/* - * The bitmap is always big endian - */ -#if defined(__LITTLE_ENDIAN) -#define FBCON_BIT(b) (7 - (b)) -#else -#define FBCON_BIT(b) (b) -#endif static inline int pattern_test_bit(u32 x, u32 y, u32 pitch, const char *pat) { u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; pat +=index; - return (test_bit(FBCON_BIT(bit), (void *)pat)); + return (*pat) & (0x80 >> bit); } static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) @@ -43,7 +35,8 @@ static inline void pattern_set_bit(u32 x, u32 y, u32 pitch, char *pat) u32 tmp = (y * pitch) + x, index = tmp / 8, bit = tmp % 8; pat += index; - set_bit(FBCON_BIT(bit), (void *)pat); + + (*pat) |= 0x80 >> bit; } static inline void rotate_ud(const char *in, char *out, u32 width, u32 height) -- cgit v0.10.2 From 7729ac5efe156129d172784fedeaddb2167a1914 Mon Sep 17 00:00:00 2001 From: Oleg Drokin Date: Mon, 28 Nov 2005 13:43:53 -0800 Subject: [PATCH] reiserfs: fix 32-bit overflow in map_block_for_writepage() I now see another overflow in reiserfs that should lead to data corruptions with files that are bigger than 4G under certain circumstances when using mmap. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 5f82352b..0a044ad 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -2194,7 +2194,7 @@ static int map_block_for_writepage(struct inode *inode, INITIALIZE_PATH(path); int pos_in_item; int jbegin_count = JOURNAL_PER_BALANCE_CNT; - loff_t byte_offset = (block << inode->i_sb->s_blocksize_bits) + 1; + loff_t byte_offset = ((loff_t)block << inode->i_sb->s_blocksize_bits)+1; int retval; int use_get_block = 0; int bytes_copied = 0; -- cgit v0.10.2 From 46596338a10a54550ff03a6f60c28145a080296b Mon Sep 17 00:00:00 2001 From: Chris Humbert Date: Mon, 28 Nov 2005 13:43:54 -0800 Subject: [PATCH] fix broken lib/genalloc.c genalloc improperly stores the sizes of freed chunks, allocates overlapping memory regions, and oopses after its in-band data is overwritten. Signed-off-by: Chris Humbert Cc: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/lib/genalloc.c b/lib/genalloc.c index d6d30d2e..9ce0a6a 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -95,12 +95,10 @@ unsigned long gen_pool_alloc(struct gen_pool *poolp, int size) if (size > max_chunk_size) return 0; - i = 0; - size = max(size, 1 << ALLOC_MIN_SHIFT); - s = roundup_pow_of_two(size); - - j = i; + i = fls(size - 1); + s = 1 << i; + j = i -= ALLOC_MIN_SHIFT; spin_lock_irqsave(&poolp->lock, flags); while (!h[j].next) { @@ -153,10 +151,10 @@ void gen_pool_free(struct gen_pool *poolp, unsigned long ptr, int size) if (size > max_chunk_size) return; - i = 0; - size = max(size, 1 << ALLOC_MIN_SHIFT); - s = roundup_pow_of_two(size); + i = fls(size - 1); + s = 1 << i; + i -= ALLOC_MIN_SHIFT; a = ptr; -- cgit v0.10.2 From ee500f274914653a7d3dfca7d0140a3d21658e32 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Mon, 28 Nov 2005 13:43:55 -0800 Subject: [PATCH] fix 32bit overflow in timespec_to_sample() fix 32bit overflow in timespec_to_sample() Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 84af54c..cae4f57 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -36,7 +36,7 @@ timespec_to_sample(clockid_t which_clock, const struct timespec *tp) union cpu_time_count ret; ret.sched = 0; /* high half always zero when .cpu used */ if (CPUCLOCK_WHICH(which_clock) == CPUCLOCK_SCHED) { - ret.sched = tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec; + ret.sched = (unsigned long long)tp->tv_sec * NSEC_PER_SEC + tp->tv_nsec; } else { ret.cpu = timespec_to_cputime(tp); } -- cgit v0.10.2 From bce61dd49d6ba7799be2de17c772e4c701558f14 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Mon, 28 Nov 2005 13:43:56 -0800 Subject: [PATCH] Fix hardcoded cpu=0 in workqueue for per_cpu_ptr() calls Tracked this down on an Ultra Enterprise 3000. It's a 6-way machine. Odd thing about this machine (and it's good for finding bugs like this) is that the CPU id's are not 0 based. For instance, on my machine the CPU's are 6/7/10/11/14/15. This caused some NULL pointer dereference in kernel/workqueue.c because for single_threaded workqueue's, it hardcoded the cpu to 0. I changed the 0's to any_online_cpu(cpu_online_mask), which cpumask.h claims is "First cpu in mask". So this fits the same usage. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 42df83d..2bd5aee 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -102,7 +102,7 @@ int fastcall queue_work(struct workqueue_struct *wq, struct work_struct *work) if (!test_and_set_bit(0, &work->pending)) { if (unlikely(is_single_threaded(wq))) - cpu = 0; + cpu = any_online_cpu(cpu_online_map); BUG_ON(!list_empty(&work->entry)); __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); ret = 1; @@ -118,7 +118,7 @@ static void delayed_work_timer_fn(unsigned long __data) int cpu = smp_processor_id(); if (unlikely(is_single_threaded(wq))) - cpu = 0; + cpu = any_online_cpu(cpu_online_map); __queue_work(per_cpu_ptr(wq->cpu_wq, cpu), work); } @@ -266,8 +266,8 @@ void fastcall flush_workqueue(struct workqueue_struct *wq) might_sleep(); if (is_single_threaded(wq)) { - /* Always use cpu 0's area. */ - flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, 0)); + /* Always use first cpu's area. */ + flush_cpu_workqueue(per_cpu_ptr(wq->cpu_wq, any_online_cpu(cpu_online_map))); } else { int cpu; @@ -320,7 +320,7 @@ struct workqueue_struct *__create_workqueue(const char *name, lock_cpu_hotplug(); if (singlethread) { INIT_LIST_HEAD(&wq->list); - p = create_workqueue_thread(wq, 0); + p = create_workqueue_thread(wq, any_online_cpu(cpu_online_map)); if (!p) destroy = 1; else @@ -374,7 +374,7 @@ void destroy_workqueue(struct workqueue_struct *wq) /* We don't need the distraction of CPUs appearing and vanishing. */ lock_cpu_hotplug(); if (is_single_threaded(wq)) - cleanup_workqueue_thread(wq, 0); + cleanup_workqueue_thread(wq, any_online_cpu(cpu_online_map)); else { for_each_online_cpu(cpu) cleanup_workqueue_thread(wq, cpu); -- cgit v0.10.2 From 91f4ab056d85d23fa6955927fdeb1558673e8cd1 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Mon, 28 Nov 2005 13:43:58 -0800 Subject: [PATCH] m32r: Fix sys_tas() syscall This patch fixes a deadlock problem of the m32r SMP kernel. In the m32r kernel, sys_tas() system call is provided as a test-and-set function for userspace, for backward compatibility. In some multi-threading application program, deadlocks were rarely caused at sys_tas() funcion. Such a deadlock was caused due to a collision of __pthread_lock() and __pthread_unlock() operations. The "tas" syscall is repeatedly called by pthread_mutex_lock() to get a lock, while a lock variable's value is not 0. On the other hand, pthead_mutex_unlock() sets the lock variable to 0 for unlocking. In the previous implementation of sys_tas() routine, there was a possibility that a unlock operation was ignored in the following case: - Assume a lock variable (*addr) was equal to 1 before sys_tas() execution. - __pthread_unlock() operation is executed by the other processor and the lock variable (*addr) is set to 0, between a read operation ("oldval = *addr;") and the following write operation ("*addr = 1;") during a execution of sys_tas(). In this case, the following write operation ("*addr = 1;") overwrites the __pthread_unlock() result, and sys_tas() fails to get a lock in the next turn and after that. According to the attatched patch, sys_tas() returns 0 value in the next turn and deadlocks never happen. Signed-off-by: Hitoshi Yamamoto Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/m32r/kernel/sys_m32r.c b/arch/m32r/kernel/sys_m32r.c index e0500e1..fe55b28 100644 --- a/arch/m32r/kernel/sys_m32r.c +++ b/arch/m32r/kernel/sys_m32r.c @@ -41,7 +41,8 @@ asmlinkage int sys_tas(int *addr) return -EFAULT; local_irq_save(flags); oldval = *addr; - *addr = 1; + if (!oldval) + *addr = 1; local_irq_restore(flags); return oldval; } @@ -59,7 +60,8 @@ asmlinkage int sys_tas(int *addr) _raw_spin_lock(&tas_lock); oldval = *addr; - *addr = 1; + if (!oldval) + *addr = 1; _raw_spin_unlock(&tas_lock); return oldval; -- cgit v0.10.2 From 0332db5aff3eec73eead6d991782b0dee1376dc0 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Mon, 28 Nov 2005 13:43:59 -0800 Subject: [PATCH] m32r: Introduce atomic_cmpxchg and atomic_inc_not_zero operations Introduce atomic_cmpxchg and atomic_inc_not_zero operations for m32r. Signed-off-by: Hayato Fujiwara Signed-off-by: Hirokazu Takata Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/asm-m32r/atomic.h b/include/asm-m32r/atomic.h index bfff69a..ef1fb8e 100644 --- a/include/asm-m32r/atomic.h +++ b/include/asm-m32r/atomic.h @@ -242,6 +242,27 @@ static __inline__ int atomic_dec_return(atomic_t *v) */ #define atomic_add_negative(i,v) (atomic_add_return((i), (v)) < 0) +#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) + +/** + * atomic_add_unless - add unless the number is a given value + * @v: pointer of type atomic_t + * @a: the amount to add to v... + * @u: ...unless v is equal to u. + * + * Atomically adds @a to @v, so long as it was not @u. + * Returns non-zero if @v was not @u, and zero otherwise. + */ +#define atomic_add_unless(v, a, u) \ +({ \ + int c, old; \ + c = atomic_read(v); \ + while (c != (u) && (old = atomic_cmpxchg((v), c, c + (a))) != c) \ + c = old; \ + c != (u); \ +}) +#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) + static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t *addr) { unsigned long flags; diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h index 73348c3..5eee832 100644 --- a/include/asm-m32r/system.h +++ b/include/asm-m32r/system.h @@ -11,6 +11,7 @@ */ #include +#include #ifdef __KERNEL__ @@ -132,8 +133,6 @@ static inline void local_irq_disable(void) !(flags & 0x40); \ }) -#endif /* __KERNEL__ */ - #define nop() __asm__ __volatile__ ("nop" : : ) #define xchg(ptr,x) \ @@ -213,6 +212,67 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, return (tmp); } +#define __HAVE_ARCH_CMPXCHG 1 + +static __inline__ unsigned long +__cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) +{ + unsigned long flags; + unsigned int retval; + + local_irq_save(flags); + __asm__ __volatile__ ( + DCACHE_CLEAR("%0", "r4", "%1") + M32R_LOCK" %0, @%1; \n" + " bne %0, %2, 1f; \n" + M32R_UNLOCK" %3, @%1; \n" + " bra 2f; \n" + " .fillinsn \n" + "1:" + M32R_UNLOCK" %2, @%1; \n" + " .fillinsn \n" + "2:" + : "=&r" (retval) + : "r" (p), "r" (old), "r" (new) + : "cbit", "memory" +#ifdef CONFIG_CHIP_M32700_TS1 + , "r4" +#endif /* CONFIG_CHIP_M32700_TS1 */ + ); + local_irq_restore(flags); + + return retval; +} + +/* This function doesn't exist, so you'll get a linker error + if something tries to do an invalid cmpxchg(). */ +extern void __cmpxchg_called_with_bad_pointer(void); + +static __inline__ unsigned long +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) +{ + switch (size) { + case 4: + return __cmpxchg_u32(ptr, old, new); +#if 0 /* we don't have __cmpxchg_u64 */ + case 8: + return __cmpxchg_u64(ptr, old, new); +#endif /* 0 */ + } + __cmpxchg_called_with_bad_pointer(); + return old; +} + +#define cmpxchg(ptr,o,n) \ + ({ \ + __typeof__(*(ptr)) _o_ = (o); \ + __typeof__(*(ptr)) _n_ = (n); \ + (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ + (unsigned long)_n_, sizeof(*(ptr))); \ + }) + +#endif /* __KERNEL__ */ + /* * Memory barrier. * -- cgit v0.10.2 From ad09d583106fadfdf751926107cfe35fba6bdbd4 Mon Sep 17 00:00:00 2001 From: Hirokazu Takata Date: Mon, 28 Nov 2005 13:44:00 -0800 Subject: [PATCH] m32r: M3A-2170(Mappi-III) IDE support This patch is for supporting IDE interface for M3A-2170(Mappi-III) board. Signed-off-by: Mamoru Sakugawa Signed-off-by: Hirokazu Takata Cc: Bartlomiej Zolnierkiewicz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c index 6716ffe..f80321a 100644 --- a/arch/m32r/kernel/io_mappi3.c +++ b/arch/m32r/kernel/io_mappi3.c @@ -36,12 +36,13 @@ static inline void *_port2addr(unsigned long port) return (void *)(port + NONCACHE_OFFSET); } -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) +#if defined(CONFIG_IDE) static inline void *__port2addr_ata(unsigned long port) { static int dummy_reg; switch (port) { + /* IDE0 CF */ case 0x1f0: return (void *)0xb4002000; case 0x1f1: return (void *)0xb4012800; case 0x1f2: return (void *)0xb4012002; @@ -51,6 +52,17 @@ static inline void *__port2addr_ata(unsigned long port) case 0x1f6: return (void *)0xb4012006; case 0x1f7: return (void *)0xb4012806; case 0x3f6: return (void *)0xb401200e; + /* IDE1 IDE */ + case 0x170: return (void *)0xb4810000; /* Data 16bit */ + case 0x171: return (void *)0xb4810002; /* Features / Error */ + case 0x172: return (void *)0xb4810004; /* Sector count */ + case 0x173: return (void *)0xb4810006; /* Sector number */ + case 0x174: return (void *)0xb4810008; /* Cylinder low */ + case 0x175: return (void *)0xb481000a; /* Cylinder high */ + case 0x176: return (void *)0xb481000c; /* Device head */ + case 0x177: return (void *)0xb481000e; /* Command */ + case 0x376: return (void *)0xb480800c; /* Device control / Alt status */ + default: return (void *)&dummy_reg; } } @@ -108,8 +120,9 @@ unsigned char _inb(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inb(PORT2ADDR_NE(port)); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ return *(volatile unsigned char *)__port2addr_ata(port); } #endif @@ -127,8 +140,9 @@ unsigned short _inw(unsigned long port) { if (port >= LAN_IOSTART && port < LAN_IOEND) return _ne_inw(PORT2ADDR_NE(port)); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ return *(volatile unsigned short *)__port2addr_ata(port); } #endif @@ -185,8 +199,9 @@ void _outb(unsigned char b, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outb(b, PORT2ADDR_NE(port)); else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ *(volatile unsigned char *)__port2addr_ata(port) = b; } else #endif @@ -203,8 +218,9 @@ void _outw(unsigned short w, unsigned long port) if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_outw(w, PORT2ADDR_NE(port)); else -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ *(volatile unsigned short *)__port2addr_ata(port) = w; } else #endif @@ -253,8 +269,9 @@ void _insb(unsigned int port, void * addr, unsigned long count) { if (port >= LAN_IOSTART && port < LAN_IOEND) _ne_insb(PORT2ADDR_NE(port), addr, count); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ unsigned char *buf = addr; unsigned char *portp = __port2addr_ata(port); while (count--) @@ -289,8 +306,9 @@ void _insw(unsigned int port, void * addr, unsigned long count) pcc_ioread_word(9, port, (void *)addr, sizeof(unsigned short), count, 1); #endif -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ portp = __port2addr_ata(port); while (count--) *buf++ = *(volatile unsigned short *)portp; @@ -321,8 +339,9 @@ void _outsb(unsigned int port, const void * addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) _ne_outb(*buf++, portp); -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ portp = __port2addr_ata(port); while (count--) *(volatile unsigned char *)portp = *buf++; @@ -348,8 +367,9 @@ void _outsw(unsigned int port, const void * addr, unsigned long count) portp = PORT2ADDR_NE(port); while (count--) *(volatile unsigned short *)portp = *buf++; -#if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC) - } else if ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) { +#if defined(CONFIG_IDE) + } else if ( ((port >= 0x170 && port <=0x177) || port == 0x376) || + ((port >= 0x1f0 && port <=0x1f7) || port == 0x3f6) ){ portp = __port2addr_ata(port); while (count--) *(volatile unsigned short *)portp = *buf++; diff --git a/arch/m32r/kernel/setup_mappi3.c b/arch/m32r/kernel/setup_mappi3.c index 9c79341..f6ecdf7 100644 --- a/arch/m32r/kernel/setup_mappi3.c +++ b/arch/m32r/kernel/setup_mappi3.c @@ -151,7 +151,7 @@ void __init init_IRQ(void) disable_mappi3_irq(M32R_IRQ_INT1); #endif /* CONFIG_USB */ - /* ICUCR40: CFC IREQ */ + /* CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; @@ -160,7 +160,7 @@ void __init init_IRQ(void) disable_mappi3_irq(PLD_IRQ_CFIREQ); #if defined(CONFIG_M32R_CFC) - /* ICUCR41: CFC Insert */ + /* ICUCR41: CFC Insert & eject */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; @@ -168,14 +168,16 @@ void __init init_IRQ(void) icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; disable_mappi3_irq(PLD_IRQ_CFC_INSERT); - /* ICUCR42: CFC Eject */ - irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi3_irq_type; - irq_desc[PLD_IRQ_CFC_EJECT].action = 0; - irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ - icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; - disable_mappi3_irq(PLD_IRQ_CFC_EJECT); #endif /* CONFIG_M32R_CFC */ + + /* IDE IREQ */ + irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; + irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_IDEIREQ].action = 0; + irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ + icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; + disable_mappi3_irq(PLD_IRQ_IDEIREQ); + } #if defined(CONFIG_SMC91X) diff --git a/drivers/pcmcia/m32r_cfc.c b/drivers/pcmcia/m32r_cfc.c index 2c22b4b..078579a 100644 --- a/drivers/pcmcia/m32r_cfc.c +++ b/drivers/pcmcia/m32r_cfc.c @@ -355,9 +355,10 @@ static void add_pcc_socket(ulong base, int irq, ulong mapaddr, kio_addr_t ioaddr #ifndef CONFIG_PLAT_USRV /* insert interrupt */ request_irq(irq, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt); +#ifndef CONFIG_PLAT_MAPPI3 /* eject interrupt */ request_irq(irq+1, pcc_interrupt, 0, "m32r_cfc", pcc_interrupt); - +#endif debug(3, "m32r_cfc: enable CFMSK, RDYSEL\n"); pcc_set(pcc_sockets, (unsigned int)PLD_CFIMASK, 0x01); #endif /* CONFIG_PLAT_USRV */ diff --git a/include/asm-m32r/ide.h b/include/asm-m32r/ide.h index 194393b..f7aa969 100644 --- a/include/asm-m32r/ide.h +++ b/include/asm-m32r/ide.h @@ -25,18 +25,21 @@ # endif #endif -#if defined(CONFIG_PLAT_M32700UT) -#include -#include -#endif +#include + #define IDE_ARCH_OBSOLETE_DEFAULTS static __inline__ int ide_default_irq(unsigned long base) { switch (base) { -#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || defined(CONFIG_PLAT_MAPPI3) +#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) + case 0x1f0: return PLD_IRQ_CFIREQ; + default: + return 0; +#elif defined(CONFIG_PLAT_MAPPI3) case 0x1f0: return PLD_IRQ_CFIREQ; + case 0x170: return PLD_IRQ_IDEIREQ; default: return 0; #else diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h index 3f1551f..1d3c25d 100644 --- a/include/asm-m32r/mappi3/mappi3_pld.h +++ b/include/asm-m32r/mappi3/mappi3_pld.h @@ -59,7 +59,7 @@ #define M32R_IRQ_I2C (28) /* I2C-BUS */ #define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ #define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert */ -#define PLD_IRQ_CFC_EJECT (8) /* INT7 CFC Card Eject */ +#define PLD_IRQ_IDEIREQ (8) /* INT7 IDE Interrupt */ #define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ #define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ -- cgit v0.10.2 From aa877b3dc9f2a1fdffac4ea36bee97c21db11a69 Mon Sep 17 00:00:00 2001 From: Glauber de Oliveira Costa Date: Mon, 28 Nov 2005 13:44:02 -0800 Subject: [PATCH] ext3: Wrong return value for EXT3_IOC_GROUP_ADD This patch corrects the return value for the EXT3_IOC_GROUP_ADD in case it fails due to the presence of multiple resizers at the filesystem. The problem is a little bit more serious than a wrong return value in this case, since the clause err=0 in the exit_journal path will lead to a call to update_backups which in turns causes a NULL pointer dereference. Signed-off-by: Glauber de Oliveira Costa Cc: "Stephen C. Tweedie" Cc: Andreas Dilger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 1be78b4b..6104ad3 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c @@ -767,6 +767,7 @@ int ext3_group_add(struct super_block *sb, struct ext3_new_group_data *input) if (input->group != EXT3_SB(sb)->s_groups_count) { ext3_warning(sb, __FUNCTION__, "multiple resizers run on filesystem!\n"); + err = -EBUSY; goto exit_journal; } -- cgit v0.10.2 From 3148890bfa4f36c9949871264e06ef4d449eeff9 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Mon, 28 Nov 2005 13:44:03 -0800 Subject: [PATCH] mm: __alloc_pages cleanup fix I believe this patch is required to fix breakage in the asynch reclaim watermark logic introduced by this patch: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7fb1d9fca5c6e3b06773b69165a73f3fb786b8ee Just some background of the watermark logic in case it isn't clear... Basically what we have is this: --- pages_high | | (a) | --- pages_low | | (b) | --- pages_min | | (c) | --- 0 Now when pages_low is reached, we want to kick asynch reclaim, which gives us an interval of "b" before we must start synch reclaim, and gives kswapd an interval of "a" before it need go back to sleep. When pages_min is reached, normal allocators must enter synch reclaim, but PF_MEMALLOC, ALLOC_HARDER, and ALLOC_HIGH (ie. atomic allocations, recursive allocations, etc.) get access to varying amounts of the reserve "c". Signed-off-by: Nick Piggin Cc: "Seth, Rohit" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 1731236..b257720 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -773,9 +773,12 @@ again: } #define ALLOC_NO_WATERMARKS 0x01 /* don't check watermarks at all */ -#define ALLOC_HARDER 0x02 /* try to alloc harder */ -#define ALLOC_HIGH 0x04 /* __GFP_HIGH set */ -#define ALLOC_CPUSET 0x08 /* check for correct cpuset */ +#define ALLOC_WMARK_MIN 0x02 /* use pages_min watermark */ +#define ALLOC_WMARK_LOW 0x04 /* use pages_low watermark */ +#define ALLOC_WMARK_HIGH 0x08 /* use pages_high watermark */ +#define ALLOC_HARDER 0x10 /* try to alloc harder */ +#define ALLOC_HIGH 0x20 /* __GFP_HIGH set */ +#define ALLOC_CPUSET 0x40 /* check for correct cpuset */ /* * Return 1 if free pages are above 'mark'. This takes into account the order @@ -830,7 +833,14 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, continue; if (!(alloc_flags & ALLOC_NO_WATERMARKS)) { - if (!zone_watermark_ok(*z, order, (*z)->pages_low, + unsigned long mark; + if (alloc_flags & ALLOC_WMARK_MIN) + mark = (*z)->pages_min; + else if (alloc_flags & ALLOC_WMARK_LOW) + mark = (*z)->pages_low; + else + mark = (*z)->pages_high; + if (!zone_watermark_ok(*z, order, mark, classzone_idx, alloc_flags)) continue; } @@ -871,7 +881,7 @@ restart: } page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, - zonelist, ALLOC_CPUSET); + zonelist, ALLOC_WMARK_LOW|ALLOC_CPUSET); if (page) goto got_pg; @@ -888,7 +898,7 @@ restart: * cannot run direct reclaim, or if the caller has realtime scheduling * policy. */ - alloc_flags = 0; + alloc_flags = ALLOC_WMARK_MIN; if ((unlikely(rt_task(p)) && !in_interrupt()) || !wait) alloc_flags |= ALLOC_HARDER; if (gfp_mask & __GFP_HIGH) @@ -959,7 +969,7 @@ rebalance: * under heavy pressure. */ page = get_page_from_freelist(gfp_mask|__GFP_HARDWALL, order, - zonelist, ALLOC_CPUSET); + zonelist, ALLOC_WMARK_HIGH|ALLOC_CPUSET); if (page) goto got_pg; -- cgit v0.10.2 From 8c4b8add83c93306b07d78469fd351dc462e4b66 Mon Sep 17 00:00:00 2001 From: Paul Jackson Date: Mon, 28 Nov 2005 13:44:05 -0800 Subject: [PATCH] cpuset fork locking fix Move the cpuset_fork() call below the write_unlock_irq call in kernel/fork.c copy_process(). Since the cpuset-dual-semaphore-locking-overhaul.patch, the cpuset_fork() routine acquires task_lock(), so cannot be called while holding the tasklist_lock for write. Signed-off-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/fork.c b/kernel/fork.c index d0d4987..fb8572a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1124,8 +1124,6 @@ static task_t *copy_process(unsigned long clone_flags, if (unlikely(p->ptrace & PT_PTRACED)) __ptrace_link(p, current->parent); - cpuset_fork(p); - attach_pid(p, PIDTYPE_PID, p->pid); attach_pid(p, PIDTYPE_TGID, p->tgid); if (thread_group_leader(p)) { @@ -1142,6 +1140,7 @@ static task_t *copy_process(unsigned long clone_flags, total_forks++; write_unlock_irq(&tasklist_lock); proc_fork_connector(p); + cpuset_fork(p); retval = 0; fork_out: -- cgit v0.10.2 From a93a117eaa0bec426d4671a49bfa96a6fdcd2ac9 Mon Sep 17 00:00:00 2001 From: Latchesar Ionkov Date: Mon, 28 Nov 2005 13:44:05 -0800 Subject: [PATCH] v9fs: fix memory leak in v9fs dentry code Assign the appropriate dentry operations to the dentry. Fixes memory leak. Signed-off-by: Latchesar Ionkov Cc: Eric Van Hensbergen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index be72881..0ea965c 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c @@ -427,6 +427,8 @@ v9fs_create(struct inode *dir, v9fs_mistat2inode(fcall->params.rstat.stat, file_inode, sb); kfree(fcall); + fcall = NULL; + file_dentry->d_op = &v9fs_dentry_operations; d_instantiate(file_dentry, file_inode); if (perm & V9FS_DMDIR) { -- cgit v0.10.2 From f7b7fd8f3ebbb2810d6893295aa984acd0fd30db Mon Sep 17 00:00:00 2001 From: Rik van Riel Date: Mon, 28 Nov 2005 13:44:07 -0800 Subject: [PATCH] temporarily disable swap token on memory pressure Some users (hi Zwane) have seen a problem when running a workload that eats nearly all of physical memory - th system does an OOM kill, even when there is still a lot of swap free. The problem appears to be a very big task that is holding the swap token, and the VM has a very hard time finding any other page in the system that is swappable. Instead of ignoring the swap token when sc->priority reaches 0, we could simply take the swap token away from the memory hog and make sure we don't give it back to the memory hog for a few seconds. This patch resolves the problem Zwane ran into. Signed-off-by: Rik van Riel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 35b30e6..33261f1 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -89,7 +89,7 @@ static inline void page_dup_rmap(struct page *page) /* * Called from mm/vmscan.c to handle paging out */ -int page_referenced(struct page *, int is_locked, int ignore_token); +int page_referenced(struct page *, int is_locked); int try_to_unmap(struct page *); /* @@ -109,7 +109,7 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); #define anon_vma_prepare(vma) (0) #define anon_vma_link(vma) do {} while (0) -#define page_referenced(page,l,i) TestClearPageReferenced(page) +#define page_referenced(page,l) TestClearPageReferenced(page) #define try_to_unmap(page) SWAP_FAIL #endif /* CONFIG_MMU */ diff --git a/include/linux/swap.h b/include/linux/swap.h index 20c9756..508668f 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -239,6 +239,11 @@ static inline void put_swap_token(struct mm_struct *mm) __put_swap_token(mm); } +static inline void disable_swap_token(void) +{ + put_swap_token(swap_token_mm); +} + #else /* CONFIG_SWAP */ #define total_swap_pages 0 @@ -283,6 +288,7 @@ static inline swp_entry_t get_swap_page(void) #define put_swap_token(x) do { } while(0) #define grab_swap_token() do { } while(0) #define has_swap_token(x) 0 +#define disable_swap_token() do { } while(0) #endif /* CONFIG_SWAP */ #endif /* __KERNEL__*/ diff --git a/mm/rmap.c b/mm/rmap.c index 6389cda..491ac35 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -290,7 +290,7 @@ pte_t *page_check_address(struct page *page, struct mm_struct *mm, * repeatedly from either page_referenced_anon or page_referenced_file. */ static int page_referenced_one(struct page *page, - struct vm_area_struct *vma, unsigned int *mapcount, int ignore_token) + struct vm_area_struct *vma, unsigned int *mapcount) { struct mm_struct *mm = vma->vm_mm; unsigned long address; @@ -311,7 +311,7 @@ static int page_referenced_one(struct page *page, /* Pretend the page is referenced if the task has the swap token and is in the middle of a page fault. */ - if (mm != current->mm && !ignore_token && has_swap_token(mm) && + if (mm != current->mm && has_swap_token(mm) && rwsem_is_locked(&mm->mmap_sem)) referenced++; @@ -321,7 +321,7 @@ out: return referenced; } -static int page_referenced_anon(struct page *page, int ignore_token) +static int page_referenced_anon(struct page *page) { unsigned int mapcount; struct anon_vma *anon_vma; @@ -334,8 +334,7 @@ static int page_referenced_anon(struct page *page, int ignore_token) mapcount = page_mapcount(page); list_for_each_entry(vma, &anon_vma->head, anon_vma_node) { - referenced += page_referenced_one(page, vma, &mapcount, - ignore_token); + referenced += page_referenced_one(page, vma, &mapcount); if (!mapcount) break; } @@ -354,7 +353,7 @@ static int page_referenced_anon(struct page *page, int ignore_token) * * This function is only called from page_referenced for object-based pages. */ -static int page_referenced_file(struct page *page, int ignore_token) +static int page_referenced_file(struct page *page) { unsigned int mapcount; struct address_space *mapping = page->mapping; @@ -392,8 +391,7 @@ static int page_referenced_file(struct page *page, int ignore_token) referenced++; break; } - referenced += page_referenced_one(page, vma, &mapcount, - ignore_token); + referenced += page_referenced_one(page, vma, &mapcount); if (!mapcount) break; } @@ -410,13 +408,10 @@ static int page_referenced_file(struct page *page, int ignore_token) * Quick test_and_clear_referenced for all mappings to a page, * returns the number of ptes which referenced the page. */ -int page_referenced(struct page *page, int is_locked, int ignore_token) +int page_referenced(struct page *page, int is_locked) { int referenced = 0; - if (!swap_token_default_timeout) - ignore_token = 1; - if (page_test_and_clear_young(page)) referenced++; @@ -425,15 +420,14 @@ int page_referenced(struct page *page, int is_locked, int ignore_token) if (page_mapped(page) && page->mapping) { if (PageAnon(page)) - referenced += page_referenced_anon(page, ignore_token); + referenced += page_referenced_anon(page); else if (is_locked) - referenced += page_referenced_file(page, ignore_token); + referenced += page_referenced_file(page); else if (TestSetPageLocked(page)) referenced++; else { if (page->mapping) - referenced += page_referenced_file(page, - ignore_token); + referenced += page_referenced_file(page); unlock_page(page); } } diff --git a/mm/thrash.c b/mm/thrash.c index eff3c18..f4c560b 100644 --- a/mm/thrash.c +++ b/mm/thrash.c @@ -57,14 +57,17 @@ void grab_swap_token(void) /* We have the token. Let others know we still need it. */ if (has_swap_token(current->mm)) { current->mm->recent_pagein = 1; + if (unlikely(!swap_token_default_timeout)) + disable_swap_token(); return; } if (time_after(jiffies, swap_token_check)) { - /* Can't get swapout protection if we exceed our RSS limit. */ - // if (current->mm->rss > current->mm->rlimit_rss) - // return; + if (!swap_token_default_timeout) { + swap_token_check = jiffies + SWAP_TOKEN_CHECK_INTERVAL; + return; + } /* ... or if we recently held the token. */ if (time_before(jiffies, current->mm->swap_token_time)) @@ -95,6 +98,7 @@ void __put_swap_token(struct mm_struct *mm) { spin_lock(&swap_token_lock); if (likely(mm == swap_token_mm)) { + mm->swap_token_time = jiffies + SWAP_TOKEN_CHECK_INTERVAL; swap_token_mm = &init_mm; swap_token_check = jiffies; } diff --git a/mm/vmscan.c b/mm/vmscan.c index 2813054..078cf92 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -407,7 +407,7 @@ static int shrink_list(struct list_head *page_list, struct scan_control *sc) if (PageWriteback(page)) goto keep_locked; - referenced = page_referenced(page, 1, sc->priority <= 0); + referenced = page_referenced(page, 1); /* In active use or really unfreeable? Activate it. */ if (referenced && page_mapping_inuse(page)) goto activate_locked; @@ -756,7 +756,7 @@ refill_inactive_zone(struct zone *zone, struct scan_control *sc) if (page_mapped(page)) { if (!reclaim_mapped || (total_swap_pages == 0 && PageAnon(page)) || - page_referenced(page, 0, sc->priority <= 0)) { + page_referenced(page, 0)) { list_add(&page->lru, &l_active); continue; } @@ -960,6 +960,8 @@ int try_to_free_pages(struct zone **zones, gfp_t gfp_mask) sc.nr_reclaimed = 0; sc.priority = priority; sc.swap_cluster_max = SWAP_CLUSTER_MAX; + if (!priority) + disable_swap_token(); shrink_caches(zones, &sc); shrink_slab(sc.nr_scanned, gfp_mask, lru_pages); if (reclaim_state) { @@ -1056,6 +1058,10 @@ loop_again: int end_zone = 0; /* Inclusive. 0 = ZONE_DMA */ unsigned long lru_pages = 0; + /* The swap token gets in the way of swapout... */ + if (!priority) + disable_swap_token(); + all_zones_ok = 1; if (nr_pages == 0) { @@ -1360,6 +1366,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) sc.nr_reclaimed = 0; /* scan at the highest priority */ sc.priority = 0; + disable_swap_token(); if (nr_pages > SWAP_CLUSTER_MAX) sc.swap_cluster_max = nr_pages; -- cgit v0.10.2 From 20c5ab6821b3a7aad31fb5a4660e9fe414fb37f6 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Mon, 28 Nov 2005 13:44:08 -0800 Subject: [PATCH] fix broken hybrid v4l-dvb frontend selection Repair broken build configuration for hybrid v4l/dvb card frontend selection. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 1a3b3c7..ecb9a31 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -26,7 +26,7 @@ config VIDEO_BT848 module will be called bttv. config VIDEO_BT848_DVB - tristate "DVB/ATSC Support for bt878 based TV cards" + bool "DVB/ATSC Support for bt878 based TV cards" depends on VIDEO_BT848 && DVB_CORE select DVB_BT8XX ---help--- diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 41818b6..85ba410 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig @@ -46,8 +46,8 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS If you are unsure, choose Y. config VIDEO_CX88_DVB_MT352 - tristate "Zarlink MT352 DVB-T Support" - default m + bool "Zarlink MT352 DVB-T Support" + default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_MT352 ---help--- @@ -55,8 +55,8 @@ config VIDEO_CX88_DVB_MT352 Connexant 2388x chip and the MT352 demodulator. config VIDEO_CX88_DVB_OR51132 - tristate "OR51132 ATSC Support" - default m + bool "OR51132 ATSC Support" + default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_OR51132 ---help--- @@ -64,8 +64,8 @@ config VIDEO_CX88_DVB_OR51132 Connexant 2388x chip and the OR51132 demodulator. config VIDEO_CX88_DVB_CX22702 - tristate "Conexant CX22702 DVB-T Support" - default m + bool "Conexant CX22702 DVB-T Support" + default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_CX22702 ---help--- @@ -73,8 +73,8 @@ config VIDEO_CX88_DVB_CX22702 Connexant 2388x chip and the CX22702 demodulator. config VIDEO_CX88_DVB_LGDT330X - tristate "LG Electronics DT3302/DT3303 ATSC Support" - default m + bool "LG Electronics DT3302/DT3303 ATSC Support" + default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_LGDT330X ---help--- @@ -82,8 +82,8 @@ config VIDEO_CX88_DVB_LGDT330X Connexant 2388x chip and the LGDT3302/LGDT3303 demodulator. config VIDEO_CX88_DVB_NXT200X - tristate "NXT2002/NXT2004 ATSC Support" - default m + bool "NXT2002/NXT2004 ATSC Support" + default y depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS select DVB_NXT200X ---help--- diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 0df40b7..54401b0 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile @@ -9,21 +9,12 @@ obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o EXTRA_CFLAGS += -I$(src)/.. EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends -ifneq ($(CONFIG_VIDEO_BUF_DVB),n) - EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1 -endif -ifneq ($(CONFIG_DVB_CX22702),n) - EXTRA_CFLAGS += -DHAVE_CX22702=1 -endif -ifneq ($(CONFIG_DVB_OR51132),n) - EXTRA_CFLAGS += -DHAVE_OR51132=1 -endif -ifneq ($(CONFIG_DVB_LGDT330X),n) - EXTRA_CFLAGS += -DHAVE_LGDT330X=1 -endif -ifneq ($(CONFIG_DVB_MT352),n) - EXTRA_CFLAGS += -DHAVE_MT352=1 -endif -ifneq ($(CONFIG_DVB_NXT200X),n) - EXTRA_CFLAGS += -DHAVE_NXT200X=1 -endif + +extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 +extra-cflags-$(CONFIG_DVB_CX22702) += -DHAVE_CX22702=1 +extra-cflags-$(CONFIG_DVB_OR51132) += -DHAVE_OR51132=1 +extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 +extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 +extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 + +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig index 7bdeabe..c512c44 100644 --- a/drivers/media/video/saa7134/Kconfig +++ b/drivers/media/video/saa7134/Kconfig @@ -42,8 +42,8 @@ config VIDEO_SAA7134_DVB_ALL_FRONTENDS If you are unsure, choose Y. config VIDEO_SAA7134_DVB_MT352 - tristate "Zarlink MT352 DVB-T Support" - default m + bool "Zarlink MT352 DVB-T Support" + default y depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS select DVB_MT352 ---help--- @@ -51,8 +51,8 @@ config VIDEO_SAA7134_DVB_MT352 Philips saa7134 chip and the MT352 demodulator. config VIDEO_SAA7134_DVB_TDA1004X - tristate "Phillips TDA10045H/TDA10046H DVB-T Support" - default m + bool "Phillips TDA10045H/TDA10046H DVB-T Support" + default y depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS select DVB_TDA1004X ---help--- @@ -60,8 +60,8 @@ config VIDEO_SAA7134_DVB_TDA1004X Philips saa7134 chip and the TDA10045H/TDA10046H demodulator. config VIDEO_SAA7134_DVB_NXT200X - tristate "NXT2002/NXT2004 ATSC Support" - default m + bool "NXT2002/NXT2004 ATSC Support" + default y depends on VIDEO_SAA7134_DVB && !VIDEO_SAA7134_DVB_ALL_FRONTENDS select DVB_NXT200X ---help--- diff --git a/drivers/media/video/saa7134/Makefile b/drivers/media/video/saa7134/Makefile index 4226b61..134f83a 100644 --- a/drivers/media/video/saa7134/Makefile +++ b/drivers/media/video/saa7134/Makefile @@ -11,15 +11,10 @@ obj-$(CONFIG_VIDEO_SAA7134_DVB) += saa7134-dvb.o EXTRA_CFLAGS += -I$(src)/.. EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/frontends -ifneq ($(CONFIG_VIDEO_BUF_DVB),n) - EXTRA_CFLAGS += -DHAVE_VIDEO_BUF_DVB=1 -endif -ifneq ($(CONFIG_DVB_MT352),n) - EXTRA_CFLAGS += -DHAVE_MT352=1 -endif -ifneq ($(CONFIG_DVB_TDA1004X),n) - EXTRA_CFLAGS += -DHAVE_TDA1004X=1 -endif -ifneq ($(CONFIG_DVB_NXT200X),n) - EXTRA_CFLAGS += -DHAVE_NXT200X=1 -endif + +extra-cflags-$(CONFIG_VIDEO_BUF_DVB) += -DHAVE_VIDEO_BUF_DVB=1 +extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 +extra-cflags-$(CONFIG_DVB_TDA1004X) += -DHAVE_TDA1004X=1 +extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 + +EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) -- cgit v0.10.2 From 22dfdf5212e5864b844f629736fb993d4611f190 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 28 Nov 2005 13:44:09 -0800 Subject: [PATCH] md: improve read speed to raid10 arrays using 'far copies' raid10 has two different layouts. One uses near-copies (so multiple copies of a block are at the same or similar offsets of different devices) and the other uses far-copies (so multiple copies of a block are stored a greatly different offsets on different devices). The point of far-copies is that it allows the first section (normally first half) to be layed out in normal raid0 style, and thus provide raid0 sequential read performance. Unfortunately, the read balancing in raid10 makes some poor decisions for far-copies arrays and you don't get the desired performance. So turn off that bad bit of read_balance for far-copies arrays. With this patch, read speed of an 'f2' array is comparable with a raid0 with the same number of devices, though write speed is ofcourse still very slow. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 867f06a..713dc9c 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -552,7 +552,11 @@ static int read_balance(conf_t *conf, r10bio_t *r10_bio) !test_bit(In_sync, &rdev->flags)) continue; - if (!atomic_read(&rdev->nr_pending)) { + /* This optimisation is debatable, and completely destroys + * sequential read speed for 'far copies' arrays. So only + * keep it for 'near' arrays, and review those later. + */ + if (conf->near_copies > 1 && !atomic_read(&rdev->nr_pending)) { disk = ndisk; slot = nslot; break; -- cgit v0.10.2 From 700e432d8364ce59c521abbe03a522051610ebc2 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 28 Nov 2005 13:44:10 -0800 Subject: [PATCH] md: fix locking problem in r5/r6 bitmap_unplug actually writes data (bits) to storage, so we shouldn't be holding a spinlock... Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e2a4028..36d5f8a 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1704,7 +1704,9 @@ static void raid5d (mddev_t *mddev) if (conf->seq_flush - conf->seq_write > 0) { int seq = conf->seq_flush; + spin_unlock_irq(&conf->device_lock); bitmap_unplug(mddev->bitmap); + spin_lock_irq(&conf->device_lock); conf->seq_write = seq; activate_bit_delay(conf); } diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index eae5a35..17d88d9 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1784,7 +1784,9 @@ static void raid6d (mddev_t *mddev) if (conf->seq_flush - conf->seq_write > 0) { int seq = conf->seq_flush; + spin_unlock_irq(&conf->device_lock); bitmap_unplug(mddev->bitmap); + spin_lock_irq(&conf->device_lock); conf->seq_write = seq; activate_bit_delay(conf); } -- cgit v0.10.2 From b5ab28a3b81381103b686ff6b9d2f5fbb944bc8c Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 28 Nov 2005 13:44:11 -0800 Subject: [PATCH] md: fix problem with raid6 intent bitmap When doing a recovery, we need to know whether the array will still be degraded after the recovery has finished, so we can know whether bits can be clearred yet or not. This patch performs the required check. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 17d88d9..00da378 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -1702,6 +1702,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i int data_disks = raid_disks - 2; sector_t max_sector = mddev->size << 1; int sync_blocks; + int still_degraded = 0; + int i; if (sector_nr >= max_sector) { /* just being told to finish up .. nothing much to do */ @@ -1710,7 +1712,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i if (mddev->curr_resync < max_sector) /* aborted */ bitmap_end_sync(mddev->bitmap, mddev->curr_resync, &sync_blocks, 1); - else /* compelted sync */ + else /* completed sync */ conf->fullsync = 0; bitmap_close_sync(mddev->bitmap); @@ -1748,7 +1750,16 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i */ schedule_timeout_uninterruptible(1); } - bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 0); + /* Need to check if array will still be degraded after recovery/resync + * We don't need to check the 'failed' flag as when that gets set, + * recovery aborts. + */ + for (i=0; iraid_disks; i++) + if (conf->disks[i].rdev == NULL) + still_degraded = 1; + + bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, still_degraded); + spin_lock(&sh->lock); set_bit(STRIPE_SYNCING, &sh->state); clear_bit(STRIPE_INSYNC, &sh->state); -- cgit v0.10.2 From b2a2703c282ce77d189a250f58039daac1da3314 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 28 Nov 2005 13:44:12 -0800 Subject: [PATCH] md: set default_bitmap_offset properly in set_array_info If an array is created using set_array_info, default_bitmap_offset isn't set properly meaning that an internal bitmap cannot be hot-added until the array is stopped and re-assembled. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/md.c b/drivers/md/md.c index 78c7418..cd12fca 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1028,7 +1028,6 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) mddev->size = le64_to_cpu(sb->size)/2; mddev->events = le64_to_cpu(sb->events); mddev->bitmap_offset = 0; - mddev->default_bitmap_offset = 0; mddev->default_bitmap_offset = 1024; mddev->recovery_cp = le64_to_cpu(sb->resync_offset); @@ -2932,6 +2931,9 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) mddev->sb_dirty = 1; + mddev->default_bitmap_offset = MD_SB_BYTES >> 9; + mddev->bitmap_offset = 0; + /* * Generate a 128 bit UUID */ -- cgit v0.10.2 From 6aea114a728db9296f42102d4885e7fb035de0a9 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 28 Nov 2005 13:44:13 -0800 Subject: [PATCH] md: fix --re-add for raid1 and raid6 If you have an array with a write-intent-bitmap, and you remove a device, then re-add it, a full recovery isn't needed. We detect a re-add by looking at saved_raid_disk. For raid1, it doesn't matter which disk it was, only whether or not it was an active device. The old code being removed set a value of 'mirror' which was then ignored, so it can go. The changed code performs the correct check. For raid6, if there are two missing devices, make sure we chose the right slot on --re-add rather than always the first slot. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 2da9d3b..3066c58 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -953,9 +953,6 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) int mirror = 0; mirror_info_t *p; - if (rdev->saved_raid_disk >= 0 && - conf->mirrors[rdev->saved_raid_disk].rdev == NULL) - mirror = rdev->saved_raid_disk; for (mirror=0; mirror < mddev->raid_disks; mirror++) if ( !(p=conf->mirrors+mirror)->rdev) { @@ -972,7 +969,10 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) p->head_position = 0; rdev->raid_disk = mirror; found = 1; - if (rdev->saved_raid_disk != mirror) + /* As all devices are equivalent, we don't need a full recovery + * if this was recently any drive of the array + */ + if (rdev->saved_raid_disk < 0) conf->fullsync = 1; rcu_assign_pointer(p->rdev, rdev); break; diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 00da378..0000d16 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c @@ -2158,9 +2158,15 @@ static int raid6_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) /* no point adding a device */ return 0; /* - * find the disk ... + * find the disk ... but prefer rdev->saved_raid_disk + * if possible. */ - for (disk=0; disk < mddev->raid_disks; disk++) + if (rdev->saved_raid_disk >= 0 && + conf->disks[rdev->saved_raid_disk].rdev == NULL) + disk = rdev->saved_raid_disk; + else + disk = 0; + for ( ; disk < mddev->raid_disks; disk++) if ((p=conf->disks + disk)->rdev == NULL) { clear_bit(In_sync, &rdev->flags); rdev->raid_disk = disk; -- cgit v0.10.2 From 154f484b92e5c25c400f6903512c511644a49322 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Mon, 28 Nov 2005 13:44:14 -0800 Subject: [PATCH] Fix oops in vfs_quotaon_mount() When quota file specified in mount options did not exist, we tried to dereference NULL pointer later. Fix it. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/dquot.c b/fs/dquot.c index 05b6028..2a62b3d 100644 --- a/fs/dquot.c +++ b/fs/dquot.c @@ -1513,10 +1513,16 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name, if (IS_ERR(dentry)) return PTR_ERR(dentry); + if (!dentry->d_inode) { + error = -ENOENT; + goto out; + } + error = security_quota_on(dentry); if (!error) error = vfs_quota_on_inode(dentry->d_inode, type, format_id); +out: dput(dentry); return error; } -- cgit v0.10.2 From ea164d73a7a0b2b2be3a1d8c2a8a4dab8999fa9c Mon Sep 17 00:00:00 2001 From: Andrea Arcangeli Date: Mon, 28 Nov 2005 13:44:15 -0800 Subject: [PATCH] shrinker->nr = LONG_MAX means deadlock for icache With Andrew Morton The slab scanning code tries to balance the scanning rate of slabs versus the scanning rate of LRU pages. To do this, it retains state concerning how many slabs have been scanned - if a particular slab shrinker didn't scan enough objects, we remember that for next time, and scan more objects on the next pass. The problem with this is that with (say) a huge number of GFP_NOIO direct-reclaim attempts, the number of objects which are to be scanned when we finally get a GFP_KERNEL request can be huge. Because some shrinker handlers just bail out if !__GFP_FS. So the patch clamps the number of objects-to-be-scanned to 2* the total number of objects in the slab cache. Signed-off-by: Andrea Arcangeli Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/mm/vmscan.c b/mm/vmscan.c index 078cf92..b0cd81c 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -201,13 +201,25 @@ static int shrink_slab(unsigned long scanned, gfp_t gfp_mask, list_for_each_entry(shrinker, &shrinker_list, list) { unsigned long long delta; unsigned long total_scan; + unsigned long max_pass = (*shrinker->shrinker)(0, gfp_mask); delta = (4 * scanned) / shrinker->seeks; - delta *= (*shrinker->shrinker)(0, gfp_mask); + delta *= max_pass; do_div(delta, lru_pages + 1); shrinker->nr += delta; - if (shrinker->nr < 0) - shrinker->nr = LONG_MAX; /* It wrapped! */ + if (shrinker->nr < 0) { + printk(KERN_ERR "%s: nr=%ld\n", + __FUNCTION__, shrinker->nr); + shrinker->nr = max_pass; + } + + /* + * Avoid risking looping forever due to too large nr value: + * never try to free more than twice the estimate number of + * freeable entries. + */ + if (shrinker->nr > max_pass * 2) + shrinker->nr = max_pass * 2; total_scan = shrinker->nr; shrinker->nr = 0; -- cgit v0.10.2 From f007d5c961448170d0ec2998b1a80eef054b6235 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 28 Nov 2005 13:44:16 -0800 Subject: [PATCH] fuse: check directory aliasing in mkdir Check the created directory inode for aliases in the mkdir() method. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index c045cc7..3a47247 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -74,6 +74,19 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) return 1; } +static int dir_alias(struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) { + /* Don't allow creating an alias to a directory */ + struct dentry *alias = d_find_alias(inode); + if (alias) { + dput(alias); + return 1; + } + } + return 0; +} + static struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, }; @@ -263,7 +276,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, fuse_put_request(fc, req); /* Don't allow userspace to do really stupid things... */ - if ((inode->i_mode ^ mode) & S_IFMT) { + if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) { iput(inode); return -EIO; } @@ -874,14 +887,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, err = fuse_lookup_iget(dir, entry, &inode); if (err) return ERR_PTR(err); - if (inode && S_ISDIR(inode->i_mode)) { - /* Don't allow creating an alias to a directory */ - struct dentry *alias = d_find_alias(inode); - if (alias) { - dput(alias); - iput(inode); - return ERR_PTR(-EIO); - } + if (inode && dir_alias(inode)) { + iput(inode); + return ERR_PTR(-EIO); } d_add(entry, inode); return NULL; -- cgit v0.10.2 From 2827d0b23b7279d0a717eea4029efeef2e1b0183 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 28 Nov 2005 13:44:16 -0800 Subject: [PATCH] fuse: check for invalid node ID in fuse_create_open() Check for invalid node ID values in the new atomic create+open method. Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 3a47247..51f5da6 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -87,6 +87,11 @@ static int dir_alias(struct inode *inode) return 0; } +static inline int invalid_nodeid(u64 nodeid) +{ + return !nodeid || nodeid == FUSE_ROOT_ID; +} + static struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, }; @@ -110,7 +115,7 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, fuse_lookup_init(req, dir, entry, &outarg); request_send(fc, req); err = req->out.h.error; - if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID)) + if (!err && invalid_nodeid(outarg.nodeid)) err = -EIO; if (!err) { inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, @@ -206,7 +211,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, } err = -EIO; - if (!S_ISREG(outentry.attr.mode)) + if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) goto out_free_ff; inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation, @@ -263,7 +268,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, fuse_put_request(fc, req); return err; } - if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) { + if (invalid_nodeid(outarg.nodeid)) { fuse_put_request(fc, req); return -EIO; } -- cgit v0.10.2 From 0e2d94f6a09d0a2d39c3b7d9529ac5c378098245 Mon Sep 17 00:00:00 2001 From: Otavio Salvador Date: Tue, 29 Nov 2005 08:02:24 +1100 Subject: [PATCH] ppc: Export symbol needed by MOL Export symbol needed to allow MOL to run. This was changed to be inline in past and forgot to be change here. Signed-off-by: Paul Mackerras diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 66073f7..bb6a5c6 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -184,7 +184,7 @@ EXPORT_SYMBOL(kernel_thread); EXPORT_SYMBOL(flush_instruction_cache); EXPORT_SYMBOL(giveup_fpu); -EXPORT_SYMBOL(flush_icache_range); +EXPORT_SYMBOL(__flush_icache_range); EXPORT_SYMBOL(flush_dcache_range); EXPORT_SYMBOL(flush_icache_user_range); EXPORT_SYMBOL(flush_dcache_page); -- cgit v0.10.2 From 624f54be206adf970cd8eece16446b027913e533 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 28 Nov 2005 19:51:27 -0800 Subject: Linux v2.6.15-rc3 diff --git a/Makefile b/Makefile index e7a0443..5187fee 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 15 -EXTRAVERSION =-rc2 +EXTRAVERSION =-rc3 NAME=Affluent Albatross # *DOCUMENTATION* -- cgit v0.10.2 From 666acb94d155106e494c6dfdd8b2fae44e0fad61 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 29 Nov 2005 15:50:58 +1100 Subject: powerpc: Export __flush_icache_range for 32-bit Both 32-bit and 64-bit use the same inline flush_icache_range definition now, so both need to export __flush_icache_range, not just 64-bit. Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index af4d1bc..94db257 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -163,15 +163,13 @@ EXPORT_SYMBOL(giveup_altivec); EXPORT_SYMBOL(giveup_spe); #endif /* CONFIG_SPE */ -#ifdef CONFIG_PPC64 -EXPORT_SYMBOL(__flush_icache_range); -#else +#ifndef CONFIG_PPC64 EXPORT_SYMBOL(flush_instruction_cache); -EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(flush_tlb_kernel_range); EXPORT_SYMBOL(flush_tlb_page); EXPORT_SYMBOL(_tlbie); #endif +EXPORT_SYMBOL(__flush_icache_range); EXPORT_SYMBOL(flush_dcache_range); #ifdef CONFIG_SMP -- cgit v0.10.2 From 220bbd748335f73aafb472a97716762a42cb0d58 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Mon, 28 Nov 2005 22:27:11 -0800 Subject: [IPV6]: Implement appropriate dummy rule 4 in ipv6_dev_get_saddr(). Ensure to update hiscore.rule in dummy rule 4 in ipv6_dev_get_saddr(). Pointed out by Yan Zheng . Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a16064b..76ff9f4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -985,6 +985,8 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, } /* Rule 4: Prefer home address -- not implemented yet */ + if (hiscore.rule < 4) + hiscore.rule++; /* Rule 5: Prefer outgoing interface */ if (hiscore.rule < 5) { -- cgit v0.10.2 From bc4117f8767203927e78b92e9e5b3ddb71d6a84d Mon Sep 17 00:00:00 2001 From: Sean Young Date: Tue, 29 Nov 2005 11:48:00 +0000 Subject: [MTD] RFD_FTL: Use lanana assigned major device number A major block device number is now assigned by lanana. Signed-off-by: Sean Young Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/rfd_ftl.c b/drivers/mtd/rfd_ftl.c index 0ab8d29..20ce212 100644 --- a/drivers/mtd/rfd_ftl.c +++ b/drivers/mtd/rfd_ftl.c @@ -30,11 +30,9 @@ MODULE_PARM_DESC(block_size, "Block size to use by RFD, defaults to erase unit s #define PREFIX "rfd_ftl: " -/* Major device # for FTL device */ - -/* A request for this major has been sent to device@lanana.org */ +/* This major has been assigned by device@lanana.org */ #ifndef RFD_FTL_MAJOR -#define RFD_FTL_MAJOR 95 +#define RFD_FTL_MAJOR 256 #endif /* Maximum number of partitions in an FTL region */ -- cgit v0.10.2 From fa2a455b028f3b6ca4dae129c6337d7edf21f12c Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 29 Nov 2005 18:43:17 +1100 Subject: [PATCH] Fix vma argument in get_usr_pages() for gate areas The system call gate area handling called vm_normal_page() with the wrong vma (which was always NULL, and caused an oops). Signed-off-by: Nick Piggin Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 9ab206b..6c1eac9 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -988,7 +988,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, return i ? : -EFAULT; } if (pages) { - struct page *page = vm_normal_page(vma, start, *pte); + struct page *page = vm_normal_page(gate_vma, start, *pte); pages[i] = page; if (page) get_page(page); -- cgit v0.10.2 From 21eeb7aa116b1f59fc23339521173cbb13e57f1a Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Tue, 29 Nov 2005 16:57:17 +0100 Subject: [JFFS2] Fix the slab cache constructor of 'struct jffs2_inode_info' objects. JFFS2 initialize f->sem mutex as "locked" in the slab constructor which is a bug. Objects are freed with unlocked f->sem mutex. So, when they allocated again, f->sem is unlocked because the slab cache constructor is not called for them. The constructor is called only once when memory pages are allocated for objects (namely, when the slab layer allocates new slabs). So, sometimes 'struct jffs2_inode_info' are allocated with unlocked f->sem, sometimes with locked. This is a bug. Instead, initialize f->sem as unlocked in the constructor. I.e., in the "constructed" state f->sem must be unlocked. From: Keijiro Yano Acked-by: Artem B. Bityutskiy Signed-off-by: Thomas Gleixner diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c index 5434206..d0fcc5f 100644 --- a/fs/jffs2/fs.c +++ b/fs/jffs2/fs.c @@ -234,6 +234,7 @@ void jffs2_read_inode (struct inode *inode) c = JFFS2_SB_INFO(inode->i_sb); jffs2_init_inode_info(f); + down(&f->sem); ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); @@ -400,6 +401,7 @@ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_i f = JFFS2_INODE_INFO(inode); jffs2_init_inode_info(f); + down(&f->sem); memset(ri, 0, sizeof(*ri)); /* Set OS-specific defaults for new inodes */ diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 9e0b545..9388381 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -51,7 +51,7 @@ static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long f if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == SLAB_CTOR_CONSTRUCTOR) { - init_MUTEX_LOCKED(&ei->sem); + init_MUTEX(&ei->sem); inode_init_once(&ei->vfs_inode); } } -- cgit v0.10.2 From b77dae5293efba42ea1ff04d410ee68e66d5b0cf Mon Sep 17 00:00:00 2001 From: Dean Roe Date: Wed, 9 Nov 2005 14:25:06 -0600 Subject: [IA64] - Make pfn_valid more precise for SGI Altix systems A single SGI Altix system can be divided into multiple partitions, each running their own instance of the Linux kernel. pfn_valid() is currently not optimal for any but the first partition, since it does not compare the pfn with min_low_pfn before calling the more costly ia64_pfn_valid(). Signed-off-by: Dean Roe Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 0157281..5db9d3b 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -42,6 +42,7 @@ EXPORT_SYMBOL(clear_page); #ifdef CONFIG_VIRTUAL_MEM_MAP #include +EXPORT_SYMBOL(min_low_pfn); /* defined by bootmem.c, but not exported by generic code */ EXPORT_SYMBOL(max_low_pfn); /* defined by bootmem.c, but not exported by generic code */ #endif diff --git a/include/asm-ia64/page.h b/include/asm-ia64/page.h index 9dd9da1..5e6362a 100644 --- a/include/asm-ia64/page.h +++ b/include/asm-ia64/page.h @@ -110,8 +110,9 @@ extern int ia64_pfn_valid (unsigned long pfn); # define pfn_to_page(pfn) (mem_map + (pfn)) #elif defined(CONFIG_DISCONTIGMEM) extern struct page *vmem_map; +extern unsigned long min_low_pfn; extern unsigned long max_low_pfn; -# define pfn_valid(pfn) (((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) +# define pfn_valid(pfn) (((pfn) >= min_low_pfn) && ((pfn) < max_low_pfn) && ia64_pfn_valid(pfn)) # define page_to_pfn(page) ((unsigned long) (page - vmem_map)) # define pfn_to_page(pfn) (vmem_map + (pfn)) #endif -- cgit v0.10.2 From 5a94bcfd2a18edcf368b3128c7df07b58e529932 Mon Sep 17 00:00:00 2001 From: Keshavamurthy Anil S Date: Tue, 22 Nov 2005 14:15:49 -0800 Subject: [IA64] Remove getting break_num by decoding instruction break.b always sets cr.iim to 0 and the current code tries to get the break_num by decoding instruction. However, their seems to be a race condition while reading the regs->cr_iip, as on other cpu the break.b at regs->cr_iip might have been replaced with the original instruction as a result of unregister_kprobe() and hence decoding instruction to obtain break_num will result in wrong value in this case. Also includes changes to kprobes.c which now has to handle break number zero. Signed-off-by: Anil S Keshavamurthy Signed-off-by: Tony Luck diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 801eeae..2895d6e 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -740,7 +740,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, switch(val) { case DIE_BREAK: /* err is break number from ia64_bad_break() */ - if (args->err == 0x80200 || args->err == 0x80300) + if (args->err == 0x80200 || args->err == 0x80300 || args->err == 0) if (pre_kprobes_handler(args)) ret = NOTIFY_STOP; break; diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index fba5fdd..d3e0ecb 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -132,24 +132,6 @@ __kprobes ia64_bad_break (unsigned long break_num, struct pt_regs *regs) siginfo_t siginfo; int sig, code; - /* break.b always sets cr.iim to 0, which causes problems for - * debuggers. Get the real break number from the original instruction, - * but only for kernel code. User space break.b is left alone, to - * preserve the existing behaviour. All break codings have the same - * format, so there is no need to check the slot type. - */ - if (break_num == 0 && !user_mode(regs)) { - struct ia64_psr *ipsr = ia64_psr(regs); - unsigned long *bundle = (unsigned long *)regs->cr_iip; - unsigned long slot; - switch (ipsr->ri) { - case 0: slot = (bundle[0] >> 5); break; - case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; - default: slot = (bundle[1] >> 23); break; - } - break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); - } - /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; -- cgit v0.10.2 From 3eb8ceac486ed9b6eceed098423f1ca6b180ec9d Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 14 Nov 2005 13:41:51 +0000 Subject: [MTD] devices/ms02-nv: phys/virt address fixups Merge from linux-mips: Use physical addresses at the interface level, letting drivers remap them as appropriate. Signed-off-by: Maciej W. Rozycki Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index f5026ce..0ff2e43 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c @@ -6,7 +6,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * $Id: ms02-nv.c,v 1.10 2005/06/20 12:24:41 macro Exp $ + * $Id: ms02-nv.c,v 1.11 2005/11/14 13:41:47 macro Exp $ */ #include @@ -293,13 +293,13 @@ static int __init ms02nv_init(void) switch (mips_machtype) { case MACH_DS5000_200: - csr = (volatile u32 *)KN02_CSR_BASE; + csr = (volatile u32 *)CKSEG1ADDR(KN02_SLOT_BASE + KN02_CSR); if (*csr & KN02_CSR_BNK32M) stride = 2; break; case MACH_DS5000_2X0: case MACH_DS5900: - csr = (volatile u32 *)KN03_MCR_BASE; + csr = (volatile u32 *)CKSEG1ADDR(KN03_SLOT_BASE + IOASIC_MCR); if (*csr & KN03_MCR_BNK32M) stride = 2; break; -- cgit v0.10.2 From 987d24018dc83d27e491674c50ff2272f51eb719 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Tue, 15 Nov 2005 23:28:20 +0000 Subject: [MTD] CFI: Use 16-bit access to autoselect/read device id data Recent models of Intel/Sharp and Spansion CFI flash now have significant bits in the upper byte of device ID codes, read via what Spansion calls "autoselect" and Intel calls "read device identifier". Currently these values are truncated to the low 8 bits in the mtd data structures, as all CFI read query info has previously been read one byte at a time. Add a new method for reading 16-bit info, currently just manufacturer and device codes; datasheets hint at future uses for upper bytes in other fields. Signed-off-by: Todd Poynor Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index 90eb30e..d65ccde 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -1,7 +1,7 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. - $Id: cfi_probe.c,v 1.84 2005/11/07 11:14:23 gleixner Exp $ + $Id: cfi_probe.c,v 1.85 2005/11/15 23:28:17 tpoynor Exp $ */ #include @@ -230,8 +230,8 @@ static int __xipram cfi_chip_setup(struct map_info *map, cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); - cfi->mfr = cfi_read_query(map, base); - cfi->id = cfi_read_query(map, base + ofs_factor); + cfi->mfr = cfi_read_query16(map, base); + cfi->id = cfi_read_query16(map, base + ofs_factor); /* Put it back into Read Mode */ cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL); diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 3c9ea4b..23a5689 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -1,7 +1,7 @@ /* Common Flash Interface structures * See http://support.intel.com/design/flash/technote/index.htm - * $Id: cfi.h,v 1.56 2005/11/07 11:14:54 gleixner Exp $ + * $Id: cfi.h,v 1.57 2005/11/15 23:28:17 tpoynor Exp $ */ #ifndef __MTD_CFI_H__ @@ -426,6 +426,22 @@ static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) } } +static inline uint16_t cfi_read_query16(struct map_info *map, uint32_t addr) +{ + map_word val = map_read(map, addr); + + if (map_bankwidth_is_1(map)) { + return val.x[0] & 0xff; + } else if (map_bankwidth_is_2(map)) { + return cfi16_to_cpu(val.x[0]); + } else { + /* No point in a 64-bit byteswap since that would just be + swapping the responses from different chips, and we are + only interested in one chip (a representative sample) */ + return cfi32_to_cpu(val.x[0]); + } +} + static inline void cfi_udelay(int us) { if (us >= 1000) { -- cgit v0.10.2 From 3c77354794939143fdf1dd669895a812f94f9a38 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Wed, 16 Nov 2005 16:23:25 +0000 Subject: [MTD] maps/ixp4xx: half-word boundary and little-endian fixups ixp4xx updates: - Handle reads that don't start on a half-word boundary. - Make it work when CPU is in little-endian mode. Signed-off-by: John Bowler Signed-off-by: Alessandro Zummo Signed-off-by: David Vrabel Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index a59f802..986c586 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c @@ -1,5 +1,5 @@ /* - * $Id: ixp4xx.c,v 1.12 2005/11/07 11:14:27 gleixner Exp $ + * $Id: ixp4xx.c,v 1.13 2005/11/16 16:23:21 dvrabel Exp $ * * drivers/mtd/maps/ixp4xx.c * @@ -34,10 +34,55 @@ #include +/* + * Read/write a 16 bit word from flash address 'addr'. + * + * When the cpu is in little-endian mode it swizzles the address lines + * ('address coherency') so we need to undo the swizzling to ensure commands + * and the like end up on the correct flash address. + * + * To further complicate matters, due to the way the expansion bus controller + * handles 32 bit reads, the byte stream ABCD is stored on the flash as: + * D15 D0 + * +---+---+ + * | A | B | 0 + * +---+---+ + * | C | D | 2 + * +---+---+ + * This means that on LE systems each 16 bit word must be swapped. Note that + * this requires CONFIG_MTD_CFI_BE_BYTE_SWAP to be enabled to 'unswap' the CFI + * data and other flash commands which are always in D7-D0. + */ #ifndef __ARMEB__ +#ifndef CONFIG_MTD_CFI_BE_BYTE_SWAP +# error CONFIG_MTD_CFI_BE_BYTE_SWAP required +#endif + +static inline u16 flash_read16(void __iomem *addr) +{ + return be16_to_cpu(__raw_readw((void __iomem *)((unsigned long)addr ^ 0x2))); +} + +static inline void flash_write16(u16 d, void __iomem *addr) +{ + __raw_writew(cpu_to_be16(d), (void __iomem *)((unsigned long)addr ^ 0x2)); +} + #define BYTE0(h) ((h) & 0xFF) #define BYTE1(h) (((h) >> 8) & 0xFF) + #else + +static inline u16 flash_read16(const void __iomem *addr) +{ + return __raw_readw(addr); +} + +static inline void flash_write16(u16 d, void __iomem *addr) +{ + __raw_writew(d, addr); +} + #define BYTE0(h) (((h) >> 8) & 0xFF) #define BYTE1(h) ((h) & 0xFF) #endif @@ -45,7 +90,7 @@ static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) { map_word val; - val.x[0] = le16_to_cpu(readw(map->virt + ofs)); + val.x[0] = flash_read16(map->virt + ofs); return val; } @@ -57,19 +102,28 @@ static map_word ixp4xx_read16(struct map_info *map, unsigned long ofs) static void ixp4xx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) { - int i; u8 *dest = (u8 *) to; void __iomem *src = map->virt + from; - u16 data; - for (i = 0; i < (len / 2); i++) { - data = le16_to_cpu(readw(src + 2*i)); - dest[i * 2] = BYTE0(data); - dest[i * 2 + 1] = BYTE1(data); + if (len <= 0) + return; + + if (from & 1) { + *dest++ = BYTE1(flash_read16(src)); + src++; + --len; } - if (len & 1) - dest[len - 1] = BYTE0(le16_to_cpu(readw(src + 2*i))); + while (len >= 2) { + u16 data = flash_read16(src); + *dest++ = BYTE0(data); + *dest++ = BYTE1(data); + src += 2; + len -= 2; + } + + if (len > 0) + *dest++ = BYTE0(flash_read16(src)); } /* @@ -79,7 +133,7 @@ static void ixp4xx_copy_from(struct map_info *map, void *to, static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long adr) { if (!(adr & 1)) - writew(cpu_to_le16(d.x[0]), map->virt + adr); + flash_write16(d.x[0], map->virt + adr); } /* @@ -87,7 +141,7 @@ static void ixp4xx_probe_write16(struct map_info *map, map_word d, unsigned long */ static void ixp4xx_write16(struct map_info *map, map_word d, unsigned long adr) { - writew(cpu_to_le16(d.x[0]), map->virt + adr); + flash_write16(d.x[0], map->virt + adr); } struct ixp4xx_flash_info { -- cgit v0.10.2 From 7ac571f8d0f843fb818f7c70ec77784545e91bc4 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 17 Nov 2005 08:20:31 +0000 Subject: [MTD] Make some tables 'const' so they can live in .rodata arjan: drivers/mtd/maps/sc520cdp.c:167: warning: par_table is never written to and should be declared 'const' arjan: drivers/mtd/maps/pci.c:105: warning: mtd_pci_map is never written to and should be declared 'const' arjan: mind fixing those up ? Signed-off-by: David Woodhouse Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 8b3570b..21822c2 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c @@ -7,7 +7,7 @@ * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * - * $Id: pci.c,v 1.13 2005/11/07 11:14:27 gleixner Exp $ + * $Id: pci.c,v 1.14 2005/11/17 08:20:27 dwmw2 Exp $ * * Generic PCI memory map driver. We support the following boards: * - Intel IQ80310 ATU. @@ -102,7 +102,7 @@ static void mtd_pci_copyto(struct map_info *_map, unsigned long to, const void * memcpy_toio(map->base + map->translate(map, to), from, len); } -static struct map_info mtd_pci_map = { +static const struct map_info mtd_pci_map = { .phys = NO_XIP, .copy_from = mtd_pci_copyfrom, .copy_to = mtd_pci_copyto, diff --git a/drivers/mtd/maps/sc520cdp.c b/drivers/mtd/maps/sc520cdp.c index 6fb9f3c..ed92afa 100644 --- a/drivers/mtd/maps/sc520cdp.c +++ b/drivers/mtd/maps/sc520cdp.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: sc520cdp.c,v 1.22 2005/11/07 11:14:28 gleixner Exp $ + * $Id: sc520cdp.c,v 1.23 2005/11/17 08:20:27 dwmw2 Exp $ * * * The SC520CDP is an evaluation board for the Elan SC520 processor available @@ -164,7 +164,7 @@ struct sc520_par_table unsigned long default_address; }; -static struct sc520_par_table par_table[NUM_FLASH_BANKS] = +static const struct sc520_par_table par_table[NUM_FLASH_BANKS] = { { /* Flash Bank #0: selected by ROMCS0 */ SC520_PAR_ROMCS0, -- cgit v0.10.2 From 8bc3b3804a6123e634be26359558aa998102506a Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 23 Nov 2005 22:07:56 +0000 Subject: [MTD] cfi_cmdset_0001: relax locking rules for multi hardware partition support Signed-off-by: Nicolas Pitre Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 143f01a..69c0494 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -4,7 +4,7 @@ * * (C) 2000 Red Hat. GPL'd * - * $Id: cfi_cmdset_0001.c,v 1.185 2005/11/07 11:14:22 gleixner Exp $ + * $Id: cfi_cmdset_0001.c,v 1.186 2005/11/23 22:07:52 nico Exp $ * * * 10/10/2000 Nicolas Pitre @@ -644,9 +644,8 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr * * - contension arbitration is handled in the owner's context. * - * The 'shared' struct can be read when its lock is taken. - * However any writes to it can only be made when the current - * owner's lock is also held. + * The 'shared' struct can be read and/or written only when + * its lock is taken. */ struct flchip_shared *shared = chip->priv; struct flchip *contender; @@ -675,14 +674,13 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr } timeo = jiffies + HZ; spin_lock(&shared->lock); + spin_unlock(contender->mutex); } /* We now own it */ shared->writing = chip; if (mode == FL_ERASING) shared->erasing = chip; - if (contender && contender != chip) - spin_unlock(contender->mutex); spin_unlock(&shared->lock); } -- cgit v0.10.2 From e2602b347aa6f62b61754c5f65191ef67ffd0dc7 Mon Sep 17 00:00:00 2001 From: Luiz Capitulino Date: Tue, 29 Nov 2005 14:30:03 +0000 Subject: [MTD] maps: sparse fixup The patch below fixes the following sparse warning: drivers/mtd/maps/nettel.c:482:27: warning: Using plain integer as NULL pointer Signed-off-by: Luiz Capitulino Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/maps/nettel.c b/drivers/mtd/maps/nettel.c index f00ee7e..632eb2a 100644 --- a/drivers/mtd/maps/nettel.c +++ b/drivers/mtd/maps/nettel.c @@ -6,7 +6,7 @@ * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com) * (C) Copyright 2001-2002, SnapGear (www.snapgear.com) * - * $Id: nettel.c,v 1.11 2005/11/07 11:14:27 gleixner Exp $ + * $Id: nettel.c,v 1.12 2005/11/29 14:30:00 gleixner Exp $ */ /****************************************************************************/ @@ -479,7 +479,7 @@ void __exit nettel_cleanup(void) } if (nettel_intel_map.virt) { iounmap(nettel_intel_map.virt); - nettel_intel_map.virt = 0; + nettel_intel_map.virt = NULL; } #endif } -- cgit v0.10.2 From 72af3b2c5a9946e78125e143b636f3d7217bcf08 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 28 Nov 2005 22:36:12 +0000 Subject: [MTD] Remove bogus PQ2FADS driver Remove disfunctional driver, which slipped through the review mechanism Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index 846a533..452ccd5 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -538,12 +538,6 @@ config MTD_MPC1211 This enables access to the flash chips on the Interface MPC-1211(CTP/PCI/MPC-SH02). If you have such a board, say 'Y'. -config MTD_PQ2FADS - tristate "JEDEC flash SIMM mapped on PQ2FADS and 8272ADS boards" - depends on (ADS8272 || PQ2FADS) && MTD_PARTITIONS && MTD_JEDECPROBE && MTD_PHYSMAP && MTD_CFI_GEOMETRY && MTD_CFI_INTELEXT - help - This enables access to flash SIMM on PQ2FADS-like boards - config MTD_OMAP_NOR tristate "TI OMAP board mappings" depends on MTD_CFI && ARCH_OMAP diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index 7d9e940..2f7e254 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile @@ -70,6 +70,5 @@ obj-$(CONFIG_MTD_DMV182) += dmv182.o obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o -obj-$(CONFIG_MTD_PQ2FADS) += pq2fads.o obj-$(CONFIG_MTD_MTX1) += mtx-1_flash.o obj-$(CONFIG_MTD_TQM834x) += tqm834x.o -- cgit v0.10.2 From ee2d49de3e3a0b846ecedb36fec0e4a5ff222dcb Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 29 Nov 2005 14:28:31 +0000 Subject: [MTD] chips: make sharps driver usable again Update the pre-CFI Sharp driver sharps.c so it compiles. map_read32 / map_write32 no longer exist in the kernel so the driver is totally broken as it stands. The replacement functions use different parameters resulting in the other changes. Change collie to use this driver until someone works out why the cfi driver fails on that machine. Signed-off-by: Richard Purdie Tested-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/chips/sharp.c b/drivers/mtd/chips/sharp.c index 2d26bde..36f61a6 100644 --- a/drivers/mtd/chips/sharp.c +++ b/drivers/mtd/chips/sharp.c @@ -4,7 +4,7 @@ * Copyright 2000,2001 David A. Schleef * 2000,2001 Lineo, Inc. * - * $Id: sharp.c,v 1.16 2005/11/07 11:14:23 gleixner Exp $ + * $Id: sharp.c,v 1.17 2005/11/29 14:28:28 gleixner Exp $ * * Devices supported: * LH28F016SCT Symmetrical block flash memory, 2Mx8 @@ -160,22 +160,28 @@ struct mtd_info *sharp_probe(struct map_info *map) return mtd; } +static inline void sharp_send_cmd(struct map_info *map, unsigned long cmd, unsigned long adr) +{ + map_word map_cmd; + map_cmd.x[0] = cmd; + map_write(map, map_cmd, adr); +} + static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) { - unsigned long tmp; + map_word tmp, read0, read4; unsigned long base = 0; - u32 read0, read4; int width = 4; - tmp = map_read32(map, base+0); + tmp = map_read(map, base+0); - map_write32(map, CMD_READ_ID, base+0); + sharp_send_cmd(map, CMD_READ_ID, base+0); - read0=map_read32(map, base+0); - read4=map_read32(map, base+4); - if(read0 == 0x89898989){ + read0 = map_read(map, base+0); + read4 = map_read(map, base+4); + if(read0.x[0] == 0x89898989){ printk("Looks like sharp flash\n"); - switch(read4){ + switch(read4.x[0]){ case 0xaaaaaaaa: case 0xa0a0a0a0: /* aa - LH28F016SCT-L95 2Mx8, 32 64k blocks*/ @@ -197,16 +203,16 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) return width; #endif default: - printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n", - read0,read4); + printk("Sort-of looks like sharp flash, 0x%08lx 0x%08lx\n", + read0.x[0], read4.x[0]); } - }else if((map_read32(map, base+0) == CMD_READ_ID)){ + }else if((map_read(map, base+0).x[0] == CMD_READ_ID)){ /* RAM, probably */ printk("Looks like RAM\n"); - map_write32(map, tmp, base+0); + map_write(map, tmp, base+0); }else{ - printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n", - read0,read4); + printk("Doesn't look like sharp flash, 0x%08lx 0x%08lx\n", + read0.x[0], read4.x[0]); } return 0; @@ -215,7 +221,8 @@ static int sharp_probe_map(struct map_info *map,struct mtd_info *mtd) /* This function returns with the chip->mutex lock held. */ static int sharp_wait(struct map_info *map, struct flchip *chip) { - int status, i; + int i; + map_word status; unsigned long timeo = jiffies + HZ; DECLARE_WAITQUEUE(wait, current); int adr = 0; @@ -225,12 +232,12 @@ retry: switch(chip->state){ case FL_READY: - map_write32(map,CMD_READ_STATUS,adr); + sharp_send_cmd(map, CMD_READ_STATUS, adr); chip->state = FL_STATUS; case FL_STATUS: for(i=0;i<100;i++){ - status = map_read32(map,adr); - if((status & SR_READY)==SR_READY) + status = map_read(map, adr); + if((status.x[0] & SR_READY)==SR_READY) break; udelay(1); } @@ -254,7 +261,7 @@ retry: goto retry; } - map_write32(map,CMD_RESET, adr); + sharp_send_cmd(map, CMD_RESET, adr); chip->state = FL_READY; @@ -351,37 +358,39 @@ static int sharp_write_oneword(struct map_info *map, struct flchip *chip, int timeo; int try; int i; - int status = 0; + map_word data, status; + status.x[0] = 0; ret = sharp_wait(map,chip); for(try=0;try<10;try++){ - map_write32(map,CMD_BYTE_WRITE,adr); + sharp_send_cmd(map, CMD_BYTE_WRITE, adr); /* cpu_to_le32 -> hack to fix the writel be->le conversion */ - map_write32(map,cpu_to_le32(datum),adr); + data.x[0] = cpu_to_le32(datum); + map_write(map, data, adr); chip->state = FL_WRITING; timeo = jiffies + (HZ/2); - map_write32(map,CMD_READ_STATUS,adr); + sharp_send_cmd(map, CMD_READ_STATUS, adr); for(i=0;i<100;i++){ - status = map_read32(map,adr); - if((status & SR_READY)==SR_READY) + status = map_read(map, adr); + if((status.x[0] & SR_READY) == SR_READY) break; } if(i==100){ printk("sharp: timed out writing\n"); } - if(!(status&SR_ERRORS)) + if(!(status.x[0] & SR_ERRORS)) break; - printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status); + printk("sharp: error writing byte at addr=%08lx status=%08lx\n", adr, status.x[0]); - map_write32(map,CMD_CLEAR_STATUS,adr); + sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); } - map_write32(map,CMD_RESET,adr); + sharp_send_cmd(map, CMD_RESET, adr); chip->state = FL_READY; wake_up(&chip->wq); @@ -434,18 +443,18 @@ static int sharp_do_wait_for_ready(struct map_info *map, struct flchip *chip, { int ret; unsigned long timeo; - int status; + map_word status; DECLARE_WAITQUEUE(wait, current); - map_write32(map,CMD_READ_STATUS,adr); - status = map_read32(map,adr); + sharp_send_cmd(map, CMD_READ_STATUS, adr); + status = map_read(map, adr); timeo = jiffies + HZ; while(time_before(jiffies, timeo)){ - map_write32(map,CMD_READ_STATUS,adr); - status = map_read32(map,adr); - if((status & SR_READY)==SR_READY){ + sharp_send_cmd(map, CMD_READ_STATUS, adr); + status = map_read(map, adr); + if((status.x[0] & SR_READY)==SR_READY){ ret = 0; goto out; } @@ -476,7 +485,7 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, { int ret; //int timeo; - int status; + map_word status; //int i; //printk("sharp_erase_oneblock()\n"); @@ -486,26 +495,26 @@ static int sharp_erase_oneblock(struct map_info *map, struct flchip *chip, sharp_unlock_oneblock(map,chip,adr); #endif - map_write32(map,CMD_BLOCK_ERASE_1,adr); - map_write32(map,CMD_BLOCK_ERASE_2,adr); + sharp_send_cmd(map, CMD_BLOCK_ERASE_1, adr); + sharp_send_cmd(map, CMD_BLOCK_ERASE_2, adr); chip->state = FL_ERASING; ret = sharp_do_wait_for_ready(map,chip,adr); if(ret<0)return ret; - map_write32(map,CMD_READ_STATUS,adr); - status = map_read32(map,adr); + sharp_send_cmd(map, CMD_READ_STATUS, adr); + status = map_read(map, adr); - if(!(status&SR_ERRORS)){ - map_write32(map,CMD_RESET,adr); + if(!(status.x[0] & SR_ERRORS)){ + sharp_send_cmd(map, CMD_RESET, adr); chip->state = FL_READY; //spin_unlock_bh(chip->mutex); return 0; } - printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status); - map_write32(map,CMD_CLEAR_STATUS,adr); + printk("sharp: error erasing block at addr=%08lx status=%08lx\n", adr, status.x[0]); + sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); //spin_unlock_bh(chip->mutex); @@ -517,20 +526,20 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr) { int i; - int status; + map_word status; - map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr); - map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr); + sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_1, adr); + sharp_send_cmd(map, CMD_CLEAR_BLOCK_LOCKS_2, adr); udelay(100); - status = map_read32(map,adr); - printk("status=%08x\n",status); + status = map_read(map, adr); + printk("status=%08lx\n", status.x[0]); for(i=0;i<1000;i++){ - //map_write32(map,CMD_READ_STATUS,adr); - status = map_read32(map,adr); - if((status & SR_READY)==SR_READY) + //sharp_send_cmd(map, CMD_READ_STATUS, adr); + status = map_read(map, adr); + if((status.x[0] & SR_READY) == SR_READY) break; udelay(100); } @@ -538,14 +547,14 @@ static void sharp_unlock_oneblock(struct map_info *map, struct flchip *chip, printk("sharp: timed out unlocking block\n"); } - if(!(status&SR_ERRORS)){ - map_write32(map,CMD_RESET,adr); + if(!(status.x[0] & SR_ERRORS)){ + sharp_send_cmd(map, CMD_RESET, adr); chip->state = FL_READY; return; } - printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status); - map_write32(map,CMD_CLEAR_STATUS,adr); + printk("sharp: error unlocking block at addr=%08lx status=%08lx\n", adr, status.x[0]); + sharp_send_cmd(map, CMD_CLEAR_STATUS, adr); } #endif -- cgit v0.10.2 From 2b9175c174b83b8d97db9398efe948fa9092938f Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Nov 2005 14:49:38 +0000 Subject: [MTD] Make functions static, include header files with prototypes This patch contains the following possible cleanups: - every file should #include the headers containing the prototypes for it's global functions - make needlessly global functions static Signed-off-by: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Thomas Gleixner diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index d65ccde..e636aa8 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c @@ -1,7 +1,7 @@ /* Common Flash Interface probe code. (C) 2000 Red Hat. GPL'd. - $Id: cfi_probe.c,v 1.85 2005/11/15 23:28:17 tpoynor Exp $ + $Id: cfi_probe.c,v 1.86 2005/11/29 14:48:31 gleixner Exp $ */ #include @@ -426,7 +426,7 @@ static struct mtd_chip_driver cfi_chipdrv = { .module = THIS_MODULE }; -int __init cfi_probe_init(void) +static int __init cfi_probe_init(void) { register_mtd_chip_driver(&cfi_chipdrv); return 0; diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 0aaa0ce..7ff403b 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -1,5 +1,5 @@ /* - * $Id: block2mtd.c,v 1.29 2005/11/07 11:14:24 gleixner Exp $ + * $Id: block2mtd.c,v 1.30 2005/11/29 14:48:32 gleixner Exp $ * * block2mtd.c - create an mtd from a block device * @@ -19,7 +19,7 @@ #include #include -#define VERSION "$Revision: 1.29 $" +#define VERSION "$Revision: 1.30 $" #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args) @@ -40,7 +40,7 @@ static LIST_HEAD(blkmtd_device_list); #define PAGE_READAHEAD 64 -void cache_readahead(struct address_space *mapping, int index) +static void cache_readahead(struct address_space *mapping, int index) { filler_t *filler = (filler_t*)mapping->a_ops->readpage; int i, pagei; diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index de7e231..8a878b3 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c @@ -1,5 +1,5 @@ /* This version ported to the Linux-MTD system by dwmw2@infradead.org - * $Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $ + * $Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $ * * Fixes: Arnaldo Carvalho de Melo * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups @@ -1084,9 +1084,9 @@ struct mtd_blktrans_ops ftl_tr = { .owner = THIS_MODULE, }; -int init_ftl(void) +static int init_ftl(void) { - DEBUG(0, "$Id: ftl.c,v 1.58 2005/11/07 11:14:19 gleixner Exp $\n"); + DEBUG(0, "$Id: ftl.c,v 1.59 2005/11/29 14:48:31 gleixner Exp $\n"); return register_mtd_blktrans(&ftl_tr); } diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c index 9ee760f..f49ebc3 100644 --- a/drivers/mtd/maps/physmap.c +++ b/drivers/mtd/maps/physmap.c @@ -1,5 +1,5 @@ /* - * $Id: physmap.c,v 1.38 2005/11/07 11:14:28 gleixner Exp $ + * $Id: physmap.c,v 1.39 2005/11/29 14:49:36 gleixner Exp $ * * Normal mappings of chips in physical memory * @@ -19,6 +19,7 @@ #include #include #include +#include static struct mtd_info *mymtd; diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index de45003..a0af92c 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -1486,7 +1486,7 @@ ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) /* * Module initialization function */ -int __init ns_init_module(void) +static int __init ns_init_module(void) { struct nand_chip *chip; struct nandsim *nand; -- cgit v0.10.2 From eca351336acb2fa943611e0846562ce3997ef53b Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Tue, 29 Nov 2005 11:45:26 -0800 Subject: [PATCH] Fix missing pfn variables caused by vm changes I image this showed up because of "unused var..." when the changes occured, because flush_cache_page() is a noop in most places. This showed up for me on parisc however, where flush_cache_page() is a real function. Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 6c1eac9..74839b3 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1345,7 +1345,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, int reuse = can_share_swap_page(old_page); unlock_page(old_page); if (reuse) { - flush_cache_page(vma, address, pfn); + flush_cache_page(vma, address, pte_pfn(orig_pte)); entry = pte_mkyoung(orig_pte); entry = maybe_mkwrite(pte_mkdirty(entry), vma); ptep_set_access_flags(vma, address, page_table, entry, 1); @@ -1389,7 +1389,7 @@ gotten: } } else inc_mm_counter(mm, anon_rss); - flush_cache_page(vma, address, pfn); + flush_cache_page(vma, address, pte_pfn(orig_pte)); entry = mk_pte(new_page, vma->vm_page_prot); entry = maybe_mkwrite(pte_mkdirty(entry), vma); ptep_establish(vma, address, page_table, entry); diff --git a/mm/rmap.c b/mm/rmap.c index 491ac35..f853c6d 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -641,7 +641,7 @@ static void try_to_unmap_cluster(unsigned long cursor, continue; /* Nuke the page table entry. */ - flush_cache_page(vma, address, pfn); + flush_cache_page(vma, address, pte_pfn(*pte)); pteval = ptep_clear_flush(vma, address, pte); /* If nonlinear, store the file page offset in the pte. */ -- cgit v0.10.2 From 238f58d898df941aa9d1cb390fb27ff4febe8965 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 13:01:56 -0800 Subject: Support strange discontiguous PFN remappings These get created by some drivers that don't generally even want a pfn remapping at all, but would really mostly prefer to just map pages they've allocated individually instead. For now, create a helper function that turns such an incomplete PFN remapping call into a loop that does that explicit mapping. In the long run we almost certainly want to export a totally different interface for that, though. Signed-off-by: Linus Torvalds diff --git a/include/linux/mm.h b/include/linux/mm.h index 6a75a7a..74f90d7 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -163,6 +163,7 @@ extern unsigned int kobjsize(const void *objp); #define VM_HUGETLB 0x00400000 /* Huge TLB Page VM */ #define VM_NONLINEAR 0x00800000 /* Is non-linear (remap_file_pages) */ #define VM_MAPPED_COPY 0x01000000 /* T if mapped copy of data (nommu mmap) */ +#define VM_INCOMPLETE 0x02000000 /* Strange partial PFN mapping marker */ #ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */ #define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS diff --git a/mm/memory.c b/mm/memory.c index 74839b3..990e7dc6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1147,6 +1147,95 @@ int zeromap_page_range(struct vm_area_struct *vma, } /* + * This is the old fallback for page remapping. + * + * For historical reasons, it only allows reserved pages. Only + * old drivers should use this, and they needed to mark their + * pages reserved for the old functions anyway. + */ +static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot) +{ + int retval; + pgd_t * pgd; + pud_t * pud; + pmd_t * pmd; + pte_t * pte; + spinlock_t *ptl; + + retval = -EINVAL; + if (PageAnon(page) || !PageReserved(page)) + goto out; + retval = -ENOMEM; + flush_dcache_page(page); + pgd = pgd_offset(mm, addr); + pud = pud_alloc(mm, pgd, addr); + if (!pud) + goto out; + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + goto out; + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + if (!pte) + goto out; + retval = -EBUSY; + if (!pte_none(*pte)) + goto out_unlock; + + /* Ok, finally just insert the thing.. */ + get_page(page); + inc_mm_counter(mm, file_rss); + page_add_file_rmap(page); + set_pte_at(mm, addr, pte, mk_pte(page, prot)); + + retval = 0; +out_unlock: + pte_unmap_unlock(pte, ptl); +out: + return retval; +} + +/* + * Somebody does a pfn remapping that doesn't actually work as a vma. + * + * Do it as individual pages instead, and warn about it. It's bad form, + * and very inefficient. + */ +static int incomplete_pfn_remap(struct vm_area_struct *vma, + unsigned long start, unsigned long end, + unsigned long pfn, pgprot_t prot) +{ + static int warn = 10; + struct page *page; + int retval; + + if (!(vma->vm_flags & VM_INCOMPLETE)) { + if (warn) { + warn--; + printk("%s does an incomplete pfn remapping", current->comm); + dump_stack(); + } + } + vma->vm_flags |= VM_INCOMPLETE | VM_IO | VM_RESERVED; + + if (start < vma->vm_start || end > vma->vm_end) + return -EINVAL; + + if (!pfn_valid(pfn)) + return -EINVAL; + + retval = 0; + page = pfn_to_page(pfn); + while (start < end) { + retval = insert_page(vma->vm_mm, start, page, prot); + if (retval < 0) + break; + start += PAGE_SIZE; + page++; + } + return retval; +} + +/* * maps a range of physical memory into the requested pages. the old * mappings are removed. any references to nonexistent pages results * in null mappings (currently treated as "copy-on-access") @@ -1220,6 +1309,9 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, struct mm_struct *mm = vma->vm_mm; int err; + if (addr != vma->vm_start || end != vma->vm_end) + return incomplete_pfn_remap(vma, addr, end, pfn, prot); + /* * Physically remapped pages are special. Tell the * rest of the world about it: -- cgit v0.10.2 From 238f9b063dcc9f23493a0d3fecca29fe332d4905 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 29 Nov 2005 21:36:16 +0100 Subject: [PATCH] fix megaraid.c locking This fixes locking in megaraid.c, namely: (1) make sure megaraid_queue release the adapter lock by changing the code to have a single return (2) remove the errornous scsi_assign_lock call Testing by Burton Windle. Signed-off-by: Christoph Hellwig Acked-by: Burton Windle Signed-off-by: Linus Torvalds diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index dfea346..f979252 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -380,23 +380,23 @@ megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *)) spin_lock_irqsave(&adapter->lock, flags); scb = mega_build_cmd(adapter, scmd, &busy); + if (!scb) + goto out; - if(scb) { - scb->state |= SCB_PENDQ; - list_add_tail(&scb->list, &adapter->pending_list); + scb->state |= SCB_PENDQ; + list_add_tail(&scb->list, &adapter->pending_list); - /* - * Check if the HBA is in quiescent state, e.g., during a - * delete logical drive opertion. If it is, don't run - * the pending_list. - */ - if(atomic_read(&adapter->quiescent) == 0) { - mega_runpendq(adapter); - } - return 0; - } - spin_unlock_irqrestore(&adapter->lock, flags); + /* + * Check if the HBA is in quiescent state, e.g., during a + * delete logical drive opertion. If it is, don't run + * the pending_list. + */ + if (atomic_read(&adapter->quiescent) == 0) + mega_runpendq(adapter); + busy = 0; + out: + spin_unlock_irqrestore(&adapter->lock, flags); return busy; } @@ -4677,7 +4677,6 @@ megaraid_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) adapter->flag = flag; spin_lock_init(&adapter->lock); - scsi_assign_lock(host, &adapter->lock); host->cmd_per_lun = max_cmd_per_lun; host->max_sectors = max_sectors_per_io; -- cgit v0.10.2 From cab3f16febeaf1a60e38159ff578f609f9976544 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 29 Nov 2005 13:59:03 -0800 Subject: [SPARC64]: Fix >8K I/O mappings. Increment the PFN field of the PTE so that the tests on vm_pfn in mm/memory.c match up. The TLB ignores these lower bits for larger page sizes, so it's OK to set things like this. Signed-off-by: David S. Miller diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c index d9396c1..580b63d 100644 --- a/arch/sparc64/mm/generic.c +++ b/arch/sparc64/mm/generic.c @@ -77,6 +77,7 @@ static inline void io_remap_pte_range(struct mm_struct *mm, pte_t * pte, BUG_ON(!pte_none(*pte)); set_pte_at(mm, address, pte, entry); address += PAGE_SIZE; + pte_val(entry) += PAGE_SIZE; pte++; } while (address < curend); } while (address < end); -- cgit v0.10.2 From c9cfcddfd65735437a4cb8563d6b66a6da8a5ed6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 14:03:14 -0800 Subject: VM: add common helper function to create the page tables This logic was duplicated four times, for no good reason. Signed-off-by: Linus Torvalds diff --git a/fs/exec.c b/fs/exec.c index 1f8a9fd..22533cc 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -306,9 +306,6 @@ void install_arg_page(struct vm_area_struct *vma, struct page *page, unsigned long address) { struct mm_struct *mm = vma->vm_mm; - pgd_t * pgd; - pud_t * pud; - pmd_t * pmd; pte_t * pte; spinlock_t *ptl; @@ -316,14 +313,7 @@ void install_arg_page(struct vm_area_struct *vma, goto out; flush_dcache_page(page); - pgd = pgd_offset(mm, address); - pud = pud_alloc(mm, pgd, address); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, address); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, address, &ptl); + pte = get_locked_pte(mm, address, &ptl); if (!pte) goto out; if (!pte_none(*pte)) { diff --git a/include/linux/mm.h b/include/linux/mm.h index 74f90d7..0e73f15 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -742,6 +742,8 @@ struct shrinker; extern struct shrinker *set_shrinker(int, shrinker_t); extern void remove_shrinker(struct shrinker *shrinker); +extern pte_t *FASTCALL(get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)); + int __pud_alloc(struct mm_struct *mm, pgd_t *pgd, unsigned long address); int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address); int __pte_alloc(struct mm_struct *mm, pmd_t *pmd, unsigned long address); diff --git a/mm/fremap.c b/mm/fremap.c index f851775..9f381e5 100644 --- a/mm/fremap.c +++ b/mm/fremap.c @@ -55,20 +55,10 @@ int install_page(struct mm_struct *mm, struct vm_area_struct *vma, pgoff_t size; int err = -ENOMEM; pte_t *pte; - pmd_t *pmd; - pud_t *pud; - pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; @@ -110,20 +100,10 @@ int install_file_pte(struct mm_struct *mm, struct vm_area_struct *vma, { int err = -ENOMEM; pte_t *pte; - pmd_t *pmd; - pud_t *pud; - pgd_t *pgd; pte_t pte_val; spinlock_t *ptl; - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; diff --git a/mm/memory.c b/mm/memory.c index 990e7dc6..74f95ae 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1146,6 +1146,18 @@ int zeromap_page_range(struct vm_area_struct *vma, return err; } +pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) +{ + pgd_t * pgd = pgd_offset(mm, addr); + pud_t * pud = pud_alloc(mm, pgd, addr); + if (pud) { + pmd_t * pmd = pmd_alloc(mm, pgd, addr); + if (pmd) + return pte_alloc_map_lock(mm, pmd, addr, ptl); + } + return NULL; +} + /* * This is the old fallback for page remapping. * @@ -1156,10 +1168,7 @@ int zeromap_page_range(struct vm_area_struct *vma, static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *page, pgprot_t prot) { int retval; - pgd_t * pgd; - pud_t * pud; - pmd_t * pmd; - pte_t * pte; + pte_t *pte; spinlock_t *ptl; retval = -EINVAL; @@ -1167,14 +1176,7 @@ static int insert_page(struct mm_struct *mm, unsigned long addr, struct page *pa goto out; retval = -ENOMEM; flush_dcache_page(page); - pgd = pgd_offset(mm, addr); - pud = pud_alloc(mm, pgd, addr); - if (!pud) - goto out; - pmd = pmd_alloc(mm, pud, addr); - if (!pmd) - goto out; - pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + pte = get_locked_pte(mm, addr, &ptl); if (!pte) goto out; retval = -EBUSY; -- cgit v0.10.2 From 5d2a2dbbc1025dbf7998b9289574d9592b8f21cc Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 14:07:55 -0800 Subject: cow_user_page: fix page alignment High Dickins points out that the user virtual address passed to the page fault handler isn't necessarily page-aligned. Also, add a comment on why the copy could fail for the user address case. Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 74f95ae..745b348 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1394,8 +1394,15 @@ static inline void cow_user_page(struct page *dst, struct page *src, unsigned lo */ if (unlikely(!src)) { void *kaddr = kmap_atomic(dst, KM_USER0); - unsigned long left = __copy_from_user_inatomic(kaddr, (void __user *)va, PAGE_SIZE); - if (left) + void __user *uaddr = (void __user *)(va & PAGE_MASK); + + /* + * This really shouldn't fail, because the page is there + * in the page tables. But it might just be unreadable, + * in which case we just give up and fill the result with + * zeroes. + */ + if (__copy_from_user_inatomic(kaddr, uaddr, PAGE_SIZE)) memset(kaddr, 0, PAGE_SIZE); kunmap_atomic(kaddr, KM_USER0); return; -- cgit v0.10.2 From e5bbe4dfc8dbfc50ef89f8641e020616d4d1e69e Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 29 Nov 2005 16:54:51 +0000 Subject: [PATCH] pfnmap: remove src_page from do_wp_page Clean away do_wp_page's "src_page": cow_user_page makes it unnecessary. Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 745b348..ae259b6 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1433,12 +1433,11 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, pte_t *page_table, pmd_t *pmd, spinlock_t *ptl, pte_t orig_pte) { - struct page *old_page, *src_page, *new_page; + struct page *old_page, *new_page; pte_t entry; int ret = VM_FAULT_MINOR; old_page = vm_normal_page(vma, address, orig_pte); - src_page = old_page; if (!old_page) goto gotten; @@ -1466,7 +1465,7 @@ gotten: if (unlikely(anon_vma_prepare(vma))) goto oom; - if (src_page == ZERO_PAGE(address)) { + if (old_page == ZERO_PAGE(address)) { new_page = alloc_zeroed_user_highpage(vma, address); if (!new_page) goto oom; @@ -1474,7 +1473,7 @@ gotten: new_page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!new_page) goto oom; - cow_user_page(new_page, src_page, address); + cow_user_page(new_page, old_page, address); } /* -- cgit v0.10.2 From 325f04dbca60a4cfe4ac25e7cf246edd07eb4c5f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Tue, 29 Nov 2005 16:55:48 +0000 Subject: [PATCH] pfnmap: do_no_page BUG_ON again Use copy_user_highpage directly instead of cow_user_page in do_no_page: in the immediately following page_cache_release, and elsewhere, it is assuming that new_page is normal. If any VM_PFNMAP driver can get to do_no_page, it's just a BUG (but not in the case of do_anonymous_page). Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index ae259b6..5bfa52a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2009,6 +2009,8 @@ static int do_no_page(struct mm_struct *mm, struct vm_area_struct *vma, int anon = 0; pte_unmap(page_table); + BUG_ON(vma->vm_flags & VM_PFNMAP); + if (vma->vm_file) { mapping = vma->vm_file->f_mapping; sequence = mapping->truncate_count; @@ -2041,7 +2043,7 @@ retry: page = alloc_page_vma(GFP_HIGHUSER, vma, address); if (!page) goto oom; - cow_user_page(page, new_page, address); + copy_user_highpage(page, new_page, address); page_cache_release(new_page); new_page = page; anon = 1; -- cgit v0.10.2 From f747307ed1defcdfd37a3ef84c48e3138691cd26 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 29 Nov 2005 14:21:57 -0800 Subject: Revert "[PATCH] drivers/message/fusion/mptbase.c: make code static" This reverts commit 252ac865535e1ea9cc2d28be83f477d8d8b961a2. It impacts the LSI customers using the mptstm target mode drivers (source tar-ball at ftp://ftp.lsil.com/HostAdapterDrivers/linux/Fusion-MPT/mptstm-1.00.13-src.tar.gz for those who care). Signed-off-by: Linus Torvalds diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 7402231..65c2ec5 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -91,9 +91,9 @@ static int mfcounter = 0; * Public data... */ int mpt_lan_index = -1; -static int mpt_stm_index = -1; +int mpt_stm_index = -1; -static struct proc_dir_entry *mpt_proc_root_dir; +struct proc_dir_entry *mpt_proc_root_dir; #define WHOINIT_UNKNOWN 0xAA @@ -6271,6 +6271,7 @@ EXPORT_SYMBOL(mpt_resume); EXPORT_SYMBOL(mpt_suspend); #endif EXPORT_SYMBOL(ioc_list); +EXPORT_SYMBOL(mpt_proc_root_dir); EXPORT_SYMBOL(mpt_register); EXPORT_SYMBOL(mpt_deregister); EXPORT_SYMBOL(mpt_event_register); @@ -6288,6 +6289,7 @@ EXPORT_SYMBOL(mpt_verify_adapter); EXPORT_SYMBOL(mpt_GetIocState); EXPORT_SYMBOL(mpt_print_ioc_summary); EXPORT_SYMBOL(mpt_lan_index); +EXPORT_SYMBOL(mpt_stm_index); EXPORT_SYMBOL(mpt_HardResetHandler); EXPORT_SYMBOL(mpt_config); EXPORT_SYMBOL(mpt_toolbox); diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index 8ad277a..5f5b3fb 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h @@ -1006,8 +1006,10 @@ extern int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); * Public data decl's... */ extern struct list_head ioc_list; +extern struct proc_dir_entry *mpt_proc_root_dir; extern int mpt_lan_index; /* needed by mptlan.c */ +extern int mpt_stm_index; /* needed by mptstm.c */ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ #endif /* } __KERNEL__ */ -- cgit v0.10.2 From 18955cfcb2a5d75a08e0cb297f13ccfb6904de48 Mon Sep 17 00:00:00 2001 From: Mike Stroyan Date: Tue, 29 Nov 2005 16:12:55 -0800 Subject: [IPV4] tcp/route: Another look at hash table sizes The tcp_ehash hash table gets too big on systems with really big memory. It is worse on systems with pages larger than 4KB. It wastes memory that could be better used. It also makes the netstat command slow because reading /proc/net/tcp and /proc/net/tcp6 needs to go through the full hash table. The default value should not be larger for larger page sizes. It seems that the effect of page size is an unintended error dating back a long time. I also wonder if the default value really should be a larger fraction of memory for systems with more memory. While systems with really big ram can afford more space for hash tables, it is not clear to me that they benefit from increasing the allocation ratio for this table. The amount of memory allocated is determined by net/ipv4/tcp.c:tcp_init and mm/page_alloc.c:alloc_large_system_hash. tcp_init calls alloc_large_system_hash passing parameters- bucketsize=sizeof(struct tcp_ehash_bucket) numentries=thash_entries scale=(num_physpages >= 128 * 1024) ? (25-PAGE_SHIFT) : (27-PAGE_SHIFT) limit=0 On i386, PAGE_SHIFT is 12 for a page size of 4K On ia64, PAGE_SHIFT defaults to 14 for a page size of 16K The num_physpages test above makes the allocation take a larger fraction of the total memory on systems with larger memory. The threshold size for a i386 system is 512MB. For an ia64 system with 16KB pages the threshold is 2GB. For smaller memory systems- On i386, scale = (27 - 12) = 15 On ia64, scale = (27 - 14) = 13 For larger memory systems- On i386, scale = (25 - 12) = 13 On ia64, scale = (25 - 14) = 11 For the rest of this discussion, I'll just track the larger memory case. The default behavior has numentries=thash_entries=0, so the allocated size is determined by either scale or by the default limit of 1/16 of total memory. In alloc_large_system_hash- | numentries = (flags & HASH_HIGHMEM) ? nr_all_pages : nr_kernel_pages; | numentries += (1UL << (20 - PAGE_SHIFT)) - 1; | numentries >>= 20 - PAGE_SHIFT; | numentries <<= 20 - PAGE_SHIFT; At this point, numentries is pages for all of memory, rounded up to the nearest megabyte boundary. | /* limit to 1 bucket per 2^scale bytes of low memory */ | if (scale > PAGE_SHIFT) | numentries >>= (scale - PAGE_SHIFT); | else | numentries <<= (PAGE_SHIFT - scale); On i386, numentries >>= (13 - 12), so numentries is 1/8196 of bytes of total memory. On ia64, numentries <<= (14 - 11), so numentries is 1/2048 of bytes of total memory. | log2qty = long_log2(numentries); | | do { | size = bucketsize << log2qty; bucketsize is 16, so size is 16 times numentries, rounded down to a power of two. On i386, size is 1/512 of bytes of total memory. On ia64, size is 1/128 of bytes of total memory. For smaller systems the results are On i386, size is 1/2048 of bytes of total memory. On ia64, size is 1/512 of bytes of total memory. The large page effect can be removed by just replacing the use of PAGE_SHIFT with a constant of 12 in the calls to alloc_large_system_hash. That makes them more like the other uses of that function from fs/inode.c and fs/dcache.c Signed-off-by: David S. Miller diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 381dd6a..e9c14f4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3149,8 +3149,7 @@ int __init ip_rt_init(void) sizeof(struct rt_hash_bucket), rhash_entries, (num_physpages >= 128 * 1024) ? - (27 - PAGE_SHIFT) : - (29 - PAGE_SHIFT), + 15 : 17, HASH_HIGHMEM, &rt_hash_log, &rt_hash_mask, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9ac7a4f..5e6bc4b 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2065,8 +2065,7 @@ void __init tcp_init(void) sizeof(struct inet_ehash_bucket), thash_entries, (num_physpages >= 128 * 1024) ? - (25 - PAGE_SHIFT) : - (27 - PAGE_SHIFT), + 13 : 15, HASH_HIGHMEM, &tcp_hashinfo.ehash_size, NULL, @@ -2082,8 +2081,7 @@ void __init tcp_init(void) sizeof(struct inet_bind_hashbucket), tcp_hashinfo.ehash_size, (num_physpages >= 128 * 1024) ? - (25 - PAGE_SHIFT) : - (27 - PAGE_SHIFT), + 13 : 15, HASH_HIGHMEM, &tcp_hashinfo.bhash_size, NULL, -- cgit v0.10.2 From c9933d0856d6d0ede6b4b30e5e7330614f5203af Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:13:32 -0800 Subject: [ATM]: always return the first interface for ATM_ITF_ANY From: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/net/atm/common.c b/net/atm/common.c index 63feea4..83454e1 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -423,33 +423,23 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS || vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) return -EINVAL; - if (itf != ATM_ITF_ANY) { + if (likely(itf != ATM_ITF_ANY)) { dev = atm_dev_lookup(itf); - if (!dev) - return -ENODEV; - error = __vcc_connect(vcc, dev, vpi, vci); - if (error) { - atm_dev_put(dev); - return error; - } } else { - struct list_head *p, *next; - dev = NULL; spin_lock(&atm_dev_lock); - list_for_each_safe(p, next, &atm_devs) { - dev = list_entry(p, struct atm_dev, dev_list); + if (!list_empty(&atm_devs)) { + dev = list_entry(atm_devs.next, struct atm_dev, dev_list); atm_dev_hold(dev); - spin_unlock(&atm_dev_lock); - if (!__vcc_connect(vcc, dev, vpi, vci)) - break; - atm_dev_put(dev); - dev = NULL; - spin_lock(&atm_dev_lock); } spin_unlock(&atm_dev_lock); - if (!dev) - return -ENODEV; + } + if (!dev) + return -ENODEV; + error = __vcc_connect(vcc, dev, vpi, vci); + if (error) { + atm_dev_put(dev); + return error; } if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) set_bit(ATM_VF_PARTIAL,&vcc->flags); -- cgit v0.10.2 From c219750b2e667f4f79f4d8faca5057dad793db87 Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:13:55 -0800 Subject: [ATM]: atm_pcr_goal() doesn't modify its argument's contents -- mark it as const Signed-off-by: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index e7d0593..37e5ee4 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -468,7 +468,7 @@ static inline void atm_dev_put(struct atm_dev *dev) int atm_charge(struct atm_vcc *vcc,int truesize); struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, gfp_t gfp_flags); -int atm_pcr_goal(struct atm_trafprm *tp); +int atm_pcr_goal(const struct atm_trafprm *tp); void vcc_release_async(struct atm_vcc *vcc, int reply); diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c index 223c7ad..02cc7e7 100644 --- a/net/atm/atm_misc.c +++ b/net/atm/atm_misc.c @@ -74,11 +74,14 @@ struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size, */ -int atm_pcr_goal(struct atm_trafprm *tp) +int atm_pcr_goal(const struct atm_trafprm *tp) { - if (tp->pcr && tp->pcr != ATM_MAX_PCR) return -tp->pcr; - if (tp->min_pcr && !tp->pcr) return tp->min_pcr; - if (tp->max_pcr != ATM_MAX_PCR) return -tp->max_pcr; + if (tp->pcr && tp->pcr != ATM_MAX_PCR) + return -tp->pcr; + if (tp->min_pcr && !tp->pcr) + return tp->min_pcr; + if (tp->max_pcr != ATM_MAX_PCR) + return -tp->max_pcr; return 0; } -- cgit v0.10.2 From c22c28f69b1e28505bd0d26bd0f64554a9e66fe8 Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:14:12 -0800 Subject: [ATM]: [lanai] better constification Signed-off-by: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 51ec147..3622627 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -305,7 +305,7 @@ struct lanai_dev { * vci with their bit set */ static void vci_bitfield_iterate(struct lanai_dev *lanai, - /*const*/ unsigned long *lp, + const unsigned long *lp, void (*func)(struct lanai_dev *,vci_t vci)) { vci_t vci = find_first_bit(lp, NUM_VCI); @@ -951,7 +951,7 @@ static int __devinit eeprom_read(struct lanai_dev *lanai) /* read a big-endian 4-byte value out of eeprom */ static inline u32 eeprom_be4(const struct lanai_dev *lanai, int address) { - return be32_to_cpup((u32 *) (&lanai->eeprom[address])); + return be32_to_cpup((const u32 *) &lanai->eeprom[address]); } /* Checksum/validate EEPROM contents */ @@ -1160,7 +1160,7 @@ static inline int vcc_tx_space(const struct lanai_vcc *lvcc, int endptr) } /* test if VCC is currently backlogged */ -static inline int vcc_is_backlogged(/*const*/ struct lanai_vcc *lvcc) +static inline int vcc_is_backlogged(const struct lanai_vcc *lvcc) { return !skb_queue_empty(&lvcc->tx.backlog); } @@ -1395,7 +1395,8 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr) { int size; struct sk_buff *skb; - /*const*/ u32 *x, *end = &lvcc->rx.buf.start[endptr * 4]; + const u32 *x; + u32 *end = &lvcc->rx.buf.start[endptr * 4]; int n = ((unsigned long) end) - ((unsigned long) lvcc->rx.buf.ptr); if (n < 0) n += lanai_buf_size(&lvcc->rx.buf); @@ -2111,7 +2112,7 @@ static int lanai_normalize_ci(struct lanai_dev *lanai, * shifted by that much as we compute * */ -static int pcr_to_cbricg(/*const*/ struct atm_qos *qos) +static int pcr_to_cbricg(const struct atm_qos *qos) { int rounddown = 0; /* 1 = Round PCR down, i.e. round ICG _up_ */ int x, icg, pcr = atm_pcr_goal(&qos->txtp); -- cgit v0.10.2 From fd22f1e037be33040f5583fe091d39d1e632e183 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 29 Nov 2005 16:14:33 -0800 Subject: [ATM]: [lanai] lanai missing unregister Signed-off-by: Dave Jones Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 3622627..2abf3ed 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -2761,6 +2761,7 @@ static void __exit lanai_module_exit(void) * gone, so there isn't much to do */ DPRINTK("cleanup_module()\n"); + pci_unregister_driver(&lanai_driver); } module_init(lanai_module_init); -- cgit v0.10.2 From e91a73568b19b4a8145fc6e05314d522ee35a0b1 Mon Sep 17 00:00:00 2001 From: Jan Pieter Date: Tue, 29 Nov 2005 16:14:58 -0800 Subject: [ATM]: drivers/atm/atmdev_init.c no longer necessary From: Jan Pieter Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/atmdev_init.c b/drivers/atm/atmdev_init.c deleted file mode 100644 index 0e09e5c..0000000 --- a/drivers/atm/atmdev_init.c +++ /dev/null @@ -1,54 +0,0 @@ -/* drivers/atm/atmdev_init.c - ATM device driver initialization */ - -/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ - - -#include -#include - - -#ifdef CONFIG_ATM_ZATM -extern int zatm_detect(void); -#endif -#ifdef CONFIG_ATM_AMBASSADOR -extern int amb_detect(void); -#endif -#ifdef CONFIG_ATM_HORIZON -extern int hrz_detect(void); -#endif -#ifdef CONFIG_ATM_FORE200E -extern int fore200e_detect(void); -#endif -#ifdef CONFIG_ATM_LANAI -extern int lanai_detect(void); -#endif - - -/* - * For historical reasons, atmdev_init returns the number of devices found. - * Note that some detections may not go via atmdev_init (e.g. eni.c), so this - * number is meaningless. - */ - -int __init atmdev_init(void) -{ - int devs; - - devs = 0; -#ifdef CONFIG_ATM_ZATM - devs += zatm_detect(); -#endif -#ifdef CONFIG_ATM_AMBASSADOR - devs += amb_detect(); -#endif -#ifdef CONFIG_ATM_HORIZON - devs += hrz_detect(); -#endif -#ifdef CONFIG_ATM_FORE200E - devs += fore200e_detect(); -#endif -#ifdef CONFIG_ATM_LANAI - devs += lanai_detect(); -#endif - return devs; -} -- cgit v0.10.2 From 50accc9c428273501dd2a6295c84a533dd1fe645 Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:15:18 -0800 Subject: [ATM]: attempt to autoload atm drivers From: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/net/atm/common.c b/net/atm/common.c index 83454e1..db9318f 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -424,7 +424,7 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) return -EINVAL; if (likely(itf != ATM_ITF_ANY)) { - dev = atm_dev_lookup(itf); + dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf); } else { dev = NULL; spin_lock(&atm_dev_lock); diff --git a/net/atm/resources.c b/net/atm/resources.c index 415d261..35f3ceb 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -245,7 +245,8 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) if (get_user(number, &sioc->number)) return -EFAULT; - if (!(dev = atm_dev_lookup(number))) + if (!(dev = try_then_request_module(atm_dev_lookup(number), + "atm-device-%d", number))) return -ENODEV; switch (cmd) { -- cgit v0.10.2 From 5045b6d34c6a9efa4a8a1815265ca9fcf44d6a7c Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Tue, 29 Nov 2005 16:15:38 -0800 Subject: [ATM]: linux/config.h only needed for #ifdef __KERNEL__ section Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 37e5ee4..8fadb07 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -7,7 +7,6 @@ #define LINUX_ATMDEV_H -#include #include #include #include @@ -210,6 +209,7 @@ struct atm_cirange { #ifdef __KERNEL__ +#include #include /* wait_queue_head_t */ #include /* struct timeval */ #include -- cgit v0.10.2 From 49693280262a149e5430d3401e263e464c88334a Mon Sep 17 00:00:00 2001 From: Mitchell Blank Jr Date: Tue, 29 Nov 2005 16:15:59 -0800 Subject: [ATM]: [lanai] kill lanai_ioctl() which just contains some old debugging code Signed-off-by: Mitchell Blank Jr Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 2abf3ed..69f4c7c 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -39,7 +39,7 @@ * o lanai_change_qos() isn't written yet * * o There aren't any ioctl's yet -- I'd like to eventually support - * setting loopback and LED modes that way. (see lanai_ioctl) + * setting loopback and LED modes that way. * * o If the segmentation engine or DMA gets shut down we should restart * card as per section 17.0i. (see lanai_reset) @@ -2435,93 +2435,6 @@ static int lanai_open(struct atm_vcc *atmvcc) return result; } -#if 0 -/* ioctl operations for card */ -/* NOTE: these are all DEBUGGING ONLY currently */ -static int lanai_ioctl(struct atm_dev *atmdev, unsigned int cmd, void __user *arg) -{ - int result = 0; - struct lanai_dev *lanai = (struct lanai_dev *) atmdev->dev_data; - switch(cmd) { - case 2106275: - shutdown_atm_dev(atmdev); - return 0; - case 2200000: { - unsigned long flags; - spin_lock_irqsave(&lanai->servicelock, flags); - run_service(lanai); - spin_unlock_irqrestore(&lanai->servicelock, flags); - return 0; } - case 2200002: - get_statistics(lanai); - return 0; - case 2200003: { - unsigned int i; - for (i = 0; i <= 0x5C ; i += 4) { - if (i==0x48) /* Write-only butt reg */ - continue; - printk(KERN_CRIT DEV_LABEL " 0x%02X: " - "0x%08X\n", i, - (unsigned int) readl(lanai->base + i)); - barrier(); mb(); - pcistatus_check(lanai, 0); - barrier(); mb(); - } - return 0; } - case 2200004: { - u8 b; - u16 w; - u32 dw; - struct pci_dev *pci = lanai->pci; - (void) pci_read_config_word(pci, PCI_VENDOR_ID, &w); - DPRINTK("vendor = 0x%X\n", (unsigned int) w); - (void) pci_read_config_word(pci, PCI_DEVICE_ID, &w); - DPRINTK("device = 0x%X\n", (unsigned int) w); - (void) pci_read_config_word(pci, PCI_COMMAND, &w); - DPRINTK("command = 0x%X\n", (unsigned int) w); - (void) pci_read_config_word(pci, PCI_STATUS, &w); - DPRINTK("status = 0x%X\n", (unsigned int) w); - (void) pci_read_config_dword(pci, - PCI_CLASS_REVISION, &dw); - DPRINTK("class/revision = 0x%X\n", (unsigned int) dw); - (void) pci_read_config_byte(pci, - PCI_CACHE_LINE_SIZE, &b); - DPRINTK("cache line size = 0x%X\n", (unsigned int) b); - (void) pci_read_config_byte(pci, PCI_LATENCY_TIMER, &b); - DPRINTK("latency = %d (0x%X)\n", - (int) b, (unsigned int) b); - (void) pci_read_config_byte(pci, PCI_HEADER_TYPE, &b); - DPRINTK("header type = 0x%X\n", (unsigned int) b); - (void) pci_read_config_byte(pci, PCI_BIST, &b); - DPRINTK("bist = 0x%X\n", (unsigned int) b); - /* skipping a few here */ - (void) pci_read_config_byte(pci, - PCI_INTERRUPT_LINE, &b); - DPRINTK("pci_int_line = 0x%X\n", (unsigned int) b); - (void) pci_read_config_byte(pci, - PCI_INTERRUPT_PIN, &b); - DPRINTK("pci_int_pin = 0x%X\n", (unsigned int) b); - (void) pci_read_config_byte(pci, PCI_MIN_GNT, &b); - DPRINTK("min_gnt = 0x%X\n", (unsigned int) b); - (void) pci_read_config_byte(pci, PCI_MAX_LAT, &b); - DPRINTK("max_lat = 0x%X\n", (unsigned int) b); } - return 0; -#ifdef USE_POWERDOWN - case 2200005: - DPRINTK("Coming out of powerdown\n"); - lanai->conf1 &= ~CONFIG1_POWERDOWN; - conf1_write(lanai); - return 0; -#endif - default: - result = -ENOIOCTLCMD; - } - return result; -} -#else /* !0 */ -#define lanai_ioctl NULL -#endif /* 0 */ - static int lanai_send(struct atm_vcc *atmvcc, struct sk_buff *skb) { struct lanai_vcc *lvcc = (struct lanai_vcc *) atmvcc->dev_data; @@ -2679,7 +2592,6 @@ static const struct atmdev_ops ops = { .dev_close = lanai_dev_close, .open = lanai_open, .close = lanai_close, - .ioctl = lanai_ioctl, .getsockopt = NULL, .setsockopt = NULL, .send = lanai_send, -- cgit v0.10.2 From aaaaaadbe7a663d110814db50fcbe7d320eb4c32 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 29 Nov 2005 16:16:21 -0800 Subject: [ATM]: avoid race conditions related to atm_devs list Use semaphore to protect atm_devs list, as no one need access to it from interrupt context. Avoid race conditions between atm_dev_register(), atm_dev_lookup() and atm_dev_deregister(). Fix double spin_unlock() bug. Signed-off-by: Stanislaw Gruszka Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/net/atm/common.c b/net/atm/common.c index db9318f..9e016f4 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -427,12 +427,12 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci) dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf); } else { dev = NULL; - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); if (!list_empty(&atm_devs)) { dev = list_entry(atm_devs.next, struct atm_dev, dev_list); atm_dev_hold(dev); } - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); } if (!dev) return -ENODEV; diff --git a/net/atm/resources.c b/net/atm/resources.c index 35f3ceb..ad533b0 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -25,7 +25,7 @@ LIST_HEAD(atm_devs); -DEFINE_SPINLOCK(atm_dev_lock); +DECLARE_MUTEX(atm_dev_mutex); static struct atm_dev *__alloc_atm_dev(const char *type) { @@ -52,7 +52,7 @@ static struct atm_dev *__atm_dev_lookup(int number) list_for_each(p, &atm_devs) { dev = list_entry(p, struct atm_dev, dev_list); - if ((dev->ops) && (dev->number == number)) { + if (dev->number == number) { atm_dev_hold(dev); return dev; } @@ -64,9 +64,9 @@ struct atm_dev *atm_dev_lookup(int number) { struct atm_dev *dev; - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); dev = __atm_dev_lookup(number); - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); return dev; } @@ -81,11 +81,11 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, type); return NULL; } - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); if (number != -1) { if ((inuse = __atm_dev_lookup(number))) { atm_dev_put(inuse); - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); kfree(dev); return NULL; } @@ -105,19 +105,17 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, memset(&dev->flags, 0, sizeof(dev->flags)); memset(&dev->stats, 0, sizeof(dev->stats)); atomic_set(&dev->refcnt, 1); - list_add_tail(&dev->dev_list, &atm_devs); - spin_unlock(&atm_dev_lock); if (atm_proc_dev_register(dev) < 0) { printk(KERN_ERR "atm_dev_register: " "atm_proc_dev_register failed for dev %s\n", type); - spin_lock(&atm_dev_lock); - list_del(&dev->dev_list); - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); kfree(dev); return NULL; } + list_add_tail(&dev->dev_list, &atm_devs); + up(&atm_dev_mutex); return dev; } @@ -129,9 +127,9 @@ void atm_dev_deregister(struct atm_dev *dev) atm_proc_dev_deregister(dev); - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); list_del(&dev->dev_list); - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); warning_time = jiffies; while (atomic_read(&dev->refcnt) != 1) { @@ -211,16 +209,16 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) return -EFAULT; if (get_user(len, &iobuf->length)) return -EFAULT; - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); list_for_each(p, &atm_devs) size += sizeof(int); if (size > len) { - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); return -E2BIG; } tmp_buf = kmalloc(size, GFP_ATOMIC); if (!tmp_buf) { - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); return -ENOMEM; } tmp_p = tmp_buf; @@ -228,7 +226,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg) dev = list_entry(p, struct atm_dev, dev_list); *tmp_p++ = dev->number; } - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); error = ((copy_to_user(buf, tmp_buf, size)) || put_user(size, &iobuf->length)) ? -EFAULT : 0; @@ -415,13 +413,13 @@ static __inline__ void *dev_get_idx(loff_t left) void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos) { - spin_lock(&atm_dev_lock); + down(&atm_dev_mutex); return *pos ? dev_get_idx(*pos) : (void *) 1; } void atm_dev_seq_stop(struct seq_file *seq, void *v) { - spin_unlock(&atm_dev_lock); + up(&atm_dev_mutex); } void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) diff --git a/net/atm/resources.h b/net/atm/resources.h index 1291061..b7fb82a 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h @@ -11,8 +11,7 @@ extern struct list_head atm_devs; -extern spinlock_t atm_dev_lock; - +extern struct semaphore atm_dev_mutex; int atm_dev_ioctl(unsigned int cmd, void __user *arg); -- cgit v0.10.2 From 64bf69ddff7637b7ed7acf9b2a823cc0ee519439 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 29 Nov 2005 16:16:41 -0800 Subject: [ATM]: deregistration removes device from atm_devs list immediately atm_dev_deregister() removes device from atm_dev list immediately to prevent operations on a phantom device. Decision to free device based only on ->refcnt now. Remove shutdown_atm_dev() use atm_dev_deregister() instead. atm_dev_deregister() also asynchronously releases all vccs related to device. Signed-off-by: Stanislaw Gruszka Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index 57f1810..fc518d8 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c @@ -246,10 +246,6 @@ static void atmtcp_c_close(struct atm_vcc *vcc) { struct atm_dev *atmtcp_dev; struct atmtcp_dev_data *dev_data; - struct sock *s; - struct hlist_node *node; - struct atm_vcc *walk; - int i; atmtcp_dev = (struct atm_dev *) vcc->dev_data; dev_data = PRIV(atmtcp_dev); @@ -257,20 +253,8 @@ static void atmtcp_c_close(struct atm_vcc *vcc) if (dev_data->persist) return; atmtcp_dev->dev_data = NULL; kfree(dev_data); - shutdown_atm_dev(atmtcp_dev); + atm_dev_deregister(atmtcp_dev); vcc->dev_data = NULL; - read_lock(&vcc_sklist_lock); - for(i = 0; i < VCC_HTABLE_SIZE; ++i) { - struct hlist_head *head = &vcc_hash[i]; - - sk_for_each(s, node, head) { - walk = atm_sk(s); - if (walk->dev != atmtcp_dev) - continue; - wake_up(s->sk_sleep); - } - } - read_unlock(&vcc_sklist_lock); module_put(THIS_MODULE); } @@ -450,7 +434,7 @@ static int atmtcp_remove_persistent(int itf) if (PRIV(dev)->vcc) return 0; kfree(dev_data); atm_dev_put(dev); - shutdown_atm_dev(dev); + atm_dev_deregister(dev); return 0; } diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index c466739..2e6593e 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -879,7 +879,7 @@ static int usbatm_atm_init(struct usbatm_data *instance) fail: instance->atm_dev = NULL; - shutdown_atm_dev(atm_dev); /* usbatm_atm_dev_close will eventually be called */ + atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ return ret; } @@ -1164,7 +1164,7 @@ void usbatm_usb_disconnect(struct usb_interface *intf) /* ATM finalize */ if (instance->atm_dev) - shutdown_atm_dev(instance->atm_dev); + atm_dev_deregister(instance->atm_dev); usbatm_put_instance(instance); /* taken in usbatm_usb_probe */ } diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index 8fadb07..b203ea8 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h @@ -274,7 +274,7 @@ enum { enum { - ATM_DF_CLOSE, /* close device when last VCC is closed */ + ATM_DF_REMOVED, /* device was removed from atm_devs list */ }; @@ -415,7 +415,6 @@ struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, int number,unsigned long *flags); /* number == -1: pick first available */ struct atm_dev *atm_dev_lookup(int number); void atm_dev_deregister(struct atm_dev *dev); -void shutdown_atm_dev(struct atm_dev *dev); void vcc_insert_socket(struct sock *sk); @@ -457,11 +456,12 @@ static inline void atm_dev_hold(struct atm_dev *dev) static inline void atm_dev_put(struct atm_dev *dev) { - atomic_dec(&dev->refcnt); - - if ((atomic_read(&dev->refcnt) == 1) && - test_bit(ATM_DF_CLOSE,&dev->flags)) - shutdown_atm_dev(dev); + if (atomic_dec_and_test(&dev->refcnt)) { + BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags)); + if (dev->ops->dev_close) + dev->ops->dev_close(dev); + kfree(dev); + } } diff --git a/net/atm/common.c b/net/atm/common.c index 9e016f4..6656b11 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -221,6 +221,29 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) EXPORT_SYMBOL(vcc_release_async); +void atm_dev_release_vccs(struct atm_dev *dev) +{ + int i; + + write_lock_irq(&vcc_sklist_lock); + for (i = 0; i < VCC_HTABLE_SIZE; i++) { + struct hlist_head *head = &vcc_hash[i]; + struct hlist_node *node, *tmp; + struct sock *s; + struct atm_vcc *vcc; + + sk_for_each_safe(s, node, tmp, head) { + vcc = atm_sk(s); + if (vcc->dev == dev) { + vcc_release_async(vcc, -EPIPE); + sk_del_node_init(s); + } + } + } + write_unlock_irq(&vcc_sklist_lock); +} + + static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) { int max_sdu; @@ -332,12 +355,13 @@ static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, short vpi, return -EINVAL; if (vci > 0 && vci < ATM_NOT_RSV_VCI && !capable(CAP_NET_BIND_SERVICE)) return -EPERM; - error = 0; + error = -ENODEV; if (!try_module_get(dev->ops->owner)) - return -ENODEV; + return error; vcc->dev = dev; write_lock_irq(&vcc_sklist_lock); - if ((error = find_ci(vcc, &vpi, &vci))) { + if (test_bit(ATM_DF_REMOVED, &dev->flags) || + (error = find_ci(vcc, &vpi, &vci))) { write_unlock_irq(&vcc_sklist_lock); goto fail_module_put; } diff --git a/net/atm/common.h b/net/atm/common.h index e49ed41c..4887c31 100644 --- a/net/atm/common.h +++ b/net/atm/common.h @@ -47,4 +47,6 @@ static inline void atm_proc_exit(void) /* SVC */ int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos); +void atm_dev_release_vccs(struct atm_dev *dev); + #endif diff --git a/net/atm/resources.c b/net/atm/resources.c index ad533b0..c8c459f 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -70,6 +70,7 @@ struct atm_dev *atm_dev_lookup(int number) return dev; } + struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, int number, unsigned long *flags) { @@ -123,37 +124,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, void atm_dev_deregister(struct atm_dev *dev) { - unsigned long warning_time; - - atm_proc_dev_deregister(dev); - + BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags)); + set_bit(ATM_DF_REMOVED, &dev->flags); + + /* + * if we remove current device from atm_devs list, new device + * with same number can appear, such we need deregister proc, + * release async all vccs and remove them from vccs list too + */ down(&atm_dev_mutex); list_del(&dev->dev_list); up(&atm_dev_mutex); - warning_time = jiffies; - while (atomic_read(&dev->refcnt) != 1) { - msleep(250); - if ((jiffies - warning_time) > 10 * HZ) { - printk(KERN_EMERG "atm_dev_deregister: waiting for " - "dev %d to become free. Usage count = %d\n", - dev->number, atomic_read(&dev->refcnt)); - warning_time = jiffies; - } - } - - kfree(dev); -} + atm_dev_release_vccs(dev); + atm_proc_dev_deregister(dev); -void shutdown_atm_dev(struct atm_dev *dev) -{ - if (atomic_read(&dev->refcnt) > 1) { - set_bit(ATM_DF_CLOSE, &dev->flags); - return; - } - if (dev->ops->dev_close) - dev->ops->dev_close(dev); - atm_dev_deregister(dev); + atm_dev_put(dev); } @@ -433,4 +419,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_dev_lookup); -EXPORT_SYMBOL(shutdown_atm_dev); -- cgit v0.10.2 From fb29644994744a63bc57186cefa79534b5d9b5a9 Mon Sep 17 00:00:00 2001 From: Chas Williams Date: Tue, 29 Nov 2005 16:17:11 -0800 Subject: [ATM]: [adummy] dummy ATM driver (similar to net/dummy) Signed-off-by: Chas Williams Signed-off-by: David S. Miller diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index 489de81..01a9f1c 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig @@ -5,6 +5,13 @@ menu "ATM drivers" depends on NETDEVICES && ATM +config ATM_DUMMY + tristate "Dummy ATM driver" + depends on ATM + help + Dummy ATM driver. Useful for proxy signalling, testing, + and development. If unsure, say N. + config ATM_TCP tristate "ATM over TCP" depends on INET && ATM diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 5b77188..b5077ce 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -31,6 +31,7 @@ ifeq ($(CONFIG_ATM_IDT77252_USE_SUNI),y) obj-$(CONFIG_ATM_IDT77252) += suni.o endif +obj-$(CONFIG_ATM_DUMMY) += adummy.o obj-$(CONFIG_ATM_TCP) += atmtcp.o obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o obj-$(CONFIG_ATM_LANAI) += lanai.o diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c new file mode 100644 index 0000000..d15c194 --- /dev/null +++ b/drivers/atm/adummy.c @@ -0,0 +1,168 @@ +/* + * adummy.c: a dummy ATM driver + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* version definition */ + +#define DRV_VERSION "1.0" + +#define DEV_LABEL "adummy" + +#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data) + +struct adummy_dev { + struct atm_dev *atm_dev; + + struct list_head entry; +}; + +/* globals */ + +static LIST_HEAD(adummy_devs); + +static int __init +adummy_start(struct atm_dev *dev) +{ + dev->ci_range.vpi_bits = 4; + dev->ci_range.vci_bits = 12; + + return 0; +} + +static int +adummy_open(struct atm_vcc *vcc) +{ + short vpi = vcc->vpi; + int vci = vcc->vci; + + if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC) + return 0; + + set_bit(ATM_VF_ADDR, &vcc->flags); + set_bit(ATM_VF_READY, &vcc->flags); + + return 0; +} + +static void +adummy_close(struct atm_vcc *vcc) +{ + clear_bit(ATM_VF_READY, &vcc->flags); + clear_bit(ATM_VF_ADDR, &vcc->flags); +} + +static int +adummy_send(struct atm_vcc *vcc, struct sk_buff *skb) +{ + if (vcc->pop) + vcc->pop(vcc, skb); + else + dev_kfree_skb_any(skb); + atomic_inc(&vcc->stats->tx); + + return 0; +} + +static int +adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page) +{ + int left = *pos; + + if (!left--) + return sprintf(page, "version %s\n", DRV_VERSION); + + return 0; +} + +static struct atmdev_ops adummy_ops = +{ + .open = adummy_open, + .close = adummy_close, + .send = adummy_send, + .proc_read = adummy_proc_read, + .owner = THIS_MODULE +}; + +static int __init adummy_init(void) +{ + struct atm_dev *atm_dev; + struct adummy_dev *adummy_dev; + int err = 0; + + printk(KERN_ERR "adummy: version %s\n", DRV_VERSION); + + adummy_dev = (struct adummy_dev *) kmalloc(sizeof(struct adummy_dev), + GFP_KERNEL); + if (!adummy_dev) { + printk(KERN_ERR DEV_LABEL ": kmalloc() failed\n"); + err = -ENOMEM; + goto out; + } + memset(adummy_dev, 0, sizeof(struct adummy_dev)); + + atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, 0); + if (!atm_dev) { + printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); + err = -ENODEV; + goto out_kfree; + } + + adummy_dev->atm_dev = atm_dev; + atm_dev->dev_data = adummy_dev; + + if (adummy_start(atm_dev)) { + printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n"); + err = -ENODEV; + goto out_unregister; + } + + list_add(&adummy_dev->entry, &adummy_devs); +out: + return err; + +out_unregister: + atm_dev_deregister(atm_dev); +out_kfree: + kfree(adummy_dev); + goto out; +} + +static void __exit adummy_cleanup(void) +{ + struct adummy_dev *adummy_dev, *next; + + list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) { + atm_dev_deregister(adummy_dev->atm_dev); + kfree(adummy_dev); + } +} + +module_init(adummy_init); +module_exit(adummy_cleanup); + +MODULE_AUTHOR("chas williams "); +MODULE_DESCRIPTION("dummy ATM driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From 9b5b5cff9a6655dbb6d2e2be365bb95eec3950eb Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Tue, 29 Nov 2005 16:21:38 -0800 Subject: [NET]: Add const markers to various variables. the patch below marks various variables const in net/; the goal is to move them to the .rodata section so that they can't false-share cachelines with things that get written to, as well as potentially helping gcc a bit with optimisations. (these were found using a gcc patch to warn about such variables) Signed-off-by: Arjan van de Ven Signed-off-by: David S. Miller diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 2a8c9af..7ea0209 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -975,7 +975,7 @@ static void fib_seq_stop(struct seq_file *seq, void *v) static unsigned fib_flag_trans(int type, u32 mask, struct fib_info *fi) { - static unsigned type2flags[RTN_MAX + 1] = { + static const unsigned type2flags[RTN_MAX + 1] = { [7] = RTF_REJECT, [8] = RTF_REJECT, }; unsigned flags = type2flags[type]; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 186f20c..6d2a6ac 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -83,7 +83,7 @@ for (nhsel=0; nhsel < 1; nhsel++) #define endfor_nexthops(fi) } -static struct +static const struct { int error; u8 scope; diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index e3eceec..92e23b2 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -220,7 +220,7 @@ struct icmp_control { short error; /* This ICMP is classed as an error message */ }; -static struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; +static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; /* * The ICMP socket(s). This is the most convenient way to flow control @@ -994,7 +994,7 @@ error: /* * This table is the definition of how we handle ICMP. */ -static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { +static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { [ICMP_ECHOREPLY] = { .output_entry = ICMP_MIB_OUTECHOREPS, .input_entry = ICMP_MIB_INECHOREPS, diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index f828fa2..2a3a8c5 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -771,7 +771,7 @@ static inline int todrop_entry(struct ip_vs_conn *cp) * The drop rate array needs tuning for real environments. * Called from timer bh only => no locking */ - static char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; + static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; static char todrop_counter[9] = {0}; int i; diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 2d66848..9bdcf31 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c @@ -1909,7 +1909,7 @@ static int ip_vs_set_timeout(struct ip_vs_timeout_user *u) #define DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user)) #define MAX_ARG_LEN SVCDEST_ARG_LEN -static unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { +static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { [SET_CMDID(IP_VS_SO_SET_ADD)] = SERVICE_ARG_LEN, [SET_CMDID(IP_VS_SO_SET_EDIT)] = SERVICE_ARG_LEN, [SET_CMDID(IP_VS_SO_SET_DEL)] = SERVICE_ARG_LEN, @@ -2180,7 +2180,7 @@ __ip_vs_get_timeouts(struct ip_vs_timeout_user *u) #define GET_TIMEOUT_ARG_LEN (sizeof(struct ip_vs_timeout_user)) #define GET_DAEMON_ARG_LEN (sizeof(struct ip_vs_daemon_user) * 2) -static unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = { +static const unsigned char get_arglen[GET_CMDID(IP_VS_SO_GET_MAX)+1] = { [GET_CMDID(IP_VS_SO_GET_VERSION)] = 64, [GET_CMDID(IP_VS_SO_GET_INFO)] = GET_INFO_ARG_LEN, [GET_CMDID(IP_VS_SO_GET_SERVICES)] = GET_SERVICES_ARG_LEN, diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c index c194089..0e878fd 100644 --- a/net/ipv4/ipvs/ip_vs_proto_tcp.c +++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c @@ -251,7 +251,7 @@ tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) #define TCP_DIR_OUTPUT 4 #define TCP_DIR_INPUT_ONLY 8 -static int tcp_state_off[IP_VS_DIR_LAST] = { +static const int tcp_state_off[IP_VS_DIR_LAST] = { [IP_VS_DIR_INPUT] = TCP_DIR_INPUT, [IP_VS_DIR_OUTPUT] = TCP_DIR_OUTPUT, [IP_VS_DIR_INPUT_ONLY] = TCP_DIR_INPUT_ONLY, diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index fa3f914..e52847f 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -37,7 +37,7 @@ MODULE_LICENSE("GPL"); module_param(master_timeout, int, 0600); MODULE_PARM_DESC(master_timeout, "timeout for the master connection"); -static char *conns[] = { "DATA ", "MESG ", "INDEX " }; +static const char *conns[] = { "DATA ", "MESG ", "INDEX " }; /* This is slow, but it's simple. --RR */ static char *amanda_buffer; diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 59e12b0..68b173b 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -55,7 +55,7 @@ static int try_rfc959(const char *, size_t, u_int32_t [], char); static int try_eprt(const char *, size_t, u_int32_t [], char); static int try_epsv_response(const char *, size_t, u_int32_t [], char); -static struct ftp_search { +static const struct ftp_search { enum ip_conntrack_dir dir; const char *pattern; size_t plen; diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index 2dea1db..d7c4042 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c @@ -59,7 +59,7 @@ MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per IRC module_param(dcc_timeout, int, 0400); MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels"); -static char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; +static const char *dccprotos[] = { "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT " }; #define MINMATCHLEN 5 #if 0 diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index e4d6b26..5f9925d 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c @@ -51,7 +51,7 @@ static int icmp_invert_tuple(struct ip_conntrack_tuple *tuple, const struct ip_conntrack_tuple *orig) { /* Add 1; spaces filled with 0. */ - static u_int8_t invmap[] + static const u_int8_t invmap[] = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, [ICMP_ECHOREPLY] = ICMP_ECHO + 1, [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, @@ -110,7 +110,7 @@ static int icmp_packet(struct ip_conntrack *ct, return NF_ACCEPT; } -static u_int8_t valid_new[] = { +static const u_int8_t valid_new[] = { [ICMP_ECHO] = 1, [ICMP_TIMESTAMP] = 1, [ICMP_INFO_REQUEST] = 1, diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 59a4a01..977fb59 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -65,7 +65,7 @@ static unsigned long ip_ct_sctp_timeout_shutdown_sent = 300 SECS / 1000; static unsigned long ip_ct_sctp_timeout_shutdown_recd = 300 SECS / 1000; static unsigned long ip_ct_sctp_timeout_shutdown_ack_sent = 3 SECS; -static unsigned long * sctp_timeouts[] +static const unsigned long * sctp_timeouts[] = { NULL, /* SCTP_CONNTRACK_NONE */ &ip_ct_sctp_timeout_closed, /* SCTP_CONNTRACK_CLOSED */ &ip_ct_sctp_timeout_cookie_wait, /* SCTP_CONNTRACK_COOKIE_WAIT */ @@ -118,7 +118,7 @@ cookie echoed to closed. */ /* SCTP conntrack state transitions */ -static enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { +static const enum sctp_conntrack sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = { { /* ORIGINAL */ /* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */ diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index ee3b7d6..6259816 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -99,7 +99,7 @@ unsigned long ip_ct_tcp_timeout_close = 10 SECS; to ~13-30min depending on RTO. */ unsigned long ip_ct_tcp_timeout_max_retrans = 5 MINS; -static unsigned long * tcp_timeouts[] +static const unsigned long * tcp_timeouts[] = { NULL, /* TCP_CONNTRACK_NONE */ &ip_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */ &ip_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */ @@ -170,7 +170,7 @@ enum tcp_bit_set { * if they are invalid * or we do not support the request (simultaneous open) */ -static enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { +static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = { { /* ORIGINAL */ /* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ @@ -817,7 +817,7 @@ void ip_conntrack_tcp_update(struct sk_buff *skb, #define TH_CWR 0x80 /* table of valid flag combinations - ECE and CWR are always valid */ -static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = +static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] = { [TH_SYN] = 1, [TH_SYN|TH_ACK] = 1, diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 75c27e9..45886c8 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1892,7 +1892,7 @@ static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) return pos; } -static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = +static const struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = { { "ip_tables_names", ipt_get_tables }, { "ip_tables_targets", ipt_get_targets }, { "ip_tables_matches", ipt_get_matches }, diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 92ed050..180d6ca 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -197,7 +197,7 @@ static void dump_packet(const struct nf_loginfo *info, } case IPPROTO_ICMP: { struct icmphdr _icmph, *ich; - static size_t required_len[NR_ICMP_TYPES+1] + static const size_t required_len[NR_ICMP_TYPES+1] = { [ICMP_ECHOREPLY] = 4, [ICMP_DEST_UNREACH] = 8 + sizeof(struct iphdr), diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index a65e508..0d7dc66 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -98,7 +98,7 @@ fold_field(void *mib[], int offt) } /* snmp items */ -static struct snmp_mib snmp4_ipstats_list[] = { +static const struct snmp_mib snmp4_ipstats_list[] = { SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES), SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS), SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS), @@ -119,7 +119,7 @@ static struct snmp_mib snmp4_ipstats_list[] = { SNMP_MIB_SENTINEL }; -static struct snmp_mib snmp4_icmp_list[] = { +static const struct snmp_mib snmp4_icmp_list[] = { SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS), SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS), SNMP_MIB_ITEM("InDestUnreachs", ICMP_MIB_INDESTUNREACHS), @@ -149,7 +149,7 @@ static struct snmp_mib snmp4_icmp_list[] = { SNMP_MIB_SENTINEL }; -static struct snmp_mib snmp4_tcp_list[] = { +static const struct snmp_mib snmp4_tcp_list[] = { SNMP_MIB_ITEM("RtoAlgorithm", TCP_MIB_RTOALGORITHM), SNMP_MIB_ITEM("RtoMin", TCP_MIB_RTOMIN), SNMP_MIB_ITEM("RtoMax", TCP_MIB_RTOMAX), @@ -167,7 +167,7 @@ static struct snmp_mib snmp4_tcp_list[] = { SNMP_MIB_SENTINEL }; -static struct snmp_mib snmp4_udp_list[] = { +static const struct snmp_mib snmp4_udp_list[] = { SNMP_MIB_ITEM("InDatagrams", UDP_MIB_INDATAGRAMS), SNMP_MIB_ITEM("NoPorts", UDP_MIB_NOPORTS), SNMP_MIB_ITEM("InErrors", UDP_MIB_INERRORS), @@ -175,7 +175,7 @@ static struct snmp_mib snmp4_udp_list[] = { SNMP_MIB_SENTINEL }; -static struct snmp_mib snmp4_net_list[] = { +static const struct snmp_mib snmp4_net_list[] = { SNMP_MIB_ITEM("SyncookiesSent", LINUX_MIB_SYNCOOKIESSENT), SNMP_MIB_ITEM("SyncookiesRecv", LINUX_MIB_SYNCOOKIESRECV), SNMP_MIB_ITEM("SyncookiesFailed", LINUX_MIB_SYNCOOKIESFAILED), diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e9c14f4..f701a13 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1371,7 +1371,7 @@ out: kfree_skb(skb); * are needed for AMPRnet AX.25 paths. */ -static unsigned short mtu_plateau[] = +static const unsigned short mtu_plateau[] = {32000, 17914, 8166, 4352, 2002, 1492, 576, 296, 216, 128 }; static __inline__ unsigned short guess_mtu(unsigned short old_mtu) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5e6bc4b..ef98b14 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1413,7 +1413,7 @@ recv_urg: * closed. */ -static unsigned char new_state[16] = { +static const unsigned char new_state[16] = { /* current state: new state: action: */ /* (Invalid) */ TCP_CLOSE, /* TCP_ESTABLISHED */ TCP_FIN_WAIT1 | TCP_ACTION_FIN, diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 1bdf0fb..34a3322 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -751,7 +751,7 @@ void icmpv6_cleanup(void) inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); } -static struct icmp6_err { +static const struct icmp6_err { int err; int fatal; } tab_unreach[] = { diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 7d49222..95d4692 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1972,7 +1972,7 @@ static int ip6t_get_matches(char *buffer, char **start, off_t offset, int length return pos; } -static struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = +static const struct { char *name; get_info_t *get_info; } ip6t_proc_entry[] = { { "ip6_tables_names", ip6t_get_tables }, { "ip6_tables_targets", ip6t_get_targets }, { "ip6_tables_matches", ip6t_get_matches }, -- cgit v0.10.2 From 4b30b1c6a3e58dc74f2dbb0aa39f16a23cfcdd56 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Nov 2005 16:27:20 -0800 Subject: [IPV4]: make two functions static This patch makes two needlessly global functions static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 4e9c74b..a4c347c 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1217,7 +1217,7 @@ static int ipgre_tunnel_init(struct net_device *dev) return 0; } -int __init ipgre_fb_tunnel_init(struct net_device *dev) +static int __init ipgre_fb_tunnel_init(struct net_device *dev) { struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv; struct iphdr *iph = &tunnel->parms.iph; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 11c2f68..eba64e2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -690,7 +690,7 @@ csum_page(struct page *page, int offset, int copy) return csum; } -inline int ip_ufo_append_data(struct sock *sk, +static inline int ip_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, -- cgit v0.10.2 From d127e94a5cf1c9c996b8c67cd2595b96c3e35e4c Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Nov 2005 16:28:18 -0800 Subject: [NETFILTER] ipv4: small cleanups This patch contains the following cleanups: - make needlessly global code static - ip_conntrack_core.c: ip_conntrack_flush() -> ip_conntrack_flush(void) Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 422ab68..7a4ecdd 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1354,7 +1354,7 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced,int size) get_order(sizeof(struct list_head) * size)); } -void ip_conntrack_flush() +void ip_conntrack_flush(void) { /* This makes sure all current packets have passed through netfilter framework. Roll on, two-stage module @@ -1408,7 +1408,7 @@ static struct list_head *alloc_hashtable(int size, int *vmalloced) return hash; } -int set_hashsize(const char *val, struct kernel_param *kp) +static int set_hashsize(const char *val, struct kernel_param *kp) { int i, bucket, hashsize, vmalloced; int old_vmalloced, old_size; diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index 762f4d9..c1a6146 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -49,7 +49,7 @@ static unsigned int ip_nat_htable_size; static struct list_head *bysource; #define MAX_IP_NAT_PROTO 256 -struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO]; +static struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO]; static inline struct ip_nat_protocol * __ip_nat_proto_find(u_int8_t protonum) diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 180d6ca..30be0f1 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -351,7 +351,7 @@ static void dump_packet(const struct nf_loginfo *info, /* maxlen = 230+ 91 + 230 + 252 = 803 */ } -struct nf_loginfo default_loginfo = { +static struct nf_loginfo default_loginfo = { .type = NF_LOG_TYPE_LOG, .u = { .log = { -- cgit v0.10.2 From 34a0b3cdc078746788ffc49e56da0db62b8b6ea4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Nov 2005 16:28:56 -0800 Subject: [IPV6]: make two functions static This patch makes two needlessly global functions static. Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index c1fa693..8523c76 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -774,7 +774,8 @@ out_err_release: *dst = NULL; return err; } -inline int ip6_ufo_append_data(struct sock *sk, + +static inline int ip6_ufo_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb), void *from, int length, int hh_len, int fragheaderlen, diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 25757ad..3620718 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -628,8 +628,8 @@ e_inval: return -EINVAL; } -int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, - char __user *optval, int len) +static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_opt_hdr *hdr, + char __user *optval, int len) { if (!hdr) return 0; -- cgit v0.10.2 From 49c91fb01ff3948285608c65754b3ffbf57d50f2 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 29 Nov 2005 19:27:22 -0500 Subject: [PATCH] VM: Fix typos in get_locked_pte Signed-off-by: Trond Myklebust Signed-off-by: Linus Torvalds diff --git a/mm/memory.c b/mm/memory.c index 5bfa52a..8d10b55 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1146,12 +1146,12 @@ int zeromap_page_range(struct vm_area_struct *vma, return err; } -pte_t *get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) +pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) { pgd_t * pgd = pgd_offset(mm, addr); pud_t * pud = pud_alloc(mm, pgd, addr); if (pud) { - pmd_t * pmd = pmd_alloc(mm, pgd, addr); + pmd_t * pmd = pmd_alloc(mm, pud, addr); if (pmd) return pte_alloc_map_lock(mm, pmd, addr, ptl); } -- cgit v0.10.2 From 8117ce76c28ef0cab8545b518fa0543f6d1437e6 Mon Sep 17 00:00:00 2001 From: Paolo Galtieri Date: Tue, 29 Nov 2005 14:26:47 -0800 Subject: [PATCH] ppc: fix floating point register corruption I recently discovered a bug on PPC which causes the floating point registers to get corrupted when CONFIG_PREEMPT=y. The problem occurred while running a multi threaded Java application that does floating point. The problem could be reproduced in anywhere from 2 to 6 hours. With the patch I have included below it ran for over a week without failure. Signed-off-by: Paolo Galtieri Cc: Kumar Gala Cc: Matt Porter Cc: Tom Rini Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index cb1c7b9..25cbdc8 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -417,6 +417,7 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -425,10 +426,12 @@ void exit_thread(void) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); } void flush_thread(void) { + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -437,6 +440,7 @@ void flush_thread(void) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); } void @@ -535,6 +539,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER; + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -543,6 +548,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC -- cgit v0.10.2 From 48abec07cf8063184d397560a6a5f27eaf9caddf Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Wed, 30 Nov 2005 13:20:54 +1100 Subject: powerpc: Fix bug causing FP registers corruption on UP + preempt This fixes a bug noticed by Paolo Galtieri and fixed for ARCH=ppc in the previous commit (ppc: fix floating point register corruption). This fixes the arch/powerpc code by adding preempt_disable/enable, and also cleans it up a bit by pulling out the code that discards any lazily-switched CPU register state into a new function, rather than having that code repeated in three places. Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index a5a7542..105d560 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -201,6 +201,28 @@ int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs) } #endif /* CONFIG_SPE */ +/* + * If we are doing lazy switching of CPU state (FP, altivec or SPE), + * and the current task has some state, discard it. + */ +static inline void discard_lazy_cpu_state(void) +{ +#ifndef CONFIG_SMP + preempt_disable(); + if (last_task_used_math == current) + last_task_used_math = NULL; +#ifdef CONFIG_ALTIVEC + if (last_task_used_altivec == current) + last_task_used_altivec = NULL; +#endif /* CONFIG_ALTIVEC */ +#ifdef CONFIG_SPE + if (last_task_used_spe == current) + last_task_used_spe = NULL; +#endif + preempt_enable(); +#endif /* CONFIG_SMP */ +} + int set_dabr(unsigned long dabr) { if (ppc_md.set_dabr) @@ -434,19 +456,7 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { kprobe_flush_task(current); - -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_SPE - if (last_task_used_spe == current) - last_task_used_spe = NULL; -#endif -#endif /* CONFIG_SMP */ + discard_lazy_cpu_state(); } void flush_thread(void) @@ -458,18 +468,7 @@ void flush_thread(void) t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); #endif -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif /* CONFIG_ALTIVEC */ -#ifdef CONFIG_SPE - if (last_task_used_spe == current) - last_task_used_spe = NULL; -#endif -#endif /* CONFIG_SMP */ + discard_lazy_cpu_state(); #ifdef CONFIG_PPC64 /* for now */ if (current->thread.dabr) { @@ -635,18 +634,7 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp) } #endif -#ifndef CONFIG_SMP - if (last_task_used_math == current) - last_task_used_math = NULL; -#ifdef CONFIG_ALTIVEC - if (last_task_used_altivec == current) - last_task_used_altivec = NULL; -#endif -#ifdef CONFIG_SPE - if (last_task_used_spe == current) - last_task_used_spe = NULL; -#endif -#endif /* CONFIG_SMP */ + discard_lazy_cpu_state(); memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC -- cgit v0.10.2 From ed1189b7e8cd8144f0b232c220aed4ee26d89463 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 29 Nov 2005 14:04:05 +0100 Subject: [PATCH] powerpc: prevent stack corruption in call_prom_ret Use the correct pointer to clear the memory of the return values, to prevent stack corruption in the callers stackframe. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 4ce0105..bcdc209 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -265,7 +265,7 @@ static int __init call_prom_ret(const char *service, int nargs, int nret, va_end(list); for (i = 0; i < nret; i++) - rets[nargs+i] = 0; + args.args[nargs+i] = 0; if (enter_prom(&args, RELOC(prom_entry)) < 0) return PROM_ERROR; -- cgit v0.10.2 From df69a60dc6afc2936d79054d30b481c1fd9720e5 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Tue, 29 Nov 2005 19:34:31 -0800 Subject: [PATCH] process events connector: uid_t gid_t size issues The uid_t and gid_t fields appear to present a 32/64-bit userspace/kernel problem for some archs. This patch addresses the problem by fixing the size to the largest size for uid_t/gid_t used in the kernel. This preserves the total size of the event structure while ensuring that the layouts of the ID change event match in 32 and 64-bit kernels and applications. Signed-off-by: Matt Helsley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 70ab563..c948f67 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -86,12 +86,12 @@ struct proc_event { pid_t process_pid; pid_t process_tgid; union { - uid_t ruid; /* current->uid */ - gid_t rgid; /* current->gid */ + __u32 ruid; /* task uid */ + __u32 rgid; /* task gid */ } r; union { - uid_t euid; - gid_t egid; + __u32 euid; + __u32 egid; } e; } id; -- cgit v0.10.2 From 5bd0190bf3d7e53043a048e809ffa29d41b9d6ac Mon Sep 17 00:00:00 2001 From: David Gibson Date: Tue, 29 Nov 2005 19:34:32 -0800 Subject: [PATCH] Fix crash when ptrace poking hugepage areas set_page_dirty() will not cope with being handed a page * which is part of a compound page, but not the master page in that compound page. This case can occur via access_process_vm() if you attemp to write to another process's hugepage memory area using ptrace() (causing an oops or hang). This patch fixes the bug by only calling set_page_dirty() from access_process_vm() if the page is not a compound page. We already use a similar fix in bio_set_pages_dirty() for the case of direct io to hugepages. Signed-off-by: David Gibson Acked-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 17ee7e5..656476e 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -241,7 +241,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in if (write) { copy_to_user_page(vma, page, addr, maddr + offset, buf, bytes); - set_page_dirty_lock(page); + if (!PageCompound(page)) + set_page_dirty_lock(page); } else { copy_from_user_page(vma, page, addr, buf, maddr + offset, bytes); -- cgit v0.10.2 From d91b14c463306eb6527550ba48617e7f5500d3ae Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Tue, 29 Nov 2005 19:34:35 -0800 Subject: [PATCH] fix rebooting on HP nc6120 laptop Anne NICOLAS and Andres Kaaber reported their HP laptop didn't reboot smoothly. Signed-off-by: Thierry Vignaud Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/i386/kernel/reboot.c b/arch/i386/kernel/reboot.c index 350ea66..2afe0f8 100644 --- a/arch/i386/kernel/reboot.c +++ b/arch/i386/kernel/reboot.c @@ -111,6 +111,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), }, }, + { /* Handle problems with rebooting on HP nc6120 */ + .callback = set_bios_reboot, + .ident = "HP Compaq nc6120", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6120"), + }, + }, { } }; -- cgit v0.10.2 From 123d3c13e2853a11b4d599d754b356acb12886e2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Tue, 29 Nov 2005 19:34:37 -0800 Subject: [PATCH] fix swsusp on machines not supporting S4 Fix swsusp on machines not supporting S4. With recent changes, it is not possible to trigger it using /sys filesystem. Swsusp does not really need any support from low-level code, it is possible to reboot or halt at the end of suspend. Signed-off-by: Pavel Machek Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/kernel/power/main.c b/kernel/power/main.c index 6ee2cad..d253f3a 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -24,7 +24,7 @@ DECLARE_MUTEX(pm_sem); -struct pm_ops * pm_ops = NULL; +struct pm_ops *pm_ops; suspend_disk_method_t pm_disk_mode = PM_DISK_SHUTDOWN; /** @@ -151,6 +151,18 @@ static char *pm_states[PM_SUSPEND_MAX] = { #endif }; +static inline int valid_state(suspend_state_t state) +{ + /* Suspend-to-disk does not really need low-level support. + * It can work with reboot if needed. */ + if (state == PM_SUSPEND_DISK) + return 1; + + if (pm_ops && pm_ops->valid && !pm_ops->valid(state)) + return 0; + return 1; +} + /** * enter_state - Do common work of entering low-power state. @@ -167,7 +179,7 @@ static int enter_state(suspend_state_t state) { int error; - if (pm_ops && pm_ops->valid && !pm_ops->valid(state)) + if (!valid_state(state)) return -ENODEV; if (down_trylock(&pm_sem)) return -EBUSY; @@ -238,9 +250,8 @@ static ssize_t state_show(struct subsystem * subsys, char * buf) char * s = buf; for (i = 0; i < PM_SUSPEND_MAX; i++) { - if (pm_states[i] && pm_ops && (!pm_ops->valid - ||(pm_ops->valid && pm_ops->valid(i)))) - s += sprintf(s,"%s ",pm_states[i]); + if (pm_states[i] && valid_state(i)) + s += sprintf(s,"%s ", pm_states[i]); } s += sprintf(s,"\n"); return (s - buf); -- cgit v0.10.2 From 9f232a125bf86b0dae09f8ea4a0553535cf6b658 Mon Sep 17 00:00:00 2001 From: Paolo Galtieri Date: Tue, 29 Nov 2005 19:34:38 -0800 Subject: [PATCH] ppc: fix floating point register corruption I recently discovered a bug on PPC which causes the floating point registers to get corrupted when CONFIG_PREEMPT=y. The problem occurred while running a multi threaded Java application that does floating point. The problem could be reproduced in anywhere from 2 to 6 hours. With the patch I have included below it ran for over a week without failure. Signed-off-by: Paolo Galtieri Cc: Kumar Gala Cc: Matt Porter Cc: Tom Rini Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index cb1c7b9..25cbdc8 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -417,6 +417,7 @@ void show_regs(struct pt_regs * regs) void exit_thread(void) { + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -425,10 +426,12 @@ void exit_thread(void) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); } void flush_thread(void) { + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -437,6 +440,7 @@ void flush_thread(void) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); } void @@ -535,6 +539,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER; + preempt_disable(); if (last_task_used_math == current) last_task_used_math = NULL; if (last_task_used_altivec == current) @@ -543,6 +548,7 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) if (last_task_used_spe == current) last_task_used_spe = NULL; #endif + preempt_enable(); memset(current->thread.fpr, 0, sizeof(current->thread.fpr)); current->thread.fpscr.val = 0; #ifdef CONFIG_ALTIVEC -- cgit v0.10.2 From 576f6d79564d0d2c1f43088e6805674d2e122935 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Tue, 29 Nov 2005 19:34:39 -0800 Subject: [PATCH] reiserfs: handle cnode allocation failure gracefully If an external device is used for a journal, by default it will use the entire device. The reiserfs journal code allocates structures per journal block when it mounts the file system. If the journal device is too large, and memory cannot be allocated for the structures, it will continue and ultimately panic when it can't pull one off the free list. This patch handles the allocation failure gracefully and prints an error message at mount time. Changes: Updated error message to be more descriptive to the user. Discussed and approved on ReiserFS Mailing List, Nov 28. Signed-off-by: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 4b15761..68b7b78 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2757,6 +2757,15 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, journal->j_cnode_used = 0; journal->j_must_wait = 0; + if (journal->j_cnode_free == 0) { + reiserfs_warning(p_s_sb, "journal-2004: Journal cnode memory " + "allocation failed (%ld bytes). Journal is " + "too large for available memory. Usually " + "this is due to a journal that is too large.", + sizeof (struct reiserfs_journal_cnode) * num_cnodes); + goto free_and_return; + } + init_journal_hash(p_s_sb); jl = journal->j_current_jl; jl->j_list_bitmap = get_list_bitmap(p_s_sb, jl); -- cgit v0.10.2 From b0b623c3b22d57d6941b200321779d56c4e79e6b Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Tue, 29 Nov 2005 19:34:41 -0800 Subject: [PATCH] hfsplus: don't modify journaled volume Access to a journaled HFS+ volume is not officially supported under Linux, so mount such a volume read-only, but users can override this behaviour using the "force" mount option. The minimum requirement to relax this check is to at least check that the journal is empty and so nothing needs to be replayed to make sure the volume is consistent. Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index c60e563..df16fcb 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -151,6 +151,7 @@ struct hfsplus_sb_info { #define HFSPLUS_SB_WRITEBACKUP 0x0001 #define HFSPLUS_SB_NODECOMPOSE 0x0002 +#define HFSPLUS_SB_FORCE 0x0004 struct hfsplus_inode_info { diff --git a/fs/hfsplus/hfsplus_raw.h b/fs/hfsplus/hfsplus_raw.h index 5bad37c..b4fbed6 100644 --- a/fs/hfsplus/hfsplus_raw.h +++ b/fs/hfsplus/hfsplus_raw.h @@ -123,11 +123,13 @@ struct hfsplus_vh { } __packed; /* HFS+ volume attributes */ -#define HFSPLUS_VOL_UNMNT (1 << 8) -#define HFSPLUS_VOL_SPARE_BLK (1 << 9) -#define HFSPLUS_VOL_NOCACHE (1 << 10) -#define HFSPLUS_VOL_INCNSTNT (1 << 11) -#define HFSPLUS_VOL_SOFTLOCK (1 << 15) +#define HFSPLUS_VOL_UNMNT (1 << 8) +#define HFSPLUS_VOL_SPARE_BLK (1 << 9) +#define HFSPLUS_VOL_NOCACHE (1 << 10) +#define HFSPLUS_VOL_INCNSTNT (1 << 11) +#define HFSPLUS_VOL_NODEID_REUSED (1 << 12) +#define HFSPLUS_VOL_JOURNALED (1 << 13) +#define HFSPLUS_VOL_SOFTLOCK (1 << 15) /* HFS+ BTree node descriptor */ struct hfs_bnode_desc { diff --git a/fs/hfsplus/options.c b/fs/hfsplus/options.c index cca0818..935dafb 100644 --- a/fs/hfsplus/options.c +++ b/fs/hfsplus/options.c @@ -22,7 +22,7 @@ enum { opt_umask, opt_uid, opt_gid, opt_part, opt_session, opt_nls, opt_nodecompose, opt_decompose, - opt_err + opt_force, opt_err }; static match_table_t tokens = { @@ -36,6 +36,7 @@ static match_table_t tokens = { { opt_nls, "nls=%s" }, { opt_decompose, "decompose" }, { opt_nodecompose, "nodecompose" }, + { opt_force, "force" }, { opt_err, NULL } }; @@ -145,6 +146,9 @@ int hfsplus_parse_options(char *input, struct hfsplus_sb_info *sbi) case opt_nodecompose: sbi->flags |= HFSPLUS_SB_NODECOMPOSE; break; + case opt_force: + sbi->flags |= HFSPLUS_SB_FORCE; + break; default: return 0; } diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 0ce1c45..8093351 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -251,16 +251,28 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) return 0; if (!(*flags & MS_RDONLY)) { struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr; + struct hfsplus_sb_info sbi; + + memset(&sbi, 0, sizeof(struct hfsplus_sb_info)); + sbi.nls = HFSPLUS_SB(sb).nls; + if (!hfsplus_parse_options(data, &sbi)) + return -EINVAL; if (!(vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_UNMNT))) { printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " "running fsck.hfsplus is recommended. leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; + } else if (sbi.flags & HFSPLUS_SB_FORCE) { + /* nothing */ } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { printk("HFS+-fs: Filesystem is marked locked, leaving read-only.\n"); sb->s_flags |= MS_RDONLY; *flags |= MS_RDONLY; + } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { + printk("HFS+-fs: Filesystem is marked journaled, leaving read-only.\n"); + sb->s_flags |= MS_RDONLY; + *flags |= MS_RDONLY; } } return 0; @@ -352,11 +364,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) printk("HFS+-fs warning: Filesystem was not cleanly unmounted, " "running fsck.hfsplus is recommended. mounting read-only.\n"); sb->s_flags |= MS_RDONLY; + } else if (sbi->flags & HFSPLUS_SB_FORCE) { + /* nothing */ } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_SOFTLOCK)) { if (!silent) printk("HFS+-fs: Filesystem is marked locked, mounting read-only.\n"); sb->s_flags |= MS_RDONLY; + } else if (vhdr->attributes & cpu_to_be32(HFSPLUS_VOL_JOURNALED)) { + if (!silent) + printk("HFS+-fs: write access to a jounaled filesystem is not supported, " + "use the force option at your own risk, mounting read-only.\n"); + sb->s_flags |= MS_RDONLY; } + sbi->flags &= ~HFSPLUS_SB_FORCE; /* Load metadata objects (B*Trees) */ HFSPLUS_SB(sb).ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID); -- cgit v0.10.2 From fe655d3a06488c8a188461bca493e9f23fc8c448 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 29 Nov 2005 19:34:42 -0800 Subject: [PATCH] setting irq affinity is broken in ia32 with MSI enabled Setting irq affinity stops working when MSI is enabled. With MSI, move_irq is empty, so we can't change irq affinity. It appears a typo in Ashok's original commit for this issue. X86_64 actually is using move_native_irq. Signed-off-by: Shaohua Li Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index cc5d7ac..22c8675 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2009,7 +2009,7 @@ static void ack_edge_ioapic_vector(unsigned int vector) { int irq = vector_to_irq(vector); - move_irq(vector); + move_native_irq(vector); ack_edge_ioapic_irq(irq); } @@ -2024,7 +2024,7 @@ static void end_level_ioapic_vector (unsigned int vector) { int irq = vector_to_irq(vector); - move_irq(vector); + move_native_irq(vector); end_level_ioapic_irq(irq); } -- cgit v0.10.2 From 49d5c7b08713c3a482d62b5a0ad41b4ec32905a5 Mon Sep 17 00:00:00 2001 From: "Antonino A. Daplas" Date: Tue, 29 Nov 2005 19:34:43 -0800 Subject: [PATCH] fbdev: cirrusfb: Driver cleanup and bug fixes - pseudo_palette is only 16 entries long - the pseudo_palette, if using the generic drawing functions, must always be u32 regardless of bpp - the fillrect accelerator is using region->color regardless of the visual. region->color is the index to the pseudo_palette if visual is truecolor Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 2858c5c..e0dbdfc 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c @@ -404,7 +404,7 @@ struct cirrusfb_info { struct cirrusfb_regs currentmode; int blank_mode; - u32 pseudo_palette[17]; + u32 pseudo_palette[16]; struct { u8 red, green, blue, pad; } palette[256]; #ifdef CONFIG_ZORRO @@ -1603,14 +1603,14 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, switch (info->var.bits_per_pixel) { case 8: - ((u8*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; case 16: - ((u16*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; case 24: case 32: - ((u32*)(info->pseudo_palette))[regno] = v; + cinfo->pseudo_palette[regno] = v; break; } return 0; @@ -2020,18 +2020,21 @@ static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo, const struct fb_fillrect *region) { int m; /* bytes per pixel */ + u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ? + cinfo->pseudo_palette[region->color] : region->color; + if(cinfo->info->var.bits_per_pixel == 1) { cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel, region->dx / 8, region->dy, region->width / 8, region->height, - region->color, + color, cinfo->currentmode.line_length); } else { m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8; cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel, region->dx * m, region->dy, region->width * m, region->height, - region->color, + color, cinfo->currentmode.line_length); } return; -- cgit v0.10.2 From 1a57198609615a936ff57da37b6957db9bafde83 Mon Sep 17 00:00:00 2001 From: Mark Fortescue Date: Tue, 29 Nov 2005 19:34:44 -0800 Subject: [PATCH] fbdev: cg3fb: Kconfig fix A cut and past error regarding the CG3 frame buffer needs to be fixed. It also affects Creator/Creator3D/Elite3D. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 25b6ca6..3e470c8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -534,6 +534,12 @@ config FB_SUN3 bool "Sun3 framebuffer support" depends on (FB = y) && (SUN3 || SUN3X) && BROKEN +config FB_SBUS + bool "SBUS and UPA framebuffers" + depends on (FB = y) && (SPARC32 || SPARC64) + help + Say Y if you want support for SBUS or UPA based frame buffer device. + config FB_BW2 bool "BWtwo support" depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) @@ -546,6 +552,7 @@ config FB_BW2 config FB_CG3 bool "CGthree support" depends on (FB = y) && ((SPARC32 || SPARC64) && FB_SBUS || (SUN3 || SUN3X) && FB_SUN3) + select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT help @@ -1210,12 +1217,6 @@ config FB_AU1100 source "drivers/video/geode/Kconfig" -config FB_SBUS - bool "SBUS and UPA framebuffers" - depends on (FB = y) && (SPARC32 || SPARC64) - help - Say Y if you want support for SBUS or UPA based frame buffer device. - config FB_FFB bool "Creator/Creator3D/Elite3D support" depends on FB_SBUS && SPARC64 -- cgit v0.10.2