From 645387d8b344865d7697d2d7964f9b39e3294760 Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Fri, 3 Jun 2005 05:25:00 -0700 Subject: [PATCH] --- yaml --- r: 1894 b: refs/heads/master c: ff89bf3bc0534aa03b5375aa906544d96911bad4 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/Documentation/DocBook/libata.tmpl | 156 +--- trunk/Makefile | 2 +- trunk/arch/arm/boot/compressed/head-xscale.S | 7 - trunk/arch/arm/kernel/entry-armv.S | 16 +- trunk/arch/arm/kernel/traps.c | 49 -- trunk/arch/arm/lib/io-writesw-armv4.S | 6 +- trunk/arch/arm/mach-pxa/mainstone.c | 9 - trunk/arch/arm/mach-pxa/pm.c | 32 +- trunk/arch/arm/mach-pxa/pxa25x.c | 29 - trunk/arch/arm/mach-pxa/pxa27x.c | 32 - trunk/arch/arm/mach-s3c2410/dma.c | 4 - trunk/arch/arm/mm/Kconfig | 15 +- trunk/arch/arm/mm/Makefile | 2 + trunk/arch/arm/mm/copypage-xscale.S | 113 +++ trunk/arch/arm/mm/copypage-xscale.c | 131 ---- trunk/arch/arm/mm/minicache.c | 73 ++ trunk/arch/ia64/sn/kernel/setup.c | 4 +- trunk/arch/m68knommu/kernel/process.c | 17 +- trunk/arch/ppc/kernel/cputable.c | 11 - trunk/arch/ppc/kernel/misc.S | 6 +- trunk/arch/ppc64/boot/prom.c | 28 +- trunk/arch/ppc64/kernel/kprobes.c | 2 + trunk/arch/ppc64/kernel/prom_init.c | 2 +- trunk/arch/s390/appldata/appldata_base.c | 72 +- trunk/arch/s390/appldata/appldata_mem.c | 2 +- trunk/arch/s390/appldata/appldata_net_sum.c | 2 +- trunk/arch/s390/appldata/appldata_os.c | 4 +- trunk/arch/s390/kernel/ptrace.c | 55 +- trunk/arch/s390/mm/fault.c | 2 +- trunk/drivers/atm/Makefile | 3 +- trunk/drivers/atm/fore200e.c | 6 +- trunk/drivers/atm/he.c | 6 +- trunk/drivers/atm/nicstar.c | 20 +- trunk/drivers/atm/zatm.c | 11 +- trunk/drivers/block/ub.c | 598 ++++++--------- trunk/drivers/char/agp/agp.h | 2 - trunk/drivers/char/agp/ali-agp.c | 4 +- trunk/drivers/char/agp/amd-k7-agp.c | 6 +- trunk/drivers/char/agp/amd64-agp.c | 4 +- trunk/drivers/char/agp/ati-agp.c | 6 +- trunk/drivers/char/agp/backend.c | 6 +- trunk/drivers/char/agp/efficeon-agp.c | 2 +- trunk/drivers/char/agp/generic.c | 36 +- trunk/drivers/char/agp/hp-agp.c | 4 +- trunk/drivers/char/agp/i460-agp.c | 4 +- trunk/drivers/char/agp/intel-agp.c | 21 +- trunk/drivers/char/agp/sgi-agp.c | 12 +- trunk/drivers/char/agp/sworks-agp.c | 8 +- trunk/drivers/char/agp/uninorth-agp.c | 2 +- trunk/drivers/char/mxser.c | 38 +- trunk/drivers/input/keyboard/atkbd.c | 2 +- trunk/drivers/net/pcmcia/3c574_cs.c | 3 - trunk/drivers/net/r8169.c | 31 +- trunk/drivers/net/shaper.c | 86 ++- trunk/drivers/net/tg3.c | 21 +- trunk/drivers/pci/pci.ids | 1 - trunk/drivers/pci/quirks.c | 35 +- trunk/drivers/scsi/ata_piix.c | 16 + trunk/drivers/scsi/libata-core.c | 470 ++---------- trunk/drivers/scsi/libata-scsi.c | 2 +- trunk/drivers/scsi/qla2xxx/qla_os.c | 24 +- trunk/drivers/scsi/scsi_scan.c | 1 - trunk/drivers/serial/sa1100.c | 2 +- trunk/drivers/serial/vr41xx_siu.c | 66 +- trunk/drivers/usb/core/sysfs.c | 22 +- trunk/drivers/usb/input/hid-core.c | 18 - trunk/drivers/usb/media/pwc/ChangeLog | 143 ++++ trunk/drivers/usb/net/usbnet.c | 2 +- trunk/drivers/usb/serial/Kconfig | 11 - trunk/drivers/usb/serial/Makefile | 1 - trunk/drivers/usb/serial/cp2101.c | 363 +++------ trunk/drivers/usb/serial/option.c | 729 ------------------- trunk/drivers/usb/storage/unusual_devs.h | 9 - trunk/fs/binfmt_flat.c | 6 +- trunk/fs/mpage.c | 5 +- trunk/fs/namei.c | 153 ++-- trunk/fs/nfs/dir.c | 49 +- trunk/include/asm-alpha/agp.h | 10 - trunk/include/asm-arm/arch-ixp2000/io.h | 16 +- trunk/include/asm-arm/arch-pxa/pxa-regs.h | 2 - trunk/include/asm-arm/elf.h | 4 +- trunk/include/asm-arm26/elf.h | 2 +- trunk/include/asm-h8300/kmap_types.h | 6 +- trunk/include/asm-h8300/mman.h | 3 - trunk/include/asm-i386/agp.h | 10 - trunk/include/asm-i386/mach-numaq/mach_ipi.h | 2 +- trunk/include/asm-ia64/agp.h | 10 - trunk/include/asm-ppc/agp.h | 10 - trunk/include/asm-ppc/sigcontext.h | 2 +- trunk/include/asm-ppc64/agp.h | 10 - trunk/include/asm-s390/user.h | 2 +- trunk/include/asm-sparc64/agp.h | 10 - trunk/include/asm-x86_64/agp.h | 10 - trunk/include/linux/acpi.h | 2 - trunk/include/linux/if_shaper.h | 3 +- trunk/include/linux/libata.h | 58 -- trunk/include/linux/netdevice.h | 2 +- trunk/include/linux/pci_ids.h | 2 - trunk/include/linux/usb.h | 6 +- trunk/mm/filemap.c | 8 +- trunk/net/core/ethtool.c | 2 +- trunk/net/ipv4/ipvs/Makefile | 2 +- trunk/net/ipv4/ipvs/ip_vs_proto.c | 3 + trunk/net/ipv4/ipvs/ip_vs_proto_icmp.c | 182 +++++ trunk/net/ipv6/ipv6_syms.c | 1 + 106 files changed, 1419 insertions(+), 2916 deletions(-) create mode 100644 trunk/arch/arm/mm/copypage-xscale.S delete mode 100644 trunk/arch/arm/mm/copypage-xscale.c create mode 100644 trunk/drivers/usb/media/pwc/ChangeLog delete mode 100644 trunk/drivers/usb/serial/option.c create mode 100644 trunk/net/ipv4/ipvs/ip_vs_proto_icmp.c diff --git a/[refs] b/[refs] index 4b19a4dea997..48024f60c615 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 97d26b8042a6f14cc4a19e84e911a953363e3d69 +refs/heads/master: ff89bf3bc0534aa03b5375aa906544d96911bad4 diff --git a/trunk/Documentation/DocBook/libata.tmpl b/trunk/Documentation/DocBook/libata.tmpl index 6df1dfd18b65..cf2fce7707da 100644 --- a/trunk/Documentation/DocBook/libata.tmpl +++ b/trunk/Documentation/DocBook/libata.tmpl @@ -14,7 +14,7 @@ - 2003-2005 + 2003 Jeff Garzik @@ -44,38 +44,30 @@ - - Introduction + + Thanks - libATA is a library used inside the Linux kernel to support ATA host - controllers and devices. libATA provides an ATA driver API, class - transports for ATA and ATAPI devices, and SCSI<->ATA translation - for ATA devices according to the T10 SAT specification. + The bulk of the ATA knowledge comes thanks to long conversations with + Andre Hedrick (www.linux-ide.org). - This Guide documents the libATA driver API, library functions, library - internals, and a couple sample ATA low-level drivers. + Thanks to Alan Cox for pointing out similarities + between SATA and SCSI, and in general for motivation to hack on + libata. + + + libata's device detection + method, ata_pio_devchk, and in general all the early probing was + based on extensive study of Hale Landis's probe/reset code in his + ATADRVR driver (www.ata-atapi.com). libata Driver API - - struct ata_port_operations is defined for every low-level libata - hardware driver, and it controls how the low-level driver - interfaces with the ATA and SCSI layers. - - - FIS-based drivers will hook into the system with ->qc_prep() and - ->qc_issue() high-level hooks. Hardware which behaves in a manner - similar to PCI IDE hardware may utilize several generic helpers, - defining at a bare minimum the bus I/O addresses of the ATA shadow - register blocks. - struct ata_port_operations - Disable ATA port void (*port_disable) (struct ata_port *); @@ -86,9 +78,6 @@ void (*port_disable) (struct ata_port *); unplug). - - - Post-IDENTIFY device configuration void (*dev_config) (struct ata_port *, struct ata_device *); @@ -99,9 +88,6 @@ void (*dev_config) (struct ata_port *, struct ata_device *); issue of SET FEATURES - XFER MODE, and prior to operation. - - - Set PIO/DMA mode void (*set_piomode) (struct ata_port *, struct ata_device *); void (*set_dmamode) (struct ata_port *, struct ata_device *); @@ -122,9 +108,6 @@ void (*post_set_mode) (struct ata_port *ap); ->set_dma_mode() is only called if DMA is possible. - - - Taskfile read/write void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); @@ -137,9 +120,6 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); taskfile register values. - - - ATA command execute void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); @@ -149,37 +129,17 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); ->tf_load(), to be initiated in hardware. - - - Per-cmd ATAPI DMA capabilities filter - -int (*check_atapi_dma) (struct ata_queued_cmd *qc); - - - -Allow low-level driver to filter ATA PACKET commands, returning a status -indicating whether or not it is OK to use DMA for the supplied PACKET -command. - - - - - Read specific ATA shadow registers u8 (*check_status)(struct ata_port *ap); -u8 (*check_altstatus)(struct ata_port *ap); -u8 (*check_err)(struct ata_port *ap); +void (*dev_select)(struct ata_port *ap, unsigned int device); - Reads the Status/AltStatus/Error ATA shadow register from - hardware. On some hardware, reading the Status register has - the side effect of clearing the interrupt condition. + Reads the Status ATA shadow register from hardware. On some + hardware, this has the side effect of clearing the interrupt + condition. - - - Select ATA device on bus void (*dev_select)(struct ata_port *ap, unsigned int device); @@ -187,13 +147,9 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); Issues the low-level hardware command(s) that causes one of N hardware devices to be considered 'selected' (active and - available for use) on the ATA bus. This generally has no -meaning on FIS-based devices. + available for use) on the ATA bus. - - - Reset ATA bus void (*phy_reset) (struct ata_port *ap); @@ -206,31 +162,17 @@ void (*phy_reset) (struct ata_port *ap); functions ata_bus_reset() or sata_phy_reset() for this hook. - - - Control PCI IDE BMDMA engine void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); -void (*bmdma_stop) (struct ata_port *ap); -u8 (*bmdma_status) (struct ata_port *ap); -When setting up an IDE BMDMA transaction, these hooks arm -(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop) -the hardware's DMA engine. ->bmdma_status is used to read the standard -PCI IDE DMA Status register. + When setting up an IDE BMDMA transaction, these hooks arm + (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA + engine. - -These hooks are typically either no-ops, or simply not implemented, in -FIS-based drivers. - - - - - High-level taskfile hooks void (*qc_prep) (struct ata_queued_cmd *qc); int (*qc_issue) (struct ata_queued_cmd *qc); @@ -248,26 +190,20 @@ int (*qc_issue) (struct ata_queued_cmd *qc); ->qc_issue is used to make a command active, once the hardware and S/G tables have been prepared. IDE BMDMA drivers use the helper function ata_qc_issue_prot() for taskfile protocol-based - dispatch. More advanced drivers implement their own ->qc_issue. + dispatch. More advanced drivers roll their own ->qc_issue + implementation, using this as the "issue new ATA command to + hardware" hook. - - - Timeout (error) handling void (*eng_timeout) (struct ata_port *ap); -This is a high level error handling function, called from the -error handling thread, when a command times out. Most newer -hardware will implement its own error handling code here. IDE BMDMA -drivers may use the helper function ata_eng_timeout(). + This is a high level error handling function, called from the + error handling thread, when a command times out. - - - Hardware interrupt handling irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); @@ -280,9 +216,6 @@ void (*irq_clear) (struct ata_port *); is quiet. - - - SATA phy read/write u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, @@ -294,9 +227,6 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, if ->phy_reset hook called the sata_phy_reset() helper function. - - - Init and shutdown int (*port_start) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap); @@ -310,17 +240,15 @@ void (*host_stop) (struct ata_host_set *host_set); tasks. + ->host_stop() is called when the rmmod or hot unplug process + begins. The hook must stop all hardware interrupts, DMA + engines, etc. + + ->port_stop() is called after ->host_stop(). It's sole function is to release DMA/memory resources, now that they are no longer actively being used. - - ->host_stop() is called after all ->port_stop() calls -have completed. The hook must finalize hardware shutdown, release DMA -and other resources, etc. - - - @@ -351,24 +279,4 @@ and other resources, etc. !Idrivers/scsi/sata_sil.c - - Thanks - - The bulk of the ATA knowledge comes thanks to long conversations with - Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA - and SCSI specifications. - - - Thanks to Alan Cox for pointing out similarities - between SATA and SCSI, and in general for motivation to hack on - libata. - - - libata's device detection - method, ata_pio_devchk, and in general all the early probing was - based on extensive study of Hale Landis's probe/reset code in his - ATADRVR driver (www.ata-atapi.com). - - - diff --git a/trunk/Makefile b/trunk/Makefile index 9e005e18c71c..c11a317ea910 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION =-rc6 +EXTRAVERSION =-rc5 NAME=Woozy Numbat # *DOCUMENTATION* diff --git a/trunk/arch/arm/boot/compressed/head-xscale.S b/trunk/arch/arm/boot/compressed/head-xscale.S index d3fe2533907e..665bd2c20743 100644 --- a/trunk/arch/arm/boot/compressed/head-xscale.S +++ b/trunk/arch/arm/boot/compressed/head-xscale.S @@ -47,10 +47,3 @@ __XScale_start: orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) #endif -#ifdef CONFIG_ARCH_IXP2000 - mov r1, #-1 - mov r0, #0xd6000000 - str r1, [r0, #0x14] - str r1, [r0, #0x18] -#endif - diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index e14278d59882..4eb36155dc93 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -269,7 +269,7 @@ __pabt_svc: add r5, sp, #S_PC ldmia r7, {r2 - r4} @ Get USR pc, cpsr -#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#if __LINUX_ARM_ARCH__ < 6 @ make sure our user space atomic helper is aborted cmp r2, #VIRT_OFFSET bichs r3, r3, #PSR_Z_BIT @@ -616,17 +616,11 @@ __kuser_helper_start: __kuser_cmpxchg: @ 0xffff0fc0 -#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) +#if __LINUX_ARM_ARCH__ < 6 - /* - * Poor you. No fast solution possible... - * The kernel itself must perform the operation. - * A special ghost syscall is used for that (see traps.c). - */ - swi #0x9ffff0 - mov pc, lr - -#elif __LINUX_ARM_ARCH__ < 6 +#ifdef CONFIG_SMP /* sanity check */ +#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" +#endif /* * Theory of operation: diff --git a/trunk/arch/arm/kernel/traps.c b/trunk/arch/arm/kernel/traps.c index 45d2a032d890..14df16b983f4 100644 --- a/trunk/arch/arm/kernel/traps.c +++ b/trunk/arch/arm/kernel/traps.c @@ -464,55 +464,6 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) #endif return 0; -#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG - /* - * Atomically store r1 in *r2 if *r2 is equal to r0 for user space. - * Return zero in r0 if *MEM was changed or non-zero if no exchange - * happened. Also set the user C flag accordingly. - * If access permissions have to be fixed up then non-zero is - * returned and the operation has to be re-attempted. - * - * *NOTE*: This is a ghost syscall private to the kernel. Only the - * __kuser_cmpxchg code in entry-armv.S should be aware of its - * existence. Don't ever use this from user code. - */ - case 0xfff0: - { - extern void do_DataAbort(unsigned long addr, unsigned int fsr, - struct pt_regs *regs); - unsigned long val; - unsigned long addr = regs->ARM_r2; - struct mm_struct *mm = current->mm; - pgd_t *pgd; pmd_t *pmd; pte_t *pte; - - regs->ARM_cpsr &= ~PSR_C_BIT; - spin_lock(&mm->page_table_lock); - pgd = pgd_offset(mm, addr); - if (!pgd_present(*pgd)) - goto bad_access; - pmd = pmd_offset(pgd, addr); - if (!pmd_present(*pmd)) - goto bad_access; - pte = pte_offset_map(pmd, addr); - if (!pte_present(*pte) || !pte_write(*pte)) - goto bad_access; - val = *(unsigned long *)addr; - val -= regs->ARM_r0; - if (val == 0) { - *(unsigned long *)addr = regs->ARM_r1; - regs->ARM_cpsr |= PSR_C_BIT; - } - spin_unlock(&mm->page_table_lock); - return val; - - bad_access: - spin_unlock(&mm->page_table_lock); - /* simulate a read access fault */ - do_DataAbort(addr, 15 + (1 << 11), regs); - return -1; - } -#endif - default: /* Calls 9f00xx..9f07ff are defined to return -ENOSYS if not implemented, rather than raising SIGILL. This diff --git a/trunk/arch/arm/lib/io-writesw-armv4.S b/trunk/arch/arm/lib/io-writesw-armv4.S index 5e240e452af6..6d1d7c27806e 100644 --- a/trunk/arch/arm/lib/io-writesw-armv4.S +++ b/trunk/arch/arm/lib/io-writesw-armv4.S @@ -87,9 +87,9 @@ ENTRY(__raw_writesw) subs r2, r2, #2 orr ip, ip, r3, push_hbyte1 strh ip, [r0] - bpl 1b + bpl 2b - tst r2, #1 -3: movne ip, r3, lsr #8 +3: tst r2, #1 +2: movne ip, r3, lsr #8 strneh ip, [r0] mov pc, lr diff --git a/trunk/arch/arm/mach-pxa/mainstone.c b/trunk/arch/arm/mach-pxa/mainstone.c index 6823ae28ae6a..3f952237ae3d 100644 --- a/trunk/arch/arm/mach-pxa/mainstone.c +++ b/trunk/arch/arm/mach-pxa/mainstone.c @@ -304,15 +304,6 @@ static void __init mainstone_map_io(void) PWER = 0xC0000002; PRER = 0x00000002; PFER = 0x00000002; - /* for use I SRAM as framebuffer. */ - PSLR |= 0xF04; - PCFR = 0x66; - /* For Keypad wakeup. */ - KPC &=~KPC_ASACT; - KPC |=KPC_AS; - PKWR = 0x000FD000; - /* Need read PKWR back after set it. */ - PKWR; } MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") diff --git a/trunk/arch/arm/mach-pxa/pm.c b/trunk/arch/arm/mach-pxa/pm.c index 9799fe80df23..82a4bf34c251 100644 --- a/trunk/arch/arm/mach-pxa/pm.c +++ b/trunk/arch/arm/mach-pxa/pm.c @@ -29,6 +29,9 @@ */ #undef DEBUG +extern void pxa_cpu_suspend(void); +extern void pxa_cpu_resume(void); + #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] @@ -60,12 +63,6 @@ enum { SLEEP_SAVE_START = 0, SLEEP_SAVE_ICMR, SLEEP_SAVE_CKEN, -#ifdef CONFIG_PXA27x - SLEEP_SAVE_MDREFR, - SLEEP_SAVE_PWER, SLEEP_SAVE_PCFR, SLEEP_SAVE_PRER, - SLEEP_SAVE_PFER, SLEEP_SAVE_PKWR, -#endif - SLEEP_SAVE_CKSUM, SLEEP_SAVE_SIZE @@ -78,7 +75,9 @@ static int pxa_pm_enter(suspend_state_t state) unsigned long checksum = 0; struct timespec delta, rtc; int i; - extern void pxa_cpu_pm_enter(suspend_state_t state); + + if (state != PM_SUSPEND_MEM) + return -EINVAL; #ifdef CONFIG_IWMMXT /* force any iWMMXt context to ram **/ @@ -101,17 +100,16 @@ static int pxa_pm_enter(suspend_state_t state) SAVE(GAFR2_L); SAVE(GAFR2_U); #ifdef CONFIG_PXA27x - SAVE(MDREFR); SAVE(GPLR3); SAVE(GPDR3); SAVE(GRER3); SAVE(GFER3); SAVE(PGSR3); SAVE(GAFR3_L); SAVE(GAFR3_U); - SAVE(PWER); SAVE(PCFR); SAVE(PRER); - SAVE(PFER); SAVE(PKWR); #endif SAVE(ICMR); ICMR = 0; SAVE(CKEN); + CKEN = 0; + SAVE(PSTR); /* Note: wake up source are set up in each machine specific files */ @@ -125,13 +123,16 @@ static int pxa_pm_enter(suspend_state_t state) /* Clear sleep reset status */ RCSR = RCSR_SMR; + /* set resume return address */ + PSPR = virt_to_phys(pxa_cpu_resume); + /* before sleeping, calculate and save a checksum */ for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++) checksum += sleep_save[i]; sleep_save[SLEEP_SAVE_CKSUM] = checksum; /* *** go zzz *** */ - pxa_cpu_pm_enter(state); + pxa_cpu_suspend(); /* after sleeping, validate the checksum */ checksum = 0; @@ -144,7 +145,7 @@ static int pxa_pm_enter(suspend_state_t state) LUB_HEXLED = 0xbadbadc5; #endif while (1) - pxa_cpu_pm_enter(state); + pxa_cpu_suspend(); } /* ensure not to come back here if it wasn't intended */ @@ -161,11 +162,8 @@ static int pxa_pm_enter(suspend_state_t state) RESTORE(PGSR0); RESTORE(PGSR1); RESTORE(PGSR2); #ifdef CONFIG_PXA27x - RESTORE(MDREFR); RESTORE(GAFR3_L); RESTORE(GAFR3_U); RESTORE_GPLEVEL(3); RESTORE(GPDR3); RESTORE(GRER3); RESTORE(GFER3); RESTORE(PGSR3); - RESTORE(PWER); RESTORE(PCFR); RESTORE(PRER); - RESTORE(PFER); RESTORE(PKWR); #endif PSSR = PSSR_RDH | PSSR_PH; @@ -199,9 +197,7 @@ unsigned long sleep_phys_sp(void *sp) */ static int pxa_pm_prepare(suspend_state_t state) { - extern int pxa_cpu_pm_prepare(suspend_state_t state); - - return pxa_cpu_pm_prepare(state); + return 0; } /* diff --git a/trunk/arch/arm/mach-pxa/pxa25x.c b/trunk/arch/arm/mach-pxa/pxa25x.c index b6d945a6e774..e887b7175ef3 100644 --- a/trunk/arch/arm/mach-pxa/pxa25x.c +++ b/trunk/arch/arm/mach-pxa/pxa25x.c @@ -102,32 +102,3 @@ unsigned int get_lcdclk_frequency_10khz(void) } EXPORT_SYMBOL(get_lcdclk_frequency_10khz); - - -int pxa_cpu_pm_prepare(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_MEM: - break; - default: - return -EINVAL; - } - - return 0; -} - -void pxa_cpu_pm_enter(suspend_state_t state) -{ - extern void pxa_cpu_suspend(unsigned int); - extern void pxa_cpu_resume(void); - - CKEN = 0; - - switch (state) { - case PM_SUSPEND_MEM: - /* set resume return address */ - PSPR = virt_to_phys(pxa_cpu_resume); - pxa_cpu_suspend(3); - break; - } -} diff --git a/trunk/arch/arm/mach-pxa/pxa27x.c b/trunk/arch/arm/mach-pxa/pxa27x.c index aa3c3b2ab75e..7e863afefb53 100644 --- a/trunk/arch/arm/mach-pxa/pxa27x.c +++ b/trunk/arch/arm/mach-pxa/pxa27x.c @@ -120,38 +120,6 @@ EXPORT_SYMBOL(get_clk_frequency_khz); EXPORT_SYMBOL(get_memclk_frequency_10khz); EXPORT_SYMBOL(get_lcdclk_frequency_10khz); -int pxa_cpu_pm_prepare(suspend_state_t state) -{ - switch (state) { - case PM_SUSPEND_MEM: - return 0; - default: - return -EINVAL; - } -} - -void pxa_cpu_pm_enter(suspend_state_t state) -{ - extern void pxa_cpu_standby(void); - extern void pxa_cpu_suspend(unsigned int); - extern void pxa_cpu_resume(void); - - CKEN = CKEN22_MEMC | CKEN9_OSTIMER; - - /* ensure voltage-change sequencer not initiated, which hangs */ - PCFR &= ~PCFR_FVC; - - /* Clear edge-detect status register. */ - PEDR = 0xDF12FE1B; - - switch (state) { - case PM_SUSPEND_MEM: - /* set resume return address */ - PSPR = virt_to_phys(pxa_cpu_resume); - pxa_cpu_suspend(3); - break; - } -} /* * device registration specific to PXA27x. diff --git a/trunk/arch/arm/mach-s3c2410/dma.c b/trunk/arch/arm/mach-s3c2410/dma.c index c7c28890d406..bc229fab86d4 100644 --- a/trunk/arch/arm/mach-s3c2410/dma.c +++ b/trunk/arch/arm/mach-s3c2410/dma.c @@ -785,10 +785,6 @@ int s3c2410_dma_free(dmach_t channel, s3c2410_dma_client_t *client) chan->client = NULL; chan->in_use = 0; - if (chan->irq_claimed) - free_irq(chan->irq, (void *)chan); - chan->irq_claimed = 0; - local_irq_restore(flags); return 0; diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index 3fefb43c67f7..48bac7da8c70 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -228,6 +228,7 @@ config CPU_SA1100 select CPU_CACHE_V4WB select CPU_CACHE_VIVT select CPU_TLB_V4WB + select CPU_MINICACHE # XScale config CPU_XSCALE @@ -238,6 +239,7 @@ config CPU_XSCALE select CPU_ABRT_EV5T select CPU_CACHE_VIVT select CPU_TLB_V4WBI + select CPU_MINICACHE # ARMv6 config CPU_V6 @@ -343,6 +345,11 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool +config CPU_MINICACHE + bool + help + Processor has a minicache. + comment "Processor Features" config ARM_THUMB @@ -422,11 +429,3 @@ config HAS_TLS_REG assume directly accessing that register and always obtain the expected value only on ARMv7 and above. -config NEEDS_SYSCALL_FOR_CMPXCHG - bool - default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) - help - SMP on a pre-ARMv6 processor? Well OK then. - Forget about fast user space cmpxchg support. - It is just not possible. - diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 59f47d4c2dfe..ccf316c11e02 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -31,6 +31,8 @@ obj-$(CONFIG_CPU_COPY_V6) += copypage-v6.o mmu.o obj-$(CONFIG_CPU_SA1100) += copypage-v4mc.o obj-$(CONFIG_CPU_XSCALE) += copypage-xscale.o +obj-$(CONFIG_CPU_MINICACHE) += minicache.o + obj-$(CONFIG_CPU_TLB_V3) += tlb-v3.o obj-$(CONFIG_CPU_TLB_V4WT) += tlb-v4.o obj-$(CONFIG_CPU_TLB_V4WB) += tlb-v4wb.o diff --git a/trunk/arch/arm/mm/copypage-xscale.S b/trunk/arch/arm/mm/copypage-xscale.S new file mode 100644 index 000000000000..bb277316ef52 --- /dev/null +++ b/trunk/arch/arm/mm/copypage-xscale.S @@ -0,0 +1,113 @@ +/* + * linux/arch/arm/lib/copypage-xscale.S + * + * Copyright (C) 2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include + +/* + * General note: + * We don't really want write-allocate cache behaviour for these functions + * since that will just eat through 8K of the cache. + */ + + .text + .align 5 +/* + * XScale optimised copy_user_page + * r0 = destination + * r1 = source + * r2 = virtual user address of ultimate destination page + * + * The source page may have some clean entries in the cache already, but we + * can safely ignore them - break_cow() will flush them out of the cache + * if we eventually end up using our copied page. + * + * What we could do is use the mini-cache to buffer reads from the source + * page. We rely on the mini-cache being smaller than one page, so we'll + * cycle through the complete cache anyway. + */ +ENTRY(xscale_mc_copy_user_page) + stmfd sp!, {r4, r5, lr} + mov r5, r0 + mov r0, r1 + bl map_page_minicache + mov r1, r5 + mov lr, #PAGE_SZ/64-1 + + /* + * Strangely enough, best performance is achieved + * when prefetching destination as well. (NP) + */ + pld [r0, #0] + pld [r0, #32] + pld [r1, #0] + pld [r1, #32] + +1: pld [r0, #64] + pld [r0, #96] + pld [r1, #64] + pld [r1, #96] + +2: ldrd r2, [r0], #8 + ldrd r4, [r0], #8 + mov ip, r1 + strd r2, [r1], #8 + ldrd r2, [r0], #8 + strd r4, [r1], #8 + ldrd r4, [r0], #8 + strd r2, [r1], #8 + strd r4, [r1], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + ldrd r2, [r0], #8 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + ldrd r4, [r0], #8 + mov ip, r1 + strd r2, [r1], #8 + ldrd r2, [r0], #8 + strd r4, [r1], #8 + ldrd r4, [r0], #8 + strd r2, [r1], #8 + strd r4, [r1], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + subs lr, lr, #1 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + bgt 1b + beq 2b + + ldmfd sp!, {r4, r5, pc} + + .align 5 +/* + * XScale optimised clear_user_page + * r0 = destination + * r1 = virtual user address of ultimate destination page + */ +ENTRY(xscale_mc_clear_user_page) + mov r1, #PAGE_SZ/32 + mov r2, #0 + mov r3, #0 +1: mov ip, r0 + strd r2, [r0], #8 + strd r2, [r0], #8 + strd r2, [r0], #8 + strd r2, [r0], #8 + mcr p15, 0, ip, c7, c10, 1 @ clean D line + subs r1, r1, #1 + mcr p15, 0, ip, c7, c6, 1 @ invalidate D line + bne 1b + mov pc, lr + + __INITDATA + + .type xscale_mc_user_fns, #object +ENTRY(xscale_mc_user_fns) + .long xscale_mc_clear_user_page + .long xscale_mc_copy_user_page + .size xscale_mc_user_fns, . - xscale_mc_user_fns diff --git a/trunk/arch/arm/mm/copypage-xscale.c b/trunk/arch/arm/mm/copypage-xscale.c deleted file mode 100644 index 42a6ee255ce0..000000000000 --- a/trunk/arch/arm/mm/copypage-xscale.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * linux/arch/arm/lib/copypage-xscale.S - * - * Copyright (C) 1995-2005 Russell King - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This handles the mini data cache, as found on SA11x0 and XScale - * processors. When we copy a user page page, we map it in such a way - * that accesses to this page will not touch the main data cache, but - * will be cached in the mini data cache. This prevents us thrashing - * the main data cache on page faults. - */ -#include -#include - -#include -#include -#include - -/* - * 0xffff8000 to 0xffffffff is reserved for any ARM architecture - * specific hacks for copying pages efficiently. - */ -#define COPYPAGE_MINICACHE 0xffff8000 - -#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ - L_PTE_CACHEABLE) - -#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) - -static DEFINE_SPINLOCK(minicache_lock); - -/* - * XScale mini-dcache optimised copy_user_page - * - * We flush the destination cache lines just before we write the data into the - * corresponding address. Since the Dcache is read-allocate, this removes the - * Dcache aliasing issue. The writes will be forwarded to the write buffer, - * and merged as appropriate. - */ -static void __attribute__((naked)) -mc_copy_user_page(void *from, void *to) -{ - /* - * Strangely enough, best performance is achieved - * when prefetching destination as well. (NP) - */ - asm volatile( - "stmfd sp!, {r4, r5, lr} \n\ - mov lr, %2 \n\ - pld [r0, #0] \n\ - pld [r0, #32] \n\ - pld [r1, #0] \n\ - pld [r1, #32] \n\ -1: pld [r0, #64] \n\ - pld [r0, #96] \n\ - pld [r1, #64] \n\ - pld [r1, #96] \n\ -2: ldrd r2, [r0], #8 \n\ - ldrd r4, [r0], #8 \n\ - mov ip, r1 \n\ - strd r2, [r1], #8 \n\ - ldrd r2, [r0], #8 \n\ - strd r4, [r1], #8 \n\ - ldrd r4, [r0], #8 \n\ - strd r2, [r1], #8 \n\ - strd r4, [r1], #8 \n\ - mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ - ldrd r2, [r0], #8 \n\ - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ - ldrd r4, [r0], #8 \n\ - mov ip, r1 \n\ - strd r2, [r1], #8 \n\ - ldrd r2, [r0], #8 \n\ - strd r4, [r1], #8 \n\ - ldrd r4, [r0], #8 \n\ - strd r2, [r1], #8 \n\ - strd r4, [r1], #8 \n\ - mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ - subs lr, lr, #1 \n\ - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ - bgt 1b \n\ - beq 2b \n\ - ldmfd sp!, {r4, r5, pc} " - : - : "r" (from), "r" (to), "I" (PAGE_SIZE / 64 - 1)); -} - -void xscale_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) -{ - spin_lock(&minicache_lock); - - set_pte(TOP_PTE(COPYPAGE_MINICACHE), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); - flush_tlb_kernel_page(COPYPAGE_MINICACHE); - - mc_copy_user_page((void *)COPYPAGE_MINICACHE, kto); - - spin_unlock(&minicache_lock); -} - -/* - * XScale optimised clear_user_page - */ -void __attribute__((naked)) -xscale_mc_clear_user_page(void *kaddr, unsigned long vaddr) -{ - asm volatile( - "mov r1, %0 \n\ - mov r2, #0 \n\ - mov r3, #0 \n\ -1: mov ip, r0 \n\ - strd r2, [r0], #8 \n\ - strd r2, [r0], #8 \n\ - strd r2, [r0], #8 \n\ - strd r2, [r0], #8 \n\ - mcr p15, 0, ip, c7, c10, 1 @ clean D line\n\ - subs r1, r1, #1 \n\ - mcr p15, 0, ip, c7, c6, 1 @ invalidate D line\n\ - bne 1b \n\ - mov pc, lr" - : - : "I" (PAGE_SIZE / 32)); -} - -struct cpu_user_fns xscale_mc_user_fns __initdata = { - .cpu_clear_user_page = xscale_mc_clear_user_page, - .cpu_copy_user_page = xscale_mc_copy_user_page, -}; diff --git a/trunk/arch/arm/mm/minicache.c b/trunk/arch/arm/mm/minicache.c index e69de29bb2d1..dedf2ab01b2a 100644 --- a/trunk/arch/arm/mm/minicache.c +++ b/trunk/arch/arm/mm/minicache.c @@ -0,0 +1,73 @@ +/* + * linux/arch/arm/mm/minicache.c + * + * Copyright (C) 2001 Russell King + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This handles the mini data cache, as found on SA11x0 and XScale + * processors. When we copy a user page page, we map it in such a way + * that accesses to this page will not touch the main data cache, but + * will be cached in the mini data cache. This prevents us thrashing + * the main data cache on page faults. + */ +#include +#include + +#include +#include +#include + +/* + * 0xffff8000 to 0xffffffff is reserved for any ARM architecture + * specific hacks for copying pages efficiently. + */ +#define minicache_address (0xffff8000) +#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ + L_PTE_CACHEABLE) + +static pte_t *minicache_pte; + +/* + * Note that this is intended to be called only from the copy_user_page + * asm code; anything else will require special locking to prevent the + * mini-cache space being re-used. (Note: probably preempt unsafe). + * + * We rely on the fact that the minicache is 2K, and we'll be pushing + * 4K of data through it, so we don't actually have to specifically + * flush the minicache when we change the mapping. + * + * Note also: assert(PAGE_OFFSET <= virt < high_memory). + * Unsafe: preempt, kmap. + */ +unsigned long map_page_minicache(unsigned long virt) +{ + set_pte(minicache_pte, pfn_pte(__pa(virt) >> PAGE_SHIFT, minicache_pgprot)); + flush_tlb_kernel_page(minicache_address); + + return minicache_address; +} + +static int __init minicache_init(void) +{ + pgd_t *pgd; + pmd_t *pmd; + + spin_lock(&init_mm.page_table_lock); + + pgd = pgd_offset_k(minicache_address); + pmd = pmd_alloc(&init_mm, pgd, minicache_address); + if (!pmd) + BUG(); + minicache_pte = pte_alloc_kernel(&init_mm, pmd, minicache_address); + if (!minicache_pte) + BUG(); + + spin_unlock(&init_mm.page_table_lock); + + return 0; +} + +core_initcall(minicache_init); diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index e64cb8175f7a..44bfc7f318cb 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -222,7 +222,7 @@ void __init early_sn_setup(void) extern int platform_intr_list[]; extern nasid_t master_nasid; -static int shub_1_1_found __initdata; +static int __initdata shub_1_1_found = 0; /* * sn_check_for_wars @@ -251,7 +251,7 @@ static void __init sn_check_for_wars(void) } else { for_each_online_node(cnode) { if (is_shub_1_1(cnodeid_to_nasid(cnode))) - sn_hub_info->shub_1_1_found = 1; + shub_1_1_found = 1; } } } diff --git a/trunk/arch/m68knommu/kernel/process.c b/trunk/arch/m68knommu/kernel/process.c index c4a33f265dc0..2b6c9d32b7a6 100644 --- a/trunk/arch/m68knommu/kernel/process.c +++ b/trunk/arch/m68knommu/kernel/process.c @@ -45,13 +45,11 @@ asmlinkage void ret_from_fork(void); */ void default_idle(void) { - local_irq_disable(); - while (!need_resched()) { - /* This stop will re-enable interrupts */ - __asm__("stop #0x2000" : : : "cc"); - local_irq_disable(); + while(1) { + if (need_resched()) + __asm__("stop #0x2000" : : : "cc"); + schedule(); } - local_irq_enable(); } void (*idle)(void) = default_idle; @@ -65,12 +63,7 @@ void (*idle)(void) = default_idle; void cpu_idle(void) { /* endless idle loop with no priority at all */ - while (1) { - idle(); - preempt_enable_no_resched(); - schedule(); - preempt_disable(); - } + idle(); } void machine_restart(char * __unused) diff --git a/trunk/arch/ppc/kernel/cputable.c b/trunk/arch/ppc/kernel/cputable.c index d44b7dc5390a..8aa5e8c69009 100644 --- a/trunk/arch/ppc/kernel/cputable.c +++ b/trunk/arch/ppc/kernel/cputable.c @@ -838,17 +838,6 @@ struct cpu_spec cpu_specs[] = { .icache_bsize = 32, .dcache_bsize = 32, }, - { /* 405EP */ - .pvr_mask = 0xffff0000, - .pvr_value = 0x51210000, - .cpu_name = "405EP", - .cpu_features = CPU_FTR_SPLIT_ID_CACHE | - CPU_FTR_USE_TB, - .cpu_user_features = PPC_FEATURE_32 | - PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC, - .icache_bsize = 32, - .dcache_bsize = 32, - }, #endif /* CONFIG_40x */ #ifdef CONFIG_44x diff --git a/trunk/arch/ppc/kernel/misc.S b/trunk/arch/ppc/kernel/misc.S index 7329ef177a18..e4f1615ec13f 100644 --- a/trunk/arch/ppc/kernel/misc.S +++ b/trunk/arch/ppc/kernel/misc.S @@ -619,7 +619,7 @@ _GLOBAL(flush_instruction_cache) _GLOBAL(flush_icache_range) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) +END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) li r5,L1_CACHE_LINE_SIZE-1 andc r3,r3,r5 subf r4,r3,r4 @@ -736,7 +736,7 @@ _GLOBAL(flush_dcache_all) _GLOBAL(__flush_dcache_icache) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) +END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) rlwinm r3,r3,0,0,19 /* Get page base address */ li r4,4096/L1_CACHE_LINE_SIZE /* Number of lines in a page */ mtctr r4 @@ -764,7 +764,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) _GLOBAL(__flush_dcache_icache_phys) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) +END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) mfmsr r10 rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 diff --git a/trunk/arch/ppc64/boot/prom.c b/trunk/arch/ppc64/boot/prom.c index d5218b15824e..7b607d1862cb 100644 --- a/trunk/arch/ppc64/boot/prom.c +++ b/trunk/arch/ppc64/boot/prom.c @@ -11,23 +11,6 @@ #include #include -extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); - -/* The unnecessary pointer compare is there - * to check for type safety (n must be 64bit) - */ -# define do_div(n,base) ({ \ - __u32 __base = (base); \ - __u32 __rem; \ - (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ - if (((n) >> 32) == 0) { \ - __rem = (__u32)(n) % __base; \ - (n) = (__u32)(n) / __base; \ - } else \ - __rem = __div64_32(&(n), __base); \ - __rem; \ - }) - int (*prom)(void *); void *chosen_handle; @@ -369,7 +352,7 @@ static int skip_atoi(const char **s) #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ -static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) +static char * number(char * str, long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -384,9 +367,9 @@ static char * number(char * str, unsigned long long num, int base, int size, int c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if ((signed long long)num < 0) { + if (num < 0) { sign = '-'; - num = - (signed long long)num; + num = -num; size--; } else if (type & PLUS) { sign = '+'; @@ -406,7 +389,8 @@ static char * number(char * str, unsigned long long num, int base, int size, int if (num == 0) tmp[i++]='0'; else while (num != 0) { - tmp[i++] = digits[do_div(num, base)]; + tmp[i++] = digits[num % base]; + num /= base; } if (i > precision) precision = i; @@ -442,7 +426,7 @@ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; - unsigned long long num; + unsigned long num; int i, base; char * str; const char *s; diff --git a/trunk/arch/ppc64/kernel/kprobes.c b/trunk/arch/ppc64/kernel/kprobes.c index 5a9f47b18c45..103daaf73573 100644 --- a/trunk/arch/ppc64/kernel/kprobes.c +++ b/trunk/arch/ppc64/kernel/kprobes.c @@ -233,6 +233,8 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, */ preempt_disable(); switch (val) { + case DIE_IABR_MATCH: + case DIE_DABR_MATCH: case DIE_BPT: if (kprobe_handler(args->regs)) ret = NOTIFY_STOP; diff --git a/trunk/arch/ppc64/kernel/prom_init.c b/trunk/arch/ppc64/kernel/prom_init.c index b7683abfbe6a..1ac531ba7056 100644 --- a/trunk/arch/ppc64/kernel/prom_init.c +++ b/trunk/arch/ppc64/kernel/prom_init.c @@ -1370,7 +1370,7 @@ static int __init prom_find_machine_type(void) } /* Default to pSeries. We need to know if we are running LPAR */ rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - if (PHANDLE_VALID(rtas)) { + if (!PHANDLE_VALID(rtas)) { int x = prom_getproplen(rtas, "ibm,hypertas-functions"); if (x != PROM_ERROR) { prom_printf("Hypertas detected, assuming LPAR !\n"); diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index c067435bae45..01ae1964c938 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -28,7 +28,6 @@ //#include #include #include -#include #include "appldata.h" @@ -134,12 +133,9 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL; static int appldata_timer_active; /* - * Work queue + * Tasklet */ -static struct workqueue_struct *appldata_wq; -static void appldata_work_fn(void *data); -static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); - +static struct tasklet_struct appldata_tasklet_struct; /* * Ops list @@ -148,11 +144,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock); static LIST_HEAD(appldata_ops_list); -/*************************** timer, work, DIAG *******************************/ +/************************* timer, tasklet, DIAG ******************************/ /* * appldata_timer_function() * - * schedule work and reschedule timer + * schedule tasklet and reschedule timer */ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) { @@ -161,22 +157,22 @@ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) atomic_read(&appldata_expire_count)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); - queue_work(appldata_wq, (struct work_struct *) data); + tasklet_schedule((struct tasklet_struct *) data); } } /* - * appldata_work_fn() + * appldata_tasklet_function() * * call data gathering function for each (active) module */ -static void appldata_work_fn(void *data) +static void appldata_tasklet_function(unsigned long data) { struct list_head *lh; struct appldata_ops *ops; int i; - P_DEBUG(" -= Work Queue =-\n"); + P_DEBUG(" -= Tasklet =-\n"); i = 0; spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { @@ -235,7 +231,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); return (int) ry; } -/************************ timer, work, DIAG ****************************/ +/********************** timer, tasklet, DIAG ***************************/ /****************************** /proc stuff **********************************/ @@ -415,7 +411,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, struct list_head *lh; found = 0; - spin_lock(&appldata_ops_lock); + spin_lock_bh(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); if (&tmp_ops->ctl_table[2] == ctl) { @@ -423,15 +419,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } } if (!found) { - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); return -ENODEV; } ops = ctl->data; if (!try_module_get(ops->owner)) { // protect this function - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); return -ENODEV; } - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); if (!*lenp || *ppos) { *lenp = 0; @@ -455,11 +451,10 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, return -EFAULT; } - spin_lock(&appldata_ops_lock); + spin_lock_bh(&appldata_ops_lock); if ((buf[0] == '1') && (ops->active == 0)) { - // protect work queue callback - if (!try_module_get(ops->owner)) { - spin_unlock(&appldata_ops_lock); + if (!try_module_get(ops->owner)) { // protect tasklet + spin_unlock_bh(&appldata_ops_lock); module_put(ops->owner); return -ENODEV; } @@ -490,7 +485,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } module_put(ops->owner); } - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); out: *lenp = len; *ppos += len; @@ -534,7 +529,7 @@ int appldata_register_ops(struct appldata_ops *ops) } memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); - spin_lock(&appldata_ops_lock); + spin_lock_bh(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { tmp_ops = list_entry(lh, struct appldata_ops, list); P_DEBUG("register_ops loop: %i) name = %s, ctl = %i\n", @@ -546,18 +541,18 @@ int appldata_register_ops(struct appldata_ops *ops) APPLDATA_PROC_NAME_LENGTH) == 0) { P_ERROR("Name \"%s\" already registered!\n", ops->name); kfree(ops->ctl_table); - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); return -EBUSY; } if (tmp_ops->ctl_nr == ops->ctl_nr) { P_ERROR("ctl_nr %i already registered!\n", ops->ctl_nr); kfree(ops->ctl_table); - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); return -EBUSY; } } list_add(&ops->list, &appldata_ops_list); - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); ops->ctl_table[0].ctl_name = CTL_APPLDATA; ops->ctl_table[0].procname = appldata_proc_name; @@ -588,12 +583,12 @@ int appldata_register_ops(struct appldata_ops *ops) */ void appldata_unregister_ops(struct appldata_ops *ops) { - spin_lock(&appldata_ops_lock); + spin_lock_bh(&appldata_ops_lock); unregister_sysctl_table(ops->sysctl_header); list_del(&ops->list); kfree(ops->ctl_table); ops->ctl_table = NULL; - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management **************************/ @@ -607,7 +602,7 @@ appldata_online_cpu(int cpu) init_virt_timer(&per_cpu(appldata_timer, cpu)); per_cpu(appldata_timer, cpu).function = appldata_timer_function; per_cpu(appldata_timer, cpu).data = (unsigned long) - &appldata_work; + &appldata_tasklet_struct; atomic_inc(&appldata_expire_count); spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -620,7 +615,7 @@ appldata_offline_cpu(int cpu) del_virt_timer(&per_cpu(appldata_timer, cpu)); if (atomic_dec_and_test(&appldata_expire_count)) { atomic_set(&appldata_expire_count, num_online_cpus()); - queue_work(appldata_wq, &appldata_work); + tasklet_schedule(&appldata_tasklet_struct); } spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -653,7 +648,7 @@ static struct notifier_block __devinitdata appldata_nb = { /* * appldata_init() * - * init timer, register /proc entries + * init timer and tasklet, register /proc entries */ static int __init appldata_init(void) { @@ -662,12 +657,6 @@ static int __init appldata_init(void) P_DEBUG("sizeof(parameter_list) = %lu\n", sizeof(struct appldata_parameter_list)); - appldata_wq = create_singlethread_workqueue("appldata"); - if (!appldata_wq) { - P_ERROR("Could not create work queue\n"); - return -ENOMEM; - } - for_each_online_cpu(i) appldata_online_cpu(i); @@ -681,6 +670,7 @@ static int __init appldata_init(void) appldata_table[1].de->owner = THIS_MODULE; #endif + tasklet_init(&appldata_tasklet_struct, appldata_tasklet_function, 0); P_DEBUG("Base interface initialized.\n"); return 0; } @@ -688,7 +678,7 @@ static int __init appldata_init(void) /* * appldata_exit() * - * stop timer, unregister /proc entries + * stop timer and tasklet, unregister /proc entries */ static void __exit appldata_exit(void) { @@ -700,7 +690,7 @@ static void __exit appldata_exit(void) /* * ops list should be empty, but just in case something went wrong... */ - spin_lock(&appldata_ops_lock); + spin_lock_bh(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, @@ -710,7 +700,7 @@ static void __exit appldata_exit(void) "return code: %d\n", ops->name, rc); } } - spin_unlock(&appldata_ops_lock); + spin_unlock_bh(&appldata_ops_lock); for_each_online_cpu(i) appldata_offline_cpu(i); @@ -719,7 +709,7 @@ static void __exit appldata_exit(void) unregister_sysctl_table(appldata_sysctl_header); - destroy_workqueue(appldata_wq); + tasklet_kill(&appldata_tasklet_struct); P_DEBUG("... module unloaded!\n"); } /**************************** init / exit ******************************/ diff --git a/trunk/arch/s390/appldata/appldata_mem.c b/trunk/arch/s390/appldata/appldata_mem.c index f0e2fbed3d4c..462ee9a84e76 100644 --- a/trunk/arch/s390/appldata/appldata_mem.c +++ b/trunk/arch/s390/appldata/appldata_mem.c @@ -68,7 +68,7 @@ struct appldata_mem_data { u64 pgmajfault; /* page faults (major only) */ // <-- New in 2.6 -} __attribute__((packed)) appldata_mem_data; +} appldata_mem_data; static inline void appldata_debug_print(struct appldata_mem_data *mem_data) diff --git a/trunk/arch/s390/appldata/appldata_net_sum.c b/trunk/arch/s390/appldata/appldata_net_sum.c index 2a4c7432db4a..dd61638d3027 100644 --- a/trunk/arch/s390/appldata/appldata_net_sum.c +++ b/trunk/arch/s390/appldata/appldata_net_sum.c @@ -57,7 +57,7 @@ struct appldata_net_sum_data { u64 rx_dropped; /* no space in linux buffers */ u64 tx_dropped; /* no space available in linux */ u64 collisions; /* collisions while transmitting */ -} __attribute__((packed)) appldata_net_sum_data; +} appldata_net_sum_data; static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) diff --git a/trunk/arch/s390/appldata/appldata_os.c b/trunk/arch/s390/appldata/appldata_os.c index e0a476bf4fd6..b83f07484551 100644 --- a/trunk/arch/s390/appldata/appldata_os.c +++ b/trunk/arch/s390/appldata/appldata_os.c @@ -49,7 +49,7 @@ struct appldata_os_per_cpu { u32 per_cpu_softirq; /* ... spent in softirqs */ u32 per_cpu_iowait; /* ... spent while waiting for I/O */ // <-- New in 2.6 -} __attribute__((packed)); +}; struct appldata_os_data { u64 timestamp; @@ -75,7 +75,7 @@ struct appldata_os_data { /* per cpu data */ struct appldata_os_per_cpu os_cpu[0]; -} __attribute__((packed)); +}; static struct appldata_os_data *appldata_os_data; diff --git a/trunk/arch/s390/kernel/ptrace.c b/trunk/arch/s390/kernel/ptrace.c index 06afa3103ace..26889366929a 100644 --- a/trunk/arch/s390/kernel/ptrace.c +++ b/trunk/arch/s390/kernel/ptrace.c @@ -40,7 +40,6 @@ #include #include #include -#include #ifdef CONFIG_S390_SUPPORT #include "compat_ptrace.h" @@ -131,19 +130,13 @@ static int peek_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset, tmp, mask; + addr_t offset, tmp; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell... */ - mask = __ADDR_MASK; -#ifdef CONFIG_ARCH_S390X - if (addr >= (addr_t) &dummy->regs.acrs && - addr < (addr_t) &dummy->regs.orig_gpr2) - mask = 3; -#endif - if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) + if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -160,16 +153,6 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; -#ifdef CONFIG_ARCH_S390X - /* - * Very special case: old & broken 64 bit gdb reading - * from acrs[15]. Result is a 64 bit value. Read the - * 32 bit acrs[15] value and shift it by 32. Sick... - */ - if (addr == (addr_t) &dummy->regs.acrs[15]) - tmp = ((unsigned long) child->thread.acrs[15]) << 32; - else -#endif tmp = *(addr_t *)((addr_t) &child->thread.acrs + offset); } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { @@ -184,9 +167,6 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) */ offset = addr - (addr_t) &dummy->regs.fp_regs; tmp = *(addr_t *)((addr_t) &child->thread.fp_regs + offset); - if (addr == (addr_t) &dummy->regs.fp_regs.fpc) - tmp &= (unsigned long) FPC_VALID_MASK - << (BITS_PER_LONG - 32); } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) { /* @@ -211,19 +191,13 @@ static int poke_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset, mask; + addr_t offset; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell indeed... */ - mask = __ADDR_MASK; -#ifdef CONFIG_ARCH_S390X - if (addr >= (addr_t) &dummy->regs.acrs && - addr < (addr_t) &dummy->regs.orig_gpr2) - mask = 3; -#endif - if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) + if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -250,17 +224,6 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; -#ifdef CONFIG_ARCH_S390X - /* - * Very special case: old & broken 64 bit gdb writing - * to acrs[15] with a 64 bit value. Ignore the lower - * half of the value and write the upper 32 bit to - * acrs[15]. Sick... - */ - if (addr == (addr_t) &dummy->regs.acrs[15]) - child->thread.acrs[15] = (unsigned int) (data >> 32); - else -#endif *(addr_t *)((addr_t) &child->thread.acrs + offset) = data; } else if (addr == (addr_t) &dummy->regs.orig_gpr2) { @@ -274,8 +237,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * floating point regs. are stored in the thread structure */ if (addr == (addr_t) &dummy->regs.fp_regs.fpc && - (data & ~((unsigned long) FPC_VALID_MASK - << (BITS_PER_LONG - 32))) != 0) + (data & ~FPC_VALID_MASK) != 0) return -EINVAL; offset = addr - (addr_t) &dummy->regs.fp_regs; *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; @@ -760,13 +722,6 @@ syscall_trace(struct pt_regs *regs, int entryexit) ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); - /* - * If the debuffer has set an invalid system call number, - * we prepare to skip the system call restart handling. - */ - if (!entryexit && regs->gprs[2] >= NR_syscalls) - regs->trap = -1; - /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the diff --git a/trunk/arch/s390/mm/fault.c b/trunk/arch/s390/mm/fault.c index 75fde949d125..80306bc8c799 100644 --- a/trunk/arch/s390/mm/fault.c +++ b/trunk/arch/s390/mm/fault.c @@ -207,7 +207,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int is_protection) * we are not in an interrupt and that there is a * user context. */ - if (user_address == 0 || in_atomic() || !mm) + if (user_address == 0 || in_interrupt() || !mm) goto no_context; /* diff --git a/trunk/drivers/atm/Makefile b/trunk/drivers/atm/Makefile index 5b77188527a9..d1dcd8eae3c9 100644 --- a/trunk/drivers/atm/Makefile +++ b/trunk/drivers/atm/Makefile @@ -39,8 +39,7 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y) fore_200e-objs += fore200e_pca_fw.o # guess the target endianess to choose the right PCA-200E firmware image ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) - byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h - CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) + CONFIG_ATM_FORE200E_PCA_FW = $(shell if test -n "`$(CC) -E -dM $(src)/../../include/asm/byteorder.h | grep ' __LITTLE_ENDIAN '`"; then echo $(obj)/pca200e.bin; else echo $(obj)/pca200e_ecd.bin2; fi) endif endif diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index 5f702199543a..9e65bfb85ba3 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -383,7 +383,8 @@ fore200e_shutdown(struct fore200e* fore200e) switch(fore200e->state) { case FORE200E_STATE_COMPLETE: - kfree(fore200e->stats); + if (fore200e->stats) + kfree(fore200e->stats); case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); @@ -962,7 +963,8 @@ fore200e_tx_irq(struct fore200e* fore200e) entry, txq->tail, entry->vc_map, entry->skb); /* free copy of misaligned data */ - kfree(entry->data); + if (entry->data) + kfree(entry->data); /* remove DMA mapping */ fore200e->bus->dma_unmap(fore200e, entry->tpd->tsd[ 0 ].buffer, entry->tpd->tsd[ 0 ].length, diff --git a/trunk/drivers/atm/he.c b/trunk/drivers/atm/he.c index df2c83fd5496..3022c548a132 100644 --- a/trunk/drivers/atm/he.c +++ b/trunk/drivers/atm/he.c @@ -412,7 +412,8 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) init_one_failure: if (atm_dev) atm_dev_deregister(atm_dev); - kfree(he_dev); + if (he_dev) + kfree(he_dev); pci_disable_device(pci_dev); return err; } @@ -2533,7 +2534,8 @@ he_open(struct atm_vcc *vcc) open_failed: if (err) { - kfree(he_vcc); + if (he_vcc) + kfree(he_vcc); clear_bit(ATM_VF_ADDR, &vcc->flags); } else diff --git a/trunk/drivers/atm/nicstar.c b/trunk/drivers/atm/nicstar.c index b2a7b754fd14..85bf5c8442b0 100644 --- a/trunk/drivers/atm/nicstar.c +++ b/trunk/drivers/atm/nicstar.c @@ -676,10 +676,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) PRINTK("nicstar%d: RSQ base at 0x%x.\n", i, (u32) card->rsq.base); /* Initialize SCQ0, the only VBR SCQ used */ - card->scq1 = NULL; - card->scq2 = NULL; + card->scq1 = (scq_info *) NULL; + card->scq2 = (scq_info *) NULL; card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); - if (card->scq0 == NULL) + if (card->scq0 == (scq_info *) NULL) { printk("nicstar%d: can't get SCQ0.\n", i); error = 12; @@ -993,24 +993,24 @@ static scq_info *get_scq(int size, u32 scd) int i; if (size != VBR_SCQSIZE && size != CBR_SCQSIZE) - return NULL; + return (scq_info *) NULL; scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL); - if (scq == NULL) - return NULL; + if (scq == (scq_info *) NULL) + return (scq_info *) NULL; scq->org = kmalloc(2 * size, GFP_KERNEL); if (scq->org == NULL) { kfree(scq); - return NULL; + return (scq_info *) NULL; } scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) * (size / NS_SCQE_SIZE), GFP_KERNEL); - if (scq->skb == NULL) + if (scq->skb == (struct sk_buff **) NULL) { kfree(scq->org); kfree(scq); - return NULL; + return (scq_info *) NULL; } scq->num_entries = size / NS_SCQE_SIZE; scq->base = (ns_scqe *) ALIGN_ADDRESS(scq->org, size); @@ -1498,7 +1498,7 @@ static int ns_open(struct atm_vcc *vcc) vc->cbr_scd = NS_FRSCD + frscdi * NS_FRSCD_SIZE; scq = get_scq(CBR_SCQSIZE, vc->cbr_scd); - if (scq == NULL) + if (scq == (scq_info *) NULL) { PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); card->scd2vc[frscdi] = NULL; diff --git a/trunk/drivers/atm/zatm.c b/trunk/drivers/atm/zatm.c index 8d5e65cb9755..47a800519ad0 100644 --- a/trunk/drivers/atm/zatm.c +++ b/trunk/drivers/atm/zatm.c @@ -902,7 +902,7 @@ static void close_tx(struct atm_vcc *vcc) zatm_dev->tx_bw += vcc->qos.txtp.min_pcr; dealloc_shaper(vcc->dev,zatm_vcc->shaper); } - kfree(zatm_vcc->ring); + if (zatm_vcc->ring) kfree(zatm_vcc->ring); } @@ -1339,9 +1339,12 @@ static int __init zatm_start(struct atm_dev *dev) return 0; out: for (i = 0; i < NR_MBX; i++) - kfree(zatm_dev->mbx_start[i]); - kfree(zatm_dev->rx_map); - kfree(zatm_dev->tx_map); + if (zatm_dev->mbx_start[i] != 0) + kfree((void *) zatm_dev->mbx_start[i]); + if (zatm_dev->rx_map != NULL) + kfree(zatm_dev->rx_map); + if (zatm_dev->tx_map != NULL) + kfree(zatm_dev->tx_map); free_irq(zatm_dev->irq, dev); return error; } diff --git a/trunk/drivers/block/ub.c b/trunk/drivers/block/ub.c index adc4dcc306f4..ce42889f98fb 100644 --- a/trunk/drivers/block/ub.c +++ b/trunk/drivers/block/ub.c @@ -8,12 +8,13 @@ * and is not licensed separately. See file COPYING for details. * * TODO (sorted by decreasing priority) - * -- Kill first_open (Al Viro fixed the block layer now) * -- Do resets with usb_device_reset (needs a thread context, use khubd) * -- set readonly flag for CDs, set removable flag for CF readers * -- do inquiry and verify we got a disk and not a tape (for LUN mismatch) + * -- support pphaneuf's SDDR-75 with two LUNs (also broken capacity...) * -- special case some senses, e.g. 3a/0 -> no media present, reduce retries * -- verify the 13 conditions and do bulk resets + * -- normal pool of commands instead of cmdv[]? * -- kill last_pipe and simply do two-state clearing on both pipes * -- verify protocol (bulk) from USB descriptors (maybe...) * -- highmem and sg @@ -48,14 +49,7 @@ #define US_SC_SCSI 0x06 /* Transparent */ /* - * This many LUNs per USB device. - * Every one of them takes a host, see UB_MAX_HOSTS. */ -#define UB_MAX_LUNS 4 - -/* - */ - #define UB_MINORS_PER_MAJOR 8 #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ @@ -71,7 +65,7 @@ struct bulk_cb_wrap { u32 Tag; /* unique per command id */ __le32 DataTransferLength; /* size of data */ u8 Flags; /* direction in bit 0 */ - u8 Lun; /* LUN */ + u8 Lun; /* LUN normally 0 */ u8 Length; /* of of the CDB */ u8 CDB[UB_MAX_CDB_SIZE]; /* max command */ }; @@ -174,7 +168,6 @@ struct ub_scsi_cmd { unsigned int len; /* Requested length */ // struct scatterlist sgv[UB_MAX_REQ_SG]; - struct ub_lun *lun; void (*done)(struct ub_dev *, struct ub_scsi_cmd *); void *back; }; @@ -259,47 +252,25 @@ struct ub_scsi_cmd_queue { }; /* - * The block device instance (one per LUN). - */ -struct ub_lun { - struct ub_dev *udev; - struct list_head link; - struct gendisk *disk; - int id; /* Host index */ - int num; /* LUN number */ - char name[16]; - - int changed; /* Media was changed */ - int removable; - int readonly; - int first_open; /* Kludge. See ub_bd_open. */ - - /* Use Ingo's mempool if or when we have more than one command. */ - /* - * Currently we never need more than one command for the whole device. - * However, giving every LUN a command is a cheap and automatic way - * to enforce fairness between them. - */ - int cmda[1]; - struct ub_scsi_cmd cmdv[1]; - - struct ub_capacity capacity; -}; - -/* - * The USB device instance. + * The UB device instance. */ struct ub_dev { spinlock_t lock; + int id; /* Number among ub's */ atomic_t poison; /* The USB device is disconnected */ int openc; /* protected by ub_lock! */ /* kref is too implicit for our taste */ unsigned int tagcnt; - char name[12]; + int changed; /* Media was changed */ + int removable; + int readonly; + int first_open; /* Kludge. See ub_bd_open. */ + char name[8]; struct usb_device *dev; struct usb_interface *intf; - struct list_head luns; + struct ub_capacity capacity; + struct gendisk *disk; unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int recv_bulk_pipe; @@ -308,6 +279,10 @@ struct ub_dev { struct tasklet_struct tasklet; + /* XXX Use Ingo's mempool (once we have more than one) */ + int cmda[1]; + struct ub_scsi_cmd cmdv[1]; + struct ub_scsi_cmd_queue cmd_queue; struct ub_scsi_cmd top_rqs_cmd; /* REQUEST SENSE */ unsigned char top_sense[UB_SENSE_SIZE]; @@ -326,9 +301,9 @@ struct ub_dev { /* */ static void ub_cleanup(struct ub_dev *sc); -static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq); -static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, - struct ub_scsi_cmd *cmd, struct request *rq); +static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq); +static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, + struct request *rq); static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, struct request *rq); static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd); @@ -345,10 +320,8 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd); static int ub_submit_clear_stall(struct ub_dev *sc, struct ub_scsi_cmd *cmd, int stalled_pipe); static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd); -static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun); -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, - struct ub_capacity *ret); -static int ub_probe_lun(struct ub_dev *sc, int lnum); +static int ub_sync_tur(struct ub_dev *sc); +static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret); /* */ @@ -369,7 +342,6 @@ MODULE_DEVICE_TABLE(usb, ub_usb_ids); */ #define UB_MAX_HOSTS 26 static char ub_hostv[UB_MAX_HOSTS]; - static DEFINE_SPINLOCK(ub_lock); /* Locks globals and ->openc */ /* @@ -434,8 +406,6 @@ static ssize_t ub_diag_show(struct device *dev, char *page) { struct usb_interface *intf; struct ub_dev *sc; - struct list_head *p; - struct ub_lun *lun; int cnt; unsigned long flags; int nc, nh; @@ -451,15 +421,9 @@ static ssize_t ub_diag_show(struct device *dev, char *page) spin_lock_irqsave(&sc->lock, flags); cnt += sprintf(page + cnt, - "qlen %d qmax %d\n", - sc->cmd_queue.qlen, sc->cmd_queue.qmax); - - list_for_each (p, &sc->luns) { - lun = list_entry(p, struct ub_lun, link); - cnt += sprintf(page + cnt, - "lun %u changed %d removable %d readonly %d\n", - lun->num, lun->changed, lun->removable, lun->readonly); - } + "qlen %d qmax %d changed %d removable %d readonly %d\n", + sc->cmd_queue.qlen, sc->cmd_queue.qmax, + sc->changed, sc->removable, sc->readonly); if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0; for (j = 0; j < SCMD_TRACE_SZ; j++) { @@ -559,63 +523,53 @@ static void ub_put(struct ub_dev *sc) */ static void ub_cleanup(struct ub_dev *sc) { - struct list_head *p; - struct ub_lun *lun; request_queue_t *q; - while (!list_empty(&sc->luns)) { - p = sc->luns.next; - lun = list_entry(p, struct ub_lun, link); - list_del(p); - - /* I don't think queue can be NULL. But... Stolen from sx8.c */ - if ((q = lun->disk->queue) != NULL) - blk_cleanup_queue(q); - /* - * If we zero disk->private_data BEFORE put_disk, we have - * to check for NULL all over the place in open, release, - * check_media and revalidate, because the block level - * semaphore is well inside the put_disk. - * But we cannot zero after the call, because *disk is gone. - * The sd.c is blatantly racy in this area. - */ - /* disk->private_data = NULL; */ - put_disk(lun->disk); - lun->disk = NULL; + /* I don't think queue can be NULL. But... Stolen from sx8.c */ + if ((q = sc->disk->queue) != NULL) + blk_cleanup_queue(q); - ub_id_put(lun->id); - kfree(lun); - } + /* + * If we zero disk->private_data BEFORE put_disk, we have to check + * for NULL all over the place in open, release, check_media and + * revalidate, because the block level semaphore is well inside the + * put_disk. But we cannot zero after the call, because *disk is gone. + * The sd.c is blatantly racy in this area. + */ + /* disk->private_data = NULL; */ + put_disk(sc->disk); + sc->disk = NULL; + ub_id_put(sc->id); kfree(sc); } /* * The "command allocator". */ -static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun) +static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc) { struct ub_scsi_cmd *ret; - if (lun->cmda[0]) + if (sc->cmda[0]) return NULL; - ret = &lun->cmdv[0]; - lun->cmda[0] = 1; + ret = &sc->cmdv[0]; + sc->cmda[0] = 1; return ret; } -static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd) +static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { - if (cmd != &lun->cmdv[0]) { + if (cmd != &sc->cmdv[0]) { printk(KERN_WARNING "%s: releasing a foreign cmd %p\n", - lun->name, cmd); + sc->name, cmd); return; } - if (!lun->cmda[0]) { - printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name); + if (!sc->cmda[0]) { + printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name); return; } - lun->cmda[0] = 0; + sc->cmda[0] = 0; } /* @@ -676,30 +630,29 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) static void ub_bd_rq_fn(request_queue_t *q) { - struct ub_lun *lun = q->queuedata; + struct ub_dev *sc = q->queuedata; struct request *rq; while ((rq = elv_next_request(q)) != NULL) { - if (ub_bd_rq_fn_1(lun, rq) != 0) { + if (ub_bd_rq_fn_1(sc, rq) != 0) { blk_stop_queue(q); break; } } } -static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) +static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) { - struct ub_dev *sc = lun->udev; struct ub_scsi_cmd *cmd; int rc; - if (atomic_read(&sc->poison) || lun->changed) { + if (atomic_read(&sc->poison) || sc->changed) { blkdev_dequeue_request(rq); ub_end_rq(rq, 0); return 0; } - if ((cmd = ub_get_cmd(lun)) == NULL) + if ((cmd = ub_get_cmd(sc)) == NULL) return -1; memset(cmd, 0, sizeof(struct ub_scsi_cmd)); @@ -708,30 +661,32 @@ static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) if (blk_pc_request(rq)) { rc = ub_cmd_build_packet(sc, cmd, rq); } else { - rc = ub_cmd_build_block(sc, lun, cmd, rq); + rc = ub_cmd_build_block(sc, cmd, rq); } if (rc != 0) { - ub_put_cmd(lun, cmd); + ub_put_cmd(sc, cmd); ub_end_rq(rq, 0); + blk_start_queue(sc->disk->queue); return 0; } + cmd->state = UB_CMDST_INIT; - cmd->lun = lun; cmd->done = ub_rw_cmd_done; cmd->back = rq; cmd->tag = sc->tagcnt++; if ((rc = ub_submit_scsi(sc, cmd)) != 0) { - ub_put_cmd(lun, cmd); + ub_put_cmd(sc, cmd); ub_end_rq(rq, 0); + blk_start_queue(sc->disk->queue); return 0; } return 0; } -static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, - struct ub_scsi_cmd *cmd, struct request *rq) +static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, + struct request *rq) { int ub_dir; #if 0 /* We use rq->buffer for now */ @@ -752,7 +707,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, sg = &cmd->sgv[0]; n_elem = blk_rq_map_sg(q, rq, sg); if (n_elem <= 0) { - ub_put_cmd(lun, cmd); + ub_put_cmd(sc, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; /* request with no s/g entries? */ @@ -761,7 +716,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, if (n_elem != 1) { /* Paranoia */ printk(KERN_WARNING "%s: request with %d segments\n", sc->name, n_elem); - ub_put_cmd(lun, cmd); + ub_put_cmd(sc, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; @@ -793,8 +748,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun, * The call to blk_queue_hardsect_size() guarantees that request * is aligned, but it is given in terms of 512 byte units, always. */ - block = rq->sector >> lun->capacity.bshift; - nblks = rq->nr_sectors >> lun->capacity.bshift; + block = rq->sector >> sc->capacity.bshift; + nblks = rq->nr_sectors >> sc->capacity.bshift; cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ @@ -848,8 +803,7 @@ static int ub_cmd_build_packet(struct ub_dev *sc, struct ub_scsi_cmd *cmd, static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) { struct request *rq = cmd->back; - struct ub_lun *lun = cmd->lun; - struct gendisk *disk = lun->disk; + struct gendisk *disk = sc->disk; request_queue_t *q = disk->queue; int uptodate; @@ -864,7 +818,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) else uptodate = 0; - ub_put_cmd(lun, cmd); + ub_put_cmd(sc, cmd); ub_end_rq(rq, uptodate); blk_start_queue(q); } @@ -933,7 +887,7 @@ static int ub_scsi_cmd_start(struct ub_dev *sc, struct ub_scsi_cmd *cmd) bcb->Tag = cmd->tag; /* Endianness is not important */ bcb->DataTransferLength = cpu_to_le32(cmd->len); bcb->Flags = (cmd->dir == UB_DIR_READ) ? 0x80 : 0; - bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0; + bcb->Lun = 0; /* No multi-LUN yet */ bcb->Length = cmd->cdb_len; /* copy the command payload */ @@ -1048,8 +1002,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * The control pipe clears itself - nothing to do. * XXX Might try to reset the device here and retry. */ - printk(KERN_NOTICE "%s: stall on control pipe\n", - sc->name); + printk(KERN_NOTICE "%s: " + "stall on control pipe for device %u\n", + sc->name, sc->dev->devnum); goto Bad_End; } @@ -1070,8 +1025,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * The control pipe clears itself - nothing to do. * XXX Might try to reset the device here and retry. */ - printk(KERN_NOTICE "%s: stall on control pipe\n", - sc->name); + printk(KERN_NOTICE "%s: " + "stall on control pipe for device %u\n", + sc->name, sc->dev->devnum); goto Bad_End; } @@ -1090,8 +1046,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear (%d)\n", - sc->name, rc); + "unable to submit clear for device %u" + " (code %d)\n", + sc->name, sc->dev->devnum, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1150,8 +1107,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear (%d)\n", - sc->name, rc); + "unable to submit clear for device %u" + " (code %d)\n", + sc->name, sc->dev->devnum, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1182,8 +1140,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) rc = ub_submit_clear_stall(sc, cmd, sc->last_pipe); if (rc != 0) { printk(KERN_NOTICE "%s: " - "unable to submit clear (%d)\n", - sc->name, rc); + "unable to submit clear for device %u" + " (code %d)\n", + sc->name, sc->dev->devnum, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1205,8 +1164,9 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) * encounter such a thing, try to read the CSW again. */ if (++cmd->stat_count >= 4) { - printk(KERN_NOTICE "%s: unable to get CSW\n", - sc->name); + printk(KERN_NOTICE "%s: " + "unable to get CSW on device %u\n", + sc->name, sc->dev->devnum); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1247,8 +1207,10 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) */ if (++cmd->stat_count >= 4) { printk(KERN_NOTICE "%s: " - "tag mismatch orig 0x%x reply 0x%x\n", - sc->name, cmd->tag, bcs->Tag); + "tag mismatch orig 0x%x reply 0x%x " + "on device %u\n", + sc->name, cmd->tag, bcs->Tag, + sc->dev->devnum); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1282,8 +1244,8 @@ static void ub_scsi_urb_compl(struct ub_dev *sc, struct ub_scsi_cmd *cmd) } else { printk(KERN_WARNING "%s: " - "wrong command state %d\n", - sc->name, cmd->state); + "wrong command state %d on device %u\n", + sc->name, cmd->state, sc->dev->devnum); goto Bad_End; } return; @@ -1326,6 +1288,7 @@ static void __ub_state_stat(struct ub_dev *sc, struct ub_scsi_cmd *cmd) if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) { /* XXX Clear stalls */ + printk("%s: CSW #%d submit failed (%d)\n", sc->name, cmd->tag, rc); /* P3 */ ub_complete(&sc->work_done); ub_state_done(sc, cmd, rc); return; @@ -1370,7 +1333,6 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd) scmd->state = UB_CMDST_INIT; scmd->data = sc->top_sense; scmd->len = UB_SENSE_SIZE; - scmd->lun = cmd->lun; scmd->done = ub_top_sense_done; scmd->back = cmd; @@ -1449,14 +1411,14 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) } if (cmd != scmd->back) { printk(KERN_WARNING "%s: " - "sense done for wrong command 0x%x\n", - sc->name, cmd->tag); + "sense done for wrong command 0x%x on device %u\n", + sc->name, cmd->tag, sc->dev->devnum); return; } if (cmd->state != UB_CMDST_SENSE) { printk(KERN_WARNING "%s: " - "sense done with bad cmd state %d\n", - sc->name, cmd->state); + "sense done with bad cmd state %d on device %u\n", + sc->name, cmd->state, sc->dev->devnum); return; } @@ -1467,32 +1429,68 @@ static void ub_top_sense_done(struct ub_dev *sc, struct ub_scsi_cmd *scmd) ub_scsi_urb_compl(sc, cmd); } +#if 0 +/* Determine what the maximum LUN supported is */ +int usb_stor_Bulk_max_lun(struct us_data *us) +{ + int result; + + /* issue the command */ + result = usb_stor_control_msg(us, us->recv_ctrl_pipe, + US_BULK_GET_MAX_LUN, + USB_DIR_IN | USB_TYPE_CLASS | + USB_RECIP_INTERFACE, + 0, us->ifnum, us->iobuf, 1, HZ); + + /* + * Some devices (i.e. Iomega Zip100) need this -- apparently + * the bulk pipes get STALLed when the GetMaxLUN request is + * processed. This is, in theory, harmless to all other devices + * (regardless of if they stall or not). + */ + if (result < 0) { + usb_stor_clear_halt(us, us->recv_bulk_pipe); + usb_stor_clear_halt(us, us->send_bulk_pipe); + } + + US_DEBUGP("GetMaxLUN command result is %d, data is %d\n", + result, us->iobuf[0]); + + /* if we have a successful request, return the result */ + if (result == 1) + return us->iobuf[0]; + + /* return the default -- no LUNs */ + return 0; +} +#endif + /* * This is called from a process context. */ -static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) +static void ub_revalidate(struct ub_dev *sc) { - lun->readonly = 0; /* XXX Query this from the device */ + sc->readonly = 0; /* XXX Query this from the device */ - lun->capacity.nsec = 0; - lun->capacity.bsize = 512; - lun->capacity.bshift = 0; + sc->capacity.nsec = 0; + sc->capacity.bsize = 512; + sc->capacity.bshift = 0; - if (ub_sync_tur(sc, lun) != 0) + if (ub_sync_tur(sc) != 0) return; /* Not ready */ - lun->changed = 0; + sc->changed = 0; - if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { + if (ub_sync_read_cap(sc, &sc->capacity) != 0) { /* * The retry here means something is wrong, either with the * device, with the transport, or with our code. * We keep this because sd.c has retries for capacity. */ - if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { - lun->capacity.nsec = 0; - lun->capacity.bsize = 512; - lun->capacity.bshift = 0; + if (ub_sync_read_cap(sc, &sc->capacity) != 0) { + sc->capacity.nsec = 0; + sc->capacity.bsize = 512; + sc->capacity.bshift = 0; } } } @@ -1505,15 +1503,12 @@ static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) static int ub_bd_open(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_lun *lun; struct ub_dev *sc; unsigned long flags; int rc; - if ((lun = disk->private_data) == NULL) + if ((sc = disk->private_data) == NULL) return -ENXIO; - sc = lun->udev; - spin_lock_irqsave(&ub_lock, flags); if (atomic_read(&sc->poison)) { spin_unlock_irqrestore(&ub_lock, flags); @@ -1534,15 +1529,15 @@ static int ub_bd_open(struct inode *inode, struct file *filp) * The bottom line is, Al Viro says that we should not allow * bdev->bd_invalidated to be set when doing add_disk no matter what. */ - if (lun->first_open) { - lun->first_open = 0; - if (lun->changed) { + if (sc->first_open) { + if (sc->changed) { + sc->first_open = 0; rc = -ENOMEDIUM; goto err_open; } } - if (lun->removable || lun->readonly) + if (sc->removable || sc->readonly) check_disk_change(inode->i_bdev); /* @@ -1550,12 +1545,12 @@ static int ub_bd_open(struct inode *inode, struct file *filp) * under some pretty murky conditions (a failure of READ CAPACITY). * We may need it one day. */ - if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { + if (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) { rc = -ENOMEDIUM; goto err_open; } - if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { + if (sc->readonly && (filp->f_mode & FMODE_WRITE)) { rc = -EROFS; goto err_open; } @@ -1572,8 +1567,7 @@ static int ub_bd_open(struct inode *inode, struct file *filp) static int ub_bd_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_lun *lun = disk->private_data; - struct ub_dev *sc = lun->udev; + struct ub_dev *sc = disk->private_data; ub_put(sc); return 0; @@ -1603,14 +1597,20 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, */ static int ub_bd_revalidate(struct gendisk *disk) { - struct ub_lun *lun = disk->private_data; - - ub_revalidate(lun->udev, lun); + struct ub_dev *sc = disk->private_data; + + ub_revalidate(sc); + /* This is pretty much a long term P3 */ + if (!atomic_read(&sc->poison)) { /* Cover sc->dev */ + printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", + sc->name, sc->dev->devnum, + sc->capacity.nsec, sc->capacity.bsize); + } /* XXX Support sector size switching like in sr.c */ - blk_queue_hardsect_size(disk->queue, lun->capacity.bsize); - set_capacity(disk, lun->capacity.nsec); - // set_disk_ro(sdkp->disk, lun->readonly); + blk_queue_hardsect_size(disk->queue, sc->capacity.bsize); + set_capacity(disk, sc->capacity.nsec); + // set_disk_ro(sdkp->disk, sc->readonly); return 0; } @@ -1626,9 +1626,9 @@ static int ub_bd_revalidate(struct gendisk *disk) */ static int ub_bd_media_changed(struct gendisk *disk) { - struct ub_lun *lun = disk->private_data; + struct ub_dev *sc = disk->private_data; - if (!lun->removable) + if (!sc->removable) return 0; /* @@ -1640,12 +1640,12 @@ static int ub_bd_media_changed(struct gendisk *disk) * will fail, then block layer discards the data. Since we never * spin drives up, such devices simply cannot be used with ub anyway. */ - if (ub_sync_tur(lun->udev, lun) != 0) { - lun->changed = 1; + if (ub_sync_tur(sc) != 0) { + sc->changed = 1; return 1; } - return lun->changed; + return sc->changed; } static struct block_device_operations ub_bd_fops = { @@ -1669,7 +1669,7 @@ static void ub_probe_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) /* * Test if the device has a check condition on it, synchronously. */ -static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) +static int ub_sync_tur(struct ub_dev *sc) { struct ub_scsi_cmd *cmd; enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) }; @@ -1688,7 +1688,6 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) cmd->cdb_len = 6; cmd->dir = UB_DIR_NONE; cmd->state = UB_CMDST_INIT; - cmd->lun = lun; /* This may be NULL, but that's ok */ cmd->done = ub_probe_done; cmd->back = &compl; @@ -1719,8 +1718,7 @@ static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) /* * Read the SCSI capacity synchronously (for probing). */ -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, - struct ub_capacity *ret) +static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) { struct ub_scsi_cmd *cmd; char *p; @@ -1745,7 +1743,6 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, cmd->state = UB_CMDST_INIT; cmd->data = p; cmd->len = 8; - cmd->lun = lun; cmd->done = ub_probe_done; cmd->back = &compl; @@ -1814,90 +1811,6 @@ static void ub_probe_timeout(unsigned long arg) complete(cop); } -/* - * Get number of LUNs by the way of Bulk GetMaxLUN command. - */ -static int ub_sync_getmaxlun(struct ub_dev *sc) -{ - int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber; - unsigned char *p; - enum { ALLOC_SIZE = 1 }; - struct usb_ctrlrequest *cr; - struct completion compl; - struct timer_list timer; - int nluns; - int rc; - - init_completion(&compl); - - rc = -ENOMEM; - if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL) - goto err_alloc; - *p = 55; - - cr = &sc->work_cr; - cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE; - cr->bRequest = US_BULK_GET_MAX_LUN; - cr->wValue = cpu_to_le16(0); - cr->wIndex = cpu_to_le16(ifnum); - cr->wLength = cpu_to_le16(1); - - usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe, - (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl); - sc->work_urb.transfer_flags = 0; - sc->work_urb.actual_length = 0; - sc->work_urb.error_count = 0; - sc->work_urb.status = 0; - - if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) { - if (rc == -EPIPE) { - printk("%s: Stall at GetMaxLUN, using 1 LUN\n", - sc->name); /* P3 */ - } else { - printk(KERN_WARNING - "%s: Unable to submit GetMaxLUN (%d)\n", - sc->name, rc); - } - goto err_submit; - } - - init_timer(&timer); - timer.function = ub_probe_timeout; - timer.data = (unsigned long) &compl; - timer.expires = jiffies + UB_CTRL_TIMEOUT; - add_timer(&timer); - - wait_for_completion(&compl); - - del_timer_sync(&timer); - usb_kill_urb(&sc->work_urb); - - if (sc->work_urb.actual_length != 1) { - printk("%s: GetMaxLUN returned %d bytes\n", sc->name, - sc->work_urb.actual_length); /* P3 */ - nluns = 0; - } else { - if ((nluns = *p) == 55) { - nluns = 0; - } else { - /* GetMaxLUN returns the maximum LUN number */ - nluns += 1; - if (nluns > UB_MAX_LUNS) - nluns = UB_MAX_LUNS; - } - printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name, - *p, nluns); /* P3 */ - } - - kfree(p); - return nluns; - -err_submit: - kfree(p); -err_alloc: - return rc; -} - /* * Clear initial stalls. */ @@ -1984,8 +1897,8 @@ static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev, } if (ep_in == NULL || ep_out == NULL) { - printk(KERN_NOTICE "%s: failed endpoint check\n", - sc->name); + printk(KERN_NOTICE "%s: device %u failed endpoint check\n", + sc->name, sc->dev->devnum); return -EIO; } @@ -2008,7 +1921,8 @@ static int ub_probe(struct usb_interface *intf, const struct usb_device_id *dev_id) { struct ub_dev *sc; - int nluns; + request_queue_t *q; + struct gendisk *disk; int rc; int i; @@ -2017,7 +1931,6 @@ static int ub_probe(struct usb_interface *intf, goto err_core; memset(sc, 0, sizeof(struct ub_dev)); spin_lock_init(&sc->lock); - INIT_LIST_HEAD(&sc->luns); usb_init_urb(&sc->work_urb); tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc); atomic_set(&sc->poison, 0); @@ -2029,16 +1942,19 @@ static int ub_probe(struct usb_interface *intf, ub_init_completion(&sc->work_done); sc->work_done.done = 1; /* A little yuk, but oh well... */ + rc = -ENOSR; + if ((sc->id = ub_id_get()) == -1) + goto err_id; + snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a'); + sc->dev = interface_to_usbdev(intf); sc->intf = intf; // sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + usb_set_intfdata(intf, sc); usb_get_dev(sc->dev); // usb_get_intf(sc->intf); /* Do we need this? */ - snprintf(sc->name, 12, DRV_NAME "(%d.%d)", - sc->dev->bus->busnum, sc->dev->devnum); - /* XXX Verify that we can handle the device (from descriptors) */ ub_get_pipes(sc, sc->dev, intf); @@ -2076,88 +1992,35 @@ static int ub_probe(struct usb_interface *intf, * In any case it's not our business how revaliadation is implemented. */ for (i = 0; i < 3; i++) { /* Retries for benh's key */ - if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; + if ((rc = ub_sync_tur(sc)) <= 0) break; if (rc != 0x6) break; msleep(10); } - nluns = 1; - for (i = 0; i < 3; i++) { - if ((rc = ub_sync_getmaxlun(sc)) < 0) { - /* - * Some devices (i.e. Iomega Zip100) need this -- - * apparently the bulk pipes get STALLed when the - * GetMaxLUN request is processed. - * XXX I have a ZIP-100, verify it does this. - */ - if (rc == -EPIPE) { - ub_probe_clear_stall(sc, sc->recv_bulk_pipe); - ub_probe_clear_stall(sc, sc->send_bulk_pipe); - } - break; - } - if (rc != 0) { - nluns = rc; - break; - } - mdelay(100); - } + sc->removable = 1; /* XXX Query this from the device */ + sc->changed = 1; /* ub_revalidate clears only */ + sc->first_open = 1; - for (i = 0; i < nluns; i++) { - ub_probe_lun(sc, i); - } - return 0; - - /* device_remove_file(&sc->intf->dev, &dev_attr_diag); */ -err_diag: - usb_set_intfdata(intf, NULL); - // usb_put_intf(sc->intf); - usb_put_dev(sc->dev); - kfree(sc); -err_core: - return rc; -} - -static int ub_probe_lun(struct ub_dev *sc, int lnum) -{ - struct ub_lun *lun; - request_queue_t *q; - struct gendisk *disk; - int rc; - - rc = -ENOMEM; - if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL) - goto err_alloc; - memset(lun, 0, sizeof(struct ub_lun)); - lun->num = lnum; - - rc = -ENOSR; - if ((lun->id = ub_id_get()) == -1) - goto err_id; - - lun->udev = sc; - list_add(&lun->link, &sc->luns); - - snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)", - lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num); - - lun->removable = 1; /* XXX Query this from the device */ - lun->changed = 1; /* ub_revalidate clears only */ - lun->first_open = 1; - ub_revalidate(sc, lun); + ub_revalidate(sc); + /* This is pretty much a long term P3 */ + printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n", + sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize); + /* + * Just one disk per sc currently, but maybe more. + */ rc = -ENOMEM; if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) goto err_diskalloc; - lun->disk = disk; - sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); - sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); + sc->disk = disk; + sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a'); + sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a'); disk->major = UB_MAJOR; - disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; + disk->first_minor = sc->id * UB_MINORS_PER_MAJOR; disk->fops = &ub_bd_fops; - disk->private_data = lun; - disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ + disk->private_data = sc; + disk->driverfs_dev = &intf->dev; rc = -ENOMEM; if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) @@ -2165,17 +2028,28 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) disk->queue = q; - blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); + // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); blk_queue_max_hw_segments(q, UB_MAX_REQ_SG); blk_queue_max_phys_segments(q, UB_MAX_REQ_SG); - blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ + // blk_queue_segment_boundary(q, CARM_SG_BOUNDARY); blk_queue_max_sectors(q, UB_MAX_SECTORS); - blk_queue_hardsect_size(q, lun->capacity.bsize); + blk_queue_hardsect_size(q, sc->capacity.bsize); + + /* + * This is a serious infraction, caused by a deficiency in the + * USB sg interface (usb_sg_wait()). We plan to remove this once + * we get mileage on the driver and can justify a change to USB API. + * See blk_queue_bounce_limit() to understand this part. + * + * XXX And I still need to be aware of the DMA mask in the HC. + */ + q->bounce_pfn = blk_max_low_pfn; + q->bounce_gfp = GFP_NOIO; - q->queuedata = lun; + q->queuedata = sc; - set_capacity(disk, lun->capacity.nsec); - if (lun->removable) + set_capacity(disk, sc->capacity.nsec); + if (sc->removable) disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); @@ -2185,20 +2059,22 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) err_blkqinit: put_disk(disk); err_diskalloc: - list_del(&lun->link); - ub_id_put(lun->id); + device_remove_file(&sc->intf->dev, &dev_attr_diag); +err_diag: + usb_set_intfdata(intf, NULL); + // usb_put_intf(sc->intf); + usb_put_dev(sc->dev); + ub_id_put(sc->id); err_id: - kfree(lun); -err_alloc: + kfree(sc); +err_core: return rc; } static void ub_disconnect(struct usb_interface *intf) { struct ub_dev *sc = usb_get_intfdata(intf); - struct list_head *p; - struct ub_lun *lun; - struct gendisk *disk; + struct gendisk *disk = sc->disk; unsigned long flags; /* @@ -2248,18 +2124,14 @@ static void ub_disconnect(struct usb_interface *intf) /* * Unregister the upper layer. */ - list_for_each (p, &sc->luns) { - lun = list_entry(p, struct ub_lun, link); - disk = lun->disk; - if (disk->flags & GENHD_FL_UP) - del_gendisk(disk); - /* - * I wish I could do: - * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); - * As it is, we rely on our internal poisoning and let - * the upper levels to spin furiously failing all the I/O. - */ - } + if (disk->flags & GENHD_FL_UP) + del_gendisk(disk); + /* + * I wish I could do: + * set_bit(QUEUE_FLAG_DEAD, &q->queue_flags); + * As it is, we rely on our internal poisoning and let + * the upper levels to spin furiously failing all the I/O. + */ /* * Taking a lock on a structure which is about to be freed @@ -2310,8 +2182,8 @@ static int __init ub_init(void) { int rc; - /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu ub_lun %zu\n", - sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev), sizeof(struct ub_lun)); + /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n", + sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev)); if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) goto err_regblkdev; diff --git a/trunk/drivers/char/agp/agp.h b/trunk/drivers/char/agp/agp.h index c1fe013c64f3..ad9c11391d81 100644 --- a/trunk/drivers/char/agp/agp.h +++ b/trunk/drivers/char/agp/agp.h @@ -278,8 +278,6 @@ void agp3_generic_cleanup(void); #define AGP_GENERIC_SIZES_ENTRIES 11 extern struct aper_size_info_16 agp3_generic_sizes[]; -#define virt_to_gart(x) (phys_to_gart(virt_to_phys(x))) -#define gart_to_virt(x) (phys_to_virt(gart_to_phys(x))) extern int agp_off; extern int agp_try_unsupported_boot; diff --git a/trunk/drivers/char/agp/ali-agp.c b/trunk/drivers/char/agp/ali-agp.c index 9c9c9c2247ce..0212febda654 100644 --- a/trunk/drivers/char/agp/ali-agp.c +++ b/trunk/drivers/char/agp/ali-agp.c @@ -150,7 +150,7 @@ static void *m1541_alloc_page(struct agp_bridge_data *bridge) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); + virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN )); return addr; } @@ -174,7 +174,7 @@ static void m1541_destroy_page(void * addr) pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | - virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); + virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN)); agp_generic_destroy_page(addr); } diff --git a/trunk/drivers/char/agp/amd-k7-agp.c b/trunk/drivers/char/agp/amd-k7-agp.c index 3a41672e4d66..e62a3c2c44a9 100644 --- a/trunk/drivers/char/agp/amd-k7-agp.c +++ b/trunk/drivers/char/agp/amd-k7-agp.c @@ -43,7 +43,7 @@ static int amd_create_page_map(struct amd_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -154,7 +154,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -167,7 +167,7 @@ static int amd_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1, + writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/trunk/drivers/char/agp/amd64-agp.c b/trunk/drivers/char/agp/amd64-agp.c index 1407945a5892..399c042f68f0 100644 --- a/trunk/drivers/char/agp/amd64-agp.c +++ b/trunk/drivers/char/agp/amd64-agp.c @@ -219,7 +219,7 @@ static struct aper_size_info_32 amd_8151_sizes[7] = static int amd_8151_configure(void) { - unsigned long gatt_bus = virt_to_gart(agp_bridge->gatt_table_real); + unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real); /* Configure AGP regs in each x86-64 host bridge. */ for_each_nb() { @@ -591,7 +591,7 @@ static void __devexit agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - release_mem_region(virt_to_gart(bridge->gatt_table_real), + release_mem_region(virt_to_phys(bridge->gatt_table_real), amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); diff --git a/trunk/drivers/char/agp/ati-agp.c b/trunk/drivers/char/agp/ati-agp.c index e572ced9100a..a65f8827c283 100644 --- a/trunk/drivers/char/agp/ati-agp.c +++ b/trunk/drivers/char/agp/ati-agp.c @@ -61,7 +61,7 @@ static int ati_create_page_map(ati_page_map *page_map) SetPageReserved(virt_to_page(page_map->real)); err = map_page_into_agp(virt_to_page(page_map->real)); - page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL || err) { ClearPageReserved(virt_to_page(page_map->real)); @@ -343,7 +343,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real); /* Write out the size register */ current_size = A_SIZE_LVL2(agp_bridge->current_size); @@ -373,7 +373,7 @@ static int ati_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) { - writel(virt_to_gart(ati_generic_private.gatt_pages[i]->real) | 1, + writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1, page_dir.remapped+GET_PAGE_DIR_OFF(addr)); readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr)); /* PCI Posting. */ } diff --git a/trunk/drivers/char/agp/backend.c b/trunk/drivers/char/agp/backend.c index 4d4e602fdc7e..2f3dfb63bdc6 100644 --- a/trunk/drivers/char/agp/backend.c +++ b/trunk/drivers/char/agp/backend.c @@ -148,7 +148,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) return -ENOMEM; } - bridge->scratch_page_real = virt_to_gart(addr); + bridge->scratch_page_real = virt_to_phys(addr); bridge->scratch_page = bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); } @@ -189,7 +189,7 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) err_out: if (bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - gart_to_virt(bridge->scratch_page_real)); + phys_to_virt(bridge->scratch_page_real)); if (got_gatt) bridge->driver->free_gatt_table(bridge); if (got_keylist) { @@ -214,7 +214,7 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge) if (bridge->driver->agp_destroy_page && bridge->driver->needs_scratch_page) bridge->driver->agp_destroy_page( - gart_to_virt(bridge->scratch_page_real)); + phys_to_virt(bridge->scratch_page_real)); } /* When we remove the global variable agp_bridge from all drivers diff --git a/trunk/drivers/char/agp/efficeon-agp.c b/trunk/drivers/char/agp/efficeon-agp.c index ac19fdcd21c1..1383c3165ea1 100644 --- a/trunk/drivers/char/agp/efficeon-agp.c +++ b/trunk/drivers/char/agp/efficeon-agp.c @@ -219,7 +219,7 @@ static int efficeon_create_gatt_table(struct agp_bridge_data *bridge) efficeon_private.l1_table[index] = page; - value = virt_to_gart(page) | pati | present | index; + value = __pa(page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); diff --git a/trunk/drivers/char/agp/generic.c b/trunk/drivers/char/agp/generic.c index f0079e991bdc..c321a924e38a 100644 --- a/trunk/drivers/char/agp/generic.c +++ b/trunk/drivers/char/agp/generic.c @@ -153,7 +153,7 @@ void agp_free_memory(struct agp_memory *curr) } if (curr->page_count != 0) { for (i = 0; i < curr->page_count; i++) { - curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i])); + curr->bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[i])); } } agp_free_key(curr->key); @@ -209,7 +209,7 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, agp_free_memory(new); return NULL; } - new->memory[i] = virt_to_gart(addr); + new->memory[i] = virt_to_phys(addr); new->page_count++; } new->bridge = bridge; @@ -295,6 +295,19 @@ int agp_num_entries(void) EXPORT_SYMBOL_GPL(agp_num_entries); +static int check_bridge_mode(struct pci_dev *dev) +{ + u32 agp3; + u8 cap_ptr; + + cap_ptr = pci_find_capability(dev, PCI_CAP_ID_AGP); + pci_read_config_dword(dev, cap_ptr+AGPSTAT, &agp3); + if (agp3 & AGPSTAT_MODE_3_0) + return 1; + return 0; +} + + /** * agp_copy_info - copy bridge state information * @@ -315,7 +328,7 @@ int agp_copy_info(struct agp_bridge_data *bridge, struct agp_kern_info *info) info->version.minor = bridge->version->minor; info->chipset = SUPPORTED; info->device = bridge->dev; - if (bridge->mode & AGPSTAT_MODE_3_0) + if (check_bridge_mode(bridge->dev)) info->mode = bridge->mode & ~AGP3_RESERVED_MASK; else info->mode = bridge->mode & ~AGP2_RESERVED_MASK; @@ -648,7 +661,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode bridge_agpstat &= ~AGPSTAT_FW; /* Check to see if we are operating in 3.0 mode */ - if (agp_bridge->mode & AGPSTAT_MODE_3_0) + if (check_bridge_mode(agp_bridge->dev)) agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); else agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); @@ -719,7 +732,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) /* Do AGP version specific frobbing. */ if (bridge->major_version >= 3) { - if (bridge->mode & AGPSTAT_MODE_3_0) { + if (check_bridge_mode(bridge->dev)) { /* If we have 3.5, we can do the isoch stuff. */ if (bridge->minor_version >= 5) agp_3_5_enable(bridge); @@ -793,7 +806,8 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) break; } - table = alloc_gatt_pages(page_order); + table = (char *) __get_free_pages(GFP_KERNEL, + page_order); if (table == NULL) { i++; @@ -824,7 +838,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) size = ((struct aper_size_info_fixed *) temp)->size; page_order = ((struct aper_size_info_fixed *) temp)->page_order; num_entries = ((struct aper_size_info_fixed *) temp)->num_entries; - table = alloc_gatt_pages(page_order); + table = (char *) __get_free_pages(GFP_KERNEL, page_order); } if (table == NULL) @@ -839,7 +853,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) agp_gatt_table = (void *)table; bridge->driver->cache_flush(); - bridge->gatt_table = ioremap_nocache(virt_to_gart(table), + bridge->gatt_table = ioremap_nocache(virt_to_phys(table), (PAGE_SIZE * (1 << page_order))); bridge->driver->cache_flush(); @@ -847,11 +861,11 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_gatt_pages(table, page_order); + free_pages((unsigned long) table, page_order); return -ENOMEM; } - bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); + bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) { @@ -905,7 +919,7 @@ int agp_generic_free_gatt_table(struct agp_bridge_data *bridge) for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) ClearPageReserved(page); - free_gatt_pages(bridge->gatt_table_real, page_order); + free_pages((unsigned long) bridge->gatt_table_real, page_order); agp_gatt_table = NULL; bridge->gatt_table = NULL; diff --git a/trunk/drivers/char/agp/hp-agp.c b/trunk/drivers/char/agp/hp-agp.c index 99762b6c19ae..6052bfa04c72 100644 --- a/trunk/drivers/char/agp/hp-agp.c +++ b/trunk/drivers/char/agp/hp-agp.c @@ -110,7 +110,7 @@ static int __init hp_zx1_ioc_shared(void) hp->gart_size = HP_ZX1_GART_SIZE; hp->gatt_entries = hp->gart_size / hp->io_page_size; - hp->io_pdir = gart_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); + hp->io_pdir = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)]; if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) { @@ -248,7 +248,7 @@ hp_zx1_configure (void) agp_bridge->mode = readl(hp->lba_regs+hp->lba_cap_offset+PCI_AGP_STATUS); if (hp->io_pdir_owner) { - writel(virt_to_gart(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); + writel(virt_to_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); readl(hp->ioc_regs+HP_ZX1_PDIR_BASE); writel(hp->io_tlb_ps, hp->ioc_regs+HP_ZX1_TCNFG); readl(hp->ioc_regs+HP_ZX1_TCNFG); diff --git a/trunk/drivers/char/agp/i460-agp.c b/trunk/drivers/char/agp/i460-agp.c index 94943298c03e..adbea896c0d2 100644 --- a/trunk/drivers/char/agp/i460-agp.c +++ b/trunk/drivers/char/agp/i460-agp.c @@ -372,7 +372,7 @@ static int i460_alloc_large_page (struct lp_desc *lp) } memset(lp->alloced_map, 0, map_size); - lp->paddr = virt_to_gart(lpage); + lp->paddr = virt_to_phys(lpage); lp->refcount = 0; atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); return 0; @@ -383,7 +383,7 @@ static void i460_free_large_page (struct lp_desc *lp) kfree(lp->alloced_map); lp->alloced_map = NULL; - free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); + free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index 51266d6b4d78..8c7d727432bb 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -286,7 +286,7 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) if (new == NULL) return NULL; - new->memory[0] = virt_to_gart(addr); + new->memory[0] = virt_to_phys(addr); if (pg_count == 4) { /* kludge to get 4 physical pages for ARGB cursor */ new->memory[1] = new->memory[0] + PAGE_SIZE; @@ -329,10 +329,10 @@ static void intel_i810_free_by_type(struct agp_memory *curr) agp_free_key(curr->key); if(curr->type == AGP_PHYS_MEMORY) { if (curr->page_count == 4) - i8xx_destroy_pages(gart_to_virt(curr->memory[0])); + i8xx_destroy_pages(phys_to_virt(curr->memory[0])); else agp_bridge->driver->agp_destroy_page( - gart_to_virt(curr->memory[0])); + phys_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); @@ -418,8 +418,7 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_48M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; @@ -427,8 +426,7 @@ static void intel_i830_init_gtt_entries(void) case I915_GMCH_GMS_STOLEN_64M: /* Check it's really I915G */ if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915G_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB || - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1664,14 +1662,6 @@ static int __devinit agp_intel_probe(struct pci_dev *pdev, } name = "915GM"; break; - case PCI_DEVICE_ID_INTEL_82945G_HB: - if (find_i830(PCI_DEVICE_ID_INTEL_82945G_IG)) { - bridge->driver = &intel_915_driver; - } else { - bridge->driver = &intel_845_driver; - } - name = "945G"; - break; case PCI_DEVICE_ID_INTEL_7505_0: bridge->driver = &intel_7505_driver; name = "E7505"; @@ -1811,7 +1801,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_7205_0), ID(PCI_DEVICE_ID_INTEL_82915G_HB), ID(PCI_DEVICE_ID_INTEL_82915GM_HB), - ID(PCI_DEVICE_ID_INTEL_82945G_HB), { } }; diff --git a/trunk/drivers/char/agp/sgi-agp.c b/trunk/drivers/char/agp/sgi-agp.c index d3aa159c9dec..4b3eda267976 100644 --- a/trunk/drivers/char/agp/sgi-agp.c +++ b/trunk/drivers/char/agp/sgi-agp.c @@ -133,14 +133,11 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, off_t j; void *temp; struct agp_bridge_data *bridge; - u64 *table; bridge = mem->bridge; if (!bridge) return -EINVAL; - table = (u64 *)bridge->gatt_table; - temp = bridge->current_size; switch (bridge->driver->size_type) { @@ -178,7 +175,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, j = pg_start; while (j < (pg_start + mem->page_count)) { - if (table[j]) + if (*(bridge->gatt_table + j)) return -EBUSY; j++; } @@ -189,7 +186,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, } for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - table[j] = + *(bridge->gatt_table + j) = bridge->driver->mask_memory(bridge, mem->memory[i], mem->type); } @@ -203,7 +200,6 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, { size_t i; struct agp_bridge_data *bridge; - u64 *table; bridge = mem->bridge; if (!bridge) @@ -213,10 +209,8 @@ static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start, return -EINVAL; } - table = (u64 *)bridge->gatt_table; - for (i = pg_start; i < (mem->page_count + pg_start); i++) { - table[i] = 0; + *(bridge->gatt_table + i) = 0; } bridge->driver->tlb_flush(mem); diff --git a/trunk/drivers/char/agp/sworks-agp.c b/trunk/drivers/char/agp/sworks-agp.c index a9fb12c20eb7..10c23302dd84 100644 --- a/trunk/drivers/char/agp/sworks-agp.c +++ b/trunk/drivers/char/agp/sworks-agp.c @@ -51,7 +51,7 @@ static int serverworks_create_page_map(struct serverworks_page_map *page_map) } SetPageReserved(virt_to_page(page_map->real)); global_cache_flush(); - page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real), PAGE_SIZE); if (page_map->remapped == NULL) { ClearPageReserved(virt_to_page(page_map->real)); @@ -162,7 +162,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Create a fake scratch directory */ for(i = 0; i < 1024; i++) { writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i); - writel(virt_to_gart(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); + writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); } retval = serverworks_create_gatt_pages(value->num_entries / 1024); @@ -174,7 +174,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) agp_bridge->gatt_table_real = (u32 *)page_dir.real; agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped; - agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real); /* Get the address for the gart region. * This is a bus address even on the alpha, b/c its @@ -187,7 +187,7 @@ static int serverworks_create_gatt_table(struct agp_bridge_data *bridge) /* Calculate the agp offset */ for(i = 0; i < value->num_entries / 1024; i++) - writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); + writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); return 0; } diff --git a/trunk/drivers/char/agp/uninorth-agp.c b/trunk/drivers/char/agp/uninorth-agp.c index c8255312b8c1..a673971f2a90 100644 --- a/trunk/drivers/char/agp/uninorth-agp.c +++ b/trunk/drivers/char/agp/uninorth-agp.c @@ -407,7 +407,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) bridge->gatt_table_real = (u32 *) table; bridge->gatt_table = (u32 *)table; - bridge->gatt_bus_addr = virt_to_gart(table); + bridge->gatt_bus_addr = virt_to_phys(table); for (i = 0; i < num_entries; i++) bridge->gatt_table[i] = 0; diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index f022f0944434..7a245068e3e5 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -1995,6 +1995,9 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) unsigned char ch, gdl; int ignored = 0; int cnt = 0; + unsigned char *cp; + char *fp; + int count; int recv_room; int max = 256; unsigned long flags; @@ -2008,6 +2011,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) //return; } + cp = tty->flip.char_buf; + fp = tty->flip.flag_buf; + count = 0; + // following add by Victor Yu. 09-02-2002 if (info->IsMoxaMustChipFlag != MOXA_OTHER_UART) { @@ -2034,10 +2041,12 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) } while (gdl--) { ch = inb(info->base + UART_RX); - tty_insert_flip_char(tty, ch, 0); + count++; + *cp++ = ch; + *fp++ = 0; cnt++; /* - if((cnt>=HI_WATER) && (info->stop_rx==0)){ + if((count>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2052,7 +2061,7 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) if (max-- < 0) break; /* - if((cnt>=HI_WATER) && (info->stop_rx==0)){ + if((count>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2069,33 +2078,36 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) if (++ignored > 100) break; } else { - char flag = 0; + count++; if (*status & UART_LSR_SPECIAL) { if (*status & UART_LSR_BI) { - flag = TTY_BREAK; + *fp++ = TTY_BREAK; /* added by casper 1/11/2000 */ info->icount.brk++; + /* */ if (info->flags & ASYNC_SAK) do_SAK(tty); } else if (*status & UART_LSR_PE) { - flag = TTY_PARITY; + *fp++ = TTY_PARITY; /* added by casper 1/11/2000 */ info->icount.parity++; /* */ } else if (*status & UART_LSR_FE) { - flag = TTY_FRAME; + *fp++ = TTY_FRAME; /* added by casper 1/11/2000 */ info->icount.frame++; /* */ } else if (*status & UART_LSR_OE) { - flag = TTY_OVERRUN; + *fp++ = TTY_OVERRUN; /* added by casper 1/11/2000 */ info->icount.overrun++; /* */ - } - } - tty_insert_flip_char(tty, ch, flag); + } else + *fp++ = 0; + } else + *fp++ = 0; + *cp++ = ch; cnt++; if (cnt >= recv_room) { if (!info->ldisc_stop_rx) { @@ -2120,13 +2132,13 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) // above add by Victor Yu. 09-02-2002 } while (*status & UART_LSR_DR); -end_intr: // add by Victor Yu. 09-02-2002 + end_intr: // add by Victor Yu. 09-02-2002 mxvar_log.rxcnt[info->port] += cnt; info->mon_data.rxcnt += cnt; info->mon_data.up_rxcnt += cnt; spin_unlock_irqrestore(&info->slock, flags); - + tty_flip_buffer_push(tty); } diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index 48fdf1e517cf..af0446c6de82 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -54,7 +54,7 @@ static int atkbd_softraw = 1; module_param_named(softraw, atkbd_softraw, bool, 0); MODULE_PARM_DESC(softraw, "Use software generated rawmode"); -static int atkbd_scroll = 0; +static int atkbd_scroll = 1; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); diff --git a/trunk/drivers/net/pcmcia/3c574_cs.c b/trunk/drivers/net/pcmcia/3c574_cs.c index c6e8b25f9685..41e517114807 100644 --- a/trunk/drivers/net/pcmcia/3c574_cs.c +++ b/trunk/drivers/net/pcmcia/3c574_cs.c @@ -1274,9 +1274,6 @@ static int el3_close(struct net_device *dev) spin_lock_irqsave(&lp->window_lock, flags); update_stats(dev); spin_unlock_irqrestore(&lp->window_lock, flags); - - /* force interrupts off */ - outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD); } link->open--; diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index b3768d844747..c59507f8a76b 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); - /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, 16383); + /* For gigabit rtl8169, MTU + header + CRC + VLAN */ + RTL_W16(RxMaxSize, tp->rx_buf_sz); /* Set Rx Config register */ i = rtl8169_rx_config | @@ -2127,11 +2127,6 @@ rtl8169_tx_interrupt(struct net_device *dev, struct rtl8169_private *tp, } } -static inline int rtl8169_fragmented_frame(u32 status) -{ - return (status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag); -} - static inline void rtl8169_rx_csum(struct sk_buff *skb, struct RxDesc *desc) { u32 opts1 = le32_to_cpu(desc->opts1); @@ -2182,41 +2177,27 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, while (rx_left > 0) { unsigned int entry = cur_rx % NUM_RX_DESC; - struct RxDesc *desc = tp->RxDescArray + entry; u32 status; rmb(); - status = le32_to_cpu(desc->opts1); + status = le32_to_cpu(tp->RxDescArray[entry].opts1); if (status & DescOwn) break; if (status & RxRES) { - printk(KERN_INFO "%s: Rx ERROR. status = %08x\n", - dev->name, status); + printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); tp->stats.rx_errors++; if (status & (RxRWT | RxRUNT)) tp->stats.rx_length_errors++; if (status & RxCRC) tp->stats.rx_crc_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); } else { + struct RxDesc *desc = tp->RxDescArray + entry; struct sk_buff *skb = tp->Rx_skbuff[entry]; int pkt_size = (status & 0x00001FFF) - 4; void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int) = pci_dma_sync_single_for_device; - /* - * The driver does not support incoming fragmented - * frames. They are seen as a symptom of over-mtu - * sized frames. - */ - if (unlikely(rtl8169_fragmented_frame(status))) { - tp->stats.rx_dropped++; - tp->stats.rx_length_errors++; - rtl8169_mark_to_asic(desc, tp->rx_buf_sz); - goto move_on; - } - rtl8169_rx_csum(skb, desc); pci_dma_sync_single_for_cpu(tp->pci_dev, @@ -2243,7 +2224,7 @@ rtl8169_rx_interrupt(struct net_device *dev, struct rtl8169_private *tp, tp->stats.rx_bytes += pkt_size; tp->stats.rx_packets++; } -move_on: + cur_rx++; rx_left--; } diff --git a/trunk/drivers/net/shaper.c b/trunk/drivers/net/shaper.c index 20edeb345792..e68cf5fb4920 100644 --- a/trunk/drivers/net/shaper.c +++ b/trunk/drivers/net/shaper.c @@ -100,8 +100,35 @@ static int sh_debug; /* Debug flag */ #define SHAPER_BANNER "CymruNet Traffic Shaper BETA 0.04 for Linux 2.1\n" +/* + * Locking + */ + +static int shaper_lock(struct shaper *sh) +{ + /* + * Lock in an interrupt must fail + */ + while (test_and_set_bit(0, &sh->locked)) + { + if (!in_interrupt()) + sleep_on(&sh->wait_queue); + else + return 0; + + } + return 1; +} + static void shaper_kick(struct shaper *sh); +static void shaper_unlock(struct shaper *sh) +{ + clear_bit(0, &sh->locked); + wake_up(&sh->wait_queue); + shaper_kick(sh); +} + /* * Compute clocks on a buffer */ @@ -130,15 +157,17 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) * Throw a frame at a shaper. */ - -static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) { - struct shaper *shaper = dev->priv; struct sk_buff *ptr; - if (down_trylock(&shaper->sem)) - return -1; - + /* + * Get ready to work on this shaper. Lock may fail if its + * an interrupt and locked. + */ + + if(!shaper_lock(shaper)) + return -1; ptr=shaper->sendq.prev; /* @@ -231,8 +260,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) dev_kfree_skb(ptr); shaper->stats.collisions++; } - shaper_kick(shaper); - up(&shaper->sem); + shaper_unlock(shaper); return 0; } @@ -269,13 +297,8 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) static void shaper_timer(unsigned long data) { - struct shaper *shaper = (struct shaper *)data; - - if (!down_trylock(&shaper->sem)) { - shaper_kick(shaper); - up(&shaper->sem); - } else - mod_timer(&shaper->timer, jiffies); + struct shaper *sh=(struct shaper *)data; + shaper_kick(sh); } /* @@ -287,6 +310,19 @@ static void shaper_kick(struct shaper *shaper) { struct sk_buff *skb; + /* + * Shaper unlock will kick + */ + + if (test_and_set_bit(0, &shaper->locked)) + { + if(sh_debug) + printk("Shaper locked.\n"); + mod_timer(&shaper->timer, jiffies); + return; + } + + /* * Walk the list (may be empty) */ @@ -328,6 +364,8 @@ static void shaper_kick(struct shaper *shaper) if(skb!=NULL) mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); + + clear_bit(0, &shaper->locked); } @@ -338,12 +376,14 @@ static void shaper_kick(struct shaper *shaper) static void shaper_flush(struct shaper *shaper) { struct sk_buff *skb; - - down(&shaper->sem); + if(!shaper_lock(shaper)) + { + printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); + return; + } while((skb=skb_dequeue(&shaper->sendq))!=NULL) dev_kfree_skb(skb); - shaper_kick(shaper); - up(&shaper->sem); + shaper_unlock(shaper); } /* @@ -386,6 +426,13 @@ static int shaper_close(struct net_device *dev) * ARP and other resolutions and not before. */ + +static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct shaper *sh=dev->priv; + return shaper_qframe(sh, skb); +} + static struct net_device_stats *shaper_get_stats(struct net_device *dev) { struct shaper *sh=dev->priv; @@ -576,6 +623,7 @@ static void shaper_init_priv(struct net_device *dev) init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; + init_waitqueue_head(&sh->wait_queue); } /* diff --git a/trunk/drivers/net/tg3.c b/trunk/drivers/net/tg3.c index e944aac258e3..fc9b5cd957aa 100644 --- a/trunk/drivers/net/tg3.c +++ b/trunk/drivers/net/tg3.c @@ -7,12 +7,7 @@ * Copyright (C) 2005 Broadcom Corporation. * * Firmware is: - * Derived from proprietary unpublished source code, - * Copyright (C) 2000-2003 Broadcom Corporation. - * - * Permission is hereby granted for the distribution of this firmware - * data in hexadecimal or equivalent format, provided this copyright - * notice is accompanying it. + * Copyright (C) 2000-2003 Broadcom Corporation. */ #include @@ -66,8 +61,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.30" -#define DRV_MODULE_RELDATE "June 6, 2005" +#define DRV_MODULE_VERSION "3.29" +#define DRV_MODULE_RELDATE "May 23, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -8560,16 +8555,6 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) case NIC_SRAM_DATA_CFG_LED_MODE_MAC: tp->led_ctrl = LED_CTRL_MODE_MAC; - - /* Default to PHY_1_MODE if 0 (MAC_MODE) is - * read on some older 5700/5701 bootcode. - */ - if (GET_ASIC_REV(tp->pci_chip_rev_id) == - ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == - ASIC_REV_5701) - tp->led_ctrl = LED_CTRL_MODE_PHY_1; - break; case SHASTA_EXT_LED_SHARED: diff --git a/trunk/drivers/pci/pci.ids b/trunk/drivers/pci/pci.ids index 1d2ef1e2ffc6..93481b41b613 100644 --- a/trunk/drivers/pci/pci.ids +++ b/trunk/drivers/pci/pci.ids @@ -7173,7 +7173,6 @@ 080f Sentry5 DDR/SDR RAM Controller 0811 Sentry5 External Interface Core 0816 BCM3302 Sentry5 MIPS32 CPU - 1600 NetXtreme BCM5752 Gigabit Ethernet PCI Express 1644 NetXtreme BCM5700 Gigabit Ethernet 1014 0277 Broadcom Vigil B5700 1000Base-T 1028 00d1 Broadcom BCM5700 diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 2194669300bf..637e9493034b 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -459,6 +459,17 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, #endif /* CONFIG_X86_IO_APIC */ +/* + * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip + * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: + * when written, it makes an internal connection to the PIC. + * For these devices, this register is defined to be 4 bits wide. + * Normally this is fine. However for IO-APIC motherboards, or + * non-x86 architectures (yes Via exists on PPC among other places), + * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get + * interrupts delivered properly. + */ + /* * FIXME: it is questionable that quirk_via_acpi * is needed. It shows up as an ISA bridge, and does not @@ -481,30 +492,28 @@ static void __devinit quirk_via_acpi(struct pci_dev *d) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi ); DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi ); -/* - * Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip - * devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature: - * when written, it makes an internal connection to the PIC. - * For these devices, this register is defined to be 4 bits wide. - * Normally this is fine. However for IO-APIC motherboards, or - * non-x86 architectures (yes Via exists on PPC among other places), - * we must mask the PCI_INTERRUPT_LINE value versus 0xf to get - * interrupts delivered properly. - */ -static void quirk_via_irq(struct pci_dev *dev) +static void quirk_via_irqpic(struct pci_dev *dev) { u8 irq, new_irq; +#ifdef CONFIG_X86_IO_APIC + if (nr_ioapics && !skip_ioapic_setup) + return; +#endif +#ifdef CONFIG_ACPI + if (acpi_irq_model != ACPI_IRQ_MODEL_PIC) + return; +#endif new_irq = dev->irq & 0xf; pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq); if (new_irq != irq) { - printk(KERN_INFO "PCI: Via IRQ fixup for %s, from %d to %d\n", + printk(KERN_INFO "PCI: Via PIC IRQ fixup for %s, from %d to %d\n", pci_name(dev), irq, new_irq); udelay(15); /* unknown if delay really needed */ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq); } } -DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irqpic); /* * PIIX3 USB: We have to disable USB interrupts that are diff --git a/trunk/drivers/scsi/ata_piix.c b/trunk/drivers/scsi/ata_piix.c index 3be546439252..54c52349adc5 100644 --- a/trunk/drivers/scsi/ata_piix.c +++ b/trunk/drivers/scsi/ata_piix.c @@ -665,6 +665,15 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return ata_pci_init_one(pdev, port_info, n_ports); } +/** + * piix_init - + * + * LOCKING: + * + * RETURNS: + * + */ + static int __init piix_init(void) { int rc; @@ -680,6 +689,13 @@ static int __init piix_init(void) return 0; } +/** + * piix_exit - + * + * LOCKING: + * + */ + static void __exit piix_exit(void) { pci_unregister_driver(&piix_pci_driver); diff --git a/trunk/drivers/scsi/libata-core.c b/trunk/drivers/scsi/libata-core.c index 21d194c6ace3..30a88f0e7bd6 100644 --- a/trunk/drivers/scsi/libata-core.c +++ b/trunk/drivers/scsi/libata-core.c @@ -186,28 +186,6 @@ static void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf) ata_wait_idle(ap); } - -/** - * ata_tf_load - send taskfile registers to host controller - * @ap: Port to which output is sent - * @tf: ATA taskfile register set - * - * Outputs ATA taskfile to standard ATA host controller using MMIO - * or PIO as indicated by the ATA_FLAG_MMIO flag. - * Writes the control, feature, nsect, lbal, lbam, and lbah registers. - * Optionally (ATA_TFLAG_LBA48) writes hob_feature, hob_nsect, - * hob_lbal, hob_lbam, and hob_lbah. - * - * This function waits for idle (!BUSY and !DRQ) after writing - * registers. If the control register has a new value, this - * function also waits for idle after writing control and before - * writing the remaining registers. - * - * May be used as the tf_load() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -217,11 +195,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_exec_command_pio - issue ATA command to host controller + * ata_exec_command - issue ATA command to host controller * @ap: port to which command is being issued * @tf: ATA taskfile register set * - * Issues PIO write to ATA command register, with proper + * Issues PIO/MMIO write to ATA command register, with proper * synchronization with interrupt handler / other threads. * * LOCKING: @@ -257,18 +235,6 @@ static void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf) ata_pause(ap); } - -/** - * ata_exec_command - issue ATA command to host controller - * @ap: port to which command is being issued - * @tf: ATA taskfile register set - * - * Issues PIO/MMIO write to ATA command register, with proper - * synchronization with interrupt handler / other threads. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -339,7 +305,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_tf_read_pio - input device's ATA taskfile shadow registers + * ata_tf_read - input device's ATA taskfile shadow registers * @ap: Port from which input is read * @tf: ATA taskfile register set for storing input * @@ -402,23 +368,6 @@ static void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf) } } - -/** - * ata_tf_read - input device's ATA taskfile shadow registers - * @ap: Port from which input is read - * @tf: ATA taskfile register set for storing input - * - * Reads ATA taskfile registers for currently-selected device - * into @tf. - * - * Reads nsect, lbal, lbam, lbah, and device. If ATA_TFLAG_LBA48 - * is set, also reads the hob registers. - * - * May be used as the tf_read() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) { if (ap->flags & ATA_FLAG_MMIO) @@ -432,7 +381,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf) * @ap: port where the device is * * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts + * and return it's value. This also clears pending interrupts * from this device * * LOCKING: @@ -448,7 +397,7 @@ static u8 ata_check_status_pio(struct ata_port *ap) * @ap: port where the device is * * Reads ATA taskfile status register for currently-selected device - * via MMIO and return its value. This also clears pending interrupts + * via MMIO and return it's value. This also clears pending interrupts * from this device * * LOCKING: @@ -459,20 +408,6 @@ static u8 ata_check_status_mmio(struct ata_port *ap) return readb((void __iomem *) ap->ioaddr.status_addr); } - -/** - * ata_check_status - Read device status reg & clear interrupt - * @ap: port where the device is - * - * Reads ATA taskfile status register for currently-selected device - * and return its value. This also clears pending interrupts - * from this device - * - * May be used as the check_status() entry in ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ u8 ata_check_status(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) @@ -480,20 +415,6 @@ u8 ata_check_status(struct ata_port *ap) return ata_check_status_pio(ap); } - -/** - * ata_altstatus - Read device alternate status reg - * @ap: port where the device is - * - * Reads ATA taskfile alternate status register for - * currently-selected device and return its value. - * - * Note: may NOT be used as the check_altstatus() entry in - * ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ u8 ata_altstatus(struct ata_port *ap) { if (ap->ops->check_altstatus) @@ -504,20 +425,6 @@ u8 ata_altstatus(struct ata_port *ap) return inb(ap->ioaddr.altstatus_addr); } - -/** - * ata_chk_err - Read device error reg - * @ap: port where the device is - * - * Reads ATA taskfile error register for - * currently-selected device and return its value. - * - * Note: may NOT be used as the check_err() entry in - * ata_port_operations. - * - * LOCKING: - * Inherited from caller. - */ u8 ata_chk_err(struct ata_port *ap) { if (ap->ops->check_err) @@ -966,24 +873,10 @@ void ata_dev_id_string(u16 *id, unsigned char *s, } } - -/** - * ata_noop_dev_select - Select device 0/1 on ATA bus - * @ap: ATA channel to manipulate - * @device: ATA device (numbered from zero) to select - * - * This function performs no actual function. - * - * May be used as the dev_select() entry in ata_port_operations. - * - * LOCKING: - * caller. - */ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) { } - /** * ata_std_dev_select - Select device 0/1 on ATA bus * @ap: ATA channel to manipulate @@ -991,9 +884,7 @@ void ata_noop_dev_select (struct ata_port *ap, unsigned int device) * * Use the method defined in the ATA specification to * make either device 0, or device 1, active on the - * ATA channel. Works with both PIO and MMIO. - * - * May be used as the dev_select() entry in ata_port_operations. + * ATA channel. * * LOCKING: * caller. @@ -1299,12 +1190,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device) * ata_bus_probe - Reset and probe ATA bus * @ap: Bus to probe * - * Master ATA bus probing function. Initiates a hardware-dependent - * bus reset, then attempts to identify any devices found on - * the bus. - * * LOCKING: - * PCI/etc. bus probe sem. * * RETURNS: * Zero on success, non-zero on error. @@ -1343,14 +1229,10 @@ static int ata_bus_probe(struct ata_port *ap) } /** - * ata_port_probe - Mark port as enabled - * @ap: Port for which we indicate enablement - * - * Modify @ap data structure such that the system - * thinks that the entire port is enabled. + * ata_port_probe - + * @ap: * - * LOCKING: host_set lock, or some other form of - * serialization. + * LOCKING: */ void ata_port_probe(struct ata_port *ap) @@ -1359,15 +1241,10 @@ void ata_port_probe(struct ata_port *ap) } /** - * __sata_phy_reset - Wake/reset a low-level SATA PHY - * @ap: SATA port associated with target SATA PHY. - * - * This function issues commands to standard SATA Sxxx - * PHY registers, to wake up the phy (and device), and - * clear any reset condition. + * __sata_phy_reset - + * @ap: * * LOCKING: - * PCI/etc. bus probe sem. * */ void __sata_phy_reset(struct ata_port *ap) @@ -1412,14 +1289,10 @@ void __sata_phy_reset(struct ata_port *ap) } /** - * sata_phy_reset - Reset SATA bus. - * @ap: SATA port associated with target SATA PHY. - * - * This function resets the SATA bus, and then probes - * the bus for devices. + * __sata_phy_reset - + * @ap: * * LOCKING: - * PCI/etc. bus probe sem. * */ void sata_phy_reset(struct ata_port *ap) @@ -1431,16 +1304,10 @@ void sata_phy_reset(struct ata_port *ap) } /** - * ata_port_disable - Disable port. - * @ap: Port to be disabled. - * - * Modify @ap data structure such that the system - * thinks that the entire port is disabled, and should - * never attempt to probe or communicate with devices - * on this port. + * ata_port_disable - + * @ap: * - * LOCKING: host_set lock, or some other form of - * serialization. + * LOCKING: */ void ata_port_disable(struct ata_port *ap) @@ -1549,10 +1416,7 @@ static void ata_host_set_dma(struct ata_port *ap, u8 xfer_mode, * ata_set_mode - Program timings and issue SET FEATURES - XFER * @ap: port on which timings will be programmed * - * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). - * * LOCKING: - * PCI/etc. bus probe sem. * */ static void ata_set_mode(struct ata_port *ap) @@ -1603,10 +1467,7 @@ static void ata_set_mode(struct ata_port *ap) * @tmout_pat: impatience timeout * @tmout: overall timeout * - * Sleep until ATA Status register bit BSY clears, - * or a timeout occurs. - * - * LOCKING: None. + * LOCKING: * */ @@ -1692,14 +1553,10 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) } /** - * ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command. - * @ap: Port to reset and probe - * - * Use the EXECUTE DEVICE DIAGNOSTIC command to reset and - * probe the bus. Not often used these days. + * ata_bus_edd - + * @ap: * * LOCKING: - * PCI/etc. bus probe sem. * */ @@ -1776,8 +1633,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * the device is ATA or ATAPI. * * LOCKING: - * PCI/etc. bus probe sem. - * Obtains host_set lock. + * Inherited from caller. Some functions called by this function + * obtain the host_set lock. * * SIDE EFFECTS: * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. @@ -2019,11 +1876,7 @@ static int fgb(u32 bitmap) * @xfer_mode_out: (output) SET FEATURES - XFER MODE code * @xfer_shift_out: (output) bit shift that selects this mode * - * Based on host and device capabilities, determine the - * maximum transfer mode that is amenable to all. - * * LOCKING: - * PCI/etc. bus probe sem. * * RETURNS: * Zero on success, negative on error. @@ -2056,11 +1909,7 @@ static int ata_choose_xfer_mode(struct ata_port *ap, * @ap: Port associated with device @dev * @dev: Device to which command will be sent * - * Issue SET FEATURES - XFER MODE command to device @dev - * on port @ap. - * * LOCKING: - * PCI/etc. bus probe sem. */ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) @@ -2098,13 +1947,10 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) } /** - * ata_sg_clean - Unmap DMA memory associated with command - * @qc: Command containing DMA memory to be released - * - * Unmap all mapped DMA memory associated with this command. + * ata_sg_clean - + * @qc: * * LOCKING: - * spin_lock_irqsave(host_set lock) */ static void ata_sg_clean(struct ata_queued_cmd *qc) @@ -2135,11 +1981,7 @@ static void ata_sg_clean(struct ata_queued_cmd *qc) * ata_fill_sg - Fill PCI IDE PRD table * @qc: Metadata associated with taskfile to be transferred * - * Fill PCI IDE PRD (scatter-gather) table with segments - * associated with the current disk command. - * * LOCKING: - * spin_lock_irqsave(host_set lock) * */ static void ata_fill_sg(struct ata_queued_cmd *qc) @@ -2186,13 +2028,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) * ata_check_atapi_dma - Check whether ATAPI DMA can be supported * @qc: Metadata associated with taskfile to check * - * Allow low-level driver to filter ATA PACKET commands, returning - * a status indicating whether or not it is OK to use DMA for the - * supplied PACKET command. - * * LOCKING: - * spin_lock_irqsave(host_set lock) - * * RETURNS: 0 when ATAPI DMA can be used * nonzero otherwise */ @@ -2210,8 +2046,6 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) * ata_qc_prep - Prepare taskfile for submission * @qc: Metadata associated with taskfile to be prepared * - * Prepare ATA taskfile for submission. - * * LOCKING: * spin_lock_irqsave(host_set lock) */ @@ -2223,32 +2057,6 @@ void ata_qc_prep(struct ata_queued_cmd *qc) ata_fill_sg(qc); } -/** - * ata_sg_init_one - Associate command with memory buffer - * @qc: Command to be associated - * @buf: Memory buffer - * @buflen: Length of memory buffer, in bytes. - * - * Initialize the data-related elements of queued_cmd @qc - * to point to a single memory buffer, @buf of byte length @buflen. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - - - -/** - * ata_sg_init_one - Prepare a one-entry scatter-gather list. - * @qc: Queued command - * @buf: transfer buffer - * @buflen: length of buf - * - * Builds a single-entry scatter-gather list to initiate a - * transfer utilizing the specified buffer. - * - * LOCKING: - */ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) { struct scatterlist *sg; @@ -2266,32 +2074,6 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) sg->length = buflen; } -/** - * ata_sg_init - Associate command with scatter-gather table. - * @qc: Command to be associated - * @sg: Scatter-gather table. - * @n_elem: Number of elements in s/g table. - * - * Initialize the data-related elements of queued_cmd @qc - * to point to a scatter-gather table @sg, containing @n_elem - * elements. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - - -/** - * ata_sg_init - Assign a scatter gather list to a queued command - * @qc: Queued command - * @sg: Scatter-gather list - * @n_elem: length of sg list - * - * Attaches a scatter-gather list to a queued command. - * - * LOCKING: - */ - void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem) { @@ -2301,16 +2083,14 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, } /** - * ata_sg_setup_one - DMA-map the memory buffer associated with a command. - * @qc: Command with memory buffer to be mapped. - * - * DMA-map the memory buffer associated with queued_cmd @qc. + * ata_sg_setup_one - + * @qc: * * LOCKING: * spin_lock_irqsave(host_set lock) * * RETURNS: - * Zero on success, negative on error. + * */ static int ata_sg_setup_one(struct ata_queued_cmd *qc) @@ -2335,16 +2115,13 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) } /** - * ata_sg_setup - DMA-map the scatter-gather table associated with a command. - * @qc: Command with scatter-gather table to be mapped. - * - * DMA-map the scatter-gather table associated with queued_cmd @qc. + * ata_sg_setup - + * @qc: * * LOCKING: * spin_lock_irqsave(host_set lock) * * RETURNS: - * Zero on success, negative on error. * */ @@ -2374,7 +2151,6 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * @ap: * * LOCKING: - * None. (executing in kernel thread context) * * RETURNS: * @@ -2422,7 +2198,6 @@ static unsigned long ata_pio_poll(struct ata_port *ap) * @ap: * * LOCKING: - * None. (executing in kernel thread context) */ static void ata_pio_complete (struct ata_port *ap) @@ -2465,18 +2240,6 @@ static void ata_pio_complete (struct ata_port *ap) ata_qc_complete(qc, drv_stat); } - -/** - * swap_buf_le16 - - * @buf: Buffer to swap - * @buf_words: Number of 16-bit words in buffer. - * - * Swap halves of 16-bit words if needed to convert from - * little-endian byte order to native cpu byte order, or - * vice-versa. - * - * LOCKING: - */ void swap_buf_le16(u16 *buf, unsigned int buf_words) { #ifdef __BIG_ENDIAN @@ -2652,7 +2415,6 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) * @ap: * * LOCKING: - * None. (executing in kernel thread context) */ static void ata_pio_block(struct ata_port *ap) @@ -2821,7 +2583,6 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, * transaction completed successfully. * * LOCKING: - * Inherited from SCSI layer (none, can sleep) */ static void ata_qc_timeout(struct ata_queued_cmd *qc) @@ -2931,7 +2692,6 @@ void ata_eng_timeout(struct ata_port *ap) * @dev: Device from whom we request an available command structure * * LOCKING: - * None. */ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) @@ -2957,7 +2717,6 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) * @dev: Device from whom we request an available command structure * * LOCKING: - * None. */ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap, @@ -3022,7 +2781,6 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc) * in case something prevents using it. * * LOCKING: - * spin_lock_irqsave(host_set lock) * */ void ata_qc_free(struct ata_queued_cmd *qc) @@ -3036,13 +2794,9 @@ void ata_qc_free(struct ata_queued_cmd *qc) /** * ata_qc_complete - Complete an active ATA command * @qc: Command to complete - * @drv_stat: ATA Status register contents - * - * Indicate to the mid and upper layers that an ATA - * command has completed, with either an ok or not-ok status. + * @drv_stat: ATA status register contents * * LOCKING: - * spin_lock_irqsave(host_set lock) * */ @@ -3138,7 +2892,6 @@ int ata_qc_issue(struct ata_queued_cmd *qc) return -1; } - /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device @@ -3148,8 +2901,6 @@ int ata_qc_issue(struct ata_queued_cmd *qc) * classes called "protocols", and issuing each type of protocol * is slightly different. * - * May be used as the qc_issue() entry in ata_port_operations. - * * LOCKING: * spin_lock_irqsave(host_set lock) * @@ -3207,7 +2958,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) } /** - * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction + * ata_bmdma_setup - Set up PCI IDE BMDMA transaction * @qc: Info associated with this ATA transaction. * * LOCKING: @@ -3314,18 +3065,6 @@ static void ata_bmdma_start_pio (struct ata_queued_cmd *qc) ap->ioaddr.bmdma_addr + ATA_DMA_CMD); } - -/** - * ata_bmdma_start - Start a PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes the ATA_DMA_START flag to the DMA command register. - * - * May be used as the bmdma_start() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ void ata_bmdma_start(struct ata_queued_cmd *qc) { if (qc->ap->flags & ATA_FLAG_MMIO) @@ -3334,20 +3073,6 @@ void ata_bmdma_start(struct ata_queued_cmd *qc) ata_bmdma_start_pio(qc); } - -/** - * ata_bmdma_setup - Set up PCI IDE BMDMA transaction - * @qc: Info associated with this ATA transaction. - * - * Writes address of PRD table to device's PRD Table Address - * register, sets the DMA control register, and calls - * ops->exec_command() to start the transfer. - * - * May be used as the bmdma_setup() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ void ata_bmdma_setup(struct ata_queued_cmd *qc) { if (qc->ap->flags & ATA_FLAG_MMIO) @@ -3356,19 +3081,6 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc) ata_bmdma_setup_pio(qc); } - -/** - * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt. - * @ap: Port associated with this ATA transaction. - * - * Clear interrupt and error flags in DMA status register. - * - * May be used as the irq_clear() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - void ata_bmdma_irq_clear(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) { @@ -3381,19 +3093,6 @@ void ata_bmdma_irq_clear(struct ata_port *ap) } - -/** - * ata_bmdma_status - Read PCI IDE BMDMA status - * @ap: Port associated with this ATA transaction. - * - * Read and return BMDMA status register. - * - * May be used as the bmdma_status() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - u8 ata_bmdma_status(struct ata_port *ap) { u8 host_stat; @@ -3405,19 +3104,6 @@ u8 ata_bmdma_status(struct ata_port *ap) return host_stat; } - -/** - * ata_bmdma_stop - Stop PCI IDE BMDMA transfer - * @ap: Port associated with this ATA transaction. - * - * Clears the ATA_DMA_START flag in the dma control register - * - * May be used as the bmdma_stop() entry in ata_port_operations. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ - void ata_bmdma_stop(struct ata_port *ap) { if (ap->flags & ATA_FLAG_MMIO) { @@ -3517,18 +3203,13 @@ inline unsigned int ata_host_intr (struct ata_port *ap, /** * ata_interrupt - Default ATA host interrupt handler - * @irq: irq line (unused) - * @dev_instance: pointer to our ata_host_set information structure + * @irq: irq line + * @dev_instance: pointer to our host information structure * @regs: unused * - * Default interrupt handler for PCI IDE devices. Calls - * ata_host_intr() for each port that is not disabled. - * * LOCKING: - * Obtains host_set lock during operation. * * RETURNS: - * IRQ_NONE or IRQ_HANDLED. * */ @@ -3621,19 +3302,6 @@ static void atapi_packet_task(void *_data) ata_qc_complete(qc, ATA_ERR); } - -/** - * ata_port_start - Set port up for dma. - * @ap: Port to initialize - * - * Called just after data structures for each port are - * initialized. Allocates space for PRD table. - * - * May be used as the port_start() entry in ata_port_operations. - * - * LOCKING: - */ - int ata_port_start (struct ata_port *ap) { struct device *dev = ap->host_set->dev; @@ -3647,18 +3315,6 @@ int ata_port_start (struct ata_port *ap) return 0; } - -/** - * ata_port_stop - Undo ata_port_start() - * @ap: Port to shut down - * - * Frees the PRD table. - * - * May be used as the port_stop() entry in ata_port_operations. - * - * LOCKING: - */ - void ata_port_stop (struct ata_port *ap) { struct device *dev = ap->host_set->dev; @@ -3701,11 +3357,7 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister) * @ent: Probe information provided by low-level driver * @port_no: Port number associated with this ata_port * - * Initialize a new ata_port structure, and its associated - * scsi_host. - * * LOCKING: - * Inherited from caller. * */ @@ -3760,13 +3412,9 @@ static void ata_host_init(struct ata_port *ap, struct Scsi_Host *host, * @host_set: Collections of ports to which we add * @port_no: Port number associated with this host * - * Attach low-level ATA driver to system. - * * LOCKING: - * PCI/etc. bus probe sem. * * RETURNS: - * New ata_port on success, for NULL on error. * */ @@ -3799,22 +3447,12 @@ static struct ata_port * ata_host_add(struct ata_probe_ent *ent, } /** - * ata_device_add - Register hardware device with ATA and SCSI layers - * @ent: Probe information describing hardware device to be registered - * - * This function processes the information provided in the probe - * information struct @ent, allocates the necessary ATA and SCSI - * host information structures, initializes them, and registers - * everything with requisite kernel subsystems. - * - * This function requests irqs, probes the ATA bus, and probes - * the SCSI bus. + * ata_device_add - + * @ent: * * LOCKING: - * PCI/etc. bus probe sem. * * RETURNS: - * Number of ports registered. Zero on error (no ports registered). * */ @@ -3966,15 +3604,7 @@ int ata_scsi_release(struct Scsi_Host *host) /** * ata_std_ports - initialize ioaddr with standard port offsets. * @ioaddr: IO address structure to be initialized - * - * Utility function which initializes data_addr, error_addr, - * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr, - * device_addr, status_addr, and command_addr to standard offsets - * relative to cmd_addr. - * - * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr. */ - void ata_std_ports(struct ata_ioports *ioaddr) { ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA; @@ -4016,20 +3646,6 @@ ata_probe_ent_alloc(struct device *dev, struct ata_port_info *port) return probe_ent; } - - -/** - * ata_pci_init_native_mode - Initialize native-mode driver - * @pdev: pci device to be initialized - * @port: array[2] of pointers to port info structures. - * - * Utility function which allocates and initializes an - * ata_probe_ent structure for a standard dual-port - * PIO-based IDE controller. The returned ata_probe_ent - * structure can be passed to ata_device_add(). The returned - * ata_probe_ent structure should then be freed with kfree(). - */ - #ifdef CONFIG_PCI struct ata_probe_ent * ata_pci_init_native_mode(struct pci_dev *pdev, struct ata_port_info **port) @@ -4111,19 +3727,10 @@ ata_pci_init_legacy_mode(struct pci_dev *pdev, struct ata_port_info **port, * @port_info: Information from low-level host driver * @n_ports: Number of ports attached to host controller * - * This is a helper function which can be called from a driver's - * xxx_init_one() probe function if the hardware uses traditional - * IDE taskfile registers. - * - * This function calls pci_enable_device(), reserves its register - * regions, sets the dma mask, enables bus master mode, and calls - * ata_device_add() - * * LOCKING: * Inherited from PCI layer (may sleep). * * RETURNS: - * Zero on success, negative on errno-based value on error. * */ @@ -4342,6 +3949,15 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits) #endif /* CONFIG_PCI */ +/** + * ata_init - + * + * LOCKING: + * + * RETURNS: + * + */ + static int __init ata_init(void) { ata_wq = create_workqueue("ata"); diff --git a/trunk/drivers/scsi/libata-scsi.c b/trunk/drivers/scsi/libata-scsi.c index 7a4adc4c8f09..416ba67ba9ee 100644 --- a/trunk/drivers/scsi/libata-scsi.c +++ b/trunk/drivers/scsi/libata-scsi.c @@ -947,7 +947,7 @@ unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf, } /** - * ata_scsiop_noop - Command handler that simply returns success. + * ata_scsiop_noop - * @args: device IDENTIFY data / SCSI command of interest. * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. * @buflen: Response buffer length. diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 3c97aa45772d..579448222d69 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -507,7 +507,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) int ret, i; unsigned int id, lun; unsigned long serial; - unsigned long flags; if (!CMD_SP(cmd)) return FAILED; @@ -520,7 +519,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) /* Check active list for command command. */ spin_unlock_irq(ha->host->host_lock); - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { sp = ha->outstanding_cmds[i]; @@ -535,7 +534,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) sp->state)); DEBUG3(qla2x00_print_scsi_cmd(cmd);) - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (qla2x00_abort_command(ha, sp)) { DEBUG2(printk("%s(%ld): abort_command " "mbx failed.\n", __func__, ha->host_no)); @@ -544,19 +543,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "mbx success.\n", __func__, ha->host_no)); ret = SUCCESS; } - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); break; } - spin_unlock_irqrestore(&ha->hardware_lock, flags); /* Wait for the command to be returned. */ if (ret == SUCCESS) { + spin_unlock(&ha->hardware_lock); if (qla2x00_eh_wait_on_command(ha, cmd) != QLA_SUCCESS) { qla_printk(KERN_ERR, ha, "scsi(%ld:%d:%d): Abort handler timed out -- %lx " "%x.\n", ha->host_no, id, lun, serial, ret); } + spin_lock(&ha->hardware_lock); } spin_lock_irq(ha->host->host_lock); @@ -588,7 +588,6 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) int status; srb_t *sp; struct scsi_cmnd *cmd; - unsigned long flags; status = 0; @@ -597,11 +596,11 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) * array */ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); if (cmd->device->id == t) { if (!qla2x00_eh_wait_on_command(ha, cmd)) { status = 1; @@ -609,7 +608,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) } } } else { - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); } } return (status); @@ -741,7 +740,6 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) int status; srb_t *sp; struct scsi_cmnd *cmd; - unsigned long flags; status = 1; @@ -750,17 +748,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) * array */ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock_irqsave(&ha->hardware_lock, flags); + spin_lock(&ha->hardware_lock); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); status = qla2x00_eh_wait_on_command(ha, cmd); if (status == 0) break; } else { - spin_unlock_irqrestore(&ha->hardware_lock, flags); + spin_unlock(&ha->hardware_lock); } } return (status); diff --git a/trunk/drivers/scsi/scsi_scan.c b/trunk/drivers/scsi/scsi_scan.c index 8d0d302844a1..cca772624ae7 100644 --- a/trunk/drivers/scsi/scsi_scan.c +++ b/trunk/drivers/scsi/scsi_scan.c @@ -1197,7 +1197,6 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, if (!starget) return ERR_PTR(-ENOMEM); - get_device(&starget->dev); down(&shost->scan_mutex); res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); if (res != SCSI_SCAN_LUN_PRESENT) diff --git a/trunk/drivers/serial/sa1100.c b/trunk/drivers/serial/sa1100.c index 98641c3f5ab9..22565a67a57c 100644 --- a/trunk/drivers/serial/sa1100.c +++ b/trunk/drivers/serial/sa1100.c @@ -197,7 +197,7 @@ static void sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) { struct tty_struct *tty = sport->port.info->tty; - unsigned int status, ch, flg; + unsigned int status, ch, flg, ignored = 0; status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | UTSR0_TO_SM(UART_GET_UTSR0(sport)); diff --git a/trunk/drivers/serial/vr41xx_siu.c b/trunk/drivers/serial/vr41xx_siu.c index 1f985327b0d4..5d2ceb623e6f 100644 --- a/trunk/drivers/serial/vr41xx_siu.c +++ b/trunk/drivers/serial/vr41xx_siu.c @@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port) return "DSIU"; } - return NULL; + return "unknown"; } static unsigned int siu_tx_empty(struct uart_port *port) @@ -482,6 +482,9 @@ static irqreturn_t siu_interrupt(int irq, void *dev_id, struct pt_regs *regs) struct uart_port *port; uint8_t iir, lsr; + if (dev_id == NULL) + return IRQ_NONE; + port = (struct uart_port *)dev_id; iir = siu_read(port, UART_IIR); @@ -504,9 +507,6 @@ static int siu_startup(struct uart_port *port) { int retval; - if (port->membase == NULL) - return -ENODEV; - siu_clear_fifo(port); (void)siu_read(port, UART_LSR); @@ -545,6 +545,9 @@ static void siu_shutdown(struct uart_port *port) unsigned long flags; uint8_t lcr; + if (port->membase == NULL) + return; + siu_write(port, UART_IER, 0); spin_lock_irqsave(&port->lock, flags); @@ -799,6 +802,53 @@ static int siu_init_ports(void) #ifdef CONFIG_SERIAL_VR41XX_CONSOLE +static void early_set_termios(struct uart_port *port, struct termios *new, + struct termios *old) +{ + tcflag_t c_cflag; + uint8_t lcr; + unsigned int baud, quot; + + c_cflag = new->c_cflag; + switch (c_cflag & CSIZE) { + case CS5: + lcr = UART_LCR_WLEN5; + break; + case CS6: + lcr = UART_LCR_WLEN6; + break; + case CS7: + lcr = UART_LCR_WLEN7; + break; + default: + lcr = UART_LCR_WLEN8; + break; + } + + if (c_cflag & CSTOPB) + lcr |= UART_LCR_STOP; + if (c_cflag & PARENB) + lcr |= UART_LCR_PARITY; + if ((c_cflag & PARODD) != PARODD) + lcr |= UART_LCR_EPAR; + if (c_cflag & CMSPAR) + lcr |= UART_LCR_SPAR; + + baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); + quot = uart_get_divisor(port, baud); + + siu_write(port, UART_LCR, lcr | UART_LCR_DLAB); + + siu_write(port, UART_DLL, (uint8_t)quot); + siu_write(port, UART_DLM, (uint8_t)(quot >> 8)); + + siu_write(port, UART_LCR, lcr); +} + +static struct uart_ops early_uart_ops = { + .set_termios = early_set_termios, +}; + #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) static void wait_for_xmitr(struct uart_port *port) @@ -865,7 +915,7 @@ static int siu_console_setup(struct console *con, char *options) if (port->membase == NULL) { if (port->mapbase == 0) return -ENODEV; - port->membase = ioremap(port->mapbase, siu_port_size(port)); + port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase); } vr41xx_select_siu_interface(SIU_INTERFACE_RS232C); @@ -899,7 +949,7 @@ static int __devinit siu_console_init(void) for (i = 0; i < num; i++) { port = &siu_uart_ports[i]; - port->ops = &siu_uart_ops; + port->ops = &early_uart_ops; } register_console(&siu_console); @@ -944,10 +994,8 @@ static int siu_probe(struct device *dev) port->dev = dev; retval = uart_add_one_port(&siu_uart_driver, port); - if (retval < 0) { - port->dev = NULL; + if (retval) break; - } } if (i == 0 && retval < 0) { diff --git a/trunk/drivers/usb/core/sysfs.c b/trunk/drivers/usb/core/sysfs.c index 4d0c9e65cd03..4ab50009291d 100644 --- a/trunk/drivers/usb/core/sysfs.c +++ b/trunk/drivers/usb/core/sysfs.c @@ -290,30 +290,32 @@ static ssize_t show_modalias(struct device *dev, char *buf) { struct usb_interface *intf; struct usb_device *udev; - int len; intf = to_usb_interface(dev); udev = interface_to_usbdev(intf); + if (udev->descriptor.bDeviceClass == 0) { + struct usb_host_interface *alt = intf->cur_altsetting; - len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", + return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct), le16_to_cpu(udev->descriptor.bcdDevice), udev->descriptor.bDeviceClass, udev->descriptor.bDeviceSubClass, - udev->descriptor.bDeviceProtocol); - buf += len; - - if (udev->descriptor.bDeviceClass == 0) { - struct usb_host_interface *alt = intf->cur_altsetting; - - return len + sprintf(buf, "%02Xisc%02Xip%02X\n", + udev->descriptor.bDeviceProtocol, alt->desc.bInterfaceClass, alt->desc.bInterfaceSubClass, alt->desc.bInterfaceProtocol); } else { - return len + sprintf(buf, "*isc*ip*\n"); + return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct), + le16_to_cpu(udev->descriptor.bcdDevice), + udev->descriptor.bDeviceClass, + udev->descriptor.bDeviceSubClass, + udev->descriptor.bDeviceProtocol); } + } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); diff --git a/trunk/drivers/usb/input/hid-core.c b/trunk/drivers/usb/input/hid-core.c index 2d8bd9dcc6ed..869ff73690ac 100644 --- a/trunk/drivers/usb/input/hid-core.c +++ b/trunk/drivers/usb/input/hid-core.c @@ -1315,8 +1315,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 #define USB_DEVICE_ID_WACOM_PTU 0x0003 -#define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 -#define USB_DEVICE_ID_WACOM_CINTIQ 0x003F #define USB_VENDOR_ID_KBGEAR 0x084e #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 @@ -1403,7 +1401,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_DELORME 0x1163 #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 -#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 #define USB_VENDOR_ID_MCC 0x09db #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 @@ -1415,12 +1412,6 @@ void hid_init_reports(struct hid_device *hid) #define USB_VENDOR_ID_BTC 0x046e #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 -#define USB_VENDOR_ID_VERNIER 0x08f7 -#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 -#define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 -#define USB_DEVICE_ID_VERNIER_SKIP 0x0003 -#define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 - /* * Alphabetically sorted blacklist by quirk type. @@ -1446,7 +1437,6 @@ static struct hid_blacklist { { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, @@ -1466,10 +1456,6 @@ static struct hid_blacklist { { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, @@ -1495,10 +1481,6 @@ static struct hid_blacklist { { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, - { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, diff --git a/trunk/drivers/usb/media/pwc/ChangeLog b/trunk/drivers/usb/media/pwc/ChangeLog new file mode 100644 index 000000000000..b2eb71a9afb5 --- /dev/null +++ b/trunk/drivers/usb/media/pwc/ChangeLog @@ -0,0 +1,143 @@ +9.0.2 + +* Adding #ifdef to compile PWC before and after 2.6.5 + +9.0.1 + +9.0 + + +8.12 + +* Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere. + +8.11.1 + +* Fix for PCVC720/40, would not be able to set videomode +* Fix for Samsung MPC models, appearantly they are based on a newer chipset + +8.11 + +* 20 dev_hints (per request) +* Hot unplugging should be better, no more dangling pointers or memory leaks +* Added reserved Logitech webcam IDs +* Device now remembers size & fps between close()/open() +* Removed palette stuff altogether + +8.10.1 + +* Added IDs for PCVC720K/40 and Creative Labs Webcam Pro + +8.10 + +* Fixed ID for QuickCam Notebook pro +* Added GREALSIZE ioctl() call +* Fixed bug in case PWCX was not loaded and invalid size was set + +8.9 + +* Merging with kernel 2.5.49 +* Adding IDs for QuickCam Zoom & QuickCam Notebook + +8.8 + +* Fixing 'leds' parameter +* Adding IDs for Logitech QuickCam Pro 4000 +* Making URB init/cleanup a little nicer + +8.7 + +* Incorporating changes in ioctl() parameter passing +* Also changes to URB mechanism + +8.6 + +* Added ID's for Visionite VCS UM100 and UC300 +* Removed YUV420-interlaced palette altogether (was confusing) +* Removed MIRROR stuff as it didn't work anyway +* Fixed a problem with the 'leds' parameter (wouldn't blink) +* Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s, + CONTOUR, BACKLIGHT, FLICKER, DYNNOISE. +* VIDIOCGCAP.name now contains real camera model name instead of + 'Philips xxx webcam' +* Added PROBE ioctl (see previous point & API doc) + +8.5 + +* Adding IDs for Creative Labs Webcam 5 +* Adding IDs for SOTEC CMS-001 webcam +* Solving possible hang in VIDIOCSYNC when unplugging the cam +* Forgot to return structure in VIDIOCPWCGAWB, oops +* Time interval for the LEDs are now in milliseconds + +8.4 + +* Fixing power_save option for Vesta range +* Handling new error codes in ISOC callback +* Adding dev_hint module parameter, to specify /dev/videoX device nodes + +8.3 + +* Adding Samsung C10 and C30 cameras +* Removing palette module parameter +* Fixed typo in ID of QuickCam 3000 Pro +* Adding LED settings (blinking while in use) for ToUCam cameras. +* Turns LED off when camera is not in use. + +8.2 + +* Making module more silent when trace = 0 +* Adding QuickCam 3000 Pro IDs +* Chrominance control for the Vesta cameras +* Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM +* Included Oliver Neukem's lock_kernel() patch +* Allocates less memory for image buffers +* Adds ioctl()s for the whitebalancing + +8.1 + +* Adding support for 750 +* Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls + +8.0 +* 'damage control' after inclusion in 2.4.5. +* Changed wait-queue mechanism in read/mmap/poll according to the book. +* Included YUV420P palette. +* Changed interface to decompressor module. +* Cleaned up pwc structure a bit. + +7.0 + +* Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned. +* There is now a clear error message when an image size is selected that + is only supported using the decompressor, and the decompressor isn't + loaded. +* When the decompressor wasn't loaded, selecting large image size + would create skewed or double images. + +6.3 + +* Introduced spinlocks for the buffer pointer manipulation; a number of + reports seem to suggest the down()/up() semaphores were the cause of + lockups, since they are not suitable for interrupt/user locking. +* Separated decompressor and core code into 2 modules. + +6.2 + +* Non-integral image sizes are now padded with gray or black. +* Added SHUTTERSPEED ioctl(). +* Fixed buglet in VIDIOCPWCSAGC; the function would always return an error, + even though the call succeeded. +* Added hotplug support for 2.4.*. +* Memory: the 645/646 uses less memory now. + +6.1 + +* VIDIOCSPICT returns -EINVAL with invalid palettes. +* Added saturation control. +* Split decompressors from rest. +* Fixed bug that would reset the framerate to the default framerate if + the rate field was set to 0 (which is not what I intended, nl. do not + change the framerate!). +* VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately. +* Workaround for a bug in the 730 sensor. diff --git a/trunk/drivers/usb/net/usbnet.c b/trunk/drivers/usb/net/usbnet.c index 4cbb408af727..85476e76b244 100644 --- a/trunk/drivers/usb/net/usbnet.c +++ b/trunk/drivers/usb/net/usbnet.c @@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) } /* expect bcdVersion 1.0, ignore */ if (memcmp(&desc->bGUID, blan_guid, 16) - && memcmp(&desc->bGUID, safe_guid, 16) ) { + && memcmp(&desc->bGUID, blan_guid, 16) ) { /* hey, this one might _really_ be MDLM! */ dev_dbg (&intf->dev, "MDLM guid\n"); goto bad_desc; diff --git a/trunk/drivers/usb/serial/Kconfig b/trunk/drivers/usb/serial/Kconfig index 9438909e87a5..bc798edf0358 100644 --- a/trunk/drivers/usb/serial/Kconfig +++ b/trunk/drivers/usb/serial/Kconfig @@ -455,17 +455,6 @@ config USB_SERIAL_XIRCOM To compile this driver as a module, choose M here: the module will be called keyspan_pda. -config USB_SERIAL_OPTION - tristate "USB Option PCMCIA serial driver" - depends on USB_SERIAL && USB_OHCI_HCD && PCCARD - help - Say Y here if you want to use an Option card. This is a - GSM card, controlled by three serial ports which are connected - via an OHCI adapter located on a PC card. - - To compile this driver as a module, choose M here: the - module will be called option. - config USB_SERIAL_OMNINET tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" depends on USB_SERIAL && EXPERIMENTAL diff --git a/trunk/drivers/usb/serial/Makefile b/trunk/drivers/usb/serial/Makefile index 6c7cdcc99a9e..d56ff6d86cce 100644 --- a/trunk/drivers/usb/serial/Makefile +++ b/trunk/drivers/usb/serial/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o -obj-$(CONFIG_USB_SERIAL_OPTION) += option.o obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o diff --git a/trunk/drivers/usb/serial/cp2101.c b/trunk/drivers/usb/serial/cp2101.c index 4ace9964fc6b..7e9bb63eb466 100644 --- a/trunk/drivers/usb/serial/cp2101.c +++ b/trunk/drivers/usb/serial/cp2101.c @@ -7,14 +7,6 @@ * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. * - * Support to set flow control line levels using TIOCMGET and TIOCMSET - * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow - * control thanks to Munir Nassar nassarmu@real-time.com - * - * Outstanding Issues: - * Buffers are not flushed when the port is opened. - * Multiple calls to write() may fail with "Resource temporarily unavailable" - * */ #include @@ -32,7 +24,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.04" +#define DRIVER_VERSION "v0.03" #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" /* @@ -43,9 +35,6 @@ static void cp2101_cleanup(struct usb_serial_port*); static void cp2101_close(struct usb_serial_port*, struct file*); static void cp2101_get_termios(struct usb_serial_port*); static void cp2101_set_termios(struct usb_serial_port*, struct termios*); -static int cp2101_tiocmget (struct usb_serial_port *, struct file *); -static int cp2101_tiocmset (struct usb_serial_port *, struct file *, - unsigned int, unsigned int); static void cp2101_break_ctl(struct usb_serial_port*, int); static int cp2101_startup (struct usb_serial *); static void cp2101_shutdown(struct usb_serial*); @@ -54,10 +43,9 @@ static void cp2101_shutdown(struct usb_serial*); static int debug; static struct usb_device_id id_table [] = { - { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ - { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ - { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ - { } /* Terminating Entry */ + {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ + {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ + { } /* Terminating Entry*/ }; MODULE_DEVICE_TABLE (usb, id_table); @@ -82,35 +70,32 @@ static struct usb_serial_device_type cp2101_device = { .close = cp2101_close, .break_ctl = cp2101_break_ctl, .set_termios = cp2101_set_termios, - .tiocmget = cp2101_tiocmget, - .tiocmset = cp2101_tiocmset, .attach = cp2101_startup, .shutdown = cp2101_shutdown, }; -/* Config request types */ +/*Config request types*/ #define REQTYPE_HOST_TO_DEVICE 0x41 #define REQTYPE_DEVICE_TO_HOST 0xc1 -/* Config SET requests. To GET, add 1 to the request number */ -#define CP2101_UART 0x00 /* Enable / Disable */ -#define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ -#define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ -#define CP2101_BREAK 0x05 /* On / Off */ -#define CP2101_CONTROL 0x07 /* Flow control line states */ -#define CP2101_MODEMCTL 0x13 /* Modem controls */ -#define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ +/*Config SET requests. To GET, add 1 to the request number*/ +#define CP2101_UART 0x00 /*Enable / Disable*/ +#define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ +#define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ +#define CP2101_BREAK 0x05 /*On / Off*/ +#define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ +#define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ +#define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ -/* CP2101_UART */ +/*CP2101_UART*/ #define UART_ENABLE 0x0001 #define UART_DISABLE 0x0000 -/* CP2101_BAUDRATE */ +/*CP2101_BAUDRATE*/ #define BAUD_RATE_GEN_FREQ 0x384000 -/* CP2101_BITS */ +/*CP2101_BITS*/ #define BITS_DATA_MASK 0X0f00 -#define BITS_DATA_5 0X0500 #define BITS_DATA_6 0X0600 #define BITS_DATA_7 0X0700 #define BITS_DATA_8 0X0800 @@ -127,137 +112,64 @@ static struct usb_serial_device_type cp2101_device = { #define BITS_STOP_1 0x0000 #define BITS_STOP_1_5 0x0001 #define BITS_STOP_2 0x0002 - -/* CP2101_BREAK */ #define BREAK_ON 0x0000 #define BREAK_OFF 0x0001 -/* CP2101_CONTROL */ -#define CONTROL_DTR 0x0001 -#define CONTROL_RTS 0x0002 -#define CONTROL_CTS 0x0010 -#define CONTROL_DSR 0x0020 -#define CONTROL_RING 0x0040 -#define CONTROL_DCD 0x0080 -#define CONTROL_WRITE_DTR 0x0100 -#define CONTROL_WRITE_RTS 0x0200 -/* - * cp2101_get_config - * Reads from the CP2101 configuration registers - * 'size' is specified in bytes. - * 'data' is a pointer to a pre-allocated array of integers large - * enough to hold 'size' bytes (with 4 bytes to each integer) - */ -static int cp2101_get_config(struct usb_serial_port* port, u8 request, - unsigned int *data, int size) +static int cp2101_get_config(struct usb_serial_port* port, u8 request) { struct usb_serial *serial = port->serial; - u32 *buf; - int result, i, length; - - /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; - - buf = kmalloc (length * sizeof(u32), GFP_KERNEL); - memset(buf, 0, length * sizeof(u32)); - - if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); - return -ENOMEM; - } + unsigned char buf[4]; + unsigned int value; + int result, i; - /* For get requests, the request number must be incremented */ + /*For get requests, the request number must be incremented*/ request++; - /* Issue the request, attempting to read 'size' bytes */ + /*Issue the request, attempting to read 4 bytes*/ result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - 0, buf, size, 300); + 0, buf, 4, 300); - /* Convert data into an array of integers */ - for (i=0; idev, "%s - Unable to send config request, " - "request=0x%x size=%d result=%d\n", - __FUNCTION__, request, size, result); - return -EPROTO; + "request=0x%x result=%d\n", + __FUNCTION__, request, result); + return result; } - return 0; + /*Assemble each byte read into an integer value*/ + value = 0; + for (i=0; i<4 && iserial; - u32 *buf; - int result, i, length; - - /* Number of integers required to contain the array */ - length = (((size - 1) | 3) + 1)/4; - - buf = kmalloc(length * sizeof(u32), GFP_KERNEL); - if (!buf) { - dev_err(&port->dev, "%s - out of memory.\n", - __FUNCTION__); - return -ENOMEM; - } + int result; + result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), + request, REQTYPE_HOST_TO_DEVICE, value, + 0, NULL, 0, 300); - /* Array of integers into bytes */ - for (i = 0; i < length; i++) - buf[i] = cpu_to_le32(data[i]); - - if (size > 2) { - result = usb_control_msg (serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, 0x0000, - 0, buf, size, 300); - } else { - result = usb_control_msg (serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); + if (result <0) { + dev_err(&port->dev, "%s - Unable to send config request, " + "request=0x%x value=0x%x result=%d\n", + __FUNCTION__, request, value, result); + return result; } - kfree(buf); - - if ((size > 2 && result != size) || result < 0) { - dev_err(&port->dev, "%s - Unable to send request, " - "request=0x%x size=%d result=%d\n", - __FUNCTION__, request, size, result); - return -EPROTO; - } + dbg(" %s - request=0x%x value=0x%x result=%d", + __FUNCTION__, request, value, result); - /* Single data value */ - result = usb_control_msg (serial->dev, - usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, data[0], - 0, NULL, 0, 300); return 0; } -/* - * cp2101_set_config_single - * Convenience function for calling cp2101_set_config on single data values - * without requiring an integer pointer - */ -static inline int cp2101_set_config_single(struct usb_serial_port* port, - u8 request, unsigned int data) -{ - return cp2101_set_config(port, request, &data, 2); -} - static int cp2101_open (struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; @@ -265,7 +177,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) dbg("%s - port %d", __FUNCTION__, port->number); - if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { + if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { dev_err(&port->dev, "%s - Unable to enable UART\n", __FUNCTION__); return -EPROTO; @@ -286,12 +198,9 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) return result; } - /* Configure the termios structure */ + /*Configure the termios structure*/ cp2101_get_termios(port); - /* Set the DTR and RTS pins low */ - cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); - return 0; } @@ -319,18 +228,16 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) usb_kill_urb(port->write_urb); usb_kill_urb(port->read_urb); - cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); + cp2101_set_config(port, CP2101_UART, UART_DISABLE); } -/* - * cp2101_get_termios - * Reads the baud rate, data bits, parity, stop bits and flow control mode - * from the device, corrects any unsupported values, and configures the - * termios structure to reflect the state of the device - */ +/* cp2101_get_termios*/ +/* Reads the baud rate, data bits, parity and stop bits from the device*/ +/* Corrects any unsupported values*/ +/* Configures the termios structure to reflect the state of the device*/ static void cp2101_get_termios (struct usb_serial_port *port) { - unsigned int cflag, modem_ctl[4]; + unsigned int cflag; int baud; int bits; @@ -342,16 +249,15 @@ static void cp2101_get_termios (struct usb_serial_port *port) } cflag = port->tty->termios->c_cflag; - cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); - /* Convert to baudrate */ + baud = cp2101_get_config(port, CP2101_BAUDRATE); + /*Convert to baudrate*/ if (baud) baud = BAUD_RATE_GEN_FREQ / baud; dbg("%s - baud rate = %d", __FUNCTION__, baud); cflag &= ~CBAUD; switch (baud) { - /* - * The baud rates which are commented out below + /* The baud rates which are commented out below * appear to be supported by the device * but are non-standard */ @@ -378,18 +284,14 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - Baud rate is not supported, " "using 9600 baud", __FUNCTION__); cflag |= B9600; - cp2101_set_config_single(port, CP2101_BAUDRATE, + cp2101_set_config(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ/9600)); break; } - cp2101_get_config(port, CP2101_BITS, &bits, 2); + bits = cp2101_get_config(port, CP2101_BITS); cflag &= ~CSIZE; switch(bits & BITS_DATA_MASK) { - case BITS_DATA_5: - dbg("%s - data bits = 5", __FUNCTION__); - cflag |= CS5; - break; case BITS_DATA_6: dbg("%s - data bits = 6", __FUNCTION__); cflag |= CS6; @@ -408,7 +310,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; default: dbg("%s - Unknown number of data bits, " @@ -416,7 +318,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) cflag |= CS8; bits &= ~BITS_DATA_MASK; bits |= BITS_DATA_8; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; } @@ -439,21 +341,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; case BITS_PARITY_SPACE: dbg("%s - parity = SPACE (not supported, " "disabling parity)", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; default: dbg("%s - Unknown parity mode, " "disabling parity", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; } @@ -464,9 +366,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) break; case BITS_STOP_1_5: dbg("%s - stop bits = 1.5 (not supported, " - "using 1 stop bit)", __FUNCTION__); + "using 1 stop bit", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __FUNCTION__); @@ -476,19 +378,10 @@ static void cp2101_get_termios (struct usb_serial_port *port) dbg("%s - Unknown number of stop bits, " "using 1 stop bit", __FUNCTION__); bits &= ~BITS_STOP_MASK; - cp2101_set_config(port, CP2101_BITS, &bits, 2); + cp2101_set_config(port, CP2101_BITS, bits); break; } - cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); - if (modem_ctl[0] & 0x0008) { - dbg("%s - flow control = CRTSCTS", __FUNCTION__); - cflag |= CRTSCTS; - } else { - dbg("%s - flow control = NONE", __FUNCTION__); - cflag &= ~CRTSCTS; - } - port->tty->termios->c_cflag = cflag; } @@ -496,8 +389,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, struct termios *old_termios) { unsigned int cflag, old_cflag=0; - int baud=0, bits; - unsigned int modem_ctl[4]; + int baud=0; + int bits; dbg("%s - port %d", __FUNCTION__, port->number); @@ -507,7 +400,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, } cflag = port->tty->termios->c_cflag; - /* Check that they really want us to change something */ + /* check that they really want us to change something */ if (old_termios) { if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(port->tty->termios->c_iflag) @@ -522,8 +415,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, /* If the baud rate is to be updated*/ if ((cflag & CBAUD) != (old_cflag & CBAUD)) { switch (cflag & CBAUD) { - /* - * The baud rates which are commented out below + /* The baud rates which are commented out below * appear to be supported by the device * but are non-standard */ @@ -556,22 +448,18 @@ static void cp2101_set_termios (struct usb_serial_port *port, if (baud) { dbg("%s - Setting baud rate to %d baud", __FUNCTION__, baud); - if (cp2101_set_config_single(port, CP2101_BAUDRATE, + if (cp2101_set_config(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ / baud))) dev_err(&port->dev, "Baud rate requested not " "supported by device\n"); } } - /* If the number of data bits is to be updated */ + /*If the number of data bits is to be updated*/ if ((cflag & CSIZE) != (old_cflag & CSIZE)) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + bits = cp2101_get_config(port, CP2101_BITS); bits &= ~BITS_DATA_MASK; switch (cflag & CSIZE) { - case CS5: - bits |= BITS_DATA_5; - dbg("%s - data bits = 5", __FUNCTION__); - break; case CS6: bits |= BITS_DATA_6; dbg("%s - data bits = 6", __FUNCTION__); @@ -595,13 +483,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_DATA_8; break; } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp2101_set_config(port, CP2101_BITS, bits)) dev_err(&port->dev, "Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + bits = cp2101_get_config(port, CP2101_BITS); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { @@ -612,13 +500,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - parity = EVEN", __FUNCTION__); } } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp2101_set_config(port, CP2101_BITS, bits)) dev_err(&port->dev, "Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - cp2101_get_config(port, CP2101_BITS, &bits, 2); + bits = cp2101_get_config(port, CP2101_BITS); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; @@ -627,90 +515,15 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_STOP_1; dbg("%s - stop bits = 1", __FUNCTION__); } - if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) + if (cp2101_set_config(port, CP2101_BITS, bits)) dev_err(&port->dev, "Number of stop bits requested " "not supported by device\n"); } - - if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { - cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); - dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __FUNCTION__, modem_ctl[0], modem_ctl[1], - modem_ctl[2], modem_ctl[3]); - - if (cflag & CRTSCTS) { - modem_ctl[0] &= ~0x7B; - modem_ctl[0] |= 0x09; - modem_ctl[1] = 0x80; - dbg("%s - flow control = CRTSCTS", __FUNCTION__); - } else { - modem_ctl[0] &= ~0x7B; - modem_ctl[0] |= 0x01; - modem_ctl[1] |= 0x40; - dbg("%s - flow control = NONE", __FUNCTION__); - } - - dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", - __FUNCTION__, modem_ctl[0], modem_ctl[1], - modem_ctl[2], modem_ctl[3]); - cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); - } - -} - -static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear) -{ - int control = 0; - - dbg("%s - port %d", __FUNCTION__, port->number); - - if (set & TIOCM_RTS) { - control |= CONTROL_RTS; - control |= CONTROL_WRITE_RTS; - } - if (set & TIOCM_DTR) { - control |= CONTROL_DTR; - control |= CONTROL_WRITE_DTR; - } - if (clear & TIOCM_RTS) { - control &= ~CONTROL_RTS; - control |= CONTROL_WRITE_RTS; - } - if (clear & TIOCM_DTR) { - control &= ~CONTROL_DTR; - control |= CONTROL_WRITE_DTR; - } - - dbg("%s - control = 0x%.4x", __FUNCTION__, control); - - return cp2101_set_config(port, CP2101_CONTROL, &control, 2); - -} - -static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) -{ - int control, result; - - dbg("%s - port %d", __FUNCTION__, port->number); - - cp2101_get_config(port, CP2101_CONTROL, &control, 1); - - result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) - |((control & CONTROL_RTS) ? TIOCM_RTS : 0) - |((control & CONTROL_CTS) ? TIOCM_CTS : 0) - |((control & CONTROL_DSR) ? TIOCM_DSR : 0) - |((control & CONTROL_RING)? TIOCM_RI : 0) - |((control & CONTROL_DCD) ? TIOCM_CD : 0); - - dbg("%s - control = 0x%.2x", __FUNCTION__, control); - - return result; } static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) { - int state; + u16 state; dbg("%s - port %d", __FUNCTION__, port->number); if (break_state == 0) @@ -719,12 +532,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) state = BREAK_ON; dbg("%s - turning break %s", __FUNCTION__, state==BREAK_OFF ? "off" : "on"); - cp2101_set_config(port, CP2101_BREAK, &state, 2); + cp2101_set_config(port, CP2101_BREAK, state); } static int cp2101_startup (struct usb_serial *serial) { - /* CP2101 buffers behave strangely unless device is reset */ + /*CP2101 buffers behave strangely unless device is reset*/ usb_reset_device(serial->dev); return 0; } @@ -735,7 +548,7 @@ static void cp2101_shutdown (struct usb_serial *serial) dbg("%s", __FUNCTION__); - /* Stop reads and writes on all ports */ + /* stop reads and writes on all ports */ for (i=0; i < serial->num_ports; ++i) { cp2101_cleanup(serial->port[i]); } @@ -747,16 +560,16 @@ static int __init cp2101_init (void) retval = usb_serial_register(&cp2101_device); if (retval) - return retval; /* Failed to register */ + return retval; /*Failed to register*/ retval = usb_register(&cp2101_driver); if (retval) { - /* Failed to register */ + /*Failed to register*/ usb_serial_deregister(&cp2101_device); return retval; } - /* Success */ + /*Success*/ info(DRIVER_DESC " " DRIVER_VERSION); return 0; } diff --git a/trunk/drivers/usb/serial/option.c b/trunk/drivers/usb/serial/option.c deleted file mode 100644 index b722175f108f..000000000000 --- a/trunk/drivers/usb/serial/option.c +++ /dev/null @@ -1,729 +0,0 @@ -/* - Option Card (PCMCIA to) USB to Serial Driver - - Copyright (C) 2005 Matthias Urlichs - - This driver is free software; you can redistribute it and/or modify - it under the terms of Version 2 of the GNU General Public License as - published by the Free Software Foundation. - - Portions copied from the Keyspan driver by Hugh Blemings - - History: - - 2005-05-19 v0.1 Initial version, based on incomplete docs - and analysis of misbehavior of the standard driver - 2005-05-20 v0.2 Extended the input buffer to avoid losing - random 64-byte chunks of data - 2005-05-21 v0.3 implemented chars_in_buffer() - turned on low_latency - simplified the code somewhat -*/ -#define DRIVER_VERSION "v0.3" -#define DRIVER_AUTHOR "Matthias Urlichs " -#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" - -#include -#include -#include -#include -#include -#include -#include -#include -#include "usb-serial.h" - -/* Function prototypes */ -static int option_open (struct usb_serial_port *port, struct file *filp); -static void option_close (struct usb_serial_port *port, struct file *filp); -static int option_startup (struct usb_serial *serial); -static void option_shutdown (struct usb_serial *serial); -static void option_rx_throttle (struct usb_serial_port *port); -static void option_rx_unthrottle (struct usb_serial_port *port); -static int option_write_room (struct usb_serial_port *port); - -static void option_instat_callback(struct urb *urb, struct pt_regs *regs); - - -static int option_write (struct usb_serial_port *port, - const unsigned char *buf, int count); - -static int option_chars_in_buffer (struct usb_serial_port *port); -static int option_ioctl (struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg); -static void option_set_termios (struct usb_serial_port *port, - struct termios *old); -static void option_break_ctl (struct usb_serial_port *port, int break_state); -static int option_tiocmget (struct usb_serial_port *port, struct file *file); -static int option_tiocmset (struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear); -static int option_send_setup (struct usb_serial_port *port); - -/* Vendor and product IDs */ -#define OPTION_VENDOR_ID 0x0AF0 - -#define OPTION_PRODUCT_OLD 0x5000 -#define OPTION_PRODUCT_WLAN 0x6000 - -static struct usb_device_id option_ids[] = { - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, - { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) }, - { } /* Terminating entry */ -}; - -MODULE_DEVICE_TABLE(usb, option_ids); - -static struct usb_driver option_driver = { - .owner = THIS_MODULE, - .name = "option", - .probe = usb_serial_probe, - .disconnect = usb_serial_disconnect, - .id_table = option_ids, -}; - -/* The card has three separate interfaces, wich the serial driver - * recognizes separately, thus num_port=1. - */ -static struct usb_serial_device_type option_3port_device = { - .owner = THIS_MODULE, - .name = "Option 3-port card", - .short_name = "option", - .id_table = option_ids, - .num_interrupt_in = NUM_DONT_CARE, - .num_bulk_in = NUM_DONT_CARE, - .num_bulk_out = NUM_DONT_CARE, - .num_ports = 1, /* 3 */ - .open = option_open, - .close = option_close, - .write = option_write, - .write_room = option_write_room, - .chars_in_buffer = option_chars_in_buffer, - .throttle = option_rx_throttle, - .unthrottle = option_rx_unthrottle, - .ioctl = option_ioctl, - .set_termios = option_set_termios, - .break_ctl = option_break_ctl, - .tiocmget = option_tiocmget, - .tiocmset = option_tiocmset, - .attach = option_startup, - .shutdown = option_shutdown, - .read_int_callback = option_instat_callback, -}; - -static int debug; - -/* per port private data */ - -#define N_IN_URB 4 -#define N_OUT_URB 1 -#define IN_BUFLEN 1024 -#define OUT_BUFLEN 1024 - -struct option_port_private { - /* Input endpoints and buffer for this port */ - struct urb *in_urbs[N_IN_URB]; - char in_buffer[N_IN_URB][IN_BUFLEN]; - /* Output endpoints and buffer for this port */ - struct urb *out_urbs[N_OUT_URB]; - char out_buffer[N_OUT_URB][OUT_BUFLEN]; - - /* Settings for the port */ - int rts_state; /* Handshaking pins (outputs) */ - int dtr_state; - int cts_state; /* Handshaking pins (inputs) */ - int dsr_state; - int dcd_state; - int ri_state; - // int break_on; - - unsigned long tx_start_time[N_OUT_URB]; -}; - - -/* Functions used by new usb-serial code. */ -static int __init -option_init (void) -{ - int retval; - retval = usb_serial_register(&option_3port_device); - if (retval) - goto failed_3port_device_register; - retval = usb_register(&option_driver); - if (retval) - goto failed_driver_register; - - info(DRIVER_DESC ": " DRIVER_VERSION); - - return 0; - -failed_driver_register: - usb_serial_deregister (&option_3port_device); -failed_3port_device_register: - return retval; -} - -static void __exit -option_exit (void) -{ - usb_deregister (&option_driver); - usb_serial_deregister (&option_3port_device); -} - -module_init(option_init); -module_exit(option_exit); - -static void -option_rx_throttle (struct usb_serial_port *port) -{ - dbg("%s", __FUNCTION__); -} - - -static void -option_rx_unthrottle (struct usb_serial_port *port) -{ - dbg("%s", __FUNCTION__); -} - - -static void -option_break_ctl (struct usb_serial_port *port, int break_state) -{ - /* Unfortunately, I don't know how to send a break */ - dbg("%s", __FUNCTION__); -} - - -static void -option_set_termios (struct usb_serial_port *port, - struct termios *old_termios) -{ - dbg("%s", __FUNCTION__); - - option_send_setup(port); -} - -static int -option_tiocmget(struct usb_serial_port *port, struct file *file) -{ - unsigned int value; - struct option_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - value = ((portdata->rts_state) ? TIOCM_RTS : 0) | - ((portdata->dtr_state) ? TIOCM_DTR : 0) | - ((portdata->cts_state) ? TIOCM_CTS : 0) | - ((portdata->dsr_state) ? TIOCM_DSR : 0) | - ((portdata->dcd_state) ? TIOCM_CAR : 0) | - ((portdata->ri_state) ? TIOCM_RNG : 0); - - return value; -} - -static int -option_tiocmset (struct usb_serial_port *port, struct file *file, - unsigned int set, unsigned int clear) -{ - struct option_port_private *portdata; - - portdata = usb_get_serial_port_data(port); - - if (set & TIOCM_RTS) - portdata->rts_state = 1; - if (set & TIOCM_DTR) - portdata->dtr_state = 1; - - if (clear & TIOCM_RTS) - portdata->rts_state = 0; - if (clear & TIOCM_DTR) - portdata->dtr_state = 0; - return option_send_setup(port); -} - -static int -option_ioctl (struct usb_serial_port *port, struct file *file, - unsigned int cmd, unsigned long arg) -{ - return -ENOIOCTLCMD; -} - -/* Write */ -static int -option_write(struct usb_serial_port *port, - const unsigned char *buf, int count) -{ - struct option_port_private *portdata; - int i; - int left, todo; - struct urb *this_urb = NULL; /* spurious */ - int err; - - portdata = usb_get_serial_port_data(port); - - dbg("%s: write (%d chars)", __FUNCTION__, count); - -#if 0 - spin_lock(&port->lock); - if (port->write_urb_busy) { - spin_unlock(&port->lock); - dbg("%s: already writing", __FUNCTION__); - return 0; - } - port->write_urb_busy = 1; - spin_unlock(&port->lock); -#endif - - i = 0; - left = count; - while (left>0) { - todo = left; - if (todo > OUT_BUFLEN) - todo = OUT_BUFLEN; - - for (;i < N_OUT_URB; i++) { - /* Check we have a valid urb/endpoint before we use it... */ - this_urb = portdata->out_urbs[i]; - if (this_urb->status != -EINPROGRESS) - break; - if (this_urb->transfer_flags & URB_ASYNC_UNLINK) - continue; - if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ)) - continue; - this_urb->transfer_flags |= URB_ASYNC_UNLINK; - usb_unlink_urb(this_urb); - } - - if (i == N_OUT_URB) { - /* no bulk out free! */ - dbg("%s: no output urb -- left %d", __FUNCTION__,count-left); -#if 0 - port->write_urb_busy = 0; -#endif - return count-left; - } - - dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i); - - memcpy (this_urb->transfer_buffer, buf, todo); - - /* send the data out the bulk port */ - this_urb->transfer_buffer_length = todo; - - this_urb->transfer_flags &= ~URB_ASYNC_UNLINK; - this_urb->dev = port->serial->dev; - err = usb_submit_urb(this_urb, GFP_ATOMIC); - if (err) { - dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status); - continue; - } - portdata->tx_start_time[i] = jiffies; - buf += todo; - left -= todo; - } - - count -= left; -#if 0 - port->write_urb_busy = 0; -#endif - dbg("%s: wrote (did %d)", __FUNCTION__, count); - return count; -} - -static void -option_indat_callback (struct urb *urb, struct pt_regs *regs) -{ - int i, err; - int endpoint; - struct usb_serial_port *port; - struct tty_struct *tty; - unsigned char *data = urb->transfer_buffer; - - dbg("%s: %p", __FUNCTION__, urb); - - endpoint = usb_pipeendpoint(urb->pipe); - port = (struct usb_serial_port *) urb->context; - - if (urb->status) { - dbg("%s: nonzero status: %d on endpoint %02x.", - __FUNCTION__, urb->status, endpoint); - } else { - tty = port->tty; - if (urb->actual_length) { - for (i = 0; i < urb->actual_length ; ++i) { - if (tty->flip.count >= TTY_FLIPBUF_SIZE) - tty_flip_buffer_push(tty); - tty_insert_flip_char(tty, data[i], 0); - } - tty_flip_buffer_push(tty); - } else { - dbg("%s: empty read urb received", __FUNCTION__); - } - - /* Resubmit urb so we continue receiving */ - if (port->open_count && urb->status != -ESHUTDOWN) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err); - } - } - return; -} - -static void -option_outdat_callback (struct urb *urb, struct pt_regs *regs) -{ - struct usb_serial_port *port; - - dbg("%s", __FUNCTION__); - - port = (struct usb_serial_port *) urb->context; - - if (port->open_count) - schedule_work(&port->work); -} - -static void -option_instat_callback (struct urb *urb, struct pt_regs *regs) -{ - int err; - struct usb_serial_port *port = (struct usb_serial_port *) urb->context; - struct option_port_private *portdata = usb_get_serial_port_data(port); - struct usb_serial *serial = port->serial; - - dbg("%s", __FUNCTION__); - dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); - - if (urb->status == 0) { - struct usb_ctrlrequest *req_pkt = - (struct usb_ctrlrequest *)urb->transfer_buffer; - - if (!req_pkt) { - dbg("%s: NULL req_pkt\n", __FUNCTION__); - return; - } - if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) { - int old_dcd_state; - unsigned char signals = *((unsigned char *) - urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); - - dbg("%s: signal x%x", __FUNCTION__, signals); - - old_dcd_state = portdata->dcd_state; - portdata->cts_state = 1; - portdata->dcd_state = ((signals & 0x01) ? 1 : 0); - portdata->dsr_state = ((signals & 0x02) ? 1 : 0); - portdata->ri_state = ((signals & 0x08) ? 1 : 0); - - if (port->tty && !C_CLOCAL(port->tty) - && old_dcd_state && !portdata->dcd_state) { - tty_hangup(port->tty); - } - } else - dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest); - } else - dbg("%s: error %d", __FUNCTION__, urb->status); - - /* Resubmit urb so we continue receiving IRQ data */ - if (urb->status != -ESHUTDOWN) { - urb->dev = serial->dev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err); - } -} - - -static int -option_write_room (struct usb_serial_port *port) -{ - struct option_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i=0; i < N_OUT_URB; i++) - this_urb = portdata->out_urbs[i]; - if (this_urb && this_urb->status != -EINPROGRESS) - data_len += OUT_BUFLEN; - - dbg("%s: %d", __FUNCTION__, data_len); - return data_len; -} - - -static int -option_chars_in_buffer (struct usb_serial_port *port) -{ - struct option_port_private *portdata; - int i; - int data_len = 0; - struct urb *this_urb; - - portdata = usb_get_serial_port_data(port); - - for (i=0; i < N_OUT_URB; i++) - this_urb = portdata->out_urbs[i]; - if (this_urb && this_urb->status == -EINPROGRESS) - data_len += this_urb->transfer_buffer_length; - - dbg("%s: %d", __FUNCTION__, data_len); - return data_len; -} - - -static int -option_open (struct usb_serial_port *port, struct file *filp) -{ - struct option_port_private *portdata; - struct usb_serial *serial = port->serial; - int i, err; - struct urb *urb; - - portdata = usb_get_serial_port_data(port); - - dbg("%s", __FUNCTION__); - - /* Set some sane defaults */ - portdata->rts_state = 1; - portdata->dtr_state = 1; - - /* Reset low level data toggle and start reading from endpoints */ - for (i = 0; i < N_IN_URB; i++) { - urb = portdata->in_urbs[i]; - if (! urb) - continue; - if (urb->dev != serial->dev) { - dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev); - continue; - } - - /* make sure endpoint data toggle is synchronized with the device */ - - usb_clear_halt(urb->dev, urb->pipe); - - err = usb_submit_urb(urb, GFP_KERNEL); - if (err) { - dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err, - urb->transfer_buffer_length); - } - } - - /* Reset low level data toggle on out endpoints */ - for (i = 0; i < N_OUT_URB; i++) { - urb = portdata->out_urbs[i]; - if (! urb) - continue; - urb->dev = serial->dev; - /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ - } - - port->tty->low_latency = 1; - - option_send_setup(port); - - return (0); -} - -static inline void -stop_urb(struct urb *urb) -{ - if (urb && urb->status == -EINPROGRESS) { - urb->transfer_flags &= ~URB_ASYNC_UNLINK; - usb_kill_urb(urb); - } -} - -static void -option_close(struct usb_serial_port *port, struct file *filp) -{ - int i; - struct usb_serial *serial = port->serial; - struct option_port_private *portdata; - - dbg("%s", __FUNCTION__); - portdata = usb_get_serial_port_data(port); - - portdata->rts_state = 0; - portdata->dtr_state = 0; - - if (serial->dev) { - option_send_setup(port); - - /* Stop reading/writing urbs */ - for (i = 0; i < N_IN_URB; i++) - stop_urb(portdata->in_urbs[i]); - for (i = 0; i < N_OUT_URB; i++) - stop_urb(portdata->out_urbs[i]); - } - port->tty = NULL; -} - - -/* Helper functions used by option_setup_urbs */ -static struct urb * -option_setup_urb (struct usb_serial *serial, int endpoint, - int dir, void *ctx, char *buf, int len, - void (*callback)(struct urb *, struct pt_regs *regs)) -{ - struct urb *urb; - - if (endpoint == -1) - return NULL; /* endpoint not needed */ - - urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ - if (urb == NULL) { - dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); - return NULL; - } - - /* Fill URB using supplied data. */ - usb_fill_bulk_urb(urb, serial->dev, - usb_sndbulkpipe(serial->dev, endpoint) | dir, - buf, len, callback, ctx); - - return urb; -} - -/* Setup urbs */ -static void -option_setup_urbs(struct usb_serial *serial) -{ - int j; - struct usb_serial_port *port; - struct option_port_private *portdata; - - dbg("%s", __FUNCTION__); - - port = serial->port[0]; - portdata = usb_get_serial_port_data(port); - - /* Do indat endpoints first */ - for (j = 0; j <= N_IN_URB; ++j) { - portdata->in_urbs[j] = option_setup_urb (serial, - port->bulk_in_endpointAddress, USB_DIR_IN, port, - portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); - } - - /* outdat endpoints */ - for (j = 0; j <= N_OUT_URB; ++j) { - portdata->out_urbs[j] = option_setup_urb (serial, - port->bulk_out_endpointAddress, USB_DIR_OUT, port, - portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); - } -} - - -static int -option_send_setup(struct usb_serial_port *port) -{ - struct usb_serial *serial = port->serial; - struct option_port_private *portdata; - - dbg("%s", __FUNCTION__); - - portdata = usb_get_serial_port_data(port); - - if (port->tty) { - int val = 0; - if (portdata->dtr_state) - val |= 0x01; - if (portdata->rts_state) - val |= 0x02; - - return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), - 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); - } - - return 0; -} - - -static int -option_startup (struct usb_serial *serial) -{ - int i, err; - struct usb_serial_port *port; - struct option_port_private *portdata; - - dbg("%s", __FUNCTION__); - - /* Now setup per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL); - if (!portdata) { - dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); - return (1); - } - memset(portdata, 0, sizeof(struct option_port_private)); - - usb_set_serial_port_data(port, portdata); - - if (! port->interrupt_in_urb) - continue; - err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); - if (err) - dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err); - } - - option_setup_urbs(serial); - - return (0); -} - -static void -option_shutdown (struct usb_serial *serial) -{ - int i, j; - struct usb_serial_port *port; - struct option_port_private *portdata; - - dbg("%s", __FUNCTION__); - - /* Stop reading/writing urbs */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - for (j = 0; j < N_IN_URB; j++) - stop_urb(portdata->in_urbs[j]); - for (j = 0; j < N_OUT_URB; j++) - stop_urb(portdata->out_urbs[j]); - } - - /* Now free them */ - for (i = 0; i < serial->num_ports; ++i) { - port = serial->port[i]; - portdata = usb_get_serial_port_data(port); - - for (j = 0; j < N_IN_URB; j++) { - if (portdata->in_urbs[j]) { - usb_free_urb(portdata->in_urbs[j]); - portdata->in_urbs[j] = NULL; - } - } - for (j = 0; j < N_OUT_URB; j++) { - if (portdata->out_urbs[j]) { - usb_free_urb(portdata->out_urbs[j]); - portdata->out_urbs[j] = NULL; - } - } - } - - /* Now free per port private data */ - for (i = 0; i < serial->num_ports; i++) { - port = serial->port[i]; - kfree(usb_get_serial_port_data(port)); - } -} - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_VERSION(DRIVER_VERSION); -MODULE_LICENSE("GPL"); - -module_param(debug, bool, S_IRUGO | S_IWUSR); -MODULE_PARM_DESC(debug, "Debug messages"); - diff --git a/trunk/drivers/usb/storage/unusual_devs.h b/trunk/drivers/usb/storage/unusual_devs.h index 9fcc7bd1fbe4..d2891f475793 100644 --- a/trunk/drivers/usb/storage/unusual_devs.h +++ b/trunk/drivers/usb/storage/unusual_devs.h @@ -862,15 +862,6 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_BULK, NULL, US_FL_NEED_OVERRIDE ), -/* Reported by Filippo Bardelli - * The device reports a subclass of RBC, which is wrong. - */ -UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100, - "Trumpion Microelectronics, Inc.", - "33520 USB Digital Voice Recorder", - US_SC_UFI, US_PR_DEVICE, NULL, - 0), - /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, "Trumpion", diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index c8998dc66882..f0cd67d9d31b 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -520,7 +520,7 @@ static int load_flat_file(struct linux_binprm * bprm, DBG_FLT("BINFMT_FLAT: ROM mapping of file (we hope)\n"); down_write(¤t->mm->mmap_sem); - textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 0); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, 0, 0); up_write(¤t->mm->mmap_sem); if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos) @@ -532,7 +532,7 @@ static int load_flat_file(struct linux_binprm * bprm, down_write(¤t->mm->mmap_sem); realdatastart = do_mmap(0, 0, data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long), - PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); + PROT_READ|PROT_WRITE|PROT_EXEC, 0, 0); up_write(¤t->mm->mmap_sem); if (realdatastart == 0 || realdatastart >= (unsigned long)-4096) { @@ -574,7 +574,7 @@ static int load_flat_file(struct linux_binprm * bprm, down_write(¤t->mm->mmap_sem); textpos = do_mmap(0, 0, text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long), - PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); + PROT_READ | PROT_EXEC | PROT_WRITE, 0, 0); up_write(¤t->mm->mmap_sem); if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos) diff --git a/trunk/fs/mpage.c b/trunk/fs/mpage.c index bb9aebe93862..b92c0e64aefa 100644 --- a/trunk/fs/mpage.c +++ b/trunk/fs/mpage.c @@ -79,11 +79,8 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err) if (--bvec >= bio->bi_io_vec) prefetchw(&bvec->bv_page->flags); - if (!uptodate){ + if (!uptodate) SetPageError(page); - if (page->mapping) - set_bit(AS_EIO, &page->mapping->flags); - } end_page_writeback(page); } while (bvec >= bio->bi_io_vec); bio_put(bio); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index a7f7f44119b3..dd78f01b6de8 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -493,21 +493,12 @@ static inline int __vfs_follow_link(struct nameidata *nd, const char *link) return PTR_ERR(link); } -struct path { - struct vfsmount *mnt; - struct dentry *dentry; -}; - -static inline int __do_follow_link(struct path *path, struct nameidata *nd) +static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) { int error; - struct dentry *dentry = path->dentry; - touch_atime(path->mnt, dentry); + touch_atime(nd->mnt, dentry); nd_set_link(nd, NULL); - - if (path->mnt == nd->mnt) - mntget(path->mnt); error = dentry->d_inode->i_op->follow_link(dentry, nd); if (!error) { char *s = nd_get_link(nd); @@ -516,8 +507,6 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) if (dentry->d_inode->i_op->put_link) dentry->d_inode->i_op->put_link(dentry, nd); } - dput(dentry); - mntput(path->mnt); return error; } @@ -529,7 +518,7 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) * Without that kind of total limit, nasty chains of consecutive * symlinks can cause almost arbitrarily long lookups. */ -static inline int do_follow_link(struct path *path, struct nameidata *nd) +static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) { int err = -ELOOP; if (current->link_count >= MAX_NESTED_LINKS) @@ -538,20 +527,17 @@ static inline int do_follow_link(struct path *path, struct nameidata *nd) goto loop; BUG_ON(nd->depth >= MAX_NESTED_LINKS); cond_resched(); - err = security_inode_follow_link(path->dentry, nd); + err = security_inode_follow_link(dentry, nd); if (err) goto loop; current->link_count++; current->total_link_count++; nd->depth++; - err = __do_follow_link(path, nd); + err = __do_follow_link(dentry, nd); current->link_count--; nd->depth--; return err; loop: - dput(path->dentry); - if (path->mnt != nd->mnt) - mntput(path->mnt); path_release(nd); return err; } @@ -579,91 +565,87 @@ int follow_up(struct vfsmount **mnt, struct dentry **dentry) /* no need for dcache_lock, as serialization is taken care in * namespace.c */ -static int __follow_mount(struct path *path) +static int follow_mount(struct vfsmount **mnt, struct dentry **dentry) { int res = 0; - while (d_mountpoint(path->dentry)) { - struct vfsmount *mounted = lookup_mnt(path->mnt, path->dentry); - if (!mounted) - break; - dput(path->dentry); - if (res) - mntput(path->mnt); - path->mnt = mounted; - path->dentry = dget(mounted->mnt_root); - res = 1; - } - return res; -} - -static void follow_mount(struct vfsmount **mnt, struct dentry **dentry) -{ while (d_mountpoint(*dentry)) { struct vfsmount *mounted = lookup_mnt(*mnt, *dentry); if (!mounted) break; - dput(*dentry); mntput(*mnt); *mnt = mounted; + dput(*dentry); *dentry = dget(mounted->mnt_root); + res = 1; } + return res; } /* no need for dcache_lock, as serialization is taken care in * namespace.c */ -int follow_down(struct vfsmount **mnt, struct dentry **dentry) +static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) { struct vfsmount *mounted; mounted = lookup_mnt(*mnt, *dentry); if (mounted) { - dput(*dentry); mntput(*mnt); *mnt = mounted; + dput(*dentry); *dentry = dget(mounted->mnt_root); return 1; } return 0; } -static inline void follow_dotdot(struct nameidata *nd) +int follow_down(struct vfsmount **mnt, struct dentry **dentry) +{ + return __follow_down(mnt,dentry); +} + +static inline void follow_dotdot(struct vfsmount **mnt, struct dentry **dentry) { while(1) { struct vfsmount *parent; - struct dentry *old = nd->dentry; + struct dentry *old = *dentry; read_lock(¤t->fs->lock); - if (nd->dentry == current->fs->root && - nd->mnt == current->fs->rootmnt) { + if (*dentry == current->fs->root && + *mnt == current->fs->rootmnt) { read_unlock(¤t->fs->lock); break; } read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); - if (nd->dentry != nd->mnt->mnt_root) { - nd->dentry = dget(nd->dentry->d_parent); + if (*dentry != (*mnt)->mnt_root) { + *dentry = dget((*dentry)->d_parent); spin_unlock(&dcache_lock); dput(old); break; } spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); - parent = nd->mnt->mnt_parent; - if (parent == nd->mnt) { + parent = (*mnt)->mnt_parent; + if (parent == *mnt) { spin_unlock(&vfsmount_lock); break; } mntget(parent); - nd->dentry = dget(nd->mnt->mnt_mountpoint); + *dentry = dget((*mnt)->mnt_mountpoint); spin_unlock(&vfsmount_lock); dput(old); - mntput(nd->mnt); - nd->mnt = parent; + mntput(*mnt); + *mnt = parent; } - follow_mount(&nd->mnt, &nd->dentry); + follow_mount(mnt, dentry); } +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + /* * It's more convoluted than I'd like it to be, but... it's still fairly * small and for now I'd prefer to have fast path as straight as possible. @@ -682,7 +664,6 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, done: path->mnt = mnt; path->dentry = dentry; - __follow_mount(path); return 0; need_lookup: @@ -770,7 +751,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) case 2: if (this.name[1] != '.') break; - follow_dotdot(nd); + follow_dotdot(&nd->mnt, &nd->dentry); inode = nd->dentry->d_inode; /* fallthrough */ case 1: @@ -790,6 +771,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) err = do_lookup(nd, &this, &next); if (err) break; + /* Check mountpoints.. */ + follow_mount(&next.mnt, &next.dentry); err = -ENOENT; inode = next.dentry->d_inode; @@ -800,7 +783,10 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { - err = do_follow_link(&next, nd); + mntget(next.mnt); + err = do_follow_link(next.dentry, nd); + dput(next.dentry); + mntput(next.mnt); if (err) goto return_err; err = -ENOENT; @@ -812,8 +798,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) break; } else { dput(nd->dentry); - if (nd->mnt != next.mnt) - mntput(nd->mnt); nd->mnt = next.mnt; nd->dentry = next.dentry; } @@ -835,7 +819,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) case 2: if (this.name[1] != '.') break; - follow_dotdot(nd); + follow_dotdot(&nd->mnt, &nd->dentry); inode = nd->dentry->d_inode; /* fallthrough */ case 1: @@ -849,17 +833,19 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) err = do_lookup(nd, &this, &next); if (err) break; + follow_mount(&next.mnt, &next.dentry); inode = next.dentry->d_inode; if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link) { - err = do_follow_link(&next, nd); + mntget(next.mnt); + err = do_follow_link(next.dentry, nd); + dput(next.dentry); + mntput(next.mnt); if (err) goto return_err; inode = nd->dentry->d_inode; } else { dput(nd->dentry); - if (nd->mnt != next.mnt) - mntput(nd->mnt); nd->mnt = next.mnt; nd->dentry = next.dentry; } @@ -899,8 +885,6 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) return 0; out_dput: dput(next.dentry); - if (nd->mnt != next.mnt) - mntput(next.mnt); break; } path_release(nd); @@ -1414,7 +1398,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) { int acc_mode, error = 0; - struct path path; + struct dentry *dentry; struct dentry *dir; int count = 0; @@ -1458,24 +1442,23 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) dir = nd->dentry; nd->flags &= ~LOOKUP_PARENT; down(&dir->d_inode->i_sem); - path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); - path.mnt = nd->mnt; + dentry = __lookup_hash(&nd->last, nd->dentry, nd); do_last: - error = PTR_ERR(path.dentry); - if (IS_ERR(path.dentry)) { + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) { up(&dir->d_inode->i_sem); goto exit; } /* Negative dentry, just create the file */ - if (!path.dentry->d_inode) { + if (!dentry->d_inode) { if (!IS_POSIXACL(dir->d_inode)) mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, path.dentry, mode, nd); + error = vfs_create(dir->d_inode, dentry, mode, nd); up(&dir->d_inode->i_sem); dput(nd->dentry); - nd->dentry = path.dentry; + nd->dentry = dentry; if (error) goto exit; /* Don't check for write permission, don't truncate */ @@ -1493,24 +1476,22 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) if (flag & O_EXCL) goto exit_dput; - if (__follow_mount(&path)) { + if (d_mountpoint(dentry)) { error = -ELOOP; if (flag & O_NOFOLLOW) goto exit_dput; + while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); } error = -ENOENT; - if (!path.dentry->d_inode) + if (!dentry->d_inode) goto exit_dput; - if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) + if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) goto do_link; dput(nd->dentry); - nd->dentry = path.dentry; - if (nd->mnt != path.mnt) - mntput(nd->mnt); - nd->mnt = path.mnt; + nd->dentry = dentry; error = -EISDIR; - if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) + if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) goto exit; ok: error = may_open(nd, acc_mode, flag); @@ -1519,9 +1500,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) return 0; exit_dput: - dput(path.dentry); - if (nd->mnt != path.mnt) - mntput(path.mnt); + dput(dentry); exit: path_release(nd); return error; @@ -1541,15 +1520,18 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) * are done. Procfs-like symlinks just set LAST_BIND. */ nd->flags |= LOOKUP_PARENT; - error = security_inode_follow_link(path.dentry, nd); + error = security_inode_follow_link(dentry, nd); if (error) goto exit_dput; - error = __do_follow_link(&path, nd); + error = __do_follow_link(dentry, nd); + dput(dentry); if (error) return error; nd->flags &= ~LOOKUP_PARENT; - if (nd->last_type == LAST_BIND) + if (nd->last_type == LAST_BIND) { + dentry = nd->dentry; goto ok; + } error = -EISDIR; if (nd->last_type != LAST_NORM) goto exit; @@ -1564,8 +1546,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) } dir = nd->dentry; down(&dir->d_inode->i_sem); - path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); - path.mnt = nd->mnt; + dentry = __lookup_hash(&nd->last, nd->dentry, nd); putname(nd->last.name); goto do_last; } diff --git a/trunk/fs/nfs/dir.c b/trunk/fs/nfs/dir.c index ff6155f5e8d9..73f96acd5d37 100644 --- a/trunk/fs/nfs/dir.c +++ b/trunk/fs/nfs/dir.c @@ -528,39 +528,19 @@ static inline void nfs_renew_times(struct dentry * dentry) dentry->d_time = jiffies; } -/* - * Return the intent data that applies to this particular path component - * - * Note that the current set of intents only apply to the very last - * component of the path. - * We check for this using LOOKUP_CONTINUE and LOOKUP_PARENT. - */ -static inline unsigned int nfs_lookup_check_intent(struct nameidata *nd, unsigned int mask) -{ - if (nd->flags & (LOOKUP_CONTINUE|LOOKUP_PARENT)) - return 0; - return nd->flags & mask; -} - -/* - * Inode and filehandle revalidation for lookups. - * - * We force revalidation in the cases where the VFS sets LOOKUP_REVAL, - * or if the intent information indicates that we're about to open this - * particular file and the "nocto" mount flag is not set. - * - */ static inline int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd) { struct nfs_server *server = NFS_SERVER(inode); if (nd != NULL) { + int ndflags = nd->flags; /* VFS wants an on-the-wire revalidation */ - if (nd->flags & LOOKUP_REVAL) + if (ndflags & LOOKUP_REVAL) goto out_force; /* This is an open(2) */ - if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && + if ((ndflags & LOOKUP_OPEN) && + !(ndflags & LOOKUP_CONTINUE) && !(server->flags & NFS_MOUNT_NOCTO)) goto out_force; } @@ -580,8 +560,12 @@ static inline int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry, struct nameidata *nd) { + int ndflags = 0; + + if (nd) + ndflags = nd->flags; /* Don't revalidate a negative dentry if we're creating a new file */ - if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) + if ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) return 0; return !nfs_check_verifier(dir, dentry); } @@ -716,16 +700,12 @@ struct dentry_operations nfs_dentry_operations = { .d_iput = nfs_dentry_iput, }; -/* - * Use intent information to check whether or not we're going to do - * an O_EXCL create using this path component. - */ static inline int nfs_is_exclusive_create(struct inode *dir, struct nameidata *nd) { if (NFS_PROTO(dir)->version == 2) return 0; - if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) + if (!nd || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) return 0; return (nd->intent.open.flags & O_EXCL) != 0; } @@ -792,13 +772,12 @@ struct dentry_operations nfs4_dentry_operations = { .d_iput = nfs_dentry_iput, }; -/* - * Use intent information to determine whether we need to substitute - * the NFSv4-style stateful OPEN for the LOOKUP call - */ static int is_atomic_open(struct inode *dir, struct nameidata *nd) { - if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) + if (!nd) + return 0; + /* Check that we are indeed trying to open this file */ + if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN)) return 0; /* NFS does not (yet) have a stateful open for directories */ if (nd->flags & LOOKUP_DIRECTORY) diff --git a/trunk/include/asm-alpha/agp.h b/trunk/include/asm-alpha/agp.h index ef855a3bc0f5..c99dbbb5bcb5 100644 --- a/trunk/include/asm-alpha/agp.h +++ b/trunk/include/asm-alpha/agp.h @@ -10,14 +10,4 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/asm-arm/arch-ixp2000/io.h b/trunk/include/asm-arm/arch-ixp2000/io.h index 083462668e18..a8e3c2daefd6 100644 --- a/trunk/include/asm-arm/arch-ixp2000/io.h +++ b/trunk/include/asm-arm/arch-ixp2000/io.h @@ -75,8 +75,8 @@ static inline void insw(u32 ptr, void *buf, int length) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && - ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { + ((port >= IXDP2X01_CS8900_VIRT_BASE) && + (port <= IXDP2X01_CS8900_VIRT_END))) { u8 *buf8 = (u8*)buf; register u32 tmp32; @@ -100,8 +100,8 @@ static inline void outsw(u32 ptr, void *buf, int length) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && - ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { + ((port >= IXDP2X01_CS8900_VIRT_BASE) && + (port <= IXDP2X01_CS8900_VIRT_END))) { register u32 tmp32; u8 *buf8 = (u8*)buf; do { @@ -124,8 +124,8 @@ static inline u16 inw(u32 ptr) * Is this cycle meant for the CS8900? */ if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && - ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { + ((port >= IXDP2X01_CS8900_VIRT_BASE) && + (port <= IXDP2X01_CS8900_VIRT_END))) { return (u16)(*port); } @@ -137,8 +137,8 @@ static inline void outw(u16 value, u32 ptr) register volatile u32 *port = (volatile u32 *)ptr; if ((machine_is_ixdp2401() || machine_is_ixdp2801()) && - (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && - ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { + ((port >= IXDP2X01_CS8900_VIRT_BASE) && + (port <= IXDP2X01_CS8900_VIRT_END))) { *port = value; return; } diff --git a/trunk/include/asm-arm/arch-pxa/pxa-regs.h b/trunk/include/asm-arm/arch-pxa/pxa-regs.h index b5e54a9e9fa7..39741d3c9a34 100644 --- a/trunk/include/asm-arm/arch-pxa/pxa-regs.h +++ b/trunk/include/asm-arm/arch-pxa/pxa-regs.h @@ -1296,7 +1296,6 @@ #define GPIO111_MMCDAT3 111 /* MMC DAT3 (PXA27x) */ #define GPIO111_MMCCS1 111 /* MMC Chip Select 1 (PXA27x) */ #define GPIO112_MMCCMD 112 /* MMC CMD (PXA27x) */ -#define GPIO113_I2S_SYSCLK 113 /* I2S System Clock (PXA27x) */ #define GPIO113_AC97_RESET_N 113 /* AC97 NRESET on (PXA27x) */ /* GPIO alternate function mode & direction */ @@ -1429,7 +1428,6 @@ #define GPIO111_MMCDAT3_MD (111 | GPIO_ALT_FN_1_OUT) #define GPIO110_MMCCS1_MD (111 | GPIO_ALT_FN_1_OUT) #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) -#define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) #define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) diff --git a/trunk/include/asm-arm/elf.h b/trunk/include/asm-arm/elf.h index a1696ba238d3..cbceacbe5afa 100644 --- a/trunk/include/asm-arm/elf.h +++ b/trunk/include/asm-arm/elf.h @@ -38,9 +38,9 @@ typedef struct user_fp elf_fpregset_t; */ #define ELF_CLASS ELFCLASS32 #ifdef __ARMEB__ -#define ELF_DATA ELFDATA2MSB +#define ELF_DATA ELFDATA2MSB; #else -#define ELF_DATA ELFDATA2LSB +#define ELF_DATA ELFDATA2LSB; #endif #define ELF_ARCH EM_ARM diff --git a/trunk/include/asm-arm26/elf.h b/trunk/include/asm-arm26/elf.h index 5a47fdb3015d..8b149474db24 100644 --- a/trunk/include/asm-arm26/elf.h +++ b/trunk/include/asm-arm26/elf.h @@ -36,7 +36,7 @@ typedef struct { void *null; } elf_fpregset_t; * These are used to set parameters in the core dumps. */ #define ELF_CLASS ELFCLASS32 -#define ELF_DATA ELFDATA2LSB +#define ELF_DATA ELFDATA2LSB; #define ELF_ARCH EM_ARM #define USE_ELF_CORE_DUMP diff --git a/trunk/include/asm-h8300/kmap_types.h b/trunk/include/asm-h8300/kmap_types.h index 1ec8a3427120..82431edeb2a1 100644 --- a/trunk/include/asm-h8300/kmap_types.h +++ b/trunk/include/asm-h8300/kmap_types.h @@ -1,5 +1,5 @@ -#ifndef _ASM_H8300_KMAP_TYPES_H -#define _ASM_H8300_KMAP_TYPES_H +#ifndef _ASM_KMAP_TYPES_H +#define _ASM_KMAP_TYPES_H enum km_type { KM_BOUNCE_READ, @@ -13,8 +13,6 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, - KM_SOFTIRQ0, - KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/trunk/include/asm-h8300/mman.h b/trunk/include/asm-h8300/mman.h index 63f727a59850..abe08856c84f 100644 --- a/trunk/include/asm-h8300/mman.h +++ b/trunk/include/asm-h8300/mman.h @@ -4,7 +4,6 @@ #define PROT_READ 0x1 /* page can be read */ #define PROT_WRITE 0x2 /* page can be written */ #define PROT_EXEC 0x4 /* page can be executed */ -#define PROT_SEM 0x8 /* page may be used for atomic ops */ #define PROT_NONE 0x0 /* page can not be accessed */ #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ @@ -20,8 +19,6 @@ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ diff --git a/trunk/include/asm-i386/agp.h b/trunk/include/asm-i386/agp.h index b82f5f3ab887..a917ff50354f 100644 --- a/trunk/include/asm-i386/agp.h +++ b/trunk/include/asm-i386/agp.h @@ -21,14 +21,4 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/asm-i386/mach-numaq/mach_ipi.h b/trunk/include/asm-i386/mach-numaq/mach_ipi.h index c6044488e9e6..1b46fd3f2ae3 100644 --- a/trunk/include/asm-i386/mach-numaq/mach_ipi.h +++ b/trunk/include/asm-i386/mach-numaq/mach_ipi.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -void send_IPI_mask_sequence(cpumask_t, int vector); +inline void send_IPI_mask_sequence(cpumask_t, int vector); static inline void send_IPI_mask(cpumask_t mask, int vector) { diff --git a/trunk/include/asm-ia64/agp.h b/trunk/include/asm-ia64/agp.h index 4e517f0e6afa..d1316f1e6ee1 100644 --- a/trunk/include/asm-ia64/agp.h +++ b/trunk/include/asm-ia64/agp.h @@ -18,14 +18,4 @@ #define flush_agp_mappings() /* nothing */ #define flush_agp_cache() mb() -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif /* _ASM_IA64_AGP_H */ diff --git a/trunk/include/asm-ppc/agp.h b/trunk/include/asm-ppc/agp.h index ca9e423307f4..be27cfa8c5b0 100644 --- a/trunk/include/asm-ppc/agp.h +++ b/trunk/include/asm-ppc/agp.h @@ -10,14 +10,4 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/asm-ppc/sigcontext.h b/trunk/include/asm-ppc/sigcontext.h index b7a417e0a921..f82dcccdee1e 100644 --- a/trunk/include/asm-ppc/sigcontext.h +++ b/trunk/include/asm-ppc/sigcontext.h @@ -2,7 +2,7 @@ #define _ASM_PPC_SIGCONTEXT_H #include -#include + struct sigcontext { unsigned long _unused[4]; diff --git a/trunk/include/asm-ppc64/agp.h b/trunk/include/asm-ppc64/agp.h index ca9e423307f4..be27cfa8c5b0 100644 --- a/trunk/include/asm-ppc64/agp.h +++ b/trunk/include/asm-ppc64/agp.h @@ -10,14 +10,4 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/asm-s390/user.h b/trunk/include/asm-s390/user.h index 1dc74baf03c4..c64f8c181df3 100644 --- a/trunk/include/asm-s390/user.h +++ b/trunk/include/asm-s390/user.h @@ -10,7 +10,7 @@ #define _S390_USER_H #include -#include +#include /* Core file format: The core file is written in such a way that gdb can understand it and provide useful information to the user (under linux we use the 'trad-core' bfd). There are quite a number of diff --git a/trunk/include/asm-sparc64/agp.h b/trunk/include/asm-sparc64/agp.h index 58f8cb6ae767..ba05bdf9a211 100644 --- a/trunk/include/asm-sparc64/agp.h +++ b/trunk/include/asm-sparc64/agp.h @@ -8,14 +8,4 @@ #define flush_agp_mappings() #define flush_agp_cache() mb() -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/asm-x86_64/agp.h b/trunk/include/asm-x86_64/agp.h index 06c52ee9c06b..0bb9019d58aa 100644 --- a/trunk/include/asm-x86_64/agp.h +++ b/trunk/include/asm-x86_64/agp.h @@ -19,14 +19,4 @@ int unmap_page_from_agp(struct page *page); worth it. Would need a page for it. */ #define flush_agp_cache() asm volatile("wbinvd":::"memory") -/* Convert a physical address to an address suitable for the GART. */ -#define phys_to_gart(x) (x) -#define gart_to_phys(x) (x) - -/* GATT allocation. Returns/accepts GATT kernel virtual address. */ -#define alloc_gatt_pages(order) \ - ((char *)__get_free_pages(GFP_KERNEL, (order))) -#define free_gatt_pages(table, order) \ - free_pages((unsigned long)(table), (order)) - #endif diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index b123cc08773d..d5a55bdb9c3c 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -25,8 +25,6 @@ #ifndef _LINUX_ACPI_H #define _LINUX_ACPI_H -#include - #ifdef CONFIG_ACPI #ifndef _LINUX diff --git a/trunk/include/linux/if_shaper.h b/trunk/include/linux/if_shaper.h index 004e6f09a6e2..0485b256d043 100644 --- a/trunk/include/linux/if_shaper.h +++ b/trunk/include/linux/if_shaper.h @@ -23,7 +23,7 @@ struct shaper __u32 shapeclock; unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ - struct semaphore sem; + unsigned long locked; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, @@ -38,6 +38,7 @@ struct shaper int (*hard_header_cache)(struct neighbour *neigh, struct hh_cache *hh); void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr); struct net_device_stats* (*get_stats)(struct net_device *dev); + wait_queue_head_t wait_queue; struct timer_list timer; }; diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index b009f801e7c5..e74f301e9bae 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -467,34 +467,12 @@ static inline u8 ata_chk_status(struct ata_port *ap) return ap->ops->check_status(ap); } - -/** - * ata_pause - Flush writes and pause 400 nanoseconds. - * @ap: Port to wait for. - * - * LOCKING: - * Inherited from caller. - */ - static inline void ata_pause(struct ata_port *ap) { ata_altstatus(ap); ndelay(400); } - -/** - * ata_busy_wait - Wait for a port status register - * @ap: Port to wait for. - * - * Waits up to max*10 microseconds for the selected bits in the port's - * status register to be cleared. - * Returns final value of status register. - * - * LOCKING: - * Inherited from caller. - */ - static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, unsigned int max) { @@ -509,18 +487,6 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, return status; } - -/** - * ata_wait_idle - Wait for a port to be idle. - * @ap: Port to wait for. - * - * Waits up to 10ms for port's BUSY and DRQ signals to clear. - * Returns final value of status register. - * - * LOCKING: - * Inherited from caller. - */ - static inline u8 ata_wait_idle(struct ata_port *ap) { u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); @@ -559,18 +525,6 @@ static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, uns tf->device = ATA_DEVICE_OBS | ATA_DEV1; } - -/** - * ata_irq_on - Enable interrupts on a port. - * @ap: Port on which interrupts are enabled. - * - * Enable interrupts on a legacy IDE device using MMIO or PIO, - * wait for idle, clear any pending interrupts. - * - * LOCKING: - * Inherited from caller. - */ - static inline u8 ata_irq_on(struct ata_port *ap) { struct ata_ioports *ioaddr = &ap->ioaddr; @@ -590,18 +544,6 @@ static inline u8 ata_irq_on(struct ata_port *ap) return tmp; } - -/** - * ata_irq_ack - Acknowledge a device interrupt. - * @ap: Port on which interrupts are enabled. - * - * Wait up to 10 ms for legacy IDE device to become idle (BUSY - * or BUSY+DRQ clear). Obtain dma status and port status from - * device. Clear the interrupt. Return port status. - * - * LOCKING: - */ - static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) { unsigned int bits = chk_drq ? ATA_BUSY | ATA_DRQ : ATA_BUSY; diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index ba5d1236aa17..470af8c1a4a0 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -204,7 +204,7 @@ struct hh_cache /* cached hardware header; allow for machine alignment needs. */ #define HH_DATA_MOD 16 #define HH_DATA_OFF(__len) \ - (HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 1)) + (HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1))) #define HH_DATA_ALIGN(__len) \ (((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1)) unsigned long hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)]; diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index 18f734ec9181..b0d6134e1ee6 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2382,8 +2382,6 @@ #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 -#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 -#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 #define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 #define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 #define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 diff --git a/trunk/include/linux/usb.h b/trunk/include/linux/usb.h index 2d1ac5058534..41d1a644c9d4 100644 --- a/trunk/include/linux/usb.h +++ b/trunk/include/linux/usb.h @@ -796,10 +796,6 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); * of the iso_frame_desc array, and the number of errors is reported in * error_count. Completion callbacks for ISO transfers will normally * (re)submit URBs to ensure a constant transfer rate. - * - * Note that even fields marked "public" should not be touched by the driver - * when the urb is owned by the hcd, that is, since the call to - * usb_submit_urb() till the entry into the completion routine. */ struct urb { @@ -807,12 +803,12 @@ struct urb struct kref kref; /* reference count of the URB */ spinlock_t lock; /* lock for the URB */ void *hcpriv; /* private data for host controller */ + struct list_head urb_list; /* list pointer to all active urbs */ int bandwidth; /* bandwidth for INT/ISO request */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ /* public, documented fields in the urb that can be used by drivers */ - struct list_head urb_list; /* list head for use by the urb owner */ struct usb_device *dev; /* (in) pointer to associated device */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 4a2fee2cb62b..1d33fec7bac6 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -1968,7 +1968,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, do { unsigned long index; unsigned long offset; - unsigned long maxlen; size_t copied; offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ @@ -1983,10 +1982,7 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, * same page as we're writing to, without it being marked * up-to-date. */ - maxlen = cur_iov->iov_len - iov_base; - if (maxlen > bytes) - maxlen = bytes; - fault_in_pages_readable(buf, maxlen); + fault_in_pages_readable(buf, bytes); page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); if (!page) { @@ -2028,8 +2024,6 @@ generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, filemap_set_next_iovec(&cur_iov, &iov_base, status); buf = cur_iov->iov_base + iov_base; - } else { - iov_base += status; } } } diff --git a/trunk/net/core/ethtool.c b/trunk/net/core/ethtool.c index a3eeb88e1c81..8ec484894d68 100644 --- a/trunk/net/core/ethtool.c +++ b/trunk/net/core/ethtool.c @@ -356,7 +356,7 @@ static int ethtool_set_coalesce(struct net_device *dev, void __user *useraddr) { struct ethtool_coalesce coalesce; - if (!dev->ethtool_ops->set_coalesce) + if (!dev->ethtool_ops->get_coalesce) return -EOPNOTSUPP; if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) diff --git a/trunk/net/ipv4/ipvs/Makefile b/trunk/net/ipv4/ipvs/Makefile index 30e85de9ffff..a788461a40c9 100644 --- a/trunk/net/ipv4/ipvs/Makefile +++ b/trunk/net/ipv4/ipvs/Makefile @@ -11,7 +11,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ - ip_vs_est.o ip_vs_proto.o \ + ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o \ $(ip_vs_proto-objs-y) diff --git a/trunk/net/ipv4/ipvs/ip_vs_proto.c b/trunk/net/ipv4/ipvs/ip_vs_proto.c index 867d4e9c6594..253c46252bd5 100644 --- a/trunk/net/ipv4/ipvs/ip_vs_proto.c +++ b/trunk/net/ipv4/ipvs/ip_vs_proto.c @@ -216,6 +216,9 @@ int ip_vs_protocol_init(void) #ifdef CONFIG_IP_VS_PROTO_UDP REGISTER_PROTOCOL(&ip_vs_protocol_udp); #endif +#ifdef CONFIG_IP_VS_PROTO_ICMP + REGISTER_PROTOCOL(&ip_vs_protocol_icmp); +#endif #ifdef CONFIG_IP_VS_PROTO_AH REGISTER_PROTOCOL(&ip_vs_protocol_ah); #endif diff --git a/trunk/net/ipv4/ipvs/ip_vs_proto_icmp.c b/trunk/net/ipv4/ipvs/ip_vs_proto_icmp.c new file mode 100644 index 000000000000..191e94aa1c1f --- /dev/null +++ b/trunk/net/ipv4/ipvs/ip_vs_proto_icmp.c @@ -0,0 +1,182 @@ +/* + * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server + * + * Authors: Julian Anastasov , March 2002 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation; + * + */ + +#include +#include +#include +#include +#include + +#include + + +static int icmp_timeouts[1] = { 1*60*HZ }; + +static char * icmp_state_name_table[1] = { "ICMP" }; + +static struct ip_vs_conn * +icmp_conn_in_get(const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct iphdr *iph, + unsigned int proto_off, + int inverse) +{ +#if 0 + struct ip_vs_conn *cp; + + if (likely(!inverse)) { + cp = ip_vs_conn_in_get(iph->protocol, + iph->saddr, 0, + iph->daddr, 0); + } else { + cp = ip_vs_conn_in_get(iph->protocol, + iph->daddr, 0, + iph->saddr, 0); + } + + return cp; + +#else + return NULL; +#endif +} + +static struct ip_vs_conn * +icmp_conn_out_get(const struct sk_buff *skb, + struct ip_vs_protocol *pp, + const struct iphdr *iph, + unsigned int proto_off, + int inverse) +{ +#if 0 + struct ip_vs_conn *cp; + + if (likely(!inverse)) { + cp = ip_vs_conn_out_get(iph->protocol, + iph->saddr, 0, + iph->daddr, 0); + } else { + cp = ip_vs_conn_out_get(IPPROTO_UDP, + iph->daddr, 0, + iph->saddr, 0); + } + + return cp; +#else + return NULL; +#endif +} + +static int +icmp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, + int *verdict, struct ip_vs_conn **cpp) +{ + *verdict = NF_ACCEPT; + return 0; +} + +static int +icmp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) +{ + if (!(skb->nh.iph->frag_off & __constant_htons(IP_OFFSET))) { + if (skb->ip_summed != CHECKSUM_UNNECESSARY) { + if (ip_vs_checksum_complete(skb, skb->nh.iph->ihl * 4)) { + IP_VS_DBG_RL_PKT(0, pp, skb, 0, "Failed checksum for"); + return 0; + } + } + } + return 1; +} + +static void +icmp_debug_packet(struct ip_vs_protocol *pp, + const struct sk_buff *skb, + int offset, + const char *msg) +{ + char buf[256]; + struct iphdr _iph, *ih; + + ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph); + if (ih == NULL) + sprintf(buf, "%s TRUNCATED", pp->name); + else if (ih->frag_off & __constant_htons(IP_OFFSET)) + sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u frag", + pp->name, NIPQUAD(ih->saddr), + NIPQUAD(ih->daddr)); + else { + struct icmphdr _icmph, *ic; + + ic = skb_header_pointer(skb, offset + ih->ihl*4, + sizeof(_icmph), &_icmph); + if (ic == NULL) + sprintf(buf, "%s TRUNCATED to %u bytes\n", + pp->name, skb->len - offset); + else + sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u T:%d C:%d", + pp->name, NIPQUAD(ih->saddr), + NIPQUAD(ih->daddr), + ic->type, ic->code); + } + printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); +} + +static int +icmp_state_transition(struct ip_vs_conn *cp, int direction, + const struct sk_buff *skb, + struct ip_vs_protocol *pp) +{ + cp->timeout = pp->timeout_table[IP_VS_ICMP_S_NORMAL]; + return 1; +} + +static int +icmp_set_state_timeout(struct ip_vs_protocol *pp, char *sname, int to) +{ + int num; + char **names; + + num = IP_VS_ICMP_S_LAST; + names = icmp_state_name_table; + return ip_vs_set_state_timeout(pp->timeout_table, num, names, sname, to); +} + + +static void icmp_init(struct ip_vs_protocol *pp) +{ + pp->timeout_table = icmp_timeouts; +} + +static void icmp_exit(struct ip_vs_protocol *pp) +{ +} + +struct ip_vs_protocol ip_vs_protocol_icmp = { + .name = "ICMP", + .protocol = IPPROTO_ICMP, + .dont_defrag = 0, + .init = icmp_init, + .exit = icmp_exit, + .conn_schedule = icmp_conn_schedule, + .conn_in_get = icmp_conn_in_get, + .conn_out_get = icmp_conn_out_get, + .snat_handler = NULL, + .dnat_handler = NULL, + .csum_check = icmp_csum_check, + .state_transition = icmp_state_transition, + .register_app = NULL, + .unregister_app = NULL, + .app_conn_bind = NULL, + .debug_packet = icmp_debug_packet, + .timeout_change = NULL, + .set_state_timeout = icmp_set_state_timeout, +}; diff --git a/trunk/net/ipv6/ipv6_syms.c b/trunk/net/ipv6/ipv6_syms.c index 5ade5a5d1990..2f4c91ddc9a3 100644 --- a/trunk/net/ipv6/ipv6_syms.c +++ b/trunk/net/ipv6/ipv6_syms.c @@ -37,4 +37,5 @@ EXPORT_SYMBOL(in6_dev_finish_destroy); EXPORT_SYMBOL(xfrm6_rcv); #endif EXPORT_SYMBOL(rt6_lookup); +EXPORT_SYMBOL(fl6_sock_lookup); EXPORT_SYMBOL(ipv6_push_nfrag_opts);