diff options
256 files changed, 4817 insertions, 2724 deletions
@@ -2475,13 +2475,9 @@ S: Potsdam, New York 13676 S: USA N: Dave Neuer -E: dneuer@innovation-charter.com -E: mr_fred_smoothie@yahoo.com +E: dave.neuer@pobox.com D: Helped implement support for Compaq's H31xx series iPAQs D: Other mostly minor tweaks & bugfixes -S: 325 E. Main St., Suite 3 -S: Carnegie, PA 15105 -S: USA N: Michael Neuffer E: mike@i-Connect.Net diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index cf2fce7707d..6df1dfd18b6 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -14,7 +14,7 @@ </authorgroup> <copyright> - <year>2003</year> + <year>2003-2005</year> <holder>Jeff Garzik</holder> </copyright> @@ -44,30 +44,38 @@ <toc></toc> - <chapter id="libataThanks"> - <title>Thanks</title> + <chapter id="libataIntroduction"> + <title>Introduction</title> <para> - The bulk of the ATA knowledge comes thanks to long conversations with - Andre Hedrick (www.linux-ide.org). + 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. </para> <para> - Thanks to Alan Cox for pointing out similarities - between SATA and SCSI, and in general for motivation to hack on - libata. - </para> - <para> - 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). + This Guide documents the libATA driver API, library functions, library + internals, and a couple sample ATA low-level drivers. </para> </chapter> <chapter id="libataDriverApi"> <title>libata Driver API</title> + <para> + 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. + </para> + <para> + 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. + </para> <sect1> <title>struct ata_port_operations</title> + <sect2><title>Disable ATA port</title> <programlisting> void (*port_disable) (struct ata_port *); </programlisting> @@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *); unplug). </para> + </sect2> + + <sect2><title>Post-IDENTIFY device configuration</title> <programlisting> void (*dev_config) (struct ata_port *, struct ata_device *); </programlisting> @@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *); issue of SET FEATURES - XFER MODE, and prior to operation. </para> + </sect2> + + <sect2><title>Set PIO/DMA mode</title> <programlisting> void (*set_piomode) (struct ata_port *, struct ata_device *); void (*set_dmamode) (struct ata_port *, struct ata_device *); @@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap); ->set_dma_mode() is only called if DMA is possible. </para> + </sect2> + + <sect2><title>Taskfile read/write</title> <programlisting> void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf); void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); @@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); taskfile register values. </para> + </sect2> + + <sect2><title>ATA command execute</title> <programlisting> void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); </programlisting> @@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); ->tf_load(), to be initiated in hardware. </para> + </sect2> + + <sect2><title>Per-cmd ATAPI DMA capabilities filter</title> + <programlisting> +int (*check_atapi_dma) (struct ata_queued_cmd *qc); + </programlisting> + + <para> +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. + </para> + + </sect2> + + <sect2><title>Read specific ATA shadow registers</title> <programlisting> u8 (*check_status)(struct ata_port *ap); -void (*dev_select)(struct ata_port *ap, unsigned int device); +u8 (*check_altstatus)(struct ata_port *ap); +u8 (*check_err)(struct ata_port *ap); </programlisting> <para> - Reads the Status ATA shadow register from hardware. On some - hardware, this has the side effect of clearing the interrupt - condition. + 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. </para> + </sect2> + + <sect2><title>Select ATA device on bus</title> <programlisting> void (*dev_select)(struct ata_port *ap, unsigned int device); </programlisting> @@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); <para> 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. + available for use) on the ATA bus. This generally has no +meaning on FIS-based devices. </para> + </sect2> + + <sect2><title>Reset ATA bus</title> <programlisting> void (*phy_reset) (struct ata_port *ap); </programlisting> @@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap); functions ata_bus_reset() or sata_phy_reset() for this hook. </para> + </sect2> + + <sect2><title>Control PCI IDE BMDMA engine</title> <programlisting> 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); </programlisting> <para> - When setting up an IDE BMDMA transaction, these hooks arm - (->bmdma_setup) and fire (->bmdma_start) the hardware's DMA - engine. +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. </para> + <para> +These hooks are typically either no-ops, or simply not implemented, in +FIS-based drivers. + </para> + + </sect2> + + <sect2><title>High-level taskfile hooks</title> <programlisting> void (*qc_prep) (struct ata_queued_cmd *qc); int (*qc_issue) (struct ata_queued_cmd *qc); @@ -190,20 +248,26 @@ 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 roll their own ->qc_issue - implementation, using this as the "issue new ATA command to - hardware" hook. + dispatch. More advanced drivers implement their own ->qc_issue. </para> + </sect2> + + <sect2><title>Timeout (error) handling</title> <programlisting> void (*eng_timeout) (struct ata_port *ap); </programlisting> <para> - This is a high level error handling function, called from the - error handling thread, when a command times out. +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(). </para> + </sect2> + + <sect2><title>Hardware interrupt handling</title> <programlisting> irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); @@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *); is quiet. </para> + </sect2> + + <sect2><title>SATA phy read/write</title> <programlisting> u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg); void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, @@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, if ->phy_reset hook called the sata_phy_reset() helper function. </para> + </sect2> + + <sect2><title>Init and shutdown</title> <programlisting> int (*port_start) (struct ata_port *ap); void (*port_stop) (struct ata_port *ap); @@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set); tasks. </para> <para> - ->host_stop() is called when the rmmod or hot unplug process - begins. The hook must stop all hardware interrupts, DMA - engines, etc. - </para> - <para> ->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. </para> + <para> + ->host_stop() is called after all ->port_stop() calls +have completed. The hook must finalize hardware shutdown, release DMA +and other resources, etc. + </para> + + </sect2> </sect1> </chapter> @@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set); !Idrivers/scsi/sata_sil.c </chapter> + <chapter id="libataThanks"> + <title>Thanks</title> + <para> + 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. + </para> + <para> + Thanks to Alan Cox for pointing out similarities + between SATA and SCSI, and in general for motivation to hack on + libata. + </para> + <para> + 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). + </para> + </chapter> + </book> diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 9838d32b2fe..4d35562b1cf 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -271,7 +271,7 @@ patch, which certifies that you wrote it or otherwise have the right to pass it on as a open-source patch. The rules are pretty simple: if you can certify the below: - Developer's Certificate of Origin 1.0 + Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: @@ -291,6 +291,12 @@ can certify the below: person who certified (a), (b) or (c) and I have not modified it. + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + then you just add a line saying Signed-off-by: Random J Developer <random@developer.org> diff --git a/Documentation/networking/vortex.txt b/Documentation/networking/vortex.txt index fa12a9e4abd..80e1cb19609 100644 --- a/Documentation/networking/vortex.txt +++ b/Documentation/networking/vortex.txt @@ -12,7 +12,7 @@ Don is no longer the prime maintainer of this version of the driver. Please report problems to one or more of: Andrew Morton <andrewm@uow.edu.au> - Netdev mailing list <netdev@oss.sgi.com> + Netdev mailing list <netdev@vger.kernel.org> Linux kernel mailing list <linux-kernel@vger.kernel.org> Please note the 'Reporting and Diagnosing Problems' section at the end diff --git a/MAINTAINERS b/MAINTAINERS index 65ad8251e4b..86ba94f16e8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -73,7 +73,7 @@ S: Status, one of the following: 3C359 NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -81,13 +81,13 @@ S: Maintained 3C505 NETWORK DRIVER P: Philip Blundell M: philb@gnu.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 3CR990 NETWORK DRIVER P: David Dillow M: dave@thedillows.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 3W-XXXX ATA-RAID CONTROLLER DRIVER @@ -130,7 +130,7 @@ S: Maintained 8169 10/100/1000 GIGABIT ETHERNET DRIVER P: Francois Romieu M: romieu@fr.zoreil.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER @@ -143,7 +143,7 @@ S: Maintained 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.] P: Paul Gortmaker M: p_gortmaker@yahoo.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained A2232 SERIAL BOARD DRIVER @@ -332,7 +332,7 @@ S: Maintained ARPD SUPPORT P: Jonathan Layes -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained ASUS ACPI EXTRAS DRIVER @@ -706,7 +706,7 @@ S: Orphaned DIGI RIGHTSWITCH NETWORK DRIVER P: Rick Richardson -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org W: http://www.digi.com S: Orphaned @@ -812,7 +812,7 @@ S: Maintained ETHEREXPRESS-16 NETWORK DRIVER P: Philip Blundell M: philb@gnu.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained ETHERNET BRIDGE @@ -875,7 +875,7 @@ S: Maintained FRAME RELAY DLCI/FRAD (Sangoma drivers too) P: Mike McLagan M: mike.mclagan@linux.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained FREEVXFS FILESYSTEM @@ -1215,7 +1215,7 @@ S: Maintained IPX NETWORK LAYER P: Arnaldo Carvalho de Melo M: acme@conectiva.com.br -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained IRDA SUBSYSTEM @@ -1482,7 +1482,7 @@ MARVELL MV64340 ETHERNET DRIVER P: Manish Lachwani M: Manish_Lachwani@pmc-sierra.com L: linux-mips@linux-mips.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported MATROX FRAMEBUFFER DRIVER @@ -1592,13 +1592,13 @@ P: Andrew Morton M: akpm@osdl.org P: Jeff Garzik M: jgarzik@pobox.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained NETWORKING [GENERAL] P: Networking Team -M: netdev@oss.sgi.com -L: netdev@oss.sgi.com +M: netdev@vger.kernel.org +L: netdev@vger.kernel.org S: Maintained NETWORKING [IPv4/IPv6] @@ -1614,7 +1614,7 @@ P: Hideaki YOSHIFUJI M: yoshfuji@linux-ipv6.org P: Patrick McHardy M: kaber@coreworks.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained IPVS @@ -1634,7 +1634,7 @@ NI5010 NETWORK DRIVER P: Jan-Pascal van Best and Andreas Mohr M: Jan-Pascal van Best <jvbest@qv3pluto.leidenuniv.nl> M: Andreas Mohr <100.30936@germany.net> -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained NINJA SCSI-3 / NINJA SCSI-32Bi (16bit/CardBus) PCMCIA SCSI HOST ADAPTER DRIVER @@ -1676,7 +1676,7 @@ P: Peter De Shrijver M: p2@ace.ulyssis.student.kuleuven.ac.be P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -1783,7 +1783,7 @@ S: Unmaintained PCNET32 NETWORK DRIVER P: Thomas Bogendörfer M: tsbogend@alpha.franken.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained PHRAM MTD DRIVER @@ -1795,7 +1795,7 @@ S: Maintained POSIX CLOCKS and TIMERS P: George Anzinger M: george@mvista.com -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported PNP SUPPORT @@ -1830,7 +1830,7 @@ S: Supported PRISM54 WIRELESS DRIVER P: Prism54 Development Team M: prism54-private@prism54.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org W: http://prism54.org S: Maintained @@ -2047,7 +2047,7 @@ SIS 900/7016 FAST ETHERNET DRIVER P: Daniele Venzano M: venza@brownhat.org W: http://www.brownhat.org/sis900.html -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained SIS FRAMEBUFFER DRIVER @@ -2106,7 +2106,7 @@ S: Maintained SONIC NETWORK DRIVER P: Thomas Bogendoerfer M: tsbogend@alpha.franken.de -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Maintained SONY VAIO CONTROL DEVICE DRIVER @@ -2163,7 +2163,7 @@ S: Supported SPX NETWORK LAYER P: Jay Schulist M: jschlst@samba.org -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org S: Supported SRM (Alpha) environment access @@ -2242,7 +2242,7 @@ S: Maintained TOKEN-RING NETWORK DRIVER P: Mike Phillips M: mikep@linuxtr.net -L: netdev@oss.sgi.com +L: netdev@vger.kernel.org L: linux-tr@linuxtr.net W: http://www.linuxtr.net S: Maintained @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION =-rc5 +EXTRAVERSION = NAME=Woozy Numbat # *DOCUMENTATION* diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index bf397a9f8ac..475950c8a83 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -497,7 +497,7 @@ source "drivers/cpufreq/Kconfig" config CPU_FREQ_SA1100 bool - depends on CPU_FREQ && (SA1100_LART || SA1100_PLEB) + depends on CPU_FREQ && (SA1100_H3100 || SA1100_H3600 || SA1100_H3800 || SA1100_LART || SA1100_PLEB || SA1100_BADGE4 || SA1100_HACKKIT) default y config CPU_FREQ_SA1110 @@ -689,7 +689,9 @@ source "drivers/block/Kconfig" source "drivers/acorn/block/Kconfig" -if ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE +if PCMCIA || ARCH_CLPS7500 || ARCH_IOP3XX || ARCH_IXP4XX \ + || ARCH_L7200 || ARCH_LH7A40X || ARCH_PXA || ARCH_RPC \ + || ARCH_S3C2410 || ARCH_SA1100 || ARCH_SHARK || FOOTBRIDGE source "drivers/ide/Kconfig" endif diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 665bd2c2074..d3fe2533907 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S @@ -47,3 +47,10 @@ __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/arch/arm/configs/badge4_defconfig b/arch/arm/configs/badge4_defconfig index 2b4059d2f8e..5d92af975d8 100644 --- a/arch/arm/configs/badge4_defconfig +++ b/arch/arm/configs/badge4_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sat Mar 26 21:32:26 2005 +# Linux kernel version: 2.6.12-rc6-git3 +# Thu Jun 9 19:00:50 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -34,6 +35,8 @@ CONFIG_EMBEDDED=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y CONFIG_CPU_CACHE_V4WB=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -122,6 +124,7 @@ CONFIG_FORCE_MAX_ZONEORDER=9 # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -131,6 +134,7 @@ CONFIG_ISA=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y # CONFIG_LEDS is not set @@ -152,12 +156,14 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -294,7 +300,6 @@ CONFIG_PARPORT_NOT_PC=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set @@ -428,7 +433,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -526,6 +530,7 @@ CONFIG_IRDA_ULTRA=y # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set CONFIG_SA1100_FIR=y +# CONFIG_VIA_FIR is not set CONFIG_BT=m CONFIG_BT_L2CAP=m # CONFIG_BT_SCO is not set @@ -618,7 +623,6 @@ CONFIG_NET_WIRELESS=y # # CONFIG_SERIO is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -687,7 +691,6 @@ CONFIG_RTC=m # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support @@ -736,6 +739,7 @@ CONFIG_I2C_ELEKTOR=m # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -747,6 +751,7 @@ CONFIG_I2C_ELEKTOR=m # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -871,7 +876,6 @@ CONFIG_USB_PRINTER=m # CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set @@ -954,9 +958,11 @@ CONFIG_USB_USS720=m # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP2101 is not set # CONFIG_USB_SERIAL_CYPRESS_M8 is not set CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -985,6 +991,7 @@ CONFIG_USB_SERIAL_KEYSPAN=m # CONFIG_USB_SERIAL_KOBIL_SCT is not set CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set # CONFIG_USB_SERIAL_TI is not set CONFIG_USB_SERIAL_CYBERJACK=m diff --git a/arch/arm/configs/h3600_defconfig b/arch/arm/configs/h3600_defconfig index b4e297dd54b..b9de07de80f 100644 --- a/arch/arm/configs/h3600_defconfig +++ b/arch/arm/configs/h3600_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Mon Mar 28 00:02:26 2005 +# Linux kernel version: 2.6.12-rc4 +# Thu Jun 9 01:59:03 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -33,6 +34,8 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -120,6 +123,7 @@ CONFIG_CPU_MINICACHE=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -138,6 +142,7 @@ CONFIG_PCMCIA_SA1100=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y # CONFIG_LEDS is not set @@ -159,12 +164,13 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y +# CONFIG_CPU_FREQ_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -298,7 +304,6 @@ CONFIG_MTD_SA1100=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=m @@ -379,7 +384,6 @@ CONFIG_NET=y # Networking options # # CONFIG_PACKET is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -476,6 +480,7 @@ CONFIG_IRCOMM=m # CONFIG_SMC_IRCC_FIR is not set # CONFIG_ALI_FIR is not set CONFIG_SA1100_FIR=m +# CONFIG_VIA_FIR is not set # CONFIG_BT is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set @@ -647,7 +652,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support @@ -676,9 +680,11 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set # CONFIG_FB_MODE_HELPERS is not set # CONFIG_FB_TILEBLITTING is not set CONFIG_FB_SA1100=y +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # diff --git a/arch/arm/configs/hackkit_defconfig b/arch/arm/configs/hackkit_defconfig index 6987c8c5ddb..fb41a36a5a6 100644 --- a/arch/arm/configs/hackkit_defconfig +++ b/arch/arm/configs/hackkit_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Mon Mar 28 00:22:34 2005 +# Linux kernel version: 2.6.12-rc6-git3 +# Thu Jun 9 20:58:58 2005 # CONFIG_ARM=y CONFIG_MMU=y @@ -16,6 +16,7 @@ CONFIG_GENERIC_IOMAP=y CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -34,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -109,7 +112,6 @@ CONFIG_CPU_ABRT_EV4=y CONFIG_CPU_CACHE_V4WB=y CONFIG_CPU_CACHE_VIVT=y CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y # # Processor Features @@ -119,6 +121,7 @@ CONFIG_CPU_MINICACHE=y # Bus support # CONFIG_ISA=y +CONFIG_ISA_DMA_API=y # # PCCARD (PCMCIA/CardBus) support @@ -128,6 +131,7 @@ CONFIG_ISA=y # # Kernel Features # +# CONFIG_SMP is not set # CONFIG_PREEMPT is not set CONFIG_DISCONTIGMEM=y CONFIG_LEDS=y @@ -151,12 +155,14 @@ CONFIG_CPU_FREQ_TABLE=y # CONFIG_CPU_FREQ_DEBUG is not set CONFIG_CPU_FREQ_STAT=y # CONFIG_CPU_FREQ_STAT_DETAILS is not set -CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_PERFORMANCE=y # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set -# CONFIG_CPU_FREQ_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_USERSPACE=y # CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set +CONFIG_CPU_FREQ_SA1100=y # # Floating point emulation @@ -280,7 +286,6 @@ CONFIG_MTD_CFI_UTIL=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set # CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set @@ -338,7 +343,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -484,7 +488,6 @@ CONFIG_SERIO=y CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices @@ -533,7 +536,6 @@ CONFIG_LEGACY_PTY_COUNT=256 # # TPM devices # -# CONFIG_TCG_TPM is not set # # I2C support diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 4eb36155dc9..e14278d5988 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/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 +#if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) @ make sure our user space atomic helper is aborted cmp r2, #VIRT_OFFSET bichs r3, r3, #PSR_Z_BIT @@ -616,11 +616,17 @@ __kuser_helper_start: __kuser_cmpxchg: @ 0xffff0fc0 -#if __LINUX_ARM_ARCH__ < 6 +#if defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifdef CONFIG_SMP /* sanity check */ -#error "CONFIG_SMP on a machine supporting pre-ARMv6 processors?" -#endif + /* + * 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 /* * Theory of operation: diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 14df16b983f..45d2a032d89 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -464,6 +464,55 @@ 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/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S index 6d1d7c27806..5e240e452af 100644 --- a/arch/arm/lib/io-writesw-armv4.S +++ b/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 2b + bpl 1b -3: tst r2, #1 -2: movne ip, r3, lsr #8 + tst r2, #1 +3: movne ip, r3, lsr #8 strneh ip, [r0] mov pc, lr diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 3b948e8c275..e0a01eef099 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -83,7 +83,6 @@ static struct map_desc intcp_io_desc[] __initdata = { { IO_ADDRESS(INTEGRATOR_UART1_BASE), INTEGRATOR_UART1_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_DBG_BASE), INTEGRATOR_DBG_BASE, SZ_4K, MT_DEVICE }, { IO_ADDRESS(INTEGRATOR_GPIO_BASE), INTEGRATOR_GPIO_BASE, SZ_4K, MT_DEVICE }, - { 0xfc900000, 0xc9000000, SZ_4K, MT_DEVICE }, { 0xfca00000, 0xca000000, SZ_4K, MT_DEVICE }, { 0xfcb00000, 0xcb000000, SZ_4K, MT_DEVICE }, }; diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index dd012d6e2f5..f2c9e0d2b24 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/init.h> #include <linux/device.h> +#include <linux/sysdev.h> #include <linux/major.h> #include <linux/fb.h> #include <linux/interrupt.h> @@ -106,6 +107,35 @@ static void __init lubbock_init_irq(void) set_irq_type(IRQ_GPIO(0), IRQT_FALLING); } +#ifdef CONFIG_PM + +static int lubbock_irq_resume(struct sys_device *dev) +{ + LUB_IRQ_MASK_EN = lubbock_irq_enabled; + return 0; +} + +static struct sysdev_class lubbock_irq_sysclass = { + set_kset_name("cpld_irq"), + .resume = lubbock_irq_resume, +}; + +static struct sys_device lubbock_irq_device = { + .cls = &lubbock_irq_sysclass, +}; + +static int __init lubbock_irq_device_init(void) +{ + int ret = sysdev_class_register(&lubbock_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&lubbock_irq_device); + return ret; +} + +device_initcall(lubbock_irq_device_init); + +#endif + static int lubbock_udc_is_connected(void) { return (LUB_MISC_RD & (1 << 9)) == 0; diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 3f952237ae3..9896afca751 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -15,6 +15,7 @@ #include <linux/init.h> #include <linux/device.h> +#include <linux/sysdev.h> #include <linux/interrupt.h> #include <linux/sched.h> #include <linux/bitops.h> @@ -62,7 +63,6 @@ static struct irqchip mainstone_irq_chip = { .unmask = mainstone_unmask_irq, }; - static void mainstone_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *regs) { @@ -100,6 +100,35 @@ static void __init mainstone_init_irq(void) set_irq_type(IRQ_GPIO(0), IRQT_FALLING); } +#ifdef CONFIG_PM + +static int mainstone_irq_resume(struct sys_device *dev) +{ + MST_INTMSKENA = mainstone_irq_enabled; + return 0; +} + +static struct sysdev_class mainstone_irq_sysclass = { + set_kset_name("cpld_irq"), + .resume = mainstone_irq_resume, +}; + +static struct sys_device mainstone_irq_device = { + .cls = &mainstone_irq_sysclass, +}; + +static int __init mainstone_irq_device_init(void) +{ + int ret = sysdev_class_register(&mainstone_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&mainstone_irq_device); + return ret; +} + +device_initcall(mainstone_irq_device_init); + +#endif + static struct resource smc91x_resources[] = { [0] = { @@ -304,6 +333,15 @@ 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/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 82a4bf34c25..9799fe80df2 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -29,9 +29,6 @@ */ #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] @@ -63,6 +60,12 @@ 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 @@ -75,9 +78,7 @@ static int pxa_pm_enter(suspend_state_t state) unsigned long checksum = 0; struct timespec delta, rtc; int i; - - if (state != PM_SUSPEND_MEM) - return -EINVAL; + extern void pxa_cpu_pm_enter(suspend_state_t state); #ifdef CONFIG_IWMMXT /* force any iWMMXt context to ram **/ @@ -100,16 +101,17 @@ 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 */ @@ -123,16 +125,13 @@ 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_suspend(); + pxa_cpu_pm_enter(state); /* after sleeping, validate the checksum */ checksum = 0; @@ -145,7 +144,7 @@ static int pxa_pm_enter(suspend_state_t state) LUB_HEXLED = 0xbadbadc5; #endif while (1) - pxa_cpu_suspend(); + pxa_cpu_pm_enter(state); } /* ensure not to come back here if it wasn't intended */ @@ -162,8 +161,11 @@ 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; @@ -197,7 +199,9 @@ unsigned long sleep_phys_sp(void *sp) */ static int pxa_pm_prepare(suspend_state_t state) { - return 0; + extern int pxa_cpu_pm_prepare(suspend_state_t state); + + return pxa_cpu_pm_prepare(state); } /* diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e887b7175ef..7869c3b4e62 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -16,6 +16,7 @@ * initialization stuff for PXA machines which can be overridden later if * need be. */ +#include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> @@ -102,3 +103,35 @@ unsigned int get_lcdclk_frequency_10khz(void) } EXPORT_SYMBOL(get_lcdclk_frequency_10khz); + +#ifdef CONFIG_PM + +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; + } +} + +#endif diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e863afefb5..893964fb965 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -120,6 +120,42 @@ EXPORT_SYMBOL(get_clk_frequency_khz); EXPORT_SYMBOL(get_memclk_frequency_10khz); EXPORT_SYMBOL(get_lcdclk_frequency_10khz); +#ifdef CONFIG_PM + +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; + } +} + +#endif /* * device registration specific to PXA27x. diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c index bc229fab86d..c7c28890d40 100644 --- a/arch/arm/mach-s3c2410/dma.c +++ b/arch/arm/mach-s3c2410/dma.c @@ -785,6 +785,10 @@ 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/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig index 50cde576dad..6923316b3d0 100644 --- a/arch/arm/mach-sa1100/Kconfig +++ b/arch/arm/mach-sa1100/Kconfig @@ -150,7 +150,7 @@ config SA1100_SSP config H3600_SLEEVE tristate "Compaq iPAQ Handheld sleeve support" - depends on SA1100_H3600 + depends on SA1100_H3100 || SA1100_H3600 help Choose this option to enable support for extension packs (sleeves) for the Compaq iPAQ H3XXX series of handheld computers. This option diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 554e1bd30d6..302c2a7b9b6 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -543,7 +543,7 @@ static void versatile_clcd_enable(struct clcd_fb *fb) val |= SYS_CLCD_MODE_5551; break; case 6: - val |= SYS_CLCD_MODE_565_BLSB; + val |= SYS_CLCD_MODE_565_RLSB; break; case 8: val |= SYS_CLCD_MODE_888; diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 48bac7da8c7..3fefb43c67f 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -228,7 +228,6 @@ config CPU_SA1100 select CPU_CACHE_V4WB select CPU_CACHE_VIVT select CPU_TLB_V4WB - select CPU_MINICACHE # XScale config CPU_XSCALE @@ -239,7 +238,6 @@ config CPU_XSCALE select CPU_ABRT_EV5T select CPU_CACHE_VIVT select CPU_TLB_V4WBI - select CPU_MINICACHE # ARMv6 config CPU_V6 @@ -345,11 +343,6 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool -config CPU_MINICACHE - bool - help - Processor has a minicache. - comment "Processor Features" config ARM_THUMB @@ -429,3 +422,11 @@ 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/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index ccf316c11e0..59f47d4c2df 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -31,8 +31,6 @@ 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/arch/arm/mm/copypage-xscale.S b/arch/arm/mm/copypage-xscale.S deleted file mode 100644 index bb277316ef5..00000000000 --- a/arch/arm/mm/copypage-xscale.S +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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 <linux/linkage.h> -#include <linux/init.h> -#include <asm/constants.h> - -/* - * 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/arch/arm/mm/copypage-xscale.c b/arch/arm/mm/copypage-xscale.c new file mode 100644 index 00000000000..42a6ee255ce --- /dev/null +++ b/arch/arm/mm/copypage-xscale.c @@ -0,0 +1,131 @@ +/* + * 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 <linux/init.h> +#include <linux/mm.h> + +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/tlbflush.h> + +/* + * 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/arch/arm/mm/minicache.c b/arch/arm/mm/minicache.c deleted file mode 100644 index dedf2ab01b2..00000000000 --- a/arch/arm/mm/minicache.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 <linux/init.h> -#include <linux/mm.h> - -#include <asm/page.h> -#include <asm/pgtable.h> -#include <asm/tlbflush.h> - -/* - * 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/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 0fbcfe00dd8..51ecd512603 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -43,7 +43,7 @@ obj-$(CONFIG_SCx200) += scx200.o # Note: kbuild does not track this dependency due to usage of .incbin $(obj)/vsyscall.o: $(obj)/vsyscall-int80.so $(obj)/vsyscall-sysenter.so targets += $(foreach F,int80 sysenter,vsyscall-$F.o vsyscall-$F.so) -targets += vsyscall.lds +targets += vsyscall-note.o vsyscall.lds # The DSO images are built using a special linker script. quiet_cmd_syscall = SYSCALL $@ diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index 45641a87255..0ff65abcd56 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -1222,6 +1222,7 @@ static int suspend(int vetoable) save_processor_state(); err = set_system_power_state(APM_STATE_SUSPEND); + ignore_normal_resume = 1; restore_processor_state(); local_irq_disable(); @@ -1229,7 +1230,6 @@ static int suspend(int vetoable) spin_lock(&i8253_lock); reinit_timer(); set_time(); - ignore_normal_resume = 1; spin_unlock(&i8253_lock); write_sequnlock(&xtime_lock); diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 4f3cdef7579..962b6c4e32b 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -460,9 +460,9 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 <- *set ;; st8 [r2]=r14 // update current->blocked with new mask - cmpxchg4.acq r14=[r9],r18,ar.ccv // current->thread_info->flags <- r18 + cmpxchg4.acq r8=[r9],r18,ar.ccv // current->thread_info->flags <- r18 ;; - cmp.ne p6,p0=r17,r14 // update failed? + cmp.ne p6,p0=r17,r8 // update failed? (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c index febc091c2f0..f1aca7cffd1 100644 --- a/arch/ia64/kernel/module.c +++ b/arch/ia64/kernel/module.c @@ -825,14 +825,16 @@ apply_relocate_add (Elf64_Shdr *sechdrs, const char *strtab, unsigned int symind * XXX Should have an arch-hook for running this after final section * addresses have been selected... */ - /* See if gp can cover the entire core module: */ - uint64_t gp = (uint64_t) mod->module_core + MAX_LTOFF / 2; - if (mod->core_size >= MAX_LTOFF) + uint64_t gp; + if (mod->core_size > MAX_LTOFF) /* * This takes advantage of fact that SHF_ARCH_SMALL gets allocated * at the end of the module. */ - gp = (uint64_t) mod->module_core + mod->core_size - MAX_LTOFF / 2; + gp = mod->core_size - MAX_LTOFF / 2; + else + gp = mod->core_size / 2; + gp = (uint64_t) mod->module_core + ((gp + 7) & -8); mod->arch.gp = gp; DEBUGP("%s: placing gp at 0x%lx\n", __FUNCTION__, gp); } diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 08c8a5eb25a..575a8f657b3 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) { struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); + /* + * Prevent migrating this task while + * we're fiddling with the FPU state + */ + preempt_disable(); if (ia64_is_local_fpu_owner(task) && psr->mfh) { psr->mfh = 0; task->thread.flags |= IA64_THREAD_FPH_VALID; ia64_save_fpu(&task->thread.fph[0]); } + preempt_enable(); } /* diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index b7e6b4cb374..d14692e0920 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -720,7 +720,8 @@ cpu_init (void) ia64_set_kr(IA64_KR_PT_BASE, __pa(ia64_imva(empty_zero_page))); /* - * Initialize default control register to defer all speculative faults. The + * Initialize default control register to defer speculative faults except + * for those arising from TLB misses, which are not deferred. The * kernel MUST NOT depend on a particular setting of these bits (in other words, * the kernel must have recovery code for all speculative accesses). Turn on * dcr.lc as per recommendation by the architecture team. Most IA-32 apps diff --git a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c index e82ad78081b..1861173bd4f 100644 --- a/arch/ia64/kernel/traps.c +++ b/arch/ia64/kernel/traps.c @@ -111,6 +111,24 @@ ia64_bad_break (unsigned long break_num, struct pt_regs *regs) siginfo_t siginfo; int sig, code; + /* break.b always sets cr.iim to 0, which causes problems for + * debuggers. Get the real break number from the original instruction, + * but only for kernel code. User space break.b is left alone, to + * preserve the existing behaviour. All break codings have the same + * format, so there is no need to check the slot type. + */ + if (break_num == 0 && !user_mode(regs)) { + struct ia64_psr *ipsr = ia64_psr(regs); + unsigned long *bundle = (unsigned long *)regs->cr_iip; + unsigned long slot; + switch (ipsr->ri) { + case 0: slot = (bundle[0] >> 5); break; + case 1: slot = (bundle[0] >> 46) | (bundle[1] << 18); break; + default: slot = (bundle[1] >> 23); break; + } + break_num = ((slot >> 36 & 1) << 20) | (slot >> 6 & 0xfffff); + } + /* SIGILL, SIGFPE, SIGSEGV, and SIGBUS want these field initialized: */ siginfo.si_addr = (void __user *) (regs->cr_iip + ia64_psr(regs)->ri); siginfo.si_imm = break_num; @@ -202,13 +220,21 @@ disabled_fph_fault (struct pt_regs *regs) /* first, grant user-level access to fph partition: */ psr->dfh = 0; + + /* + * Make sure that no other task gets in on this processor + * while we're claiming the FPU + */ + preempt_disable(); #ifndef CONFIG_SMP { struct task_struct *fpu_owner = (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER); - if (ia64_is_local_fpu_owner(current)) + if (ia64_is_local_fpu_owner(current)) { + preempt_enable_no_resched(); return; + } if (fpu_owner) ia64_flush_fph(fpu_owner); @@ -226,6 +252,7 @@ disabled_fph_fault (struct pt_regs *regs) */ psr->mfh = 1; } + preempt_enable_no_resched(); } static inline int diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index 547785e3cba..4eb2f52b87a 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -305,8 +305,9 @@ setup_gate (void) struct page *page; /* - * Map the gate page twice: once read-only to export the ELF headers etc. and once - * execute-only page to enable privilege-promotion via "epc": + * Map the gate page twice: once read-only to export the ELF + * headers etc. and once execute-only page to enable + * privilege-promotion via "epc": */ page = virt_to_page(ia64_imva(__start_gate_section)); put_kernel_page(page, GATE_ADDR, PAGE_READONLY); @@ -315,6 +316,20 @@ setup_gate (void) put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE); #else put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE); + /* Fill in the holes (if any) with read-only zero pages: */ + { + unsigned long addr; + + for (addr = GATE_ADDR + PAGE_SIZE; + addr < GATE_ADDR + PERCPU_PAGE_SIZE; + addr += PAGE_SIZE) + { + put_kernel_page(ZERO_PAGE(0), addr, + PAGE_READONLY); + put_kernel_page(ZERO_PAGE(0), addr + PERCPU_PAGE_SIZE, + PAGE_READONLY); + } + } #endif ia64_patch_gate(); } diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index e64cb8175f7..44bfc7f318c 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/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/arch/m68k/configs/amiga_defconfig b/arch/m68k/configs/amiga_defconfig index 7dbf997ff20..5649fbae430 100644 --- a/arch/m68k/configs/amiga_defconfig +++ b/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:05:59 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:23 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -135,7 +137,6 @@ CONFIG_PARPORT_1284=y # CONFIG_AMIGA_FLOPPY=y CONFIG_AMIGA_Z2RAM=y -# CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y @@ -223,17 +224,12 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_PPA is not set @@ -244,7 +240,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set CONFIG_A3000_SCSI=y CONFIG_A2091_SCSI=y @@ -492,7 +487,6 @@ CONFIG_HYDRA=m CONFIG_ZORRO8390=m CONFIG_APNE=m # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set @@ -620,7 +614,6 @@ CONFIG_SERIO_SERPORT=m # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/apollo_defconfig b/arch/m68k/configs/apollo_defconfig index 505a2968e60..63024b0b7ac 100644 --- a/arch/m68k/configs/apollo_defconfig +++ b/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:00 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:27 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/atari_defconfig b/arch/m68k/configs/atari_defconfig index 617aa73c325..6433da2d2ce 100644 --- a/arch/m68k/configs/atari_defconfig +++ b/arch/m68k/configs/atari_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:18 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:32 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -531,7 +533,6 @@ CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/bvme6000_defconfig b/arch/m68k/configs/bvme6000_defconfig index b501db51d9e..da2a23a2146 100644 --- a/arch/m68k/configs/bvme6000_defconfig +++ b/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:19 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:37 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -496,7 +498,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/hp300_defconfig b/arch/m68k/configs/hp300_defconfig index 2bf6cef4f2b..51251883adf 100644 --- a/arch/m68k/configs/hp300_defconfig +++ b/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:21 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:41 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mac_defconfig b/arch/m68k/configs/mac_defconfig index 7074f856820..15b80abfe94 100644 --- a/arch/m68k/configs/mac_defconfig +++ b/arch/m68k/configs/mac_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:24 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:45 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -540,7 +542,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mvme147_defconfig b/arch/m68k/configs/mvme147_defconfig index 61f09bc4846..f0d5534f683 100644 --- a/arch/m68k/configs/mvme147_defconfig +++ b/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:28 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:50 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -498,7 +500,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/mvme16x_defconfig b/arch/m68k/configs/mvme16x_defconfig index 69c01004ec4..1d5c46ff3c8 100644 --- a/arch/m68k/configs/mvme16x_defconfig +++ b/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:31 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:53 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/q40_defconfig b/arch/m68k/configs/q40_defconfig index 550ec26006c..856238634d4 100644 --- a/arch/m68k/configs/q40_defconfig +++ b/arch/m68k/configs/q40_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:34 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:58 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -125,7 +127,6 @@ CONFIG_FW_LOADER=m # Block devices # # CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_CRYPTOLOOP=m @@ -210,17 +211,12 @@ CONFIG_SCSI_CONSTANTS=y # # SCSI low-level drivers # -# CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AIC7XXX_OLD is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set # CONFIG_SCSI_NCR53C406A is not set @@ -229,7 +225,6 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_QLOGIC_FAS is not set # CONFIG_SCSI_SYM53C416 is not set # CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set # @@ -466,7 +461,6 @@ CONFIG_EQUALIZER=m CONFIG_NET_ETHERNET=y CONFIG_MII=m # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set # CONFIG_AT1700 is not set @@ -570,7 +564,6 @@ CONFIG_SERIO_Q40KBD=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/sun3_defconfig b/arch/m68k/configs/sun3_defconfig index 5b5a619645a..af903b5c570 100644 --- a/arch/m68k/configs/sun3_defconfig +++ b/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:37 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:35:02 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y # # CONFIG_SCSI_SATA is not set # CONFIG_SCSI_DEBUG is not set -CONFIG_SUN3_SCSI=y # # Multi-device support (RAID and LVM) @@ -487,7 +488,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/configs/sun3x_defconfig b/arch/m68k/configs/sun3x_defconfig index 704e42344cb..997143b7928 100644 --- a/arch/m68k/configs/sun3x_defconfig +++ b/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:06:40 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:35:06 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -35,6 +35,8 @@ CONFIG_KOBJECT_UEVENT=y CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -497,7 +499,6 @@ CONFIG_SERIO_SERPORT=m CONFIG_SERIO_LIBPS2=m # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig index 5b2296ecba8..7d935e48a9a 100644 --- a/arch/m68k/defconfig +++ b/arch/m68k/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc2-m68k -# Tue Apr 5 14:05:31 2005 +# Linux kernel version: 2.6.12-rc6-m68k +# Tue Jun 7 20:34:17 2005 # CONFIG_M68K=y CONFIG_MMU=y @@ -33,6 +33,8 @@ CONFIG_KOBJECT_UEVENT=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -355,7 +357,6 @@ CONFIG_SERIO_SERPORT=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set # CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y # # Character devices diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 2b6c9d32b7a..c4a33f265dc 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c @@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void); */ void default_idle(void) { - while(1) { - if (need_resched()) - __asm__("stop #0x2000" : : : "cc"); - schedule(); + local_irq_disable(); + while (!need_resched()) { + /* This stop will re-enable interrupts */ + __asm__("stop #0x2000" : : : "cc"); + local_irq_disable(); } + local_irq_enable(); } void (*idle)(void) = default_idle; @@ -63,7 +65,12 @@ void (*idle)(void) = default_idle; void cpu_idle(void) { /* endless idle loop with no priority at all */ - idle(); + while (1) { + idle(); + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } } void machine_restart(char * __unused) diff --git a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c index 8aa5e8c6900..d44b7dc5390 100644 --- a/arch/ppc/kernel/cputable.c +++ b/arch/ppc/kernel/cputable.c @@ -838,6 +838,17 @@ 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/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index e4f1615ec13..7329ef177a1 100644 --- a/arch/ppc/kernel/misc.S +++ b/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_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_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_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_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_IFSET(PPC_FEATURE_UNIFIED_CACHE) _GLOBAL(__flush_dcache_icache_phys) BEGIN_FTR_SECTION blr /* for 601, do nothing */ -END_FTR_SECTION_IFSET(PPC_FEATURE_UNIFIED_CACHE) +END_FTR_SECTION_IFCLR(CPU_FTR_SPLIT_ID_CACHE) mfmsr r10 rlwinm r0,r10,0,28,26 /* clear DR */ mtmsr r0 diff --git a/arch/ppc/platforms/pmac_cpufreq.c b/arch/ppc/platforms/pmac_cpufreq.c index 937f46df711..5fdd4f607a4 100644 --- a/arch/ppc/platforms/pmac_cpufreq.c +++ b/arch/ppc/platforms/pmac_cpufreq.c @@ -83,7 +83,7 @@ static u32 frequency_gpio; static u32 slew_done_gpio; static int no_schedule; static int has_cpu_l2lve; - +static int is_pmu_based; /* There are only two frequency states for each processor. Values * are in kHz for the time being. @@ -463,7 +463,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state) */ no_schedule = 1; sleep_freq = cur_freq; - if (cur_freq == low_freq) + if (cur_freq == low_freq && !is_pmu_based) do_set_cpu_speed(CPUFREQ_HIGH, 0); return 0; } @@ -588,6 +588,7 @@ static int __pmac pmac_cpufreq_init_MacRISC3(struct device_node *cpunode) return 1; hi_freq = (*value) / 1000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; return 0; } @@ -692,6 +693,7 @@ static int __init pmac_cpufreq_setup(void) hi_freq = cur_freq; low_freq = 400000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; } /* Else check for TiPb 400 & 500 */ else if (machine_is_compatible("PowerBook3,2")) { @@ -703,6 +705,7 @@ static int __init pmac_cpufreq_setup(void) hi_freq = cur_freq; low_freq = 300000; set_speed_proc = pmu_set_cpu_speed; + is_pmu_based = 1; } /* Else check for 750FX */ else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000) diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 7b607d1862c..d5218b15824 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -11,6 +11,23 @@ #include <linux/string.h> #include <linux/ctype.h> +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; @@ -352,7 +369,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, long num, int base, int size, int precision, int type) +static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if (num < 0) { + if ((signed long long)num < 0) { sign = '-'; - num = -num; + num = - (signed long long)num; size--; } else if (type & PLUS) { sign = '+'; @@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in if (num == 0) tmp[i++]='0'; else while (num != 0) { - tmp[i++] = digits[num % base]; - num /= base; + tmp[i++] = digits[do_div(num, base)]; } if (i > precision) precision = i; @@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...); int vsprintf(char *buf, const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; char * str; const char *s; diff --git a/arch/ppc64/configs/g5_defconfig b/arch/ppc64/configs/g5_defconfig index 0f90df0b3f9..1eb33398648 100644 --- a/arch/ppc64/configs/g5_defconfig +++ b/arch/ppc64/configs/g5_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11 -# Thu Mar 10 16:47:04 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 16:59:20 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -31,19 +32,20 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 @@ -87,6 +89,8 @@ CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set CONFIG_GENERIC_HARDIRQS=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -97,6 +101,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # CONFIG_HOTPLUG_CPU is not set # @@ -105,10 +110,6 @@ CONFIG_PCI_NAMES=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # PCI Hotplug Support # # CONFIG_HOTPLUG_PCI is not set @@ -293,7 +294,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -301,7 +301,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -310,6 +309,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -332,6 +332,7 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set # # Fusion MPT device support @@ -394,7 +395,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -564,6 +564,8 @@ CONFIG_E1000=y # CONFIG_R8169 is not set # CONFIG_SK98LIN is not set CONFIG_TIGON3=m +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -631,18 +633,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y @@ -660,6 +650,16 @@ CONFIG_INPUT_MOUSE=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -676,6 +676,7 @@ CONFIG_HW_CONSOLE=y # Non-8250 serial port support # # CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -698,9 +699,12 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +CONFIG_AGP=m +CONFIG_AGP_UNINORTH=m # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set # # TPM devices @@ -730,12 +734,11 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set CONFIG_I2C_KEYWEST=y -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set -# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set # CONFIG_SCx200_ACB is not set @@ -772,6 +775,7 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set @@ -785,6 +789,7 @@ CONFIG_I2C_KEYWEST=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -817,6 +822,11 @@ CONFIG_I2C_KEYWEST=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -830,6 +840,7 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set CONFIG_FB_RIVA=y # CONFIG_FB_RIVA_I2C is not set # CONFIG_FB_RIVA_DEBUG is not set @@ -847,6 +858,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -880,6 +892,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -890,8 +904,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -917,7 +929,6 @@ CONFIG_USB_PRINTER=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_RW_DETECT=y CONFIG_USB_STORAGE_DATAFAB=y CONFIG_USB_STORAGE_FREECOM=y CONFIG_USB_STORAGE_ISD200=y @@ -1004,8 +1015,10 @@ CONFIG_USB_MON=y # CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +# CONFIG_USB_SERIAL_CP2101 is not set CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m @@ -1034,6 +1047,7 @@ CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m +# CONFIG_USB_SERIAL_HP4X is not set CONFIG_USB_SERIAL_SAFE=m CONFIG_USB_SERIAL_SAFE_PADDED=y CONFIG_USB_SERIAL_TI=m @@ -1270,11 +1284,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y -# CONFIG_PRINTK_TIME is not set +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set diff --git a/arch/ppc64/configs/iSeries_defconfig b/arch/ppc64/configs/iSeries_defconfig index a39e9d2e25d..f6a2b99afd6 100644 --- a/arch/ppc64/configs/iSeries_defconfig +++ b/arch/ppc64/configs/iSeries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:52 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:01:28 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -79,6 +85,8 @@ CONFIG_NR_CPUS=32 CONFIG_GENERIC_HARDIRQS=y CONFIG_MSCHUNKS=y CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -89,6 +97,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -96,10 +105,6 @@ CONFIG_PCI_NAMES=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # PCI Hotplug Support # # CONFIG_HOTPLUG_PCI is not set @@ -210,7 +215,6 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -219,7 +223,6 @@ CONFIG_SCSI_IBMVSCSI=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -228,6 +231,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -250,6 +254,7 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +# CONFIG_DM_MULTIPATH is not set # # Fusion MPT device support @@ -280,7 +285,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -445,7 +449,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -471,6 +474,7 @@ CONFIG_E1000=m # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -539,14 +543,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - -# # Input Device Drivers # # CONFIG_INPUT_KEYBOARD is not set @@ -556,6 +552,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # # CONFIG_SERIAL_NONSTANDARD is not set @@ -570,6 +572,7 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_SERIAL_CORE=m CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -592,9 +595,16 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -633,13 +643,9 @@ CONFIG_MAX_RAW_DEVS=256 # # USB support # -# CONFIG_USB is not set CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information -# +# CONFIG_USB is not set # # USB Gadget Support @@ -848,10 +854,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -881,6 +890,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m diff --git a/arch/ppc64/configs/maple_defconfig b/arch/ppc64/configs/maple_defconfig index cf527501915..8051b0f47b6 100644 --- a/arch/ppc64/configs/maple_defconfig +++ b/arch/ppc64/configs/maple_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:53 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:12:48 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_AUDIT is not set # CONFIG_HOTPLUG is not set CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -84,6 +89,8 @@ CONFIG_NR_CPUS=2 # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set CONFIG_GENERIC_HARDIRQS=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -94,6 +101,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCCARD (PCMCIA/CardBus) support @@ -101,10 +109,6 @@ CONFIG_PCI_NAMES=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # PCI Hotplug Support # # CONFIG_HOTPLUG_PCI is not set @@ -261,7 +265,6 @@ CONFIG_NET=y # CONFIG_PACKET=y CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y @@ -376,6 +379,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -432,14 +437,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=1200 # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -# CONFIG_SERIO is not set -# CONFIG_SERIO_I8042 is not set - -# # Input Device Drivers # # CONFIG_INPUT_KEYBOARD is not set @@ -449,6 +446,12 @@ CONFIG_SOUND_GAMEPORT=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -469,7 +472,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -492,8 +495,15 @@ CONFIG_LEGACY_PTY_COUNT=256 # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set # CONFIG_RAW_DRIVER is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -518,8 +528,8 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_AMD8111=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_PROSAVAGE is not set @@ -545,7 +555,9 @@ CONFIG_I2C_AMD8111=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -556,9 +568,11 @@ CONFIG_I2C_AMD8111=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -568,6 +582,7 @@ CONFIG_I2C_AMD8111=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -615,6 +630,8 @@ CONFIG_DUMMY_CONSOLE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -625,8 +642,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -635,6 +650,8 @@ CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_SPLIT_ISO=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -688,6 +705,7 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_PEGASUS=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -699,8 +717,10 @@ CONFIG_USB_PEGASUS=y CONFIG_USB_SERIAL=y # CONFIG_USB_SERIAL_CONSOLE is not set CONFIG_USB_SERIAL_GENERIC=y +# CONFIG_USB_SERIAL_AIRPRIME is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_CP2101 is not set CONFIG_USB_SERIAL_CYPRESS_M8=m # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set @@ -729,6 +749,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set # CONFIG_USB_SERIAL_PL2303 is not set +# CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set CONFIG_USB_SERIAL_TI=m # CONFIG_USB_SERIAL_CYBERJACK is not set @@ -750,6 +771,7 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -936,10 +958,13 @@ CONFIG_NLS_UTF8=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set CONFIG_DEBUG_SLAB=y +# CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -971,6 +996,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set diff --git a/arch/ppc64/configs/pSeries_defconfig b/arch/ppc64/configs/pSeries_defconfig index 4fecf237d5c..3eb5ef25d3a 100644 --- a/arch/ppc64/configs/pSeries_defconfig +++ b/arch/ppc64/configs/pSeries_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:54 2005 +# Linux kernel version: 2.6.12-rc6 +# Tue Jun 14 17:13:47 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,29 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CPUSETS=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -89,9 +95,12 @@ CONFIG_SCHED_SMT=y CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y +CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -102,6 +111,7 @@ CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set CONFIG_HOTPLUG_CPU=y # @@ -110,10 +120,6 @@ CONFIG_HOTPLUG_CPU=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # PCI Hotplug Support # CONFIG_HOTPLUG_PCI=m @@ -147,11 +153,10 @@ CONFIG_FW_LOADER=y # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_1284 is not set # @@ -293,7 +298,6 @@ CONFIG_SCSI_ISCSI_ATTRS=m # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -310,7 +314,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -319,6 +322,7 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -341,6 +345,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # # Fusion MPT device support @@ -371,7 +377,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -539,7 +544,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -565,6 +569,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -636,20 +642,6 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y @@ -669,6 +661,18 @@ CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_UINPUT is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -689,8 +693,8 @@ CONFIG_SERIAL_8250_NR_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_SERIAL_PMACZILOG is not set CONFIG_SERIAL_ICOM=m +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -718,9 +722,16 @@ CONFIG_HVCS=m # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=1024 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -745,8 +756,8 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -773,7 +784,9 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -784,9 +797,11 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -796,6 +811,7 @@ CONFIG_I2C_ALGOBIT=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -828,8 +844,13 @@ CONFIG_I2C_ALGOBIT=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y -# CONFIG_FB_TILEBLITTING is not set +CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set @@ -838,6 +859,7 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y @@ -858,6 +880,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -891,6 +914,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -901,8 +926,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -911,6 +934,8 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -926,12 +951,11 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -975,6 +999,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1000,6 +1025,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -1208,10 +1234,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -1243,6 +1272,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m diff --git a/arch/ppc64/defconfig b/arch/ppc64/defconfig index 537b1cc82ea..2f31bf3046f 100644 --- a/arch/ppc64/defconfig +++ b/arch/ppc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.11-rc3-bk6 -# Wed Feb 9 23:34:51 2005 +# Linux kernel version: 2.6.12-rc5-git9 +# Sun Jun 5 09:26:47 2005 # CONFIG_64BIT=y CONFIG_MMU=y @@ -11,7 +11,7 @@ CONFIG_GENERIC_ISA_DMA=y CONFIG_HAVE_DEC_LOCK=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y -CONFIG_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_FORCE_MAX_ZONEORDER=13 # @@ -20,6 +20,7 @@ CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_EXPERIMENTAL=y CONFIG_CLEAN_COMPILE=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -30,24 +31,28 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_AUDIT is not set CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y +CONFIG_CPUSETS=y # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -91,9 +96,12 @@ CONFIG_DISCONTIGMEM=y CONFIG_EEH=y CONFIG_GENERIC_HARDIRQS=y CONFIG_PPC_RTAS=y +CONFIG_RTAS_PROC=y CONFIG_RTAS_FLASH=m CONFIG_SCANLOG=m CONFIG_LPARCFG=y +CONFIG_SECCOMP=y +CONFIG_ISA_DMA_API=y # # General setup @@ -104,6 +112,7 @@ CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m # CONFIG_PCI_LEGACY_PROC is not set # CONFIG_PCI_NAMES is not set +# CONFIG_PCI_DEBUG is not set CONFIG_HOTPLUG_CPU=y # @@ -112,10 +121,6 @@ CONFIG_HOTPLUG_CPU=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # PCI Hotplug Support # CONFIG_HOTPLUG_PCI=m @@ -149,11 +154,10 @@ CONFIG_FW_LOADER=y # CONFIG_PARPORT=m CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_1284 is not set # @@ -301,6 +305,7 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_ATA_PIIX is not set # CONFIG_SCSI_SATA_NV is not set # CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_QSTOR is not set # CONFIG_SCSI_SATA_SX4 is not set # CONFIG_SCSI_SATA_SIL is not set # CONFIG_SCSI_SATA_SIS is not set @@ -310,7 +315,6 @@ CONFIG_SCSI_SATA_SVW=y # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set @@ -327,7 +331,6 @@ CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_IPR=y CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -# CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set CONFIG_SCSI_QLA2XXX=y @@ -336,6 +339,7 @@ CONFIG_SCSI_QLA22XX=m CONFIG_SCSI_QLA2300=m CONFIG_SCSI_QLA2322=m CONFIG_SCSI_QLA6312=m +CONFIG_SCSI_LPFC=m # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set CONFIG_SCSI_DEBUG=m @@ -358,6 +362,8 @@ CONFIG_DM_CRYPT=m CONFIG_DM_SNAPSHOT=m CONFIG_DM_MIRROR=m CONFIG_DM_ZERO=m +CONFIG_DM_MULTIPATH=m +CONFIG_DM_MULTIPATH_EMC=m # # Fusion MPT device support @@ -405,6 +411,7 @@ CONFIG_IEEE1394_AMDTP=m # CONFIG_ADB=y CONFIG_ADB_PMU=y +CONFIG_PMAC_SMU=y # CONFIG_PMAC_PBOOK is not set # CONFIG_PMAC_BACKLIGHT is not set # CONFIG_INPUT_ADBHID is not set @@ -420,7 +427,6 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y CONFIG_NET_KEY=m CONFIG_INET=y @@ -588,7 +594,6 @@ CONFIG_PCNET32=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -614,6 +619,8 @@ CONFIG_E1000=y # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set +# CONFIG_MV643XX_ETH is not set # # Ethernet (10000 Mbit) @@ -683,20 +690,6 @@ CONFIG_INPUT_EVDEV=m # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -CONFIG_SERIO_I8042=y -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PARKBD is not set -# CONFIG_SERIO_PCIPS2 is not set -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y @@ -716,6 +709,18 @@ CONFIG_INPUT_PCSPKR=m # CONFIG_INPUT_UINPUT is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_I8042=y +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PARKBD is not set +# CONFIG_SERIO_PCIPS2 is not set +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -738,6 +743,7 @@ CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_SERIAL_PMACZILOG is not set CONFIG_SERIAL_ICOM=m +CONFIG_SERIAL_JSM=m CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -766,9 +772,16 @@ CONFIG_HVCS=m # # Ftape, the floppy tape device driver # +# CONFIG_AGP is not set # CONFIG_DRM is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=256 +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -793,9 +806,9 @@ CONFIG_I2C_ALGOBIT=y CONFIG_I2C_AMD8111=y # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set CONFIG_I2C_KEYWEST=y -# CONFIG_I2C_MPC is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -822,7 +835,9 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -833,9 +848,11 @@ CONFIG_I2C_KEYWEST=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set @@ -845,6 +862,7 @@ CONFIG_I2C_KEYWEST=y # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set # CONFIG_SENSORS_PCF8591 is not set @@ -877,6 +895,11 @@ CONFIG_I2C_KEYWEST=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +CONFIG_FB_MACMODES=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # CONFIG_FB_CIRRUS is not set @@ -890,9 +913,8 @@ CONFIG_FB_OF=y # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set -CONFIG_FB_RIVA=y -CONFIG_FB_RIVA_I2C=y -# CONFIG_FB_RIVA_DEBUG is not set +# CONFIG_FB_NVIDIA is not set +# CONFIG_FB_RIVA is not set CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y @@ -913,6 +935,7 @@ CONFIG_FB_RADEON_I2C=y # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -946,6 +969,8 @@ CONFIG_LCD_DEVICE=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -956,8 +981,6 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -966,6 +989,8 @@ CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -981,12 +1006,11 @@ CONFIG_USB_OHCI_HCD=y # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_RW_DETECT=y # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -1030,6 +1054,7 @@ CONFIG_USB_HIDDEV=y CONFIG_USB_PEGASUS=y # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +# CONFIG_USB_MON is not set # # USB port drivers @@ -1055,6 +1080,7 @@ CONFIG_USB_PEGASUS=y # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_TEST is not set # @@ -1276,10 +1302,13 @@ CONFIG_OPROFILE=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set +# CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set @@ -1311,6 +1340,7 @@ CONFIG_CRYPTO_SHA1=m CONFIG_CRYPTO_SHA256=m CONFIG_CRYPTO_SHA512=m CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=m diff --git a/arch/ppc64/kernel/entry.S b/arch/ppc64/kernel/entry.S index d3604056e1a..b61572eb2a7 100644 --- a/arch/ppc64/kernel/entry.S +++ b/arch/ppc64/kernel/entry.S @@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) REST_8GPRS(14, r1) REST_10GPRS(22, r1) -#ifdef CONFIG_PPC_ISERIES - clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */ - ld r7,TI_FLAGS(r7) /* Get run light flag */ - mfspr r9,CTRLF - srdi r7,r7,TIF_RUN_LIGHT - insrdi r9,r7,1,63 /* Insert run light into CTRL */ - mtspr CTRLT,r9 -#endif - /* convert old thread to its task_struct for return value */ addi r3,r3,-THREAD ld r7,_NIP(r1) /* Return to _switch caller in new task */ diff --git a/arch/ppc64/kernel/head.S b/arch/ppc64/kernel/head.S index 92a744c31ab..346dbf606b5 100644 --- a/arch/ppc64/kernel/head.S +++ b/arch/ppc64/kernel/head.S @@ -626,10 +626,10 @@ system_reset_iSeries: lhz r24,PACAPACAINDEX(r13) /* Get processor # */ cmpwi 0,r24,0 /* Are we processor 0? */ beq .__start_initialization_iSeries /* Start up the first processor */ - mfspr r4,CTRLF - li r5,RUNLATCH /* Turn off the run light */ + mfspr r4,SPRN_CTRLF + li r5,CTRL_RUNLATCH /* Turn off the run light */ andc r4,r4,r5 - mtspr CTRLT,r4 + mtspr SPRN_CTRLT,r4 1: HMT_LOW @@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary) mfspr r4, HID0 ori r4, r4, 0x1 mtspr HID0, r4 - mfspr r4, CTRLF + mfspr r4, SPRN_CTRLF oris r4, r4, 0x40 - mtspr CTRLT, r4 + mtspr SPRN_CTRLT, r4 blr #endif diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index da20120f226..6d06eb550a3 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -852,6 +852,28 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); +static int set_spread_lpevents(char *str) +{ + unsigned long i; + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + for (i = 1; i < val; ++i) + paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; + + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } + + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + void __init iSeries_early_setup(void) { iSeries_fixup_klimit(); diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 6abc621d3ba..f24ce2b8720 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -75,13 +75,9 @@ static int iSeries_idle(void) { struct paca_struct *lpaca; long oldval; - unsigned long CTRL; /* ensure iSeries run light will be out when idle */ - clear_thread_flag(TIF_RUN_LIGHT); - CTRL = mfspr(CTRLF); - CTRL &= ~RUNLATCH; - mtspr(CTRLT, CTRL); + ppc64_runlatch_off(); lpaca = get_paca(); @@ -111,7 +107,9 @@ static int iSeries_idle(void) } } + ppc64_runlatch_on(); schedule(); + ppc64_runlatch_off(); } return 0; diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 103daaf7357..e950a2058a1 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -45,12 +45,17 @@ static struct pt_regs jprobe_saved_regs; int arch_prepare_kprobe(struct kprobe *p) { + int ret = 0; kprobe_opcode_t insn = *p->addr; - if (IS_MTMSRD(insn) || IS_RFID(insn)) - /* cannot put bp on RFID/MTMSRD */ - return 1; - return 0; + if ((unsigned long)p->addr & 0x03) { + printk("Attempt to register kprobe at an unaligned address\n"); + ret = -EINVAL; + } else if (IS_MTMSRD(insn) || IS_RFID(insn)) { + printk("Cannot register a kprobe on rfid or mtmsrd\n"); + ret = -EINVAL; + } + return ret; } void arch_copy_kprobe(struct kprobe *p) @@ -172,8 +177,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) ret = emulate_step(regs, p->ainsn.insn[0]); if (ret == 0) regs->nip = (unsigned long)p->addr + 4; - - regs->msr &= ~MSR_SE; } static inline int post_kprobe_handler(struct pt_regs *regs) @@ -210,6 +213,7 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) if (kprobe_status & KPROBE_HIT_SS) { resume_execution(current_kprobe, regs); + regs->msr &= ~MSR_SE; regs->msr |= kprobe_saved_msr; unlock_kprobes(); @@ -233,8 +237,6 @@ 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/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index b944717c1db..e3c73b3425d 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S @@ -792,7 +792,7 @@ _GLOBAL(sys_call_table32) .llong .compat_sys_newstat .llong .compat_sys_newlstat .llong .compat_sys_newfstat - .llong .sys_uname + .llong .sys32_uname .llong .sys_ni_syscall /* 110 old iopl syscall */ .llong .sys_vhangup .llong .sys_ni_syscall /* old idle syscall */ diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c index 8b068612273..cdfecbeb331 100644 --- a/arch/ppc64/kernel/process.c +++ b/arch/ppc64/kernel/process.c @@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp, childregs->gpr[1] = sp + sizeof(struct pt_regs); p->thread.regs = NULL; /* no user register state */ clear_ti_thread_flag(p->thread_info, TIF_32BIT); -#ifdef CONFIG_PPC_ISERIES - set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT); -#endif } else { childregs->gpr[1] = usp; p->thread.regs = childregs; diff --git a/arch/ppc64/kernel/prom_init.c b/arch/ppc64/kernel/prom_init.c index 3de950de367..b7683abfbe6 100644 --- a/arch/ppc64/kernel/prom_init.c +++ b/arch/ppc64/kernel/prom_init.c @@ -211,13 +211,23 @@ struct { */ #define ADDR(x) (u32) ((unsigned long)(x) - offset) +/* + * Error results ... some OF calls will return "-1" on error, some + * will return 0, some will return either. To simplify, here are + * macros to use with any ihandle or phandle return value to check if + * it is valid + */ + +#define PROM_ERROR (-1u) +#define PHANDLE_VALID(p) ((p) != 0 && (p) != PROM_ERROR) +#define IHANDLE_VALID(i) ((i) != 0 && (i) != PROM_ERROR) + + /* This is the one and *ONLY* place where we actually call open * firmware from, since we need to make sure we're running in 32b * mode when we do. We switch back to 64b mode upon return. */ -#define PROM_ERROR (-1) - static int __init call_prom(const char *service, int nargs, int nret, ...) { int i; @@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void) { unsigned long offset = reloc_offset(); ihandle elfloader; - int ret; elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader")); if (elfloader == 0) { prom_printf("couldn't open /packages/elf-loader\n"); return; } - ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"), + call_prom("call-method", 3, 1, ADDR("process-elf-header"), elfloader, ADDR(&fake_elf)); call_prom("close", 1, 0, elfloader); } @@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) base = _ALIGN_UP(base + 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if ((int)addr != PROM_ERROR) + if (addr != PROM_ERROR) break; addr = 0; if (align == 0) @@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align, for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align)) { prom_debug(" trying: 0x%x\n\r", base); addr = (unsigned long)prom_claim(base, size, 0); - if ((int)addr != PROM_ERROR) + if (addr != PROM_ERROR) break; addr = 0; } @@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void) { unsigned long offset = reloc_offset(); struct prom_t *_prom = PTRRELOC(&prom); - phandle prom_rtas, rtas_node; + phandle rtas_node; + ihandle rtas_inst; u32 base, entry = 0; u32 size = 0; prom_debug("prom_instantiate_rtas: start...\n"); - prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas")); - prom_debug("prom_rtas: %x\n", prom_rtas); - if (prom_rtas == (phandle) -1) + rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas")); + prom_debug("rtas_node: %x\n", rtas_node); + if (!PHANDLE_VALID(rtas_node)) return; - prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size)); + prom_getprop(rtas_node, "rtas-size", &size, sizeof(size)); if (size == 0) return; @@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void) prom_printf("RTAS allocation failed !\n"); return; } - prom_printf("instantiating rtas at 0x%x", base); - rtas_node = call_prom("open", 1, 1, ADDR("/rtas")); - prom_printf("..."); + rtas_inst = call_prom("open", 1, 1, ADDR("/rtas")); + if (!IHANDLE_VALID(rtas_inst)) { + prom_printf("opening rtas package failed"); + return; + } + + prom_printf("instantiating rtas at 0x%x ...", base); if (call_prom("call-method", 3, 2, ADDR("instantiate-rtas"), - rtas_node, base) != PROM_ERROR) { + rtas_inst, base) != PROM_ERROR) { entry = (long)_prom->args.rets[1]; } if (entry == 0) { @@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void) reserve_mem(base, size); - prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base)); - prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry)); + prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base)); + prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry)); prom_debug("rtas base = 0x%x\n", base); prom_debug("rtas entry = 0x%x\n", entry); @@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void) prom_printf("opening PHB %s", path); phb_node = call_prom("open", 1, 1, path); - if ( (long)phb_node <= 0) + if (phb_node == 0) prom_printf("... failed\n"); else prom_printf("... done\n"); @@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp) /* get a handle for the stdout device */ _prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen")); - if ((long)_prom->chosen <= 0) + if (!PHANDLE_VALID(_prom->chosen)) prom_panic("cannot find chosen"); /* msg won't be printed :( */ /* get device tree root */ _prom->root = call_prom("finddevice", 1, 1, ADDR("/")); - if ((long)_prom->root <= 0) + if (!PHANDLE_VALID(_prom->root)) prom_panic("cannot find device tree root"); /* msg won't be printed :( */ } @@ -1356,9 +1370,8 @@ 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 (rtas != (phandle) -1) { - unsigned long x; - x = prom_getproplen(rtas, "ibm,hypertas-functions"); + if (PHANDLE_VALID(rtas)) { + int x = prom_getproplen(rtas, "ibm,hypertas-functions"); if (x != PROM_ERROR) { prom_printf("Hypertas detected, assuming LPAR !\n"); return PLATFORM_PSERIES_LPAR; @@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void) * leave some room at the end of the path for appending extra * arguments */ - if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0) + if (call_prom("package-to-path", 3, 1, node, path, + PROM_SCRATCH_SIZE-10) == PROM_ERROR) continue; prom_printf("found display : %s, opening ... ", path); ih = call_prom("open", 1, 1, path); - if (ih == (ihandle)0 || ih == (ihandle)-1) { + if (ih == 0) { prom_printf("failed\n"); continue; } @@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str) return 0; } +/* + * The Open Firmware 1275 specification states properties must be 31 bytes or + * less, however not all firmwares obey this. Make it 64 bytes to be safe. + */ +#define MAX_PROPERTY_NAME 64 + static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, unsigned long *mem_end) { @@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, /* get and store all property names */ prev_name = RELOC(""); for (;;) { - - /* 32 is max len of name including nul. */ - namep = make_room(mem_start, mem_end, 32, 1); - if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) { + int rc; + + /* 64 is max len of name including nul. */ + namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1); + rc = call_prom("nextprop", 3, 1, node, prev_name, namep); + if (rc != 1) { /* No more nodes: unwind alloc */ *mem_start = (unsigned long)namep; break; @@ -1555,12 +1577,6 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start, } } -/* - * The Open Firmware 1275 specification states properties must be 31 bytes or - * less, however not all firmwares obey this. Make it 64 bytes to be safe. - */ -#define MAX_PROPERTY_NAME 64 - static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, unsigned long *mem_end) { @@ -1607,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, prev_name = RELOC(""); sstart = (char *)RELOC(dt_string_start); for (;;) { - if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0) + int rc; + + rc = call_prom("nextprop", 3, 1, node, prev_name, pname); + if (rc != 1) break; /* find string offset */ @@ -1623,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start, l = call_prom("getproplen", 2, 1, node, pname); /* sanity checks */ - if (l < 0) + if (l == PROM_ERROR) continue; if (l > MAX_PROPERTY_LENGTH) { prom_printf("WARNING: ignoring large property "); @@ -1771,17 +1790,18 @@ static void __init fixup_device_tree(void) /* Some G5s have a missing interrupt definition, fix it up here */ u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000")); - if ((long)u3 <= 0) + if (!PHANDLE_VALID(u3)) return; i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000")); - if ((long)i2c <= 0) + if (!PHANDLE_VALID(i2c)) return; mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000")); - if ((long)mpic <= 0) + if (!PHANDLE_VALID(mpic)) return; /* check if proper rev of u3 */ - if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) <= 0) + if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev)) + == PROM_ERROR) return; if (u3_rev != 0x35) return; diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 21c57f539c2..dce198d3932 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c @@ -103,11 +103,6 @@ extern void unflatten_device_tree(void); extern void smp_release_cpus(void); -unsigned long decr_overclock = 1; -unsigned long decr_overclock_proc0 = 1; -unsigned long decr_overclock_set = 0; -unsigned long decr_overclock_proc0_set = 0; - int have_of = 1; int boot_cpuid = 0; int boot_cpuid_phys = 0; @@ -1120,64 +1115,15 @@ void ppc64_dump_msg(unsigned int src, const char *msg) printk("[dump]%04x %s\n", src, msg); } -int set_spread_lpevents( char * str ) -{ - /* The parameter is the number of processors to share in processing lp events */ - unsigned long i; - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val > 0 ) && ( val <= NR_CPUS ) ) { - for ( i=1; i<val; ++i ) - paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; - printk("lpevent processing spread over %ld processors\n", val); - } - else - printk("invalid spreaqd_lpevents %ld\n", val); - return 1; -} - /* This should only be called on processor 0 during calibrate decr */ void setup_default_decr(void) { struct paca_struct *lpaca = get_paca(); - if ( decr_overclock_set && !decr_overclock_proc0_set ) - decr_overclock_proc0 = decr_overclock; - - lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0; + lpaca->default_decr = tb_ticks_per_jiffy; lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy; } -int set_decr_overclock_proc0( char * str ) -{ - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val >= 1 ) && ( val <= 48 ) ) { - decr_overclock_proc0_set = 1; - decr_overclock_proc0 = val; - printk("proc 0 decrementer overclock factor of %ld\n", val); - } - else - printk("invalid proc 0 decrementer overclock factor of %ld\n", val); - return 1; -} - -int set_decr_overclock( char * str ) -{ - unsigned long val = simple_strtoul( str, NULL, 0 ); - if ( ( val >= 1 ) && ( val <= 48 ) ) { - decr_overclock_set = 1; - decr_overclock = val; - printk("decrementer overclock factor of %ld\n", val); - } - else - printk("invalid decrementer overclock factor of %ld\n", val); - return 1; - -} - -__setup("spread_lpevents=", set_spread_lpevents ); -__setup("decr_overclock_proc0=", set_decr_overclock_proc0 ); -__setup("decr_overclock=", set_decr_overclock ); - #ifndef CONFIG_PPC_ISERIES /* * This function can be used by platforms to "find" legacy serial ports. diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c index 3b906cd9403..9ef5d36d6b2 100644 --- a/arch/ppc64/kernel/smp.c +++ b/arch/ppc64/kernel/smp.c @@ -334,7 +334,6 @@ void smp_call_function_interrupt(void) } } -extern unsigned long decr_overclock; extern struct gettimeofday_struct do_gtod; struct thread_info *current_set[NR_CPUS]; @@ -491,7 +490,7 @@ int __devinit __cpu_up(unsigned int cpu) if (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)) return -EINVAL; - paca[cpu].default_decr = tb_ticks_per_jiffy / decr_overclock; + paca[cpu].default_decr = tb_ticks_per_jiffy; if (!cpu_has_feature(CPU_FTR_SLB)) { void *tmp; diff --git a/arch/ppc64/kernel/sys_ppc32.c b/arch/ppc64/kernel/sys_ppc32.c index 7cf7a960002..9c8e317c598 100644 --- a/arch/ppc64/kernel/sys_ppc32.c +++ b/arch/ppc64/kernel/sys_ppc32.c @@ -791,31 +791,6 @@ asmlinkage int sys32_pciconfig_iobase(u32 which, u32 in_bus, u32 in_devfn) } -asmlinkage int ppc64_newuname(struct new_utsname __user * name) -{ - int errno = sys_newuname(name); - - if (current->personality == PER_LINUX32 && !errno) { - if(copy_to_user(name->machine, "ppc\0\0", 8)) { - errno = -EFAULT; - } - } - return errno; -} - -asmlinkage int ppc64_personality(unsigned long personality) -{ - int ret; - if (current->personality == PER_LINUX32 && personality == PER_LINUX) - personality = PER_LINUX32; - ret = sys_personality(personality); - if (ret == PER_LINUX32) - ret = PER_LINUX; - return ret; -} - - - /* Note: it is necessary to treat mode as an unsigned int, * with the corresponding cast to a signed int to insure that the * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) @@ -1158,26 +1133,47 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } #endif +asmlinkage int sys32_uname(struct old_utsname __user * name) +{ + int err = 0; + + down_read(&uts_sem); + if (copy_to_user(name, &system_utsname, sizeof(*name))) + err = -EFAULT; + up_read(&uts_sem); + if (!err && personality(current->personality) == PER_LINUX32) { + /* change "ppc64" to "ppc" */ + if (__put_user(0, name->machine + 3) + || __put_user(0, name->machine + 4)) + err = -EFAULT; + } + return err; +} + asmlinkage int sys32_olduname(struct oldold_utsname __user * name) { int error; - - if (!name) - return -EFAULT; + if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); - error -= __put_user(0,name->sysname+__OLD_UTS_LEN); - error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); - error -= __put_user(0,name->nodename+__OLD_UTS_LEN); - error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); - error -= __put_user(0,name->release+__OLD_UTS_LEN); - error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); - error -= __put_user(0,name->version+__OLD_UTS_LEN); - error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); - error = __put_user(0,name->machine+__OLD_UTS_LEN); + error |= __put_user(0,name->sysname+__OLD_UTS_LEN); + error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); + error |= __put_user(0,name->nodename+__OLD_UTS_LEN); + error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); + error |= __put_user(0,name->release+__OLD_UTS_LEN); + error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); + error |= __put_user(0,name->version+__OLD_UTS_LEN); + error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); + error |= __put_user(0,name->machine+__OLD_UTS_LEN); + if (personality(current->personality) == PER_LINUX32) { + /* change "ppc64" to "ppc" */ + error |= __put_user(0, name->machine + 3); + error |= __put_user(0, name->machine + 4); + } + up_read(&uts_sem); error = error ? -EFAULT : 0; diff --git a/arch/ppc64/kernel/syscalls.c b/arch/ppc64/kernel/syscalls.c index f2865ff8d2f..a8cbb202b8c 100644 --- a/arch/ppc64/kernel/syscalls.c +++ b/arch/ppc64/kernel/syscalls.c @@ -199,24 +199,33 @@ out: return ret; } -static int __init set_fakeppc(char *str) +long ppc64_personality(unsigned long personality) { - if (*str) - return 0; - init_task.personality = PER_LINUX32; - return 1; + long ret; + + if (personality(current->personality) == PER_LINUX32 + && personality == PER_LINUX) + personality = PER_LINUX32; + ret = sys_personality(personality); + if (ret == PER_LINUX32) + ret = PER_LINUX; + return ret; } -__setup("fakeppc", set_fakeppc); -asmlinkage int sys_uname(struct old_utsname __user * name) +long ppc64_newuname(struct new_utsname __user * name) { - int err = -EFAULT; - + int err = 0; + down_read(&uts_sem); - if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) - err = 0; + if (copy_to_user(name, &system_utsname, sizeof(*name))) + err = -EFAULT; up_read(&uts_sem); - + if (!err && personality(current->personality) == PER_LINUX32) { + /* change ppc64 to ppc */ + if (__put_user(0, name->machine + 3) + || __put_user(0, name->machine + 4)) + err = -EFAULT; + } return err; } diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index 0925694c3ce..c8fa6569b2f 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -113,7 +113,6 @@ void ppc64_enable_pmcs(void) #ifdef CONFIG_PPC_PSERIES unsigned long set, reset; int ret; - unsigned int ctrl; #endif /* CONFIG_PPC_PSERIES */ /* Only need to enable them once */ @@ -167,11 +166,8 @@ void ppc64_enable_pmcs(void) * On SMT machines we have to set the run latch in the ctrl register * in order to make PMC6 spin. */ - if (cpu_has_feature(CPU_FTR_SMT)) { - ctrl = mfspr(CTRLF); - ctrl |= RUNLATCH; - mtspr(CTRLT, ctrl); - } + if (cpu_has_feature(CPU_FTR_SMT)) + ppc64_runlatch_on(); #endif /* CONFIG_PPC_PSERIES */ } diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 01ae1964c93..c067435bae4 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -28,6 +28,7 @@ //#include <linux/kernel_stat.h> #include <linux/notifier.h> #include <linux/cpu.h> +#include <linux/workqueue.h> #include "appldata.h" @@ -133,9 +134,12 @@ static int appldata_interval = APPLDATA_CPU_INTERVAL; static int appldata_timer_active; /* - * Tasklet + * Work queue */ -static struct tasklet_struct appldata_tasklet_struct; +static struct workqueue_struct *appldata_wq; +static void appldata_work_fn(void *data); +static DECLARE_WORK(appldata_work, appldata_work_fn, NULL); + /* * Ops list @@ -144,11 +148,11 @@ static DEFINE_SPINLOCK(appldata_ops_lock); static LIST_HEAD(appldata_ops_list); -/************************* timer, tasklet, DIAG ******************************/ +/*************************** timer, work, DIAG *******************************/ /* * appldata_timer_function() * - * schedule tasklet and reschedule timer + * schedule work and reschedule timer */ static void appldata_timer_function(unsigned long data, struct pt_regs *regs) { @@ -157,22 +161,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()); - tasklet_schedule((struct tasklet_struct *) data); + queue_work(appldata_wq, (struct work_struct *) data); } } /* - * appldata_tasklet_function() + * appldata_work_fn() * * call data gathering function for each (active) module */ -static void appldata_tasklet_function(unsigned long data) +static void appldata_work_fn(void *data) { struct list_head *lh; struct appldata_ops *ops; int i; - P_DEBUG(" -= Tasklet =-\n"); + P_DEBUG(" -= Work Queue =-\n"); i = 0; spin_lock(&appldata_ops_lock); list_for_each(lh, &appldata_ops_list) { @@ -231,7 +235,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, : "=d" (ry) : "d" (&(appldata_parameter_list)) : "cc"); return (int) ry; } -/********************** timer, tasklet, DIAG <END> ***************************/ +/************************ timer, work, DIAG <END> ****************************/ /****************************** /proc stuff **********************************/ @@ -411,7 +415,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, struct list_head *lh; found = 0; - spin_lock_bh(&appldata_ops_lock); + spin_lock(&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) { @@ -419,15 +423,15 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } } if (!found) { - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } ops = ctl->data; if (!try_module_get(ops->owner)) { // protect this function - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -ENODEV; } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); if (!*lenp || *ppos) { *lenp = 0; @@ -451,10 +455,11 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, return -EFAULT; } - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); if ((buf[0] == '1') && (ops->active == 0)) { - if (!try_module_get(ops->owner)) { // protect tasklet - spin_unlock_bh(&appldata_ops_lock); + // protect work queue callback + if (!try_module_get(ops->owner)) { + spin_unlock(&appldata_ops_lock); module_put(ops->owner); return -ENODEV; } @@ -485,7 +490,7 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, } module_put(ops->owner); } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); out: *lenp = len; *ppos += len; @@ -529,7 +534,7 @@ int appldata_register_ops(struct appldata_ops *ops) } memset(ops->ctl_table, 0, 4*sizeof(struct ctl_table)); - spin_lock_bh(&appldata_ops_lock); + spin_lock(&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", @@ -541,18 +546,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_bh(&appldata_ops_lock); + spin_unlock(&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_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); return -EBUSY; } } list_add(&ops->list, &appldata_ops_list); - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); ops->ctl_table[0].ctl_name = CTL_APPLDATA; ops->ctl_table[0].procname = appldata_proc_name; @@ -583,12 +588,12 @@ int appldata_register_ops(struct appldata_ops *ops) */ void appldata_unregister_ops(struct appldata_ops *ops) { - spin_lock_bh(&appldata_ops_lock); + spin_lock(&appldata_ops_lock); unregister_sysctl_table(ops->sysctl_header); list_del(&ops->list); kfree(ops->ctl_table); ops->ctl_table = NULL; - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); P_INFO("%s-ops unregistered!\n", ops->name); } /********************** module-ops management <END> **************************/ @@ -602,7 +607,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_tasklet_struct; + &appldata_work; atomic_inc(&appldata_expire_count); spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -615,7 +620,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()); - tasklet_schedule(&appldata_tasklet_struct); + queue_work(appldata_wq, &appldata_work); } spin_lock(&appldata_timer_lock); __appldata_vtimer_setup(APPLDATA_MOD_TIMER); @@ -648,7 +653,7 @@ static struct notifier_block __devinitdata appldata_nb = { /* * appldata_init() * - * init timer and tasklet, register /proc entries + * init timer, register /proc entries */ static int __init appldata_init(void) { @@ -657,6 +662,12 @@ 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); @@ -670,7 +681,6 @@ 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; } @@ -678,7 +688,7 @@ static int __init appldata_init(void) /* * appldata_exit() * - * stop timer and tasklet, unregister /proc entries + * stop timer, unregister /proc entries */ static void __exit appldata_exit(void) { @@ -690,7 +700,7 @@ static void __exit appldata_exit(void) /* * ops list should be empty, but just in case something went wrong... */ - spin_lock_bh(&appldata_ops_lock); + spin_lock(&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, @@ -700,7 +710,7 @@ static void __exit appldata_exit(void) "return code: %d\n", ops->name, rc); } } - spin_unlock_bh(&appldata_ops_lock); + spin_unlock(&appldata_ops_lock); for_each_online_cpu(i) appldata_offline_cpu(i); @@ -709,7 +719,7 @@ static void __exit appldata_exit(void) unregister_sysctl_table(appldata_sysctl_header); - tasklet_kill(&appldata_tasklet_struct); + destroy_workqueue(appldata_wq); P_DEBUG("... module unloaded!\n"); } /**************************** init / exit <END> ******************************/ diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 462ee9a84e7..f0e2fbed3d4 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -68,7 +68,7 @@ struct appldata_mem_data { u64 pgmajfault; /* page faults (major only) */ // <-- New in 2.6 -} appldata_mem_data; +} __attribute__((packed)) appldata_mem_data; static inline void appldata_debug_print(struct appldata_mem_data *mem_data) diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c index dd61638d302..2a4c7432db4 100644 --- a/arch/s390/appldata/appldata_net_sum.c +++ b/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 */ -} appldata_net_sum_data; +} __attribute__((packed)) appldata_net_sum_data; static inline void appldata_print_debug(struct appldata_net_sum_data *net_data) diff --git a/arch/s390/appldata/appldata_os.c b/arch/s390/appldata/appldata_os.c index b83f0748455..e0a476bf4fd 100644 --- a/arch/s390/appldata/appldata_os.c +++ b/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/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 26889366929..06afa3103ac 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -40,6 +40,7 @@ #include <asm/pgalloc.h> #include <asm/system.h> #include <asm/uaccess.h> +#include <asm/unistd.h> #ifdef CONFIG_S390_SUPPORT #include "compat_ptrace.h" @@ -130,13 +131,19 @@ static int peek_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset, tmp; + addr_t offset, tmp, mask; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell... */ - if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) + 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) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -153,6 +160,16 @@ 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) { @@ -167,6 +184,9 @@ 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)) { /* @@ -191,13 +211,19 @@ static int poke_user(struct task_struct *child, addr_t addr, addr_t data) { struct user *dummy = NULL; - addr_t offset; + addr_t offset, mask; /* * Stupid gdb peeks/pokes the access registers in 64 bit with * an alignment of 4. Programmers from hell indeed... */ - if ((addr & 3) || addr > sizeof(struct user) - __ADDR_MASK) + 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) return -EIO; if (addr < (addr_t) &dummy->regs.acrs) { @@ -224,6 +250,17 @@ 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) { @@ -237,7 +274,8 @@ 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 & ~FPC_VALID_MASK) != 0) + (data & ~((unsigned long) FPC_VALID_MASK + << (BITS_PER_LONG - 32))) != 0) return -EINVAL; offset = addr - (addr_t) &dummy->regs.fp_regs; *(addr_t *)((addr_t) &child->thread.fp_regs + offset) = data; @@ -723,6 +761,13 @@ syscall_trace(struct pt_regs *regs, int entryexit) ? 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 * stopping signal is not SIGTRAP. -brl diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 80306bc8c79..75fde949d12 100644 --- a/arch/s390/mm/fault.c +++ b/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_interrupt() || !mm) + if (user_address == 0 || in_atomic() || !mm) goto no_context; /* diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char index 3e50fdb6762..62d87b71179 100644 --- a/arch/um/Kconfig_char +++ b/arch/um/Kconfig_char @@ -204,5 +204,11 @@ config UML_RANDOM http://sourceforge.net/projects/gkernel/). rngd periodically reads /dev/hwrng and injects the entropy into /dev/random. +config MMAPPER + tristate "iomem emulation driver" + help + This driver allows a host file to be used as emulated IO memory inside + UML. + endmenu diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile index 323f72c64cd..b2de9916c32 100644 --- a/arch/um/drivers/Makefile +++ b/arch/um/drivers/Makefile @@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o obj-$(CONFIG_SSL) += ssl.o obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o -obj-$(CONFIG_UML_NET_SLIP) += slip.o -obj-$(CONFIG_UML_NET_SLIRP) += slirp.o +obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o +obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o obj-$(CONFIG_UML_NET_DAEMON) += daemon.o obj-$(CONFIG_UML_NET_MCAST) += mcast.o #obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) @@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o obj-$(CONFIG_UML_RANDOM) += random.o -USER_OBJS := fd.o null.o pty.o tty.o xterm.o +USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o include arch/um/scripts/Makefile.rules diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 583b8e137c3..5d3768156c9 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c @@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) { struct winch_data data; unsigned long stack; - int fds[2], pid, n, err; + int fds[2], n, err; char c; err = os_pipe(fds, 1, 1); if(err < 0){ printk("winch_tramp : os_pipe failed, err = %d\n", -err); - return(err); + goto out; } data = ((struct winch_data) { .pty_fd = fd, .pipe_fd = fds[1], .close_me = fds[0] } ); - pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); - if(pid < 0){ + err = run_helper_thread(winch_thread, &data, 0, &stack, 0); + if(err < 0){ printk("fork of winch_thread failed - errno = %d\n", errno); - return(pid); + goto out_close; } os_close_file(fds[1]); @@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) printk("winch_tramp : failed to read synchronization byte\n"); printk("read failed, err = %d\n", -n); printk("fd %d will not support SIGWINCH\n", fd); - *fd_out = -1; + err = -EINVAL; + goto out_close1; } - return(pid); + return err ; + + out_close: + os_close_file(fds[1]); + out_close1: + os_close_file(fds[0]); + out: + return err; } void register_winch(int fd, struct tty_struct *tty) { - int pid, thread, thread_fd; + int pid, thread, thread_fd = -1; int count; char c = 1; @@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty) if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) && (pid == -1)){ thread = winch_tramp(fd, tty, &thread_fd); - if(fd != -1){ + if(thread > 0){ register_winch_irq(thread_fd, fd, thread, tty); count = os_write_file(thread_fd, &c, sizeof(c)); diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a63231dffe0..a37a5ac13c2 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/miscdevice.h> #include <asm/uaccess.h> #include <asm/irq.h> #include <asm/pgtable.h> @@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = { .release = mmapper_release, }; +static struct miscdevice mmapper_dev = { + .minor = MISC_DYNAMIC_MINOR, + .name = "mmapper", + .fops = &mmapper_fops +}; + static int __init mmapper_init(void) { + int err; + printk(KERN_INFO "Mapper v0.1\n"); v_buf = (char *) find_iomem("mmapper", &mmapper_size); if(mmapper_size == 0){ printk(KERN_ERR "mmapper_init - find_iomem failed\n"); - return(0); + goto out; } - p_buf = __pa(v_buf); + err = misc_register(&mmapper_dev); + if(err){ + printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", + err); + goto out; + } - devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); - return(0); + p_buf = __pa(v_buf); +out: + return 0; } static void mmapper_exit(void) { + misc_deregister(&mmapper_dev); } module_init(mmapper_init); diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 47229fe4a81..3730d4f1271 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c @@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr) return(0); } -void tap_check_ips(char *gate_addr, char *eth_addr) +void tap_check_ips(char *gate_addr, unsigned char *eth_addr) { int tap_addr[4]; diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h index 495f2f1b142..bb0dab41c2e 100644 --- a/arch/um/drivers/slip.h +++ b/arch/um/drivers/slip.h @@ -1,10 +1,7 @@ #ifndef __UM_SLIP_H #define __UM_SLIP_H -#define BUF_SIZE 1500 - /* two bytes each for a (pathological) max packet of escaped chars + * - * terminating END char + initial END char */ -#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) +#include "slip_common.h" struct slip_data { void *dev; @@ -12,28 +9,12 @@ struct slip_data { char *addr; char *gate_addr; int slave; - char ibuf[ENC_BUF_SIZE]; - char obuf[ENC_BUF_SIZE]; - int more; /* more data: do not read fd until ibuf has been drained */ - int pos; - int esc; + struct slip_proto slip; }; extern struct net_user_info slip_user_info; -extern int set_umn_addr(int fd, char *addr, char *ptp_addr); extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c new file mode 100644 index 00000000000..e89cfc68fc3 --- /dev/null +++ b/arch/um/drivers/slip_common.c @@ -0,0 +1,54 @@ +#include <string.h> +#include "slip_common.h" +#include "net_user.h" + +int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip) +{ + int i, n, size, start; + + if(slip->more > 0){ + i = 0; + while(i < slip->more){ + size = slip_unesc(slip->ibuf[i++], slip->ibuf, + &slip->pos, &slip->esc); + if(size){ + memcpy(buf, slip->ibuf, size); + memmove(slip->ibuf, &slip->ibuf[i], + slip->more - i); + slip->more = slip->more - i; + return size; + } + } + slip->more = 0; + } + + n = net_read(fd, &slip->ibuf[slip->pos], + sizeof(slip->ibuf) - slip->pos); + if(n <= 0) + return n; + + start = slip->pos; + for(i = 0; i < n; i++){ + size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos, + &slip->esc); + if(size){ + memcpy(buf, slip->ibuf, size); + memmove(slip->ibuf, &slip->ibuf[start+i+1], + n - (i + 1)); + slip->more = n - (i + 1); + return size; + } + } + return 0; +} + +int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip) +{ + int actual, n; + + actual = slip_esc(buf, slip->obuf, len); + n = net_write(fd, slip->obuf, actual); + if(n < 0) + return n; + else return len; +} diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h index 7206361ace4..2ae76d8f1be 100644 --- a/arch/um/drivers/slip_proto.h +++ b/arch/um/drivers/slip_common.h @@ -1,10 +1,10 @@ -/* - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) - * Licensed under the GPL - */ +#ifndef __UM_SLIP_COMMON_H +#define __UM_SLIP_COMMON_H -#ifndef __UM_SLIP_PROTO_H__ -#define __UM_SLIP_PROTO_H__ +#define BUF_SIZE 1500 + /* two bytes each for a (pathological) max packet of escaped chars + * + * terminating END char + initial END char */ +#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) /* SLIP protocol characters. */ #define SLIP_END 0300 /* indicates end of frame */ @@ -12,7 +12,8 @@ #define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ #define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ -static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) +static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos, + int *esc) { int ret; @@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len) return (ptr - d); } -#endif +struct slip_proto { + unsigned char ibuf[ENC_BUF_SIZE]; + unsigned char obuf[ENC_BUF_SIZE]; + int more; /* more data: do not read fd until ibuf has been drained */ + int pos; + int esc; +}; + +#define SLIP_PROTO_INIT { \ + .ibuf = { '\0' }, \ + .obuf = { '\0' }, \ + .more = 0, \ + .pos = 0, \ + .esc = 0 \ +} -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ +extern int slip_proto_read(int fd, void *buf, int len, + struct slip_proto *slip); +extern int slip_proto_write(int fd, void *buf, int len, + struct slip_proto *slip); + +#endif diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 0886eedba21..9a6f5c85f90 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c @@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data) .addr = NULL, .gate_addr = init->gate_addr, .slave = -1, - .ibuf = { '\0' }, - .obuf = { '\0' }, - .pos = 0, - .esc = 0, + .slip = SLIP_PROTO_INIT, .dev = dev }); dev->init = NULL; + dev->header_cache_update = NULL; + dev->hard_header_cache = NULL; + dev->hard_header = NULL; dev->hard_header_len = 0; - dev->addr_len = 4; - dev->type = ARPHRD_ETHER; + dev->addr_len = 0; + dev->type = ARPHRD_SLIP; dev->tx_queue_len = 256; dev->flags = IFF_NOARP; printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c index d94846b1b4c..71af444e591 100644 --- a/arch/um/drivers/slip_user.c +++ b/arch/um/drivers/slip_user.c @@ -13,7 +13,7 @@ #include "user.h" #include "net_user.h" #include "slip.h" -#include "slip_proto.h" +#include "slip_common.h" #include "helper.h" #include "os.h" @@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd) err = os_pipe(fds, 1, 0); if(err < 0){ printk("slip_tramp : pipe failed, err = %d\n", -err); - return(err); + goto out; } err = 0; pe_data.stdin = fd; pe_data.stdout = fds[1]; pe_data.close_me = fds[0]; - pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); + err = run_helper(slip_pre_exec, &pe_data, argv, NULL); + if(err < 0) + goto out_close; + pid = err; + + output_len = page_size(); + output = um_kmalloc(output_len); + if(output == NULL){ + printk("slip_tramp : failed to allocate output buffer\n"); + os_kill_process(pid, 1); + err = -ENOMEM; + goto out_free; + } - if(pid < 0) err = pid; - else { - output_len = page_size(); - output = um_kmalloc(output_len); - if(output == NULL) - printk("slip_tramp : failed to allocate output " - "buffer\n"); - - os_close_file(fds[1]); - read_output(fds[0], output, output_len); - if(output != NULL){ - printk("%s", output); - kfree(output); - } - CATCH_EINTR(err = waitpid(pid, &status, 0)); - if(err < 0) - err = errno; - else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ - printk("'%s' didn't exit with status 0\n", argv[0]); - err = -EINVAL; - } + os_close_file(fds[1]); + read_output(fds[0], output, output_len); + printk("%s", output); + + CATCH_EINTR(err = waitpid(pid, &status, 0)); + if(err < 0) + err = errno; + else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ + printk("'%s' didn't exit with status 0\n", argv[0]); + err = -EINVAL; } + else err = 0; os_close_file(fds[0]); - return(err); +out_free: + kfree(output); + return err; + +out_close: + os_close_file(fds[0]); + os_close_file(fds[1]); +out: + return err; } static int slip_open(void *data) @@ -123,21 +133,26 @@ static int slip_open(void *data) NULL }; int sfd, mfd, err; - mfd = get_pty(); - if(mfd < 0){ - printk("umn : Failed to open pty, err = %d\n", -mfd); - return(mfd); + err = get_pty(); + if(err < 0){ + printk("slip-open : Failed to open pty, err = %d\n", -err); + goto out; } - sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); - if(sfd < 0){ - printk("Couldn't open tty for slip line, err = %d\n", -sfd); - os_close_file(mfd); - return(sfd); + mfd = err; + + err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); + if(err < 0){ + printk("Couldn't open tty for slip line, err = %d\n", -err); + goto out_close; } - if(set_up_tty(sfd)) return(-1); + sfd = err; + + if(set_up_tty(sfd)) + goto out_close2; + pri->slave = sfd; - pri->pos = 0; - pri->esc = 0; + pri->slip.pos = 0; + pri->slip.esc = 0; if(pri->gate_addr != NULL){ sprintf(version_buf, "%d", UML_NET_VERSION); strcpy(gate_buf, pri->gate_addr); @@ -146,12 +161,12 @@ static int slip_open(void *data) if(err < 0){ printk("slip_tramp failed - err = %d\n", -err); - return(err); + goto out_close2; } err = os_get_ifname(pri->slave, pri->name); if(err < 0){ printk("get_ifname failed, err = %d\n", -err); - return(err); + goto out_close2; } iter_addresses(pri->dev, open_addr, pri->name); } @@ -160,10 +175,16 @@ static int slip_open(void *data) if(err < 0){ printk("Failed to set slip discipline encapsulation - " "err = %d\n", -err); - return(err); + goto out_close2; } } return(mfd); +out_close2: + os_close_file(sfd); +out_close: + os_close_file(mfd); +out: + return err; } static void slip_close(int fd, void *data) @@ -190,48 +211,12 @@ static void slip_close(int fd, void *data) int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) { - int i, n, size, start; - - if(pri->more>0) { - i = 0; - while(i < pri->more) { - size = slip_unesc(pri->ibuf[i++], - pri->ibuf, &pri->pos, &pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); - pri->more=pri->more-i; - return(size); - } - } - pri->more=0; - } - - n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); - if(n <= 0) return(n); - - start = pri->pos; - for(i = 0; i < n; i++){ - size = slip_unesc(pri->ibuf[start + i], - pri->ibuf, &pri->pos, &pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); - pri->more=n-(i+1); - return(size); - } - } - return(0); + return slip_proto_read(fd, buf, len, &pri->slip); } int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) { - int actual, n; - - actual = slip_esc(buf, pri->obuf, len); - n = net_write(fd, pri->obuf, actual); - if(n < 0) return(n); - else return(len); + return slip_proto_write(fd, buf, len, &pri->slip); } static int slip_set_mtu(int mtu, void *data) @@ -267,14 +252,3 @@ struct net_user_info slip_user_info = { .delete_address = slip_del_addr, .max_packet = BUF_SIZE }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h index 04e407d1e44..6cf88ab580c 100644 --- a/arch/um/drivers/slirp.h +++ b/arch/um/drivers/slirp.h @@ -1,10 +1,7 @@ #ifndef __UM_SLIRP_H #define __UM_SLIRP_H -#define BUF_SIZE 1500 - /* two bytes each for a (pathological) max packet of escaped chars + * - * terminating END char + initial END char */ -#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) +#include "slip_common.h" #define SLIRP_MAX_ARGS 100 /* @@ -24,28 +21,13 @@ struct slirp_data { struct arg_list_dummy_wrapper argw; int pid; int slave; - char ibuf[ENC_BUF_SIZE]; - char obuf[ENC_BUF_SIZE]; - int more; /* more data: do not read fd until ibuf has been drained */ - int pos; - int esc; + struct slip_proto slip; }; extern struct net_user_info slirp_user_info; -extern int set_umn_addr(int fd, char *addr, char *ptp_addr); extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); -extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); +extern int slirp_user_write(int fd, void *buf, int len, + struct slirp_data *pri); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index c9d6b52a831..9864d27afdb 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c @@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data) { .argw = init->argw, .pid = -1, .slave = -1, - .ibuf = { '\0' }, - .obuf = { '\0' }, - .pos = 0, - .esc = 0, + .slip = SLIP_PROTO_INIT, .dev = dev }); dev->init = NULL; diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c index c322515c71c..8d91f663d82 100644 --- a/arch/um/drivers/slirp_user.c +++ b/arch/um/drivers/slirp_user.c @@ -12,7 +12,7 @@ #include "user.h" #include "net_user.h" #include "slirp.h" -#include "slip_proto.h" +#include "slip_common.h" #include "helper.h" #include "os.h" @@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd) return(pid); } -/* XXX This is just a trivial wrapper around os_pipe */ -static int slirp_datachan(int *mfd, int *sfd) -{ - int fds[2], err; - - err = os_pipe(fds, 1, 1); - if(err < 0){ - printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); - return(err); - } - - *mfd = fds[0]; - *sfd = fds[1]; - return(0); -} - static int slirp_open(void *data) { struct slirp_data *pri = data; - int sfd, mfd, pid, err; + int fds[2], pid, err; - err = slirp_datachan(&mfd, &sfd); + err = os_pipe(fds, 1, 1); if(err) return(err); - pid = slirp_tramp(pri->argw.argv, sfd); - - if(pid < 0){ - printk("slirp_tramp failed - errno = %d\n", -pid); - os_close_file(sfd); - os_close_file(mfd); - return(pid); + err = slirp_tramp(pri->argw.argv, fds[1]); + if(err < 0){ + printk("slirp_tramp failed - errno = %d\n", -err); + goto out; } - - pri->slave = sfd; - pri->pos = 0; - pri->esc = 0; - - pri->pid = pid; - - return(mfd); + pid = err; + + pri->slave = fds[1]; + pri->slip.pos = 0; + pri->slip.esc = 0; + pri->pid = err; + + return(fds[0]); +out: + os_close_file(fds[0]); + os_close_file(fds[1]); + return err; } static void slirp_close(int fd, void *data) @@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data) int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) { - int i, n, size, start; - - if(pri->more>0) { - i = 0; - while(i < pri->more) { - size = slip_unesc(pri->ibuf[i++], - pri->ibuf,&pri->pos,&pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); - pri->more=pri->more-i; - return(size); - } - } - pri->more=0; - } - - n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); - if(n <= 0) return(n); - - start = pri->pos; - for(i = 0; i < n; i++){ - size = slip_unesc(pri->ibuf[start + i], - pri->ibuf,&pri->pos,&pri->esc); - if(size){ - memcpy(buf, pri->ibuf, size); - memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); - pri->more=n-(i+1); - return(size); - } - } - return(0); + return slip_proto_read(fd, buf, len, &pri->slip); } int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) { - int actual, n; - - actual = slip_esc(buf, pri->obuf, len); - n = net_write(fd, pri->obuf, actual); - if(n < 0) return(n); - else return(len); + return slip_proto_write(fd, buf, len, &pri->slip); } static int slirp_set_mtu(int mtu, void *data) @@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = { .delete_address = NULL, .max_packet = BUF_SIZE }; - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c index 98565b53d17..429ae8e6c7e 100644 --- a/arch/um/drivers/stderr_console.c +++ b/arch/um/drivers/stderr_console.c @@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string, } static struct console stderr_console = { - .name "stderr", - .write stderr_console_write, - .flags CON_PRINTBUFFER, + .name = "stderr", + .write = stderr_console_write, + .flags = CON_PRINTBUFFER, }; static int __init stderr_console_init(void) diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 9fbe3083fdd..cfa368e045a 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -56,7 +56,7 @@ struct mc_request int as_interrupt; int originating_fd; - int originlen; + unsigned int originlen; unsigned char origin[128]; /* sockaddr_un */ struct mconsole_request request; diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h index 36807b796e9..89885a77a77 100644 --- a/arch/um/include/net_user.h +++ b/arch/um/include/net_user.h @@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out); extern void free_output_buffer(void *buffer); extern int tap_open_common(void *dev, char *gate_addr); -extern void tap_check_ips(char *gate_addr, char *eth_addr); +extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr); extern void read_output(int fd, char *output_out, int len); diff --git a/arch/um/include/os.h b/arch/um/include/os.h index d246d5a2460..881d2988d2d 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset); extern int os_open_file(char *file, struct openflags flags, int mode); extern int os_read_file(int fd, void *buf, int len); extern int os_write_file(int fd, const void *buf, int count); -extern int os_file_size(char *file, long long *size_out); +extern int os_file_size(char *file, unsigned long long *size_out); extern int os_file_modtime(char *file, unsigned long *modtime); extern int os_pipe(int *fd, int stream, int close_on_exec); extern int os_set_fd_async(int fd, int owner); diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 6eaeb991998..c8ee9559f3a 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h @@ -8,6 +8,8 @@ #include "uml-config.h" #include "user_constants.h" +#include "sysdep/faultinfo.h" +#include "choose-mode.h" #define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) #define MAX_REG_OFFSET (UM_FRAME_SIZE) @@ -58,9 +60,6 @@ extern int sysemu_supported; #define PTRACE_SYSEMU_SINGLESTEP 32 #endif -#include "sysdep/faultinfo.h" -#include "choose-mode.h" - union uml_pt_regs { #ifdef UML_CONFIG_MODE_TT struct tt_regs { diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index b8c5b8a9525..7b6a24dfd30 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -41,9 +41,6 @@ extern unsigned long highmem; extern char host_info[]; extern char saved_command_line[]; -extern char command_line[]; - -extern char *tempdir; extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; extern unsigned long _unprotected_end; diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c index e42e6364ca1..e59f5815267 100644 --- a/arch/um/kernel/main.c +++ b/arch/um/kernel/main.c @@ -24,8 +24,6 @@ #include "mode.h" #include "choose-mode.h" #include "uml-config.h" -#include "irq_user.h" -#include "time_user.h" #include "os.h" /* Set in set_stklim, which is called from main and __wrap_malloc. diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 51f8e5a8ac6..1b5ef3e96c7 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -30,7 +30,6 @@ #include "init.h" #include "os.h" #include "uml-config.h" -#include "ptrace_user.h" #include "choose-mode.h" #include "mode.h" #ifdef UML_CONFIG_MODE_SKAS @@ -131,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack, return(arg.pid); } -static int ptrace_child(void *arg) +static int ptrace_child(void) { int ret; int pid = os_getpid(), ppid = getppid(); @@ -160,20 +159,16 @@ static int ptrace_child(void *arg) _exit(ret); } -static int start_ptraced_child(void **stack_out) +static int start_ptraced_child(void) { - void *stack; - unsigned long sp; int pid, n, status; - stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if(stack == MAP_FAILED) - panic("check_ptrace : mmap failed, errno = %d", errno); - sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); - pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); + pid = fork(); + if(pid == 0) + ptrace_child(); + if(pid < 0) - panic("check_ptrace : clone failed, errno = %d", errno); + panic("check_ptrace : fork failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); if(n < 0) panic("check_ptrace : wait failed, errno = %d", errno); @@ -181,7 +176,6 @@ static int start_ptraced_child(void **stack_out) panic("check_ptrace : expected SIGSTOP, got status = %d", status); - *stack_out = stack; return(pid); } @@ -189,12 +183,12 @@ static int start_ptraced_child(void **stack_out) * just avoid using sysemu, not panic, but only if SYSEMU features are broken. * So only for SYSEMU features we test mustpanic, while normal host features * must work anyway!*/ -static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) +static int stop_ptraced_child(int pid, int exitcode, int mustexit) { int status, n, ret = 0; if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) - panic("check_ptrace : ptrace failed, errno = %d", errno); + panic("stop_ptraced_child : ptrace failed, errno = %d", errno); CATCH_EINTR(n = waitpid(pid, &status, 0)); if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); @@ -205,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) printk("check_ptrace : child exited with exitcode %d, while " "expecting %d; status 0x%x", exit_with, exitcode, status); - if (mustpanic) + if (mustexit) panic("\n"); else printk("\n"); ret = -1; } - if(munmap(stack, PAGE_SIZE) < 0) - panic("check_ptrace : munmap failed, errno = %d", errno); return ret; } @@ -235,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param, static void __init check_sysemu(void) { - void *stack; int pid, syscall, n, status, count=0; printk("Checking syscall emulation patch for ptrace..."); sysemu_supported = 0; - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) goto fail; @@ -258,7 +249,7 @@ static void __init check_sysemu(void) panic("check_sysemu : failed to modify system " "call return, errno = %d", errno); - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 1; @@ -266,7 +257,7 @@ static void __init check_sysemu(void) set_using_sysemu(!force_sysemu_disabled); printk("Checking advanced syscall emulation patch for ptrace..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); while(1){ count++; if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) @@ -291,7 +282,7 @@ static void __init check_sysemu(void) break; } } - if (stop_ptraced_child(pid, stack, 0, 0) < 0) + if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; sysemu_supported = 2; @@ -302,18 +293,17 @@ static void __init check_sysemu(void) return; fail: - stop_ptraced_child(pid, stack, 1, 0); + stop_ptraced_child(pid, 1, 0); fail_stopped: printk("missing\n"); } void __init check_ptrace(void) { - void *stack; int pid, syscall, n, status; printk("Checking that ptrace can change system call numbers..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); @@ -340,7 +330,7 @@ void __init check_ptrace(void) break; } } - stop_ptraced_child(pid, stack, 0, 1); + stop_ptraced_child(pid, 0, 1); printk("OK\n"); check_sysemu(); } @@ -372,11 +362,10 @@ void forward_pending_sigio(int target) static inline int check_skas3_ptrace_support(void) { struct ptrace_faultinfo fi; - void *stack; int pid, n, ret = 1; printf("Checking for the skas3 patch in the host..."); - pid = start_ptraced_child(&stack); + pid = start_ptraced_child(); n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); if (n < 0) { @@ -391,7 +380,7 @@ static inline int check_skas3_ptrace_support(void) } init_registers(pid); - stop_ptraced_child(pid, stack, 1, 1); + stop_ptraced_child(pid, 1, 1); return(ret); } diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index ab5d3271da0..fc71ef29578 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -68,8 +68,11 @@ void new_thread_handler(int sig) * 0 if it just exits */ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); - if(n == 1) + if(n == 1){ + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); + } else do_exit(0); } @@ -96,6 +99,8 @@ void fork_handler(int sig) schedule_tail(current->thread.prev_sched); current->thread.prev_sched = NULL; + /* Handle any immediate reschedules or signals */ + interrupt_end(); userspace(¤t->thread.regs.regs); } diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 418427107b2..8736d098f0e 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -26,7 +26,6 @@ #include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" -#include "asm/setup.h" #include "user_util.h" #include "kern_util.h" #include "kern.h" diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9aee0b62ebc..f0d6060e3e5 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c @@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp) elf_aux_hwcap = auxv->a_un.a_val; break; case AT_PLATFORM: - elf_aux_platform = auxv->a_un.a_ptr; + /* elf.h removed the pointer elements from + * a_un, so we have to use a_val, which is + * all that's left. + */ + elf_aux_platform = (char *) auxv->a_un.a_val; break; case AT_PAGESZ: page_size = auxv->a_un.a_val; diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 77d4066d1af..fd45bb26090 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len) (int (*)(int, void *, int)) write, copy_to_user_proc)); } -int os_file_size(char *file, long long *size_out) +int os_file_size(char *file, unsigned long long *size_out) { struct uml_stat buf; int err; diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 0b2491883d9..98346c71149 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -14,7 +14,7 @@ quiet_cmd_make_link = SYMLINK $@ cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ # this needs to be before the foreach, because targets does not accept -# complete paths like $(obj)/$(f). To make sure this works, use a := assignment, +# complete paths like $(obj)/$(f). To make sure this works, use a := assignment # or we will get $(obj)/$(f) in the "targets" value. # Also, this forces you to use the := syntax when assigning to targets. # Otherwise the line below will cause an infinite loop (if you don't know why, diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c index a491f72cc96..504e6347499 100644 --- a/arch/x86_64/kernel/aperture.c +++ b/arch/x86_64/kernel/aperture.c @@ -33,12 +33,10 @@ int fallback_aper_force __initdata = 0; int fix_aperture __initdata = 1; -#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) +/* This code runs before the PCI subsystem is initialized, so just + access the northbridge directly. */ -static struct resource aper_res = { - .name = "Aperture", - .flags = IORESOURCE_MEM, -}; +#define NB_ID_3 (PCI_VENDOR_ID_AMD | (0x1103<<16)) static u32 __init allocate_aperture(void) { @@ -55,24 +53,11 @@ static u32 __init allocate_aperture(void) aper_size = (32 * 1024 * 1024) << fallback_aper_order; /* - * Aperture has to be naturally aligned. This means an 2GB - * aperture won't have much chances to find a place in the - * lower 4GB of memory. Unfortunately we cannot move it up - * because that would make the IOMMU useless. + * Aperture has to be naturally aligned. This means an 2GB aperture won't + * have much chances to find a place in the lower 4GB of memory. + * Unfortunately we cannot move it up because that would make the + * IOMMU useless. */ - - /* First try to find some free unused space */ - if (!allocate_resource(&iomem_resource, &aper_res, - aper_size, - 0, 0xffffffff, - aper_size, - NULL, NULL)) { - printk(KERN_INFO "Putting aperture at %lx-%lx\n", - aper_res.start, aper_res.end); - return aper_res.start; - } - - /* No free space found. Go on to waste some memory... */ p = __alloc_bootmem_node(nd0, aper_size, aper_size, 0); if (!p || __pa(p)+aper_size > 0xffffffff) { printk("Cannot allocate aperture memory hole (%p,%uK)\n", @@ -81,7 +66,7 @@ static u32 __init allocate_aperture(void) free_bootmem_node(nd0, (unsigned long)p, aper_size); return 0; } - printk("Mapping aperture over %d KB of precious RAM @ %lx\n", + printk("Mapping aperture over %d KB of RAM @ %lx\n", aper_size >> 10, __pa(p)); return (u32)__pa(p); } @@ -102,16 +87,10 @@ static int __init aperture_valid(char *name, u64 aper_base, u32 aper_size) printk("Aperture from %s pointing to e820 RAM. Ignoring.\n",name); return 0; } - /* Don't check the resource here because the aperture is usually - in an e820 reserved area, and we allocated these earlier. */ return 1; } -/* - * Find a PCI capability. - * This code runs before the PCI subsystem is initialized, so just - * access the northbridge directly. - */ +/* Find a PCI capability */ static __u32 __init find_cap(int num, int slot, int func, int cap) { u8 pos; @@ -276,6 +255,8 @@ void __init iommu_hole_init(void) fallback_aper_force) { printk("Your BIOS doesn't leave a aperture memory hole\n"); printk("Please enable the IOMMU option in the BIOS setup\n"); + printk("This costs you %d MB of RAM\n", + 32 << fallback_aper_order); aper_order = fallback_aper_order; aper_alloc = allocate_aperture(); diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index d1dcd8eae3c..5b77188527a 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -39,7 +39,8 @@ 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) - 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) + 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) endif endif diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index 9e65bfb85ba..5f702199543 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c @@ -383,8 +383,7 @@ fore200e_shutdown(struct fore200e* fore200e) switch(fore200e->state) { case FORE200E_STATE_COMPLETE: - if (fore200e->stats) - kfree(fore200e->stats); + kfree(fore200e->stats); case FORE200E_STATE_IRQ: free_irq(fore200e->irq, fore200e->atm_dev); @@ -963,8 +962,7 @@ fore200e_tx_irq(struct fore200e* fore200e) entry, txq->tail, entry->vc_map, entry->skb); /* free copy of misaligned data */ - if (entry->data) - kfree(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/drivers/atm/he.c b/drivers/atm/he.c index 3022c548a13..df2c83fd549 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c @@ -412,8 +412,7 @@ 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); - if (he_dev) - kfree(he_dev); + kfree(he_dev); pci_disable_device(pci_dev); return err; } @@ -2534,8 +2533,7 @@ he_open(struct atm_vcc *vcc) open_failed: if (err) { - if (he_vcc) - kfree(he_vcc); + kfree(he_vcc); clear_bit(ATM_VF_ADDR, &vcc->flags); } else diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 85bf5c8442b..b2a7b754fd1 100644 --- a/drivers/atm/nicstar.c +++ b/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 = (scq_info *) NULL; - card->scq2 = (scq_info *) NULL; + card->scq1 = NULL; + card->scq2 = NULL; card->scq0 = get_scq(VBR_SCQSIZE, NS_VRSCD0); - if (card->scq0 == (scq_info *) NULL) + if (card->scq0 == 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 (scq_info *) NULL; + return NULL; scq = (scq_info *) kmalloc(sizeof(scq_info), GFP_KERNEL); - if (scq == (scq_info *) NULL) - return (scq_info *) NULL; + if (scq == NULL) + return NULL; scq->org = kmalloc(2 * size, GFP_KERNEL); if (scq->org == NULL) { kfree(scq); - return (scq_info *) NULL; + return NULL; } scq->skb = (struct sk_buff **) kmalloc(sizeof(struct sk_buff *) * (size / NS_SCQE_SIZE), GFP_KERNEL); - if (scq->skb == (struct sk_buff **) NULL) + if (scq->skb == NULL) { kfree(scq->org); kfree(scq); - return (scq_info *) NULL; + return 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 == (scq_info *) NULL) + if (scq == NULL) { PRINTK("nicstar%d: can't get fixed rate SCQ.\n", card->index); card->scd2vc[frscdi] = NULL; diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 47a800519ad..8d5e65cb975 100644 --- a/drivers/atm/zatm.c +++ b/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); } - if (zatm_vcc->ring) kfree(zatm_vcc->ring); + kfree(zatm_vcc->ring); } @@ -1339,12 +1339,9 @@ static int __init zatm_start(struct atm_dev *dev) return 0; out: for (i = 0; i < NR_MBX; i++) - 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); + kfree(zatm_dev->mbx_start[i]); + kfree(zatm_dev->rx_map); + kfree(zatm_dev->tx_map); free_irq(zatm_dev->irq, dev); return error; } diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index 0ef7a0065ec..2210bacad56 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c @@ -1202,13 +1202,16 @@ retry: if (new_cfqq) { cfqq = new_cfqq; new_cfqq = NULL; - } else if (gfp_mask & __GFP_WAIT) { + } else { spin_unlock_irq(cfqd->queue->queue_lock); new_cfqq = kmem_cache_alloc(cfq_pool, gfp_mask); spin_lock_irq(cfqd->queue->queue_lock); + + if (!new_cfqq && !(gfp_mask & __GFP_WAIT)) + goto out; + goto retry; - } else - goto out; + } memset(cfqq, 0, sizeof(*cfqq)); diff --git a/drivers/block/elevator.c b/drivers/block/elevator.c index 6b79b431462..89982925f9e 100644 --- a/drivers/block/elevator.c +++ b/drivers/block/elevator.c @@ -220,11 +220,6 @@ void elevator_exit(elevator_t *e) kfree(e); } -static int elevator_global_init(void) -{ - return 0; -} - int elv_merge(request_queue_t *q, struct request **req, struct bio *bio) { elevator_t *e = q->elevator; @@ -322,7 +317,7 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, int nrq = q->rq.count[READ] + q->rq.count[WRITE] - q->in_flight; - if (nrq == q->unplug_thresh) + if (nrq >= q->unplug_thresh) __generic_unplug_device(q); } } else @@ -692,8 +687,6 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) return len; } -module_init(elevator_global_init); - EXPORT_SYMBOL(elv_add_request); EXPORT_SYMBOL(__elv_add_request); EXPORT_SYMBOL(elv_requeue_request); diff --git a/drivers/block/ub.c b/drivers/block/ub.c index ce42889f98f..19c5e59bcfa 100644 --- a/drivers/block/ub.c +++ b/drivers/block/ub.c @@ -8,13 +8,12 @@ * 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 @@ -49,7 +48,14 @@ #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 9 + +/* + */ + #define UB_MINORS_PER_MAJOR 8 #define UB_MAX_CDB_SIZE 16 /* Corresponds to Bulk */ @@ -65,7 +71,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 normally 0 */ + u8 Lun; /* LUN */ u8 Length; /* of of the CDB */ u8 CDB[UB_MAX_CDB_SIZE]; /* max command */ }; @@ -168,6 +174,7 @@ 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; }; @@ -252,25 +259,47 @@ struct ub_scsi_cmd_queue { }; /* - * The UB device instance. + * 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. */ 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; - int changed; /* Media was changed */ - int removable; - int readonly; - int first_open; /* Kludge. See ub_bd_open. */ - char name[8]; + char name[12]; struct usb_device *dev; struct usb_interface *intf; - struct ub_capacity capacity; - struct gendisk *disk; + struct list_head luns; unsigned int send_bulk_pipe; /* cached pipe values */ unsigned int recv_bulk_pipe; @@ -279,10 +308,6 @@ 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]; @@ -301,9 +326,9 @@ struct ub_dev { /* */ static void ub_cleanup(struct ub_dev *sc); -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_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_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); @@ -320,8 +345,10 @@ 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); -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret); +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); /* */ @@ -342,6 +369,7 @@ 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 */ /* @@ -406,6 +434,8 @@ 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; @@ -421,9 +451,15 @@ 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 changed %d removable %d readonly %d\n", - sc->cmd_queue.qlen, sc->cmd_queue.qmax, - sc->changed, sc->removable, sc->readonly); + "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); + } if ((nc = sc->tr.cur + 1) == SCMD_TRACE_SZ) nc = 0; for (j = 0; j < SCMD_TRACE_SZ; j++) { @@ -523,53 +559,63 @@ 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; - /* I don't think queue can be NULL. But... Stolen from sx8.c */ - if ((q = sc->disk->queue) != NULL) - blk_cleanup_queue(q); + while (!list_empty(&sc->luns)) { + p = sc->luns.next; + lun = list_entry(p, struct ub_lun, link); + list_del(p); - /* - * 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; + /* 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; + + ub_id_put(lun->id); + kfree(lun); + } - ub_id_put(sc->id); kfree(sc); } /* * The "command allocator". */ -static struct ub_scsi_cmd *ub_get_cmd(struct ub_dev *sc) +static struct ub_scsi_cmd *ub_get_cmd(struct ub_lun *lun) { struct ub_scsi_cmd *ret; - if (sc->cmda[0]) + if (lun->cmda[0]) return NULL; - ret = &sc->cmdv[0]; - sc->cmda[0] = 1; + ret = &lun->cmdv[0]; + lun->cmda[0] = 1; return ret; } -static void ub_put_cmd(struct ub_dev *sc, struct ub_scsi_cmd *cmd) +static void ub_put_cmd(struct ub_lun *lun, struct ub_scsi_cmd *cmd) { - if (cmd != &sc->cmdv[0]) { + if (cmd != &lun->cmdv[0]) { printk(KERN_WARNING "%s: releasing a foreign cmd %p\n", - sc->name, cmd); + lun->name, cmd); return; } - if (!sc->cmda[0]) { - printk(KERN_WARNING "%s: releasing a free cmd\n", sc->name); + if (!lun->cmda[0]) { + printk(KERN_WARNING "%s: releasing a free cmd\n", lun->name); return; } - sc->cmda[0] = 0; + lun->cmda[0] = 0; } /* @@ -630,29 +676,30 @@ static struct ub_scsi_cmd *ub_cmdq_pop(struct ub_dev *sc) static void ub_bd_rq_fn(request_queue_t *q) { - struct ub_dev *sc = q->queuedata; + struct ub_lun *lun = q->queuedata; struct request *rq; while ((rq = elv_next_request(q)) != NULL) { - if (ub_bd_rq_fn_1(sc, rq) != 0) { + if (ub_bd_rq_fn_1(lun, rq) != 0) { blk_stop_queue(q); break; } } } -static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) +static int ub_bd_rq_fn_1(struct ub_lun *lun, struct request *rq) { + struct ub_dev *sc = lun->udev; struct ub_scsi_cmd *cmd; int rc; - if (atomic_read(&sc->poison) || sc->changed) { + if (atomic_read(&sc->poison) || lun->changed) { blkdev_dequeue_request(rq); ub_end_rq(rq, 0); return 0; } - if ((cmd = ub_get_cmd(sc)) == NULL) + if ((cmd = ub_get_cmd(lun)) == NULL) return -1; memset(cmd, 0, sizeof(struct ub_scsi_cmd)); @@ -661,32 +708,30 @@ static int ub_bd_rq_fn_1(struct ub_dev *sc, struct request *rq) if (blk_pc_request(rq)) { rc = ub_cmd_build_packet(sc, cmd, rq); } else { - rc = ub_cmd_build_block(sc, cmd, rq); + rc = ub_cmd_build_block(sc, lun, cmd, rq); } if (rc != 0) { - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, 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(sc, cmd); + ub_put_cmd(lun, 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_scsi_cmd *cmd, - 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) { int ub_dir; #if 0 /* We use rq->buffer for now */ @@ -707,7 +752,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, sg = &cmd->sgv[0]; n_elem = blk_rq_map_sg(q, rq, sg); if (n_elem <= 0) { - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; /* request with no s/g entries? */ @@ -716,7 +761,7 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, if (n_elem != 1) { /* Paranoia */ printk(KERN_WARNING "%s: request with %d segments\n", sc->name, n_elem); - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, 0); blk_start_queue(q); return 0; @@ -748,8 +793,8 @@ static int ub_cmd_build_block(struct ub_dev *sc, struct ub_scsi_cmd *cmd, * 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 >> sc->capacity.bshift; - nblks = rq->nr_sectors >> sc->capacity.bshift; + block = rq->sector >> lun->capacity.bshift; + nblks = rq->nr_sectors >> lun->capacity.bshift; cmd->cdb[0] = (ub_dir == UB_DIR_READ)? READ_10: WRITE_10; /* 10-byte uses 4 bytes of LBA: 2147483648KB, 2097152MB, 2048GB */ @@ -803,7 +848,8 @@ 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 gendisk *disk = sc->disk; + struct ub_lun *lun = cmd->lun; + struct gendisk *disk = lun->disk; request_queue_t *q = disk->queue; int uptodate; @@ -818,7 +864,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd) else uptodate = 0; - ub_put_cmd(sc, cmd); + ub_put_cmd(lun, cmd); ub_end_rq(rq, uptodate); blk_start_queue(q); } @@ -887,7 +933,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 = 0; /* No multi-LUN yet */ + bcb->Lun = (cmd->lun != NULL) ? cmd->lun->num : 0; bcb->Length = cmd->cdb_len; /* copy the command payload */ @@ -1002,9 +1048,8 @@ 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 for device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: stall on control pipe\n", + sc->name); goto Bad_End; } @@ -1025,9 +1070,8 @@ 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 for device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: stall on control pipe\n", + sc->name); goto Bad_End; } @@ -1046,9 +1090,8 @@ 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 for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1107,9 +1150,8 @@ 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 for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1140,9 +1182,8 @@ 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 for device %u" - " (code %d)\n", - sc->name, sc->dev->devnum, rc); + "unable to submit clear (%d)\n", + sc->name, rc); /* * This is typically ENOMEM or some other such shit. * Retrying is pointless. Just do Bad End on it... @@ -1164,9 +1205,8 @@ 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 on device %u\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: unable to get CSW\n", + sc->name); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1207,10 +1247,8 @@ 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 " - "on device %u\n", - sc->name, cmd->tag, bcs->Tag, - sc->dev->devnum); + "tag mismatch orig 0x%x reply 0x%x\n", + sc->name, cmd->tag, bcs->Tag); goto Bad_End; } __ub_state_stat(sc, cmd); @@ -1244,8 +1282,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 on device %u\n", - sc->name, cmd->state, sc->dev->devnum); + "wrong command state %d\n", + sc->name, cmd->state); goto Bad_End; } return; @@ -1288,7 +1326,6 @@ 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; @@ -1333,6 +1370,7 @@ 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; @@ -1411,14 +1449,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 on device %u\n", - sc->name, cmd->tag, sc->dev->devnum); + "sense done for wrong command 0x%x\n", + sc->name, cmd->tag); return; } if (cmd->state != UB_CMDST_SENSE) { printk(KERN_WARNING "%s: " - "sense done with bad cmd state %d on device %u\n", - sc->name, cmd->state, sc->dev->devnum); + "sense done with bad cmd state %d\n", + sc->name, cmd->state); return; } @@ -1429,68 +1467,32 @@ 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) +static void ub_revalidate(struct ub_dev *sc, struct ub_lun *lun) { - sc->readonly = 0; /* XXX Query this from the device */ + lun->readonly = 0; /* XXX Query this from the device */ - sc->capacity.nsec = 0; - sc->capacity.bsize = 512; - sc->capacity.bshift = 0; + lun->capacity.nsec = 0; + lun->capacity.bsize = 512; + lun->capacity.bshift = 0; - if (ub_sync_tur(sc) != 0) + if (ub_sync_tur(sc, lun) != 0) return; /* Not ready */ - sc->changed = 0; + lun->changed = 0; - if (ub_sync_read_cap(sc, &sc->capacity) != 0) { + if (ub_sync_read_cap(sc, lun, &lun->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, &sc->capacity) != 0) { - sc->capacity.nsec = 0; - sc->capacity.bsize = 512; - sc->capacity.bshift = 0; + if (ub_sync_read_cap(sc, lun, &lun->capacity) != 0) { + lun->capacity.nsec = 0; + lun->capacity.bsize = 512; + lun->capacity.bshift = 0; } } } @@ -1503,12 +1505,15 @@ static void ub_revalidate(struct ub_dev *sc) 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 ((sc = disk->private_data) == NULL) + if ((lun = 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); @@ -1529,15 +1534,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 (sc->first_open) { - if (sc->changed) { - sc->first_open = 0; + if (lun->first_open) { + lun->first_open = 0; + if (lun->changed) { rc = -ENOMEDIUM; goto err_open; } } - if (sc->removable || sc->readonly) + if (lun->removable || lun->readonly) check_disk_change(inode->i_bdev); /* @@ -1545,12 +1550,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 (sc->removable && sc->changed && !(filp->f_flags & O_NDELAY)) { + if (lun->removable && lun->changed && !(filp->f_flags & O_NDELAY)) { rc = -ENOMEDIUM; goto err_open; } - if (sc->readonly && (filp->f_mode & FMODE_WRITE)) { + if (lun->readonly && (filp->f_mode & FMODE_WRITE)) { rc = -EROFS; goto err_open; } @@ -1567,7 +1572,8 @@ err_open: static int ub_bd_release(struct inode *inode, struct file *filp) { struct gendisk *disk = inode->i_bdev->bd_disk; - struct ub_dev *sc = disk->private_data; + struct ub_lun *lun = disk->private_data; + struct ub_dev *sc = lun->udev; ub_put(sc); return 0; @@ -1597,20 +1603,14 @@ static int ub_bd_ioctl(struct inode *inode, struct file *filp, */ static int ub_bd_revalidate(struct gendisk *disk) { - 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); - } + struct ub_lun *lun = disk->private_data; + + ub_revalidate(lun->udev, lun); /* XXX Support sector size switching like in sr.c */ - blk_queue_hardsect_size(disk->queue, sc->capacity.bsize); - set_capacity(disk, sc->capacity.nsec); - // set_disk_ro(sdkp->disk, sc->readonly); + blk_queue_hardsect_size(disk->queue, lun->capacity.bsize); + set_capacity(disk, lun->capacity.nsec); + // set_disk_ro(sdkp->disk, lun->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_dev *sc = disk->private_data; + struct ub_lun *lun = disk->private_data; - if (!sc->removable) + if (!lun->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(sc) != 0) { - sc->changed = 1; + if (ub_sync_tur(lun->udev, lun) != 0) { + lun->changed = 1; return 1; } - return sc->changed; + return lun->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) +static int ub_sync_tur(struct ub_dev *sc, struct ub_lun *lun) { struct ub_scsi_cmd *cmd; enum { ALLOC_SIZE = sizeof(struct ub_scsi_cmd) }; @@ -1688,6 +1688,7 @@ static int ub_sync_tur(struct ub_dev *sc) 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; @@ -1718,7 +1719,8 @@ err_alloc: /* * Read the SCSI capacity synchronously (for probing). */ -static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) +static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun, + struct ub_capacity *ret) { struct ub_scsi_cmd *cmd; char *p; @@ -1743,6 +1745,7 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_capacity *ret) cmd->state = UB_CMDST_INIT; cmd->data = p; cmd->len = 8; + cmd->lun = lun; cmd->done = ub_probe_done; cmd->back = &compl; @@ -1812,6 +1815,90 @@ static void ub_probe_timeout(unsigned long arg) } /* + * 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. */ static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe) @@ -1897,8 +1984,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: device %u failed endpoint check\n", - sc->name, sc->dev->devnum); + printk(KERN_NOTICE "%s: failed endpoint check\n", + sc->name); return -EIO; } @@ -1921,8 +2008,7 @@ static int ub_probe(struct usb_interface *intf, const struct usb_device_id *dev_id) { struct ub_dev *sc; - request_queue_t *q; - struct gendisk *disk; + int nluns; int rc; int i; @@ -1931,6 +2017,7 @@ 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); @@ -1942,19 +2029,16 @@ 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); @@ -1992,35 +2076,88 @@ 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)) <= 0) break; + if ((rc = ub_sync_tur(sc, NULL)) <= 0) break; if (rc != 0x6) break; msleep(10); } - sc->removable = 1; /* XXX Query this from the device */ - sc->changed = 1; /* ub_revalidate clears only */ - sc->first_open = 1; + 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; + } + msleep(100); + } - 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); + 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); - /* - * Just one disk per sc currently, but maybe more. - */ rc = -ENOMEM; if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL) goto err_diskalloc; - sc->disk = disk; - sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a'); - sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a'); + lun->disk = disk; + sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a'); + sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a'); disk->major = UB_MAJOR; - disk->first_minor = sc->id * UB_MINORS_PER_MAJOR; + disk->first_minor = lun->id * UB_MINORS_PER_MAJOR; disk->fops = &ub_bd_fops; - disk->private_data = sc; - disk->driverfs_dev = &intf->dev; + disk->private_data = lun; + disk->driverfs_dev = &sc->intf->dev; /* XXX Many to one ok? */ rc = -ENOMEM; if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL) @@ -2028,28 +2165,17 @@ static int ub_probe(struct usb_interface *intf, disk->queue = q; - // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask); + blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH); 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, CARM_SG_BOUNDARY); + blk_queue_segment_boundary(q, 0xffffffff); /* Dubious. */ blk_queue_max_sectors(q, UB_MAX_SECTORS); - 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; + blk_queue_hardsect_size(q, lun->capacity.bsize); - q->queuedata = sc; + q->queuedata = lun; - set_capacity(disk, sc->capacity.nsec); - if (sc->removable) + set_capacity(disk, lun->capacity.nsec); + if (lun->removable) disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); @@ -2059,22 +2185,20 @@ static int ub_probe(struct usb_interface *intf, err_blkqinit: put_disk(disk); err_diskalloc: - 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); + list_del(&lun->link); + ub_id_put(lun->id); err_id: - kfree(sc); -err_core: + kfree(lun); +err_alloc: return rc; } static void ub_disconnect(struct usb_interface *intf) { struct ub_dev *sc = usb_get_intfdata(intf); - struct gendisk *disk = sc->disk; + struct list_head *p; + struct ub_lun *lun; + struct gendisk *disk; unsigned long flags; /* @@ -2124,14 +2248,18 @@ static void ub_disconnect(struct usb_interface *intf) /* * Unregister the upper layer. */ - 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. - */ + 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. + */ + } /* * Taking a lock on a structure which is about to be freed @@ -2182,8 +2310,8 @@ static int __init ub_init(void) { int rc; - /* P3 */ printk("ub: sizeof ub_scsi_cmd %zu ub_dev %zu\n", - sizeof(struct ub_scsi_cmd), sizeof(struct ub_dev)); + /* 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)); if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0) goto err_regblkdev; diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index ad9c11391d8..c1fe013c64f 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -278,6 +278,8 @@ 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/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index 0212febda65..9c9c9c2247c 100644 --- a/drivers/char/agp/ali-agp.c +++ b/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_phys(addr)) | ALI_CACHE_FLUSH_EN )); + virt_to_gart(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_phys(addr)) | ALI_CACHE_FLUSH_EN)); + virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); agp_generic_destroy_page(addr); } diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index e62a3c2c44a..3a41672e4d6 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/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_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(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_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(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_phys(amd_irongate_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(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/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 399c042f68f..1407945a589 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/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_phys(agp_bridge->gatt_table_real); + unsigned long gatt_bus = virt_to_gart(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_phys(bridge->gatt_table_real), + release_mem_region(virt_to_gart(bridge->gatt_table_real), amd64_aperture_sizes[bridge->aperture_size_idx].size); agp_remove_bridge(bridge); agp_put_bridge(bridge); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index a65f8827c28..e572ced9100 100644 --- a/drivers/char/agp/ati-agp.c +++ b/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_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(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_bus(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(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_bus(ati_generic_private.gatt_pages[i]->real) | 1, + writel(virt_to_gart(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/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 2f3dfb63bdc..4d4e602fdc7 100644 --- a/drivers/char/agp/backend.c +++ b/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_phys(addr); + bridge->scratch_page_real = virt_to_gart(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( - phys_to_virt(bridge->scratch_page_real)); + gart_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( - phys_to_virt(bridge->scratch_page_real)); + gart_to_virt(bridge->scratch_page_real)); } /* When we remove the global variable agp_bridge from all drivers diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 1383c3165ea..ac19fdcd21c 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/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 = __pa(page) | pati | present | index; + value = virt_to_gart(page) | pati | present | index; pci_write_config_dword(agp_bridge->dev, EFFICEON_ATTPAGE, value); diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index c321a924e38..f0079e991bd 100644 --- a/drivers/char/agp/generic.c +++ b/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(phys_to_virt(curr->memory[i])); + curr->bridge->driver->agp_destroy_page(gart_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_phys(addr); + new->memory[i] = virt_to_gart(addr); new->page_count++; } new->bridge = bridge; @@ -295,19 +295,6 @@ 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 * @@ -328,7 +315,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 (check_bridge_mode(bridge->dev)) + if (bridge->mode & AGPSTAT_MODE_3_0) info->mode = bridge->mode & ~AGP3_RESERVED_MASK; else info->mode = bridge->mode & ~AGP2_RESERVED_MASK; @@ -661,7 +648,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 (check_bridge_mode(agp_bridge->dev)) + if (agp_bridge->mode & AGPSTAT_MODE_3_0) agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); else agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); @@ -732,7 +719,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode) /* Do AGP version specific frobbing. */ if (bridge->major_version >= 3) { - if (check_bridge_mode(bridge->dev)) { + if (bridge->mode & AGPSTAT_MODE_3_0) { /* If we have 3.5, we can do the isoch stuff. */ if (bridge->minor_version >= 5) agp_3_5_enable(bridge); @@ -806,8 +793,7 @@ int agp_generic_create_gatt_table(struct agp_bridge_data *bridge) break; } - table = (char *) __get_free_pages(GFP_KERNEL, - page_order); + table = alloc_gatt_pages(page_order); if (table == NULL) { i++; @@ -838,7 +824,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 = (char *) __get_free_pages(GFP_KERNEL, page_order); + table = alloc_gatt_pages(page_order); } if (table == NULL) @@ -853,7 +839,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_phys(table), + bridge->gatt_table = ioremap_nocache(virt_to_gart(table), (PAGE_SIZE * (1 << page_order))); bridge->driver->cache_flush(); @@ -861,11 +847,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_pages((unsigned long) table, page_order); + free_gatt_pages(table, page_order); return -ENOMEM; } - bridge->gatt_bus_addr = virt_to_phys(bridge->gatt_table_real); + bridge->gatt_bus_addr = virt_to_gart(bridge->gatt_table_real); /* AK: bogus, should encode addresses > 4GB */ for (i = 0; i < num_entries; i++) { @@ -919,7 +905,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_pages((unsigned long) bridge->gatt_table_real, page_order); + free_gatt_pages(bridge->gatt_table_real, page_order); agp_gatt_table = NULL; bridge->gatt_table = NULL; diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 6052bfa04c7..99762b6c19a 100644 --- a/drivers/char/agp/hp-agp.c +++ b/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 = phys_to_virt(readq(hp->ioc_regs+HP_ZX1_PDIR_BASE)); + hp->io_pdir = gart_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_phys(hp->io_pdir), hp->ioc_regs+HP_ZX1_PDIR_BASE); + writel(virt_to_gart(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/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index adbea896c0d..94943298c03 100644 --- a/drivers/char/agp/i460-agp.c +++ b/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_phys(lpage); + lp->paddr = virt_to_gart(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) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); + free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); } diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 8c7d727432b..51266d6b4d7 100644 --- a/drivers/char/agp/intel-agp.c +++ b/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_phys(addr); + new->memory[0] = virt_to_gart(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(phys_to_virt(curr->memory[0])); + i8xx_destroy_pages(gart_to_virt(curr->memory[0])); else agp_bridge->driver->agp_destroy_page( - phys_to_virt(curr->memory[0])); + gart_to_virt(curr->memory[0])); vfree(curr->memory); } kfree(curr); @@ -418,7 +418,8 @@ 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_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(48) - KB(size); else gtt_entries = 0; @@ -426,7 +427,8 @@ 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_82915GM_HB || + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82945G_HB) gtt_entries = MB(64) - KB(size); else gtt_entries = 0; @@ -1662,6 +1664,14 @@ 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"; @@ -1801,6 +1811,7 @@ 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/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 4b3eda26797..d3aa159c9de 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -133,11 +133,14 @@ 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) { @@ -175,7 +178,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 (*(bridge->gatt_table + j)) + if (table[j]) return -EBUSY; j++; } @@ -186,7 +189,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++) { - *(bridge->gatt_table + j) = + table[j] = bridge->driver->mask_memory(bridge, mem->memory[i], mem->type); } @@ -200,6 +203,7 @@ 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) @@ -209,8 +213,10 @@ 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++) { - *(bridge->gatt_table + i) = 0; + table[i] = 0; } bridge->driver->tlb_flush(mem); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 10c23302dd8..a9fb12c20eb 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/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_phys(page_map->real), + page_map->remapped = ioremap_nocache(virt_to_gart(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_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i); + writel(virt_to_gart(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_phys(page_dir.real); + agp_bridge->gatt_bus_addr = virt_to_gart(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_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); + writel(virt_to_gart(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i); return 0; } diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a673971f2a9..c8255312b8c 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/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_phys(table); + bridge->gatt_bus_addr = virt_to_gart(table); for (i = 0; i < num_entries; i++) bridge->gatt_table[i] = 0; diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 54a2914e3a3..11c6950158b 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h @@ -220,5 +220,6 @@ {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ + {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ {0, 0, 0} diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c index 5b18bee6492..cd25f28e26a 100644 --- a/drivers/char/drm/radeon_irq.c +++ b/drivers/char/drm/radeon_irq.c @@ -123,11 +123,6 @@ static int radeon_wait_irq(drm_device_t *dev, int swi_nr) dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE; - /* This is a hack to work around mysterious freezes on certain - * systems: - */ - radeon_acknowledge_irqs( dev_priv ); - DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr ); diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index 7a245068e3e..f022f094443 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c @@ -1995,9 +1995,6 @@ 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; @@ -2011,10 +2008,6 @@ 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) { @@ -2041,12 +2034,10 @@ static void mxser_receive_chars(struct mxser_struct *info, int *status) } while (gdl--) { ch = inb(info->base + UART_RX); - count++; - *cp++ = ch; - *fp++ = 0; + tty_insert_flip_char(tty, ch, 0); cnt++; /* - if((count>=HI_WATER) && (info->stop_rx==0)){ + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2061,7 +2052,7 @@ intr_old: if (max-- < 0) break; /* - if((count>=HI_WATER) && (info->stop_rx==0)){ + if((cnt>=HI_WATER) && (info->stop_rx==0)){ mxser_stoprx(tty); info->stop_rx=1; break; @@ -2078,36 +2069,33 @@ intr_old: if (++ignored > 100) break; } else { - count++; + char flag = 0; if (*status & UART_LSR_SPECIAL) { if (*status & UART_LSR_BI) { - *fp++ = TTY_BREAK; + flag = 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) { - *fp++ = TTY_PARITY; + flag = TTY_PARITY; /* added by casper 1/11/2000 */ info->icount.parity++; /* */ } else if (*status & UART_LSR_FE) { - *fp++ = TTY_FRAME; + flag = TTY_FRAME; /* added by casper 1/11/2000 */ info->icount.frame++; /* */ } else if (*status & UART_LSR_OE) { - *fp++ = TTY_OVERRUN; + flag = TTY_OVERRUN; /* added by casper 1/11/2000 */ info->icount.overrun++; /* */ - } else - *fp++ = 0; - } else - *fp++ = 0; - *cp++ = ch; + } + } + tty_insert_flip_char(tty, ch, flag); cnt++; if (cnt >= recv_room) { if (!info->ldisc_stop_rx) { @@ -2132,13 +2120,13 @@ intr_old: // 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/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 00c7b958361..ab82d6addd7 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -745,7 +745,8 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); /* Register our host with the SCSI stack. */ - scsi_host = scsi_host_alloc(&scsi_driver_template, 0); + scsi_host = scsi_host_alloc(&scsi_driver_template, + sizeof (unsigned long)); if (!scsi_host) { SBP2_ERR("failed to register scsi host"); goto failed_alloc; diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index af0446c6de8..48fdf1e517c 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/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 = 1; +static int atkbd_scroll = 0; module_param_named(scroll, atkbd_scroll, bool, 0); MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 42a9f7f6f8c..7bf4be733e9 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -352,7 +352,7 @@ static int alps_reconnect(struct psmouse *psmouse) if (alps_get_status(psmouse, param)) return -1; - if (param[0] & 0x04) + if (!(param[0] & 0x04)) alps_tap_mode(psmouse, 1); if (alps_absolute_mode(psmouse)) { diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index bb9f4044c74..b941ee22099 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2593,6 +2593,9 @@ powerbook_sleep_Core99(void) /* Restore VIA */ restore_via_state(); + /* tweak LPJ before cpufreq is there */ + loops_per_jiffy *= 2; + /* Restore video */ pmac_call_early_video_resume(); @@ -2613,6 +2616,9 @@ powerbook_sleep_Core99(void) pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask); pmu_wait_complete(&req); + /* Restore LPJ, cpufreq will adjust the cpu frequency */ + loops_per_jiffy /= 2; + pmac_wakeup_devices(); return 0; diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 1e97b3c12bd..0c1b8520ef8 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c @@ -985,6 +985,9 @@ static int do_end_io(struct multipath *m, struct bio *bio, if (!error) return 0; /* I/O complete */ + if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) + return error; + spin_lock(&m->lock); if (!m->nr_valid_paths) { if (!m->queue_if_no_path || m->suspended) { diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index 7b74c87b569..4830b775906 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -573,6 +573,7 @@ static int i2o_block_reply(struct i2o_controller *c, u32 m, static void i2o_block_event(struct i2o_event *evt) { osm_info("block-osm: event received\n"); + kfree(evt); }; /* diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 1c563f905a5..a7f15d9f13e 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -374,29 +374,6 @@ static inline void do_kiss_params(struct baycom_state *bc, } /* --------------------------------------------------------------------- */ -/* - * high performance HDLC encoder - * yes, it's ugly, but generates pretty good code - */ - -#define ENCODEITERA(j) \ -({ \ - if (!(notbitstream & (0x1f0 << j))) \ - goto stuff##j; \ - encodeend##j: ; \ -}) - -#define ENCODEITERB(j) \ -({ \ - stuff##j: \ - bitstream &= ~(0x100 << j); \ - bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | \ - ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); \ - numbit++; \ - notbitstream = ~bitstream; \ - goto encodeend##j; \ -}) - static void encode_hdlc(struct baycom_state *bc) { @@ -405,6 +382,7 @@ static void encode_hdlc(struct baycom_state *bc) int pkt_len; unsigned bitstream, notbitstream, bitbuf, numbit, crc; unsigned char crcarr[2]; + int j; if (bc->hdlctx.bufcnt > 0) return; @@ -429,24 +407,14 @@ static void encode_hdlc(struct baycom_state *bc) pkt_len--; if (!pkt_len) bp = crcarr; - ENCODEITERA(0); - ENCODEITERA(1); - ENCODEITERA(2); - ENCODEITERA(3); - ENCODEITERA(4); - ENCODEITERA(5); - ENCODEITERA(6); - ENCODEITERA(7); - goto enditer; - ENCODEITERB(0); - ENCODEITERB(1); - ENCODEITERB(2); - ENCODEITERB(3); - ENCODEITERB(4); - ENCODEITERB(5); - ENCODEITERB(6); - ENCODEITERB(7); - enditer: + for (j = 0; j < 8; j++) + if (unlikely(!(notbitstream & (0x1f0 << j)))) { + bitstream &= ~(0x100 << j); + bitbuf = (bitbuf & (((2 << j) << numbit) - 1)) | + ((bitbuf & ~(((2 << j) << numbit) - 1)) << 1); + numbit++; + notbitstream = ~bitstream; + } numbit += 8; while (numbit >= 8) { *wp++ = bitbuf; @@ -610,37 +578,6 @@ static void do_rxpacket(struct net_device *dev) bc->stats.rx_packets++; } -#define DECODEITERA(j) \ -({ \ - if (!(notbitstream & (0x0fc << j))) /* flag or abort */ \ - goto flgabrt##j; \ - if ((bitstream & (0x1f8 << j)) == (0xf8 << j)) /* stuffed bit */ \ - goto stuff##j; \ - enditer##j: ; \ -}) - -#define DECODEITERB(j) \ -({ \ - flgabrt##j: \ - if (!(notbitstream & (0x1fc << j))) { /* abort received */ \ - state = 0; \ - goto enditer##j; \ - } \ - if ((bitstream & (0x1fe << j)) != (0x0fc << j)) /* flag received */ \ - goto enditer##j; \ - if (state) \ - do_rxpacket(dev); \ - bc->hdlcrx.bufcnt = 0; \ - bc->hdlcrx.bufptr = bc->hdlcrx.buf; \ - state = 1; \ - numbits = 7-j; \ - goto enditer##j; \ - stuff##j: \ - numbits--; \ - bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); \ - goto enditer##j; \ -}) - static int receive(struct net_device *dev, int cnt) { struct baycom_state *bc = netdev_priv(dev); @@ -649,6 +586,7 @@ static int receive(struct net_device *dev, int cnt) unsigned char tmp[128]; unsigned char *cp; int cnt2, ret = 0; + int j; numbits = bc->hdlcrx.numbits; state = bc->hdlcrx.state; @@ -669,24 +607,32 @@ static int receive(struct net_device *dev, int cnt) bitbuf |= (*cp) << 8; numbits += 8; notbitstream = ~bitstream; - DECODEITERA(0); - DECODEITERA(1); - DECODEITERA(2); - DECODEITERA(3); - DECODEITERA(4); - DECODEITERA(5); - DECODEITERA(6); - DECODEITERA(7); - goto enddec; - DECODEITERB(0); - DECODEITERB(1); - DECODEITERB(2); - DECODEITERB(3); - DECODEITERB(4); - DECODEITERB(5); - DECODEITERB(6); - DECODEITERB(7); - enddec: + for (j = 0; j < 8; j++) { + + /* flag or abort */ + if (unlikely(!(notbitstream & (0x0fc << j)))) { + + /* abort received */ + if (!(notbitstream & (0x1fc << j))) + state = 0; + + /* not flag received */ + else if (!(bitstream & (0x1fe << j)) != (0x0fc << j)) { + if (state) + do_rxpacket(dev); + bc->hdlcrx.bufcnt = 0; + bc->hdlcrx.bufptr = bc->hdlcrx.buf; + state = 1; + numbits = 7-j; + } + } + + /* stuffed bit */ + else if (unlikely((bitstream & (0x1f8 << j)) == (0xf8 << j))) { + numbits--; + bitbuf = (bitbuf & ((~0xff) << j)) | ((bitbuf & ~((~0xff) << j)) << 1); + } + } while (state && numbits >= 8) { if (bc->hdlcrx.bufcnt >= TXBUFFER_SIZE) { state = 0; diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig index 1c553d7efdd..ca5914091d3 100644 --- a/drivers/net/irda/Kconfig +++ b/drivers/net/irda/Kconfig @@ -389,7 +389,7 @@ config VIA_FIR help Say Y here if you want to build support for the VIA VT8231 and VIA VT1211 IrDA controllers, found on the motherboards using - those those VIA chipsets. To use this controller, you will need + those VIA chipsets. To use this controller, you will need to plug a specific 5 pins FIR IrDA dongle in the specific motherboard connector. The driver provides support for SIR, MIR and FIR (4Mbps) speeds. diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c index 13ed8dc1e91..55af32e9bf0 100644 --- a/drivers/net/iseries_veth.c +++ b/drivers/net/iseries_veth.c @@ -802,13 +802,14 @@ static void veth_tx_timeout(struct net_device *dev) spin_lock_irqsave(&port->pending_gate, flags); + if (!port->pending_lpmask) { + spin_unlock_irqrestore(&port->pending_gate, flags); + return; + } + printk(KERN_WARNING "%s: Tx timeout! Resetting lp connections: %08x\n", dev->name, port->pending_lpmask); - /* If we've timed out the queue must be stopped, which should - * only ever happen when there is a pending packet. */ - WARN_ON(! port->pending_lpmask); - for (i = 0; i < HVMAXARCHITECTEDLPS; i++) { struct veth_lpar_connection *cnx = veth_cnx[i]; diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 41e51711480..c6e8b25f968 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c @@ -1274,6 +1274,9 @@ 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/drivers/net/r8169.c b/drivers/net/r8169.c index c59507f8a76..d6d0e43dab6 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -415,7 +415,7 @@ struct rtl8169_private { struct work_struct task; }; -MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@oss.sgi.com>"); +MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); MODULE_DESCRIPTION("RealTek RTL-8169 Gigabit Ethernet driver"); module_param_array(media, int, &num_media, 0); module_param(rx_copybreak, int, 0); @@ -1585,8 +1585,8 @@ rtl8169_hw_start(struct net_device *dev) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W8(EarlyTxThres, EarlyTxThld); - /* For gigabit rtl8169, MTU + header + CRC + VLAN */ - RTL_W16(RxMaxSize, tp->rx_buf_sz); + /* Low hurts. Let's disable the filtering. */ + RTL_W16(RxMaxSize, 16383); /* Set Rx Config register */ i = rtl8169_rx_config | @@ -2127,6 +2127,11 @@ 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); @@ -2177,27 +2182,41 @@ 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(tp->RxDescArray[entry].opts1); + status = le32_to_cpu(desc->opts1); if (status & DescOwn) break; if (status & RxRES) { - printk(KERN_INFO "%s: Rx ERROR!!!\n", dev->name); + printk(KERN_INFO "%s: Rx ERROR. status = %08x\n", + dev->name, status); 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, @@ -2224,7 +2243,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/drivers/net/shaper.c b/drivers/net/shaper.c index e68cf5fb492..20edeb34579 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -100,35 +100,8 @@ 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 */ @@ -157,17 +130,15 @@ static void shaper_setspeed(struct shaper *shaper, int bitspersec) * Throw a frame at a shaper. */ -static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) + +static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { + struct shaper *shaper = dev->priv; struct sk_buff *ptr; - /* - * Get ready to work on this shaper. Lock may fail if its - * an interrupt and locked. - */ - - if(!shaper_lock(shaper)) - return -1; + if (down_trylock(&shaper->sem)) + return -1; + ptr=shaper->sendq.prev; /* @@ -260,7 +231,8 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb) dev_kfree_skb(ptr); shaper->stats.collisions++; } - shaper_unlock(shaper); + shaper_kick(shaper); + up(&shaper->sem); return 0; } @@ -297,8 +269,13 @@ static void shaper_queue_xmit(struct shaper *shaper, struct sk_buff *skb) static void shaper_timer(unsigned long data) { - struct shaper *sh=(struct shaper *)data; - shaper_kick(sh); + struct shaper *shaper = (struct shaper *)data; + + if (!down_trylock(&shaper->sem)) { + shaper_kick(shaper); + up(&shaper->sem); + } else + mod_timer(&shaper->timer, jiffies); } /* @@ -311,19 +288,6 @@ 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) */ @@ -364,8 +328,6 @@ static void shaper_kick(struct shaper *shaper) if(skb!=NULL) mod_timer(&shaper->timer, SHAPERCB(skb)->shapeclock); - - clear_bit(0, &shaper->locked); } @@ -376,14 +338,12 @@ static void shaper_kick(struct shaper *shaper) static void shaper_flush(struct shaper *shaper) { struct sk_buff *skb; - if(!shaper_lock(shaper)) - { - printk(KERN_ERR "shaper: shaper_flush() called by an irq!\n"); - return; - } + + down(&shaper->sem); while((skb=skb_dequeue(&shaper->sendq))!=NULL) dev_kfree_skb(skb); - shaper_unlock(shaper); + shaper_kick(shaper); + up(&shaper->sem); } /* @@ -426,13 +386,6 @@ 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; @@ -623,7 +576,6 @@ 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/drivers/net/tg3.c b/drivers/net/tg3.c index fc9b5cd957a..a0b8848049c 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -7,7 +7,12 @@ * Copyright (C) 2005 Broadcom Corporation. * * Firmware is: - * Copyright (C) 2000-2003 Broadcom Corporation. + * 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. */ #include <linux/config.h> @@ -61,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.29" -#define DRV_MODULE_RELDATE "May 23, 2005" +#define DRV_MODULE_VERSION "3.31" +#define DRV_MODULE_RELDATE "June 8, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -8555,6 +8560,16 @@ 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: @@ -9680,10 +9695,24 @@ static int __devinit tg3_test_dma(struct tg3 *tp) } if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != DMA_RWCTRL_WRITE_BNDRY_16) { + static struct pci_device_id dma_wait_state_chipsets[] = { + { PCI_DEVICE(PCI_VENDOR_ID_APPLE, + PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, + { }, + }; + /* DMA test passed without adjusting DMA boundary, - * just restore the calculated DMA boundary + * now look for chipsets that are known to expose the + * DMA bug without failing the test. */ - tp->dma_rwctrl = saved_dma_rwctrl; + if (pci_dev_present(dma_wait_state_chipsets)) { + tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; + tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; + } + else + /* Safe to use the calculated DMA boundary. */ + tp->dma_rwctrl = saved_dma_rwctrl; + tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); } diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 8132d946c38..30af105271a 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c @@ -217,6 +217,8 @@ static void release_slot(struct hotplug_slot *hotplug_slot) kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); + if (slot->dev) + pci_dev_put(slot->dev); kfree(slot); } diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index c878028ad21..225b5e551dd 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c @@ -315,9 +315,12 @@ int cpci_unconfigure_slot(struct slot* slot) PCI_DEVFN(PCI_SLOT(slot->devfn), i)); if (dev) { pci_remove_bus_device(dev); - slot->dev = NULL; + pci_dev_put(dev); } } + pci_dev_put(slot->dev); + slot->dev = NULL; + dbg("%s - exit", __FUNCTION__); return 0; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index fe98553c978..f315df2005b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -393,7 +393,10 @@ int pci_register_driver(struct pci_driver *drv) drv->driver.bus = &pci_bus_type; drv->driver.probe = pci_device_probe; drv->driver.remove = pci_device_remove; - drv->driver.shutdown = pci_device_shutdown, + /* FIXME, once all of the existing PCI drivers have been fixed to set + * the pci shutdown function, this test can go away. */ + if (!drv->driver.shutdown) + drv->driver.shutdown = pci_device_shutdown, drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; pci_init_dynids(&drv->dynids); diff --git a/drivers/pci/pci.ids b/drivers/pci/pci.ids index 93481b41b61..1d2ef1e2ffc 100644 --- a/drivers/pci/pci.ids +++ b/drivers/pci/pci.ids @@ -7173,6 +7173,7 @@ 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/drivers/pci/probe.c b/drivers/pci/probe.c index b7ae87823c6..fd48b201eb5 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -125,7 +125,7 @@ static inline unsigned int pci_calc_resource_flags(unsigned int flags) /* * Find the extent of a PCI decode.. */ -static u32 pci_size(u32 base, u32 maxbase, unsigned long mask) +static u32 pci_size(u32 base, u32 maxbase, u32 mask) { u32 size = mask & maxbase; /* Find the significant bits */ if (!size) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 637e9493034..968033fd29f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -456,21 +456,16 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_APIC, quirk_amd_8131_ioapic ); +static void __init quirk_svw_msi(struct pci_dev *dev) +{ + pci_msi_quirk = 1; + printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n"); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi ); #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 * support the PCI_INTERRUPT_LINE register at all. Therefore @@ -492,28 +487,30 @@ 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 ); -static void quirk_via_irqpic(struct pci_dev *dev) +/* + * 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) { 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 PIC IRQ fixup for %s, from %d to %d\n", + printk(KERN_INFO "PCI: Via 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_irqpic); +DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq); /* * PIIX3 USB: We have to disable USB interrupts that are diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 1811cb24031..27fec8a5eb5 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1752,7 +1752,7 @@ config SCSI_NCR53C7xx_FAST config SUN3_SCSI tristate "Sun3 NCR5380 SCSI" - depends on SUN3 && SCSI + depends on SUN3 && SCSI && BROKEN help This option will enable support for the OBIO (onboard io) NCR5380 SCSI controller found in the Sun 3/50 and 3/60, as well as for diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index 54c52349adc..3be54643925 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c @@ -665,15 +665,6 @@ 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; @@ -689,13 +680,6 @@ 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/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 30a88f0e7bd..9e58f134f68 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -186,6 +186,28 @@ 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) @@ -195,11 +217,11 @@ void ata_tf_load(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_exec_command - issue ATA command to host controller + * ata_exec_command_pio - 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 + * Issues PIO write to ATA command register, with proper * synchronization with interrupt handler / other threads. * * LOCKING: @@ -235,6 +257,18 @@ 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) @@ -305,7 +339,7 @@ void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf) } /** - * ata_tf_read - input device's ATA taskfile shadow registers + * ata_tf_read_pio - input device's ATA taskfile shadow registers * @ap: Port from which input is read * @tf: ATA taskfile register set for storing input * @@ -368,6 +402,23 @@ 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) @@ -381,7 +432,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 it's value. This also clears pending interrupts + * and return its value. This also clears pending interrupts * from this device * * LOCKING: @@ -397,7 +448,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 it's value. This also clears pending interrupts + * via MMIO and return its value. This also clears pending interrupts * from this device * * LOCKING: @@ -408,6 +459,20 @@ 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) @@ -415,6 +480,20 @@ 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) @@ -425,6 +504,20 @@ 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) @@ -873,10 +966,24 @@ 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 @@ -884,7 +991,9 @@ 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. + * ATA channel. Works with both PIO and MMIO. + * + * May be used as the dev_select() entry in ata_port_operations. * * LOCKING: * caller. @@ -1190,7 +1299,12 @@ err_out: * 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. @@ -1229,10 +1343,14 @@ err_out: } /** - * ata_port_probe - - * @ap: + * ata_port_probe - Mark port as enabled + * @ap: Port for which we indicate enablement * - * LOCKING: + * Modify @ap data structure such that the system + * thinks that the entire port is enabled. + * + * LOCKING: host_set lock, or some other form of + * serialization. */ void ata_port_probe(struct ata_port *ap) @@ -1241,10 +1359,15 @@ void ata_port_probe(struct ata_port *ap) } /** - * __sata_phy_reset - - * @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. * * LOCKING: + * PCI/etc. bus probe sem. * */ void __sata_phy_reset(struct ata_port *ap) @@ -1289,10 +1412,14 @@ void __sata_phy_reset(struct ata_port *ap) } /** - * __sata_phy_reset - - * @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. * * LOCKING: + * PCI/etc. bus probe sem. * */ void sata_phy_reset(struct ata_port *ap) @@ -1304,10 +1431,16 @@ void sata_phy_reset(struct ata_port *ap) } /** - * ata_port_disable - - * @ap: + * ata_port_disable - Disable port. + * @ap: Port to be disabled. * - * LOCKING: + * 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. + * + * LOCKING: host_set lock, or some other form of + * serialization. */ void ata_port_disable(struct ata_port *ap) @@ -1416,7 +1549,10 @@ 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) @@ -1467,7 +1603,10 @@ err_out: * @tmout_pat: impatience timeout * @tmout: overall timeout * - * LOCKING: + * Sleep until ATA Status register bit BSY clears, + * or a timeout occurs. + * + * LOCKING: None. * */ @@ -1553,10 +1692,14 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask) } /** - * ata_bus_edd - - * @ap: + * 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. * * LOCKING: + * PCI/etc. bus probe sem. * */ @@ -1633,8 +1776,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap, * the device is ATA or ATAPI. * * LOCKING: - * Inherited from caller. Some functions called by this function - * obtain the host_set lock. + * PCI/etc. bus probe sem. + * Obtains host_set lock. * * SIDE EFFECTS: * Sets ATA_FLAG_PORT_DISABLED if bus reset fails. @@ -1876,7 +2019,11 @@ 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. @@ -1909,7 +2056,11 @@ 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) @@ -1947,10 +2098,13 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev) } /** - * ata_sg_clean - - * @qc: + * 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. * * LOCKING: + * spin_lock_irqsave(host_set lock) */ static void ata_sg_clean(struct ata_queued_cmd *qc) @@ -1981,7 +2135,11 @@ 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) @@ -2028,7 +2186,13 @@ 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 */ @@ -2046,6 +2210,8 @@ 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) */ @@ -2057,6 +2223,32 @@ 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; @@ -2074,6 +2266,32 @@ 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) { @@ -2083,14 +2301,16 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, } /** - * ata_sg_setup_one - - * @qc: + * 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. * * 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) @@ -2115,13 +2335,16 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc) } /** - * ata_sg_setup - - * @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. * * LOCKING: * spin_lock_irqsave(host_set lock) * * RETURNS: + * Zero on success, negative on error. * */ @@ -2151,6 +2374,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) * @ap: * * LOCKING: + * None. (executing in kernel thread context) * * RETURNS: * @@ -2198,6 +2422,7 @@ 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) @@ -2240,6 +2465,18 @@ 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 @@ -2340,7 +2577,6 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) next_sg: sg = &qc->sg[qc->cursg]; -next_page: page = sg->page; offset = sg->offset + qc->cursg_ofs; @@ -2348,6 +2584,7 @@ next_page: page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; + /* don't overrun current sg */ count = min(sg->length - qc->cursg_ofs, bytes); /* don't cross page boundaries */ @@ -2372,8 +2609,6 @@ next_page: kunmap(page); if (bytes) { - if (qc->cursg_ofs < sg->length) - goto next_page; goto next_sg; } } @@ -2415,6 +2650,7 @@ err_out: * @ap: * * LOCKING: + * None. (executing in kernel thread context) */ static void ata_pio_block(struct ata_port *ap) @@ -2583,6 +2819,7 @@ 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) @@ -2692,6 +2929,7 @@ out: * @dev: Device from whom we request an available command structure * * LOCKING: + * None. */ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) @@ -2717,6 +2955,7 @@ 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, @@ -2781,6 +3020,7 @@ 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) @@ -2794,9 +3034,13 @@ 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 + * @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. * * LOCKING: + * spin_lock_irqsave(host_set lock) * */ @@ -2892,6 +3136,7 @@ err_out: return -1; } + /** * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner * @qc: command to issue to device @@ -2901,6 +3146,8 @@ err_out: * 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) * @@ -2958,7 +3205,7 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) } /** - * ata_bmdma_setup - Set up PCI IDE BMDMA transaction + * ata_bmdma_setup_mmio - Set up PCI IDE BMDMA transaction * @qc: Info associated with this ATA transaction. * * LOCKING: @@ -3065,6 +3312,18 @@ 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) @@ -3073,6 +3332,20 @@ 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) @@ -3081,6 +3354,19 @@ 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) { @@ -3093,6 +3379,19 @@ 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; @@ -3104,6 +3403,19 @@ 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) { @@ -3203,13 +3515,18 @@ idle_irq: /** * ata_interrupt - Default ATA host interrupt handler - * @irq: irq line - * @dev_instance: pointer to our host information structure + * @irq: irq line (unused) + * @dev_instance: pointer to our ata_host_set 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. * */ @@ -3302,6 +3619,19 @@ err_out: 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; @@ -3315,6 +3645,18 @@ 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; @@ -3357,7 +3699,11 @@ 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. * */ @@ -3412,9 +3758,13 @@ 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. * */ @@ -3447,12 +3797,22 @@ err_out: } /** - * ata_device_add - - * @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. * * LOCKING: + * PCI/etc. bus probe sem. * * RETURNS: + * Number of ports registered. Zero on error (no ports registered). * */ @@ -3604,7 +3964,15 @@ 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; @@ -3646,6 +4014,20 @@ 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) @@ -3727,10 +4109,19 @@ 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. * */ @@ -3949,15 +4340,6 @@ 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/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 416ba67ba9e..7a4adc4c8f0 100644 --- a/drivers/scsi/libata-scsi.c +++ b/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 - + * ata_scsiop_noop - Command handler that simply returns success. * @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/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 579448222d6..3c97aa45772 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -507,6 +507,7 @@ 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; @@ -519,7 +520,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) /* Check active list for command command. */ spin_unlock_irq(ha->host->host_lock); - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++) { sp = ha->outstanding_cmds[i]; @@ -534,7 +535,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) sp->state)); DEBUG3(qla2x00_print_scsi_cmd(cmd);) - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); if (qla2x00_abort_command(ha, sp)) { DEBUG2(printk("%s(%ld): abort_command " "mbx failed.\n", __func__, ha->host_no)); @@ -543,20 +544,19 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "mbx success.\n", __func__, ha->host_no)); ret = SUCCESS; } - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); 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,6 +588,7 @@ 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; @@ -596,11 +597,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(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); if (cmd->device->id == t) { if (!qla2x00_eh_wait_on_command(ha, cmd)) { status = 1; @@ -608,7 +609,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) } } } else { - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); } } return (status); @@ -740,6 +741,7 @@ 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; @@ -748,17 +750,17 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) * array */ for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) { - spin_lock(&ha->hardware_lock); + spin_lock_irqsave(&ha->hardware_lock, flags); sp = ha->outstanding_cmds[cnt]; if (sp) { cmd = sp->cmd; - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); status = qla2x00_eh_wait_on_command(ha, cmd); if (status == 0) break; } else { - spin_unlock(&ha->hardware_lock); + spin_unlock_irqrestore(&ha->hardware_lock, flags); } } return (status); diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 238580d244e..49ed557a4b6 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c @@ -432,7 +432,13 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) writeb(cls, mmio_base + SIL_FIFO_R0); writeb(cls, mmio_base + SIL_FIFO_W0); writeb(cls, mmio_base + SIL_FIFO_R1); - writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_W1); + if (ent->driver_data == sil_3114) { + writeb(cls, mmio_base + SIL_FIFO_R2); + writeb(cls, mmio_base + SIL_FIFO_W2); + writeb(cls, mmio_base + SIL_FIFO_R3); + writeb(cls, mmio_base + SIL_FIFO_W3); + } } else printk(KERN_WARNING DRV_NAME "(%s): cache line size not set. Driver may not function\n", pci_name(pdev)); diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index cca772624ae..8d0d302844a 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1197,6 +1197,7 @@ 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/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 22565a67a57..98641c3f5ab 100644 --- a/drivers/serial/sa1100.c +++ b/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, ignored = 0; + unsigned int status, ch, flg; status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | UTSR0_TO_SM(UART_GET_UTSR0(sport)); diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 5d2ceb623e6..1f985327b0d 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c @@ -234,7 +234,7 @@ static inline const char *siu_type_name(struct uart_port *port) return "DSIU"; } - return "unknown"; + return NULL; } static unsigned int siu_tx_empty(struct uart_port *port) @@ -482,9 +482,6 @@ 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); @@ -507,6 +504,9 @@ 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,9 +545,6 @@ 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); @@ -802,53 +799,6 @@ 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) @@ -915,7 +865,7 @@ static int siu_console_setup(struct console *con, char *options) if (port->membase == NULL) { if (port->mapbase == 0) return -ENODEV; - port->membase = (unsigned char __iomem *)KSEG1ADDR(port->mapbase); + port->membase = ioremap(port->mapbase, siu_port_size(port)); } vr41xx_select_siu_interface(SIU_INTERFACE_RS232C); @@ -949,7 +899,7 @@ static int __devinit siu_console_init(void) for (i = 0; i < num; i++) { port = &siu_uart_ports[i]; - port->ops = &early_uart_ops; + port->ops = &siu_uart_ops; } register_console(&siu_console); @@ -994,8 +944,10 @@ static int siu_probe(struct device *dev) port->dev = dev; retval = uart_add_one_port(&siu_uart_driver, port); - if (retval) + if (retval < 0) { + port->dev = NULL; break; + } } if (i == 0 && retval < 0) { diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4ab50009291..4d0c9e65cd0 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -290,32 +290,30 @@ 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; - return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", + len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", 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, + 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", alt->desc.bInterfaceClass, alt->desc.bInterfaceSubClass, alt->desc.bInterfaceProtocol); } else { - 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); + return len + sprintf(buf, "*isc*ip*\n"); } - } static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 429330bc38d..d7b4f7939de 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -439,9 +439,12 @@ static int ehci_hub_control ( /* force reset to complete */ writel (temp & ~PORT_RESET, &ehci->regs->port_status [wIndex]); + /* REVISIT: some hardware needs 550+ usec to clear + * this bit; seems too long to spin routinely... + */ retval = handshake ( &ehci->regs->port_status [wIndex], - PORT_RESET, 0, 500); + PORT_RESET, 0, 750); if (retval != 0) { ehci_err (ehci, "port %d reset error %d\n", wIndex + 1, retval); diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 869ff73690a..2d8bd9dcc6e 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1315,6 +1315,8 @@ 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 @@ -1401,6 +1403,7 @@ 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 @@ -1412,6 +1415,12 @@ 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. @@ -1437,6 +1446,7 @@ 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 }, @@ -1456,6 +1466,10 @@ 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 }, @@ -1481,6 +1495,10 @@ 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/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog deleted file mode 100644 index b2eb71a9afb..00000000000 --- a/drivers/usb/media/pwc/ChangeLog +++ /dev/null @@ -1,143 +0,0 @@ -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/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5429ff3b975..b77e65c0365 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c @@ -332,10 +332,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) #endif ; } - if (kbuf == NULL) { - Err("Failed to allocate decompress table.\n"); - return -ENOMEM; - } pdev->decompress_data = kbuf; /* Allocate image buffer; double buffer for mmap() */ diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index a9a7cf4a38e..fd6ff4cb2c6 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -520,7 +520,7 @@ static void int_callback(struct urb *u, struct pt_regs *regs) /* we check the link state to report changes */ if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) { - if (!act_state) + if (act_state) netif_carrier_on(kaweth->net); else netif_carrier_off(kaweth->net); diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 85476e76b24..4cbb408af72 100644 --- a/drivers/usb/net/usbnet.c +++ b/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, blan_guid, 16) ) { + && memcmp(&desc->bGUID, safe_guid, 16) ) { /* hey, this one might _really_ be MDLM! */ dev_dbg (&intf->dev, "MDLM guid\n"); goto bad_desc; diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index bc798edf035..9438909e87a 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig @@ -455,6 +455,17 @@ 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/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index d56ff6d86cc..6c7cdcc99a9 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile @@ -32,6 +32,7 @@ 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/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 7e9bb63eb46..4ace9964fc6 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -7,6 +7,14 @@ * 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 <linux/config.h> @@ -24,7 +32,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.03" +#define DRIVER_VERSION "v0.04" #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" /* @@ -35,6 +43,9 @@ 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*); @@ -43,9 +54,10 @@ 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(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ - { } /* Terminating Entry*/ + { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ + { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ + { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ + { } /* Terminating Entry */ }; MODULE_DEVICE_TABLE (usb, id_table); @@ -70,32 +82,35 @@ 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)(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 ???*/ +/* 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 ??? */ -/*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 @@ -112,64 +127,137 @@ 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 -static int cp2101_get_config(struct usb_serial_port* port, u8 request) +/* + * 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) { struct usb_serial *serial = port->serial; - unsigned char buf[4]; - unsigned int value; - int result, i; + 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; + } - /*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 4 bytes*/ + /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), request, REQTYPE_DEVICE_TO_HOST, 0x0000, - 0, buf, 4, 300); + 0, buf, size, 300); - if (result < 0) { - dev_err(&port->dev, "%s - Unable to send config request, " - "request=0x%x result=%d\n", - __FUNCTION__, request, result); - return result; - } + /* Convert data into an array of integers */ + for (i=0; i<length; i++) + data[i] = le32_to_cpu(buf[i]); - /*Assemble each byte read into an integer value*/ - value = 0; - for (i=0; i<4 && i<result; i++) - value |= (buf[i] << (i * 8)); + kfree(buf); - dbg( " %s - request=0x%x result=%d value=0x%x", - __FUNCTION__, request, result, value); + if (result != size) { + dev_err(&port->dev, "%s - Unable to send config request, " + "request=0x%x size=%d result=%d\n", + __FUNCTION__, request, size, result); + return -EPROTO; + } - return value; + return 0; } -static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) +/* + * cp2101_set_config + * Writes to the CP2101 configuration registers + * Values less than 16 bits wide are sent directly + * 'size' is specified in bytes. + */ +static int cp2101_set_config(struct usb_serial_port* port, u8 request, + unsigned int *data, int size) { struct usb_serial *serial = port->serial; - int result; - result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), - request, REQTYPE_HOST_TO_DEVICE, value, - 0, NULL, 0, 300); + u32 *buf; + int result, i, length; - 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; + /* 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; + } + + /* 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); } - dbg(" %s - request=0x%x value=0x%x result=%d", - __FUNCTION__, request, value, 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; + } + /* 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; @@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) dbg("%s - port %d", __FUNCTION__, port->number); - if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { + if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { dev_err(&port->dev, "%s - Unable to enable UART\n", __FUNCTION__); return -EPROTO; @@ -198,9 +286,12 @@ 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; } @@ -228,16 +319,18 @@ 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(port, CP2101_UART, UART_DISABLE); + cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); } -/* 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*/ +/* + * 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 + */ static void cp2101_get_termios (struct usb_serial_port *port) { - unsigned int cflag; + unsigned int cflag, modem_ctl[4]; int baud; int bits; @@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port) } cflag = port->tty->termios->c_cflag; - baud = cp2101_get_config(port, CP2101_BAUDRATE); - /*Convert to baudrate*/ + cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); + /* 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 */ @@ -284,14 +378,18 @@ 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(port, CP2101_BAUDRATE, + cp2101_set_config_single(port, CP2101_BAUDRATE, (BAUD_RATE_GEN_FREQ/9600)); break; } - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); 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; @@ -310,7 +408,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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown number of data bits, " @@ -318,7 +416,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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -341,21 +439,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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); 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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; default: dbg("%s - Unknown parity mode, " "disabling parity", __FUNCTION__); cflag &= ~PARENB; bits &= ~BITS_PARITY_MASK; - cp2101_set_config(port, CP2101_BITS, bits); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; } @@ -366,9 +464,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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); break; case BITS_STOP_2: dbg("%s - stop bits = 2", __FUNCTION__); @@ -378,10 +476,19 @@ 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); + cp2101_set_config(port, CP2101_BITS, &bits, 2); 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; } @@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, struct termios *old_termios) { unsigned int cflag, old_cflag=0; - int baud=0; - int bits; + int baud=0, bits; + unsigned int modem_ctl[4]; dbg("%s - port %d", __FUNCTION__, port->number); @@ -400,7 +507,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) @@ -415,7 +522,8 @@ 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 */ @@ -448,18 +556,22 @@ 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(port, CP2101_BAUDRATE, + if (cp2101_set_config_single(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)) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); 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__); @@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, bits |= BITS_DATA_8; break; } - if (cp2101_set_config(port, CP2101_BITS, bits)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Number of data bits requested " "not supported by device\n"); } if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_PARITY_MASK; if (cflag & PARENB) { if (cflag & PARODD) { @@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, dbg("%s - parity = EVEN", __FUNCTION__); } } - if (cp2101_set_config(port, CP2101_BITS, bits)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) dev_err(&port->dev, "Parity mode not supported " "by device\n"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { - bits = cp2101_get_config(port, CP2101_BITS); + cp2101_get_config(port, CP2101_BITS, &bits, 2); bits &= ~BITS_STOP_MASK; if (cflag & CSTOPB) { bits |= BITS_STOP_2; @@ -515,15 +627,90 @@ 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)) + if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) 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) { - u16 state; + int state; dbg("%s - port %d", __FUNCTION__, port->number); if (break_state == 0) @@ -532,12 +719,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); + cp2101_set_config(port, CP2101_BREAK, &state, 2); } 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; } @@ -548,7 +735,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]); } @@ -560,16 +747,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/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 051c3a77b41..3bfcc7b9f86 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -264,7 +264,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.4.1" +#define DRIVER_VERSION "v1.4.2" #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" #define DRIVER_DESC "USB FTDI Serial Converters Driver" @@ -687,6 +687,8 @@ struct ftdi_private { char prev_status, diff_status; /* Used for TIOCMIWAIT */ __u8 rx_flags; /* receive state flags (throttling) */ spinlock_t rx_lock; /* spinlock for receive state */ + struct work_struct rx_work; + int rx_processed; __u16 interface; /* FT2232C port interface (0 for FT232/245) */ @@ -717,7 +719,7 @@ static int ftdi_write_room (struct usb_serial_port *port); static int ftdi_chars_in_buffer (struct usb_serial_port *port); static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); -static void ftdi_process_read (struct usb_serial_port *port); +static void ftdi_process_read (void *param); static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); @@ -1387,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial) port->read_urb->transfer_buffer_length = BUFSZ; } + INIT_WORK(&priv->rx_work, ftdi_process_read, port); + /* Free port's existing write urb and transfer buffer. */ if (port->write_urb) { usb_free_urb (port->write_urb); @@ -1617,6 +1621,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) spin_unlock_irqrestore(&priv->rx_lock, flags); /* Start reading from the device */ + priv->rx_processed = 0; usb_fill_bulk_urb(port->read_urb, dev, usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, @@ -1667,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) err("Error from RTS LOW urb"); } } /* Note change no line if hupcl is off */ + + /* cancel any scheduled reading */ + cancel_delayed_work(&priv->rx_work); + flush_scheduled_work(); /* shutdown our bulk read */ if (port->read_urb) @@ -1862,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs) return; } - /* If throttled, delay receive processing until unthrottled. */ - spin_lock(&priv->rx_lock); - if (priv->rx_flags & THROTTLED) { - dbg("Deferring read urb processing until unthrottled"); - priv->rx_flags |= ACTUALLY_THROTTLED; - spin_unlock(&priv->rx_lock); - return; - } - spin_unlock(&priv->rx_lock); - ftdi_process_read(port); } /* ftdi_read_bulk_callback */ -static void ftdi_process_read (struct usb_serial_port *port) +static void ftdi_process_read (void *param) { /* ftdi_process_read */ + struct usb_serial_port *port = (struct usb_serial_port*)param; struct urb *urb; struct tty_struct *tty; struct ftdi_private *priv; @@ -1889,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port) int result; int need_flip; int packet_offset; + unsigned long flags; dbg("%s - port %d", __FUNCTION__, port->number); @@ -1915,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port) data = urb->transfer_buffer; - /* The first two bytes of every read packet are status */ - if (urb->actual_length > 2) { - usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + if (priv->rx_processed) { + dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__, + priv->rx_processed, + urb->actual_length - priv->rx_processed); } else { - dbg("Status only: %03oo %03oo",data[0],data[1]); - } + /* The first two bytes of every read packet are status */ + if (urb->actual_length > 2) { + usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); + } else { + dbg("Status only: %03oo %03oo",data[0],data[1]); + } + } /* TO DO -- check for hung up line and handle appropriately: */ @@ -1929,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port) /* if CD is dropped and the line is not CLOCAL then we should hangup */ need_flip = 0; - for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) { + for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) { + int length; + /* Compare new line status to the old one, signal if different */ + /* N.B. packet may be processed more than once, but differences + * are only processed once. */ if (priv != NULL) { char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; if (new_status != priv->prev_status) { @@ -1940,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port) } } + length = min(PKTSZ, urb->actual_length-packet_offset)-2; + if (length < 0) { + err("%s - bad packet length: %d", __FUNCTION__, length+2); + length = 0; + } + + /* have to make sure we don't overflow the buffer + with tty_insert_flip_char's */ + if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { + tty_flip_buffer_push(tty); + need_flip = 0; + + if (tty->flip.count != 0) { + /* flip didn't work, this happens when ftdi_process_read() is + * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ + dbg("%s - flip buffer push failed", __FUNCTION__); + break; + } + } + if (priv->rx_flags & THROTTLED) { + dbg("%s - throttled", __FUNCTION__); + break; + } + if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { + /* break out & wait for throttling/unthrottling to happen */ + dbg("%s - receive room low", __FUNCTION__); + break; + } + /* Handle errors and break */ error_flag = TTY_NORMAL; /* Although the device uses a bitmask and hence can have multiple */ @@ -1962,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port) error_flag = TTY_FRAME; dbg("FRAMING error"); } - if (urb->actual_length > packet_offset + 2) { - for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) { - /* have to make sure we don't overflow the buffer - with tty_insert_flip_char's */ - if(tty->flip.count >= TTY_FLIPBUF_SIZE) { - tty_flip_buffer_push(tty); - } + if (length > 0) { + for (i = 2; i < length+2; i++) { /* Note that the error flag is duplicated for every character received since we don't know which character it applied to */ @@ -2005,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port) tty_flip_buffer_push(tty); } + if (packet_offset < urb->actual_length) { + /* not completely processed - record progress */ + priv->rx_processed = packet_offset; + dbg("%s - incomplete, %d bytes processed, %d remain", + __FUNCTION__, packet_offset, + urb->actual_length - packet_offset); + /* check if we were throttled while processing */ + spin_lock_irqsave(&priv->rx_lock, flags); + if (priv->rx_flags & THROTTLED) { + priv->rx_flags |= ACTUALLY_THROTTLED; + spin_unlock_irqrestore(&priv->rx_lock, flags); + dbg("%s - deferring remainder until unthrottled", + __FUNCTION__); + return; + } + spin_unlock_irqrestore(&priv->rx_lock, flags); + /* if the port is closed stop trying to read */ + if (port->open_count > 0){ + /* delay processing of remainder */ + schedule_delayed_work(&priv->rx_work, 1); + } else { + dbg("%s - port is closed", __FUNCTION__); + } + return; + } + + /* urb is completely processed */ + priv->rx_processed = 0; + /* if the port is closed stop trying to read */ if (port->open_count > 0){ /* Continue trying to always read */ @@ -2444,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) spin_unlock_irqrestore(&priv->rx_lock, flags); if (actually_throttled) - ftdi_process_read(port); + schedule_work(&priv->rx_work); } static int __init ftdi_init (void) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c new file mode 100644 index 00000000000..b722175f108 --- /dev/null +++ b/drivers/usb/serial/option.c @@ -0,0 +1,729 @@ +/* + Option Card (PCMCIA to) USB to Serial Driver + + Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> + + 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 <hugh@blemings.org> + + 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 <smurf@smurf.noris.de>" +#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/jiffies.h> +#include <linux/errno.h> +#include <linux/tty.h> +#include <linux/tty_flip.h> +#include <linux/module.h> +#include <linux/usb.h> +#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/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d2891f47579..9fcc7bd1fbe 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -862,6 +862,15 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, US_SC_DEVICE, US_PR_BULK, NULL, US_FL_NEED_OVERRIDE ), +/* Reported by Filippo Bardelli <filibard@libero.it> + * 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/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index ee25b9e8db6..47a6b12bc96 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -2374,10 +2374,9 @@ static int radeonfb_pci_register (struct pci_dev *pdev, } while ( rinfo->fb_base == 0 && ((rinfo->mapped_vram /=2) >= MIN_MAPPED_VRAM) ); - if (rinfo->fb_base) - memset_io(rinfo->fb_base, 0, rinfo->mapped_vram); - else { - printk (KERN_ERR "radeonfb (%s): cannot map FB\n", pci_name(rinfo->pdev)); + if (rinfo->fb_base == NULL) { + printk (KERN_ERR "radeonfb (%s): cannot map FB\n", + pci_name(rinfo->pdev)); ret = -EIO; goto err_unmap_rom; } diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index c78a2c5961d..277d733c6d0 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c @@ -241,7 +241,7 @@ static ssize_t show_virtual(struct class_device *class_device, char *buf) struct fb_info *fb_info = (struct fb_info *)class_get_devdata(class_device); return snprintf(buf, PAGE_SIZE, "%d,%d\n", fb_info->var.xres_virtual, - fb_info->var.xres_virtual); + fb_info->var.yres_virtual); } static ssize_t store_cmap(struct class_device *class_device, const char * buf, diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c index de5a0f38360..2fc71081f7e 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/macmodes.c @@ -387,3 +387,4 @@ int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info, } EXPORT_SYMBOL(mac_find_mode); +MODULE_LICENSE("GPL"); diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index c374be51b04..f8f6b6b7617 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -1125,7 +1125,7 @@ static int dump_write(struct file *file, const void *addr, int nr) return file->f_op->write(file, addr, nr, &file->f_pos) == nr; } -static int dump_seek(struct file *file, off_t off) +static int dump_seek(struct file *file, loff_t off) { if (file->f_op->llseek) { if (file->f_op->llseek(file, off, 0) != off) diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c index f0cd67d9d31..c8998dc6688 100644 --- a/fs/binfmt_flat.c +++ b/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, 0, 0); + textpos = do_mmap(bprm->file, 0, text_len, PROT_READ|PROT_EXEC, MAP_SHARED, 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, 0, 0); + PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 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, 0, 0); + PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); up_write(¤t->mm->mmap_sem); if (!textpos || textpos >= (unsigned long) -4096) { if (!textpos) diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 95483baab70..dab4774ee7b 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -6,7 +6,8 @@ kills the cifsd thread (NB: killing the cifs kernel threads is not recommended, unmount and rmmod cifs will kill them when they are no longer needed). Fix readdir to ASCII servers (ie older servers which do not support Unicode) and also require asterik. - +Fix out of memory case in which data could be written one page +off in the page cache. Version 1.33 ------------ diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index d00b3bfe1a5..78af5850c55 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -96,5 +96,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); extern int cifs_ioctl (struct inode * inode, struct file * filep, unsigned int command, unsigned long arg); -#define CIFS_VERSION "1.34" +#define CIFS_VERSION "1.35" #endif /* _CIFSFS_H */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index dde2d251fc3..30ab70ce554 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1352,6 +1352,8 @@ static void cifs_copy_cache_pages(struct address_space *mapping, GFP_KERNEL)) { page_cache_release(page); cFYI(1, ("Add page cache failed")); + data += PAGE_CACHE_SIZE; + bytes_read -= PAGE_CACHE_SIZE; continue; } diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index b8b78cbb34c..8d336a90025 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -82,12 +82,12 @@ int cifs_get_inode_info_unix(struct inode **pinode, /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - if(*pinode == NULL) + if (*pinode == NULL) return -ENOMEM; /* Is an i_ino of zero legal? */ /* Are there sanity checks we can use to ensure that the server is really filling in that field? */ - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { (*pinode)->i_ino = (unsigned long)findData.UniqueId; } /* note ino incremented to unique num in new_inode */ @@ -134,7 +134,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, inode->i_gid = le64_to_cpu(findData.Gid); inode->i_nlink = le64_to_cpu(findData.Nlinks); - if(is_size_safe_to_change(cifsInfo)) { + if (is_size_safe_to_change(cifsInfo)) { /* can not safely change the file size here if the client is writing to it due to potential races */ @@ -162,7 +162,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; @@ -198,17 +198,17 @@ int cifs_get_inode_info(struct inode **pinode, pTcon = cifs_sb->tcon; cFYI(1,("Getting info on %s ", search_path)); - if((pfindData == NULL) && (*pinode != NULL)) { - if(CIFS_I(*pinode)->clientCanCacheRead) { + if ((pfindData == NULL) && (*pinode != NULL)) { + if (CIFS_I(*pinode)->clientCanCacheRead) { cFYI(1,("No need to revalidate cached inode sizes")); return rc; } } /* if file info not passed in then get it from server */ - if(pfindData == NULL) { + if (pfindData == NULL) { buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); - if(buf == NULL) + if (buf == NULL) return -ENOMEM; pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ @@ -268,7 +268,7 @@ int cifs_get_inode_info(struct inode **pinode, IndexNumber field is not guaranteed unique? */ #ifdef CONFIG_CIFS_EXPERIMENTAL - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM){ int rc1 = 0; __u64 inode_num; @@ -277,7 +277,7 @@ int cifs_get_inode_info(struct inode **pinode, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); - if(rc1) { + if (rc1) { cFYI(1,("GetSrvInodeNum rc %d", rc1)); /* BB EOPNOSUPP disable SERVER_INUM? */ } else /* do we need cast or hash to ino? */ @@ -355,7 +355,7 @@ int cifs_get_inode_info(struct inode **pinode, if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); inode->i_op = &cifs_file_inode_ops; - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) inode->i_fop = &cifs_file_direct_ops; else inode->i_fop = &cifs_file_ops; @@ -422,7 +422,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } else if (rc == -ENOENT) { d_drop(direntry); @@ -441,7 +441,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } } else if (rc == -EACCES) { @@ -496,7 +496,7 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } else if (rc == -ETXTBSY) { int oplock = FALSE; @@ -517,14 +517,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry) cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, netfid); - if(direntry->d_inode) + if (direntry->d_inode) direntry->d_inode->i_nlink--; } /* BB if rc = -ETXTBUSY goto the rename logic BB */ } } } - if(direntry->d_inode) { + if (direntry->d_inode) { cifsInode = CIFS_I(direntry->d_inode); cifsInode->time = 0; /* will force revalidate to get info when needed */ @@ -582,7 +582,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) if (direntry->d_inode) direntry->d_inode->i_nlink = 2; if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, (__u64)current->euid, diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 98d830401c5..5a97e346bd9 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) } else { jbd_unlock_bh_state(bh); } - jh = next_jh; } while (jh != last_jh); return ret; @@ -339,8 +338,10 @@ int log_do_checkpoint(journal_t *journal) } } while (jh != last_jh && !retry); - if (batch_count) + if (batch_count) { __flush_batch(journal, bhs, &batch_count); + retry = 1; + } /* * If someone cleaned up this transaction while we slept, we're diff --git a/fs/mpage.c b/fs/mpage.c index b92c0e64aef..bb9aebe9386 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -79,8 +79,11 @@ 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/fs/namei.c b/fs/namei.c index dd78f01b6de..a7f7f44119b 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -493,12 +493,21 @@ fail: return PTR_ERR(link); } -static inline int __do_follow_link(struct dentry *dentry, struct nameidata *nd) +struct path { + struct vfsmount *mnt; + struct dentry *dentry; +}; + +static inline int __do_follow_link(struct path *path, struct nameidata *nd) { int error; + struct dentry *dentry = path->dentry; - touch_atime(nd->mnt, dentry); + touch_atime(path->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); @@ -507,6 +516,8 @@ static inline int __do_follow_link(struct dentry *dentry, 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; } @@ -518,7 +529,7 @@ static inline int __do_follow_link(struct dentry *dentry, 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 dentry *dentry, struct nameidata *nd) +static inline int do_follow_link(struct path *path, struct nameidata *nd) { int err = -ELOOP; if (current->link_count >= MAX_NESTED_LINKS) @@ -527,17 +538,20 @@ static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) goto loop; BUG_ON(nd->depth >= MAX_NESTED_LINKS); cond_resched(); - err = security_inode_follow_link(dentry, nd); + err = security_inode_follow_link(path->dentry, nd); if (err) goto loop; current->link_count++; current->total_link_count++; nd->depth++; - err = __do_follow_link(dentry, nd); + err = __do_follow_link(path, 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; } @@ -565,87 +579,91 @@ 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 vfsmount **mnt, struct dentry **dentry) +static int __follow_mount(struct path *path) { 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 */ -static inline int __follow_down(struct vfsmount **mnt, struct dentry **dentry) +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; } -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) +static inline void follow_dotdot(struct nameidata *nd) { while(1) { struct vfsmount *parent; - struct dentry *old = *dentry; + struct dentry *old = nd->dentry; read_lock(¤t->fs->lock); - if (*dentry == current->fs->root && - *mnt == current->fs->rootmnt) { + if (nd->dentry == current->fs->root && + nd->mnt == current->fs->rootmnt) { read_unlock(¤t->fs->lock); break; } read_unlock(¤t->fs->lock); spin_lock(&dcache_lock); - if (*dentry != (*mnt)->mnt_root) { - *dentry = dget((*dentry)->d_parent); + if (nd->dentry != nd->mnt->mnt_root) { + nd->dentry = dget(nd->dentry->d_parent); spin_unlock(&dcache_lock); dput(old); break; } spin_unlock(&dcache_lock); spin_lock(&vfsmount_lock); - parent = (*mnt)->mnt_parent; - if (parent == *mnt) { + parent = nd->mnt->mnt_parent; + if (parent == nd->mnt) { spin_unlock(&vfsmount_lock); break; } mntget(parent); - *dentry = dget((*mnt)->mnt_mountpoint); + nd->dentry = dget(nd->mnt->mnt_mountpoint); spin_unlock(&vfsmount_lock); dput(old); - mntput(*mnt); - *mnt = parent; + mntput(nd->mnt); + nd->mnt = parent; } - follow_mount(mnt, dentry); + follow_mount(&nd->mnt, &nd->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. @@ -664,6 +682,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, done: path->mnt = mnt; path->dentry = dentry; + __follow_mount(path); return 0; need_lookup: @@ -751,7 +770,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) case 2: if (this.name[1] != '.') break; - follow_dotdot(&nd->mnt, &nd->dentry); + follow_dotdot(nd); inode = nd->dentry->d_inode; /* fallthrough */ case 1: @@ -771,8 +790,6 @@ 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; @@ -783,10 +800,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) goto out_dput; if (inode->i_op->follow_link) { - mntget(next.mnt); - err = do_follow_link(next.dentry, nd); - dput(next.dentry); - mntput(next.mnt); + err = do_follow_link(&next, nd); if (err) goto return_err; err = -ENOENT; @@ -798,6 +812,8 @@ 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; } @@ -819,7 +835,7 @@ last_component: case 2: if (this.name[1] != '.') break; - follow_dotdot(&nd->mnt, &nd->dentry); + follow_dotdot(nd); inode = nd->dentry->d_inode; /* fallthrough */ case 1: @@ -833,19 +849,17 @@ last_component: 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) { - mntget(next.mnt); - err = do_follow_link(next.dentry, nd); - dput(next.dentry); - mntput(next.mnt); + err = do_follow_link(&next, nd); 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; } @@ -885,6 +899,8 @@ return_base: return 0; out_dput: dput(next.dentry); + if (nd->mnt != next.mnt) + mntput(next.mnt); break; } path_release(nd); @@ -1398,7 +1414,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 dentry *dentry; + struct path path; struct dentry *dir; int count = 0; @@ -1442,23 +1458,24 @@ 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); - dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.mnt = nd->mnt; do_last: - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) { + error = PTR_ERR(path.dentry); + if (IS_ERR(path.dentry)) { up(&dir->d_inode->i_sem); goto exit; } /* Negative dentry, just create the file */ - if (!dentry->d_inode) { + if (!path.dentry->d_inode) { if (!IS_POSIXACL(dir->d_inode)) mode &= ~current->fs->umask; - error = vfs_create(dir->d_inode, dentry, mode, nd); + error = vfs_create(dir->d_inode, path.dentry, mode, nd); up(&dir->d_inode->i_sem); dput(nd->dentry); - nd->dentry = dentry; + nd->dentry = path.dentry; if (error) goto exit; /* Don't check for write permission, don't truncate */ @@ -1476,22 +1493,24 @@ do_last: if (flag & O_EXCL) goto exit_dput; - if (d_mountpoint(dentry)) { + if (__follow_mount(&path)) { error = -ELOOP; if (flag & O_NOFOLLOW) goto exit_dput; - while (__follow_down(&nd->mnt,&dentry) && d_mountpoint(dentry)); } error = -ENOENT; - if (!dentry->d_inode) + if (!path.dentry->d_inode) goto exit_dput; - if (dentry->d_inode->i_op && dentry->d_inode->i_op->follow_link) + if (path.dentry->d_inode->i_op && path.dentry->d_inode->i_op->follow_link) goto do_link; dput(nd->dentry); - nd->dentry = dentry; + nd->dentry = path.dentry; + if (nd->mnt != path.mnt) + mntput(nd->mnt); + nd->mnt = path.mnt; error = -EISDIR; - if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)) + if (path.dentry->d_inode && S_ISDIR(path.dentry->d_inode->i_mode)) goto exit; ok: error = may_open(nd, acc_mode, flag); @@ -1500,7 +1519,9 @@ ok: return 0; exit_dput: - dput(dentry); + dput(path.dentry); + if (nd->mnt != path.mnt) + mntput(path.mnt); exit: path_release(nd); return error; @@ -1520,18 +1541,15 @@ do_link: * are done. Procfs-like symlinks just set LAST_BIND. */ nd->flags |= LOOKUP_PARENT; - error = security_inode_follow_link(dentry, nd); + error = security_inode_follow_link(path.dentry, nd); if (error) goto exit_dput; - error = __do_follow_link(dentry, nd); - dput(dentry); + error = __do_follow_link(&path, nd); if (error) return error; nd->flags &= ~LOOKUP_PARENT; - if (nd->last_type == LAST_BIND) { - dentry = nd->dentry; + if (nd->last_type == LAST_BIND) goto ok; - } error = -EISDIR; if (nd->last_type != LAST_NORM) goto exit; @@ -1546,7 +1564,8 @@ do_link: } dir = nd->dentry; down(&dir->d_inode->i_sem); - dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.dentry = __lookup_hash(&nd->last, nd->dentry, nd); + path.mnt = nd->mnt; putname(nd->last.name); goto do_last; } diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 73f96acd5d3..ff6155f5e8d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -528,19 +528,39 @@ 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 (ndflags & LOOKUP_REVAL) + if (nd->flags & LOOKUP_REVAL) goto out_force; /* This is an open(2) */ - if ((ndflags & LOOKUP_OPEN) && - !(ndflags & LOOKUP_CONTINUE) && + if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && !(server->flags & NFS_MOUNT_NOCTO)) goto out_force; } @@ -560,12 +580,8 @@ 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 ((ndflags & LOOKUP_CREATE) && !(ndflags & LOOKUP_CONTINUE)) + if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) return 0; return !nfs_check_verifier(dir, dentry); } @@ -700,12 +716,16 @@ 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 || (nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_CREATE)) + if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_CREATE) == 0) return 0; return (nd->intent.open.flags & O_EXCL) != 0; } @@ -772,12 +792,13 @@ 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) - return 0; - /* Check that we are indeed trying to open this file */ - if ((nd->flags & LOOKUP_CONTINUE) || !(nd->flags & LOOKUP_OPEN)) + if (nd == NULL || nfs_lookup_check_intent(nd, LOOKUP_OPEN) == 0) return 0; /* NFS does not (yet) have a stateful open for directories */ if (nd->flags & LOOKUP_DIRECTORY) diff --git a/fs/nfs/file.c b/fs/nfs/file.c index f06eee6dcff..55c90759249 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c @@ -37,6 +37,7 @@ static int nfs_file_open(struct inode *, struct file *); static int nfs_file_release(struct inode *, struct file *); +static loff_t nfs_file_llseek(struct file *file, loff_t offset, int origin); static int nfs_file_mmap(struct file *, struct vm_area_struct *); static ssize_t nfs_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *); static ssize_t nfs_file_read(struct kiocb *, char __user *, size_t, loff_t); @@ -48,7 +49,7 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl); static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl); struct file_operations nfs_file_operations = { - .llseek = remote_llseek, + .llseek = nfs_file_llseek, .read = do_sync_read, .write = do_sync_write, .aio_read = nfs_file_read, @@ -114,6 +115,45 @@ nfs_file_release(struct inode *inode, struct file *filp) return NFS_PROTO(inode)->file_release(inode, filp); } +/** + * nfs_revalidate_size - Revalidate the file size + * @inode - pointer to inode struct + * @file - pointer to struct file + * + * Revalidates the file length. This is basically a wrapper around + * nfs_revalidate_inode() that takes into account the fact that we may + * have cached writes (in which case we don't care about the server's + * idea of what the file length is), or O_DIRECT (in which case we + * shouldn't trust the cache). + */ +static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) +{ + struct nfs_server *server = NFS_SERVER(inode); + struct nfs_inode *nfsi = NFS_I(inode); + + if (server->flags & NFS_MOUNT_NOAC) + goto force_reval; + if (filp->f_flags & O_DIRECT) + goto force_reval; + if (nfsi->npages != 0) + return 0; + return nfs_revalidate_inode(server, inode); +force_reval: + return __nfs_revalidate_inode(server, inode); +} + +static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) +{ + /* origin == SEEK_END => we must revalidate the cached file length */ + if (origin == 2) { + struct inode *inode = filp->f_mapping->host; + int retval = nfs_revalidate_file_size(inode, filp); + if (retval < 0) + return (loff_t)retval; + } + return remote_llseek(filp, offset, origin); +} + /* * Flush all dirty pages, and check for write errors. * diff --git a/include/asm-alpha/agp.h b/include/asm-alpha/agp.h index c99dbbb5bcb..ef855a3bc0f 100644 --- a/include/asm-alpha/agp.h +++ b/include/asm-alpha/agp.h @@ -10,4 +10,14 @@ #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/include/asm-arm/arch-integrator/platform.h b/include/asm-arm/arch-integrator/platform.h index bd364f5a99b..96ad3d2a66d 100644 --- a/include/asm-arm/arch-integrator/platform.h +++ b/include/asm-arm/arch-integrator/platform.h @@ -293,7 +293,11 @@ #define INTEGRATOR_DBG_SWITCH (INTEGRATOR_DBG_BASE + INTEGRATOR_DBG_SWITCH_OFFSET) +#if defined(CONFIG_ARCH_INTEGRATOR_AP) #define INTEGRATOR_GPIO_BASE 0x1B000000 /* GPIO */ +#elif defined(CONFIG_ARCH_INTEGRATOR_CP) +#define INTEGRATOR_GPIO_BASE 0xC9000000 /* GPIO */ +#endif /* ------------------------------------------------------------------------ * KMI keyboard/mouse definitions diff --git a/include/asm-arm/arch-ixp2000/io.h b/include/asm-arm/arch-ixp2000/io.h index a8e3c2daefd..083462668e1 100644 --- a/include/asm-arm/arch-ixp2000/io.h +++ b/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()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)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()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)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()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)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()) && - ((port >= IXDP2X01_CS8900_VIRT_BASE) && - (port <= IXDP2X01_CS8900_VIRT_END))) { + (((u32)port >= (u32)IXDP2X01_CS8900_VIRT_BASE) && + ((u32)port <= (u32)IXDP2X01_CS8900_VIRT_END))) { *port = value; return; } diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 39741d3c9a3..b5e54a9e9fa 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1296,6 +1296,7 @@ #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 */ @@ -1428,6 +1429,7 @@ #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/include/asm-arm/arch-versatile/platform.h b/include/asm-arm/arch-versatile/platform.h index 2598d1f0854..a71093e44c5 100644 --- a/include/asm-arm/arch-versatile/platform.h +++ b/include/asm-arm/arch-versatile/platform.h @@ -498,11 +498,17 @@ /* * IB2 Versatile/AB expansion board definitions */ -#define VERSATILE_IB2_CAMERA_BANK 0x24000000 -#define VERSATILE_IB2_KBD_DATAREG 0x25000000 -#define VERSATILE_IB2_IER 0x26000000 /* for VICINTSOURCE27 */ -#define VERSATILE_IB2_CTRL 0x27000000 -#define VERSATILE_IB2_STAT 0x27000004 +#define VERSATILE_IB2_CAMERA_BANK VERSATILE_IB2_BASE +#define VERSATILE_IB2_KBD_DATAREG (VERSATILE_IB2_BASE + 0x01000000) + +/* VICINTSOURCE27 */ +#define VERSATILE_IB2_INT_BASE (VERSATILE_IB2_BASE + 0x02000000) +#define VERSATILE_IB2_IER (VERSATILE_IB2_INT_BASE + 0) +#define VERSATILE_IB2_ISR (VERSATILE_IB2_INT_BASE + 4) + +#define VERSATILE_IB2_CTL_BASE (VERSATILE_IB2_BASE + 0x03000000) +#define VERSATILE_IB2_CTRL (VERSATILE_IB2_CTL_BASE + 0) +#define VERSATILE_IB2_STAT (VERSATILE_IB2_CTL_BASE + 4) #endif #endif diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h index cbceacbe5af..a1696ba238d 100644 --- a/include/asm-arm/elf.h +++ b/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/include/asm-arm26/elf.h b/include/asm-arm26/elf.h index 8b149474db2..5a47fdb3015 100644 --- a/include/asm-arm26/elf.h +++ b/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/include/asm-arm26/signal.h b/include/asm-arm26/signal.h index dedb2928030..37ad2535559 100644 --- a/include/asm-arm26/signal.h +++ b/include/asm-arm26/signal.h @@ -166,9 +166,6 @@ typedef struct sigaltstack { #include <asm/sigcontext.h> #define sigmask(sig) (1UL << ((sig) - 1)) -//FIXME!!! -//#define HAVE_ARCH_GET_SIGNAL_TO_DELIVER - #endif diff --git a/include/asm-h8300/kmap_types.h b/include/asm-h8300/kmap_types.h index 82431edeb2a..1ec8a342712 100644 --- a/include/asm-h8300/kmap_types.h +++ b/include/asm-h8300/kmap_types.h @@ -1,5 +1,5 @@ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H +#ifndef _ASM_H8300_KMAP_TYPES_H +#define _ASM_H8300_KMAP_TYPES_H enum km_type { KM_BOUNCE_READ, @@ -13,6 +13,8 @@ enum km_type { KM_PTE1, KM_IRQ0, KM_IRQ1, + KM_SOFTIRQ0, + KM_SOFTIRQ1, KM_TYPE_NR }; diff --git a/include/asm-h8300/mman.h b/include/asm-h8300/mman.h index abe08856c84..63f727a5985 100644 --- a/include/asm-h8300/mman.h +++ b/include/asm-h8300/mman.h @@ -4,6 +4,7 @@ #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 */ @@ -19,6 +20,8 @@ #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/include/asm-i386/agp.h b/include/asm-i386/agp.h index a917ff50354..b82f5f3ab88 100644 --- a/include/asm-i386/agp.h +++ b/include/asm-i386/agp.h @@ -21,4 +21,14 @@ 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/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h index 1b46fd3f2ae..c6044488e9e 100644 --- a/include/asm-i386/mach-numaq/mach_ipi.h +++ b/include/asm-i386/mach-numaq/mach_ipi.h @@ -1,7 +1,7 @@ #ifndef __ASM_MACH_IPI_H #define __ASM_MACH_IPI_H -inline void send_IPI_mask_sequence(cpumask_t, int vector); +void send_IPI_mask_sequence(cpumask_t, int vector); static inline void send_IPI_mask(cpumask_t mask, int vector) { diff --git a/include/asm-ia64/agp.h b/include/asm-ia64/agp.h index d1316f1e6ee..4e517f0e6af 100644 --- a/include/asm-ia64/agp.h +++ b/include/asm-ia64/agp.h @@ -18,4 +18,14 @@ #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/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h index ea121a00230..fcc9c3344ab 100644 --- a/include/asm-ia64/pgtable.h +++ b/include/asm-ia64/pgtable.h @@ -8,7 +8,7 @@ * This hopefully works with any (fixed) IA-64 page-size, as defined * in <asm/page.h>. * - * Copyright (C) 1998-2004 Hewlett-Packard Co + * Copyright (C) 1998-2005 Hewlett-Packard Co * David Mosberger-Tang <davidm@hpl.hp.com> */ @@ -551,7 +551,11 @@ do { \ /* These tell get_user_pages() that the first gate page is accessible from user-level. */ #define FIXADDR_USER_START GATE_ADDR -#define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) +#ifdef HAVE_BUGGY_SEGREL +# define FIXADDR_USER_END (GATE_ADDR + 2*PAGE_SIZE) +#else +# define FIXADDR_USER_END (GATE_ADDR + 2*PERCPU_PAGE_SIZE) +#endif #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 9e1ba8b7fb6..91bbd1f2246 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h @@ -403,7 +403,10 @@ extern void ia64_setreg_unknown_kr (void); * task_struct at this point. */ -/* Return TRUE if task T owns the fph partition of the CPU we're running on. */ +/* + * Return TRUE if task T owns the fph partition of the CPU we're running on. + * Must be called from code that has preemption disabled. + */ #define ia64_is_local_fpu_owner(t) \ ({ \ struct task_struct *__ia64_islfo_task = (t); \ @@ -411,7 +414,10 @@ extern void ia64_setreg_unknown_kr (void); && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER)); \ }) -/* Mark task T as owning the fph partition of the CPU we're running on. */ +/* + * Mark task T as owning the fph partition of the CPU we're running on. + * Must be called from code that has preemption disabled. + */ #define ia64_set_local_fpu_owner(t) do { \ struct task_struct *__ia64_slfo_task = (t); \ __ia64_slfo_task->thread.last_fph_cpu = smp_processor_id(); \ diff --git a/include/asm-ppc/agp.h b/include/asm-ppc/agp.h index be27cfa8c5b..ca9e423307f 100644 --- a/include/asm-ppc/agp.h +++ b/include/asm-ppc/agp.h @@ -10,4 +10,14 @@ #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/include/asm-ppc/sigcontext.h b/include/asm-ppc/sigcontext.h index f82dcccdee1..b7a417e0a92 100644 --- a/include/asm-ppc/sigcontext.h +++ b/include/asm-ppc/sigcontext.h @@ -2,7 +2,7 @@ #define _ASM_PPC_SIGCONTEXT_H #include <asm/ptrace.h> - +#include <linux/compiler.h> struct sigcontext { unsigned long _unused[4]; diff --git a/include/asm-ppc64/agp.h b/include/asm-ppc64/agp.h index be27cfa8c5b..ca9e423307f 100644 --- a/include/asm-ppc64/agp.h +++ b/include/asm-ppc64/agp.h @@ -10,4 +10,14 @@ #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/include/asm-ppc64/elf.h b/include/asm-ppc64/elf.h index 6c42d61bedd..085eedb956f 100644 --- a/include/asm-ppc64/elf.h +++ b/include/asm-ppc64/elf.h @@ -221,9 +221,7 @@ do { \ set_thread_flag(TIF_ABI_PENDING); \ else \ clear_thread_flag(TIF_ABI_PENDING); \ - if (ibcs2) \ - set_personality(PER_SVR4); \ - else if (current->personality != PER_LINUX32) \ + if (personality(current->personality) != PER_LINUX32) \ set_personality(PER_LINUX); \ } while (0) diff --git a/include/asm-ppc64/processor.h b/include/asm-ppc64/processor.h index 0035efe2db2..809c634ba1d 100644 --- a/include/asm-ppc64/processor.h +++ b/include/asm-ppc64/processor.h @@ -120,103 +120,18 @@ /* Special Purpose Registers (SPRNs)*/ -#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ #define SPRN_CTR 0x009 /* Count Register */ #define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ -#define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ -#define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ +#define DABR_TRANSLATION (1UL << 2) #define SPRN_DAR 0x013 /* Data Address Register */ -#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ -#define DBCR_EDM 0x80000000 -#define DBCR_IDM 0x40000000 -#define DBCR_RST(x) (((x) & 0x3) << 28) -#define DBCR_RST_NONE 0 -#define DBCR_RST_CORE 1 -#define DBCR_RST_CHIP 2 -#define DBCR_RST_SYSTEM 3 -#define DBCR_IC 0x08000000 /* Instruction Completion Debug Evnt */ -#define DBCR_BT 0x04000000 /* Branch Taken Debug Event */ -#define DBCR_EDE 0x02000000 /* Exception Debug Event */ -#define DBCR_TDE 0x01000000 /* TRAP Debug Event */ -#define DBCR_FER 0x00F80000 /* First Events Remaining Mask */ -#define DBCR_FT 0x00040000 /* Freeze Timers on Debug Event */ -#define DBCR_IA1 0x00020000 /* Instr. Addr. Compare 1 Enable */ -#define DBCR_IA2 0x00010000 /* Instr. Addr. Compare 2 Enable */ -#define DBCR_D1R 0x00008000 /* Data Addr. Compare 1 Read Enable */ -#define DBCR_D1W 0x00004000 /* Data Addr. Compare 1 Write Enable */ -#define DBCR_D1S(x) (((x) & 0x3) << 12) /* Data Adrr. Compare 1 Size */ -#define DAC_BYTE 0 -#define DAC_HALF 1 -#define DAC_WORD 2 -#define DAC_QUAD 3 -#define DBCR_D2R 0x00000800 /* Data Addr. Compare 2 Read Enable */ -#define DBCR_D2W 0x00000400 /* Data Addr. Compare 2 Write Enable */ -#define DBCR_D2S(x) (((x) & 0x3) << 8) /* Data Addr. Compare 2 Size */ -#define DBCR_SBT 0x00000040 /* Second Branch Taken Debug Event */ -#define DBCR_SED 0x00000020 /* Second Exception Debug Event */ -#define DBCR_STD 0x00000010 /* Second Trap Debug Event */ -#define DBCR_SIA 0x00000008 /* Second IAC Enable */ -#define DBCR_SDA 0x00000004 /* Second DAC Enable */ -#define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ -#define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ -#define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ -#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ -#define SPRN_DBSR 0x3F0 /* Debug Status Register */ -#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ -#define DCCR_NOCACHE 0 /* Noncacheable */ -#define DCCR_CACHE 1 /* Cacheable */ -#define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */ -#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ -#define DCWR_COPY 0 /* Copy-back */ -#define DCWR_WRITE 1 /* Write-through */ -#define SPRN_DEAR 0x3D5 /* Data Error Address Register */ #define SPRN_DEC 0x016 /* Decrement Register */ -#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ #define DSISR_NOHPTE 0x40000000 /* no translation found */ #define DSISR_PROTFAULT 0x08000000 /* protection fault */ #define DSISR_ISSTORE 0x02000000 /* access was a store */ #define DSISR_DABRMATCH 0x00400000 /* hit data breakpoint */ #define DSISR_NOSEGMENT 0x00200000 /* STAB/SLB miss */ -#define SPRN_EAR 0x11A /* External Address Register */ -#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ -#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ -#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ -#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ -#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ -#define ESR_PIL 0x08000000 /* Program Exception - Illegal */ -#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ -#define ESR_PTR 0x02000000 /* Program Exception - Trap */ -#define ESR_DST 0x00800000 /* Storage Exception - Data miss */ -#define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ -#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ -#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ -#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ #define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ -#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ -#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ -#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ -#define HID0_SBCLK (1<<27) -#define HID0_EICE (1<<26) -#define HID0_ECLK (1<<25) -#define HID0_PAR (1<<24) -#define HID0_DOZE (1<<23) -#define HID0_NAP (1<<22) -#define HID0_SLEEP (1<<21) -#define HID0_DPM (1<<20) -#define HID0_ICE (1<<15) /* Instruction Cache Enable */ -#define HID0_DCE (1<<14) /* Data Cache Enable */ -#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ -#define HID0_DLOCK (1<<12) /* Data Cache Lock */ -#define HID0_ICFI (1<<11) /* Instr. Cache Flash Invalidate */ -#define HID0_DCI (1<<10) /* Data Cache Invalidate */ -#define HID0_SPD (1<<9) /* Speculative disable */ -#define HID0_SGE (1<<7) /* Store Gathering Enable */ -#define HID0_SIED (1<<7) /* Serial Instr. Execution [Disable] */ -#define HID0_BTIC (1<<5) /* Branch Target Instruction Cache Enable */ -#define HID0_ABE (1<<3) /* Address Broadcast Enable */ -#define HID0_BHTE (1<<2) /* Branch History Table Enable */ -#define HID0_BTCD (1<<1) /* Branch target cache disable */ #define SPRN_MSRDORM 0x3F1 /* Hardware Implementation Register 1 */ #define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ #define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ @@ -225,23 +140,8 @@ #define SPRN_HID5 0x3F6 /* 970 HID5 */ #define SPRN_TSC 0x3FD /* Thread switch control */ #define SPRN_TST 0x3FC /* Thread switch timeout */ -#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ -#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ -#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ -#define ICCR_NOCACHE 0 /* Noncacheable */ -#define ICCR_CACHE 1 /* Cacheable */ -#define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */ -#define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ -#define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ -#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ -#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ #define SPRN_LR 0x008 /* Link Register */ -#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ -#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ -#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ -#define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ -#define SPRN_PID 0x3B1 /* Process ID */ #define SPRN_PIR 0x3FF /* Processor Identification Register */ #define SPRN_PIT 0x3DB /* Programmable Interval Timer */ #define SPRN_PURR 0x135 /* Processor Utilization of Resources Register */ @@ -249,9 +149,6 @@ #define SPRN_RPA 0x3D6 /* Required Physical Address Register */ #define SPRN_SDA 0x3BF /* Sampled Data Address Register */ #define SPRN_SDR1 0x019 /* MMU Hash Base Register */ -#define SPRN_SGR 0x3B9 /* Storage Guarded Register */ -#define SGR_NORMAL 0 -#define SGR_GUARDED 1 #define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ #define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ #define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ @@ -264,50 +161,12 @@ #define SPRN_TBWL 0x11C /* Time Base Lower Register (super, W/O) */ #define SPRN_TBWU 0x11D /* Time Base Write Upper Register (super, W/O) */ #define SPRN_HIOR 0x137 /* 970 Hypervisor interrupt offset */ -#define SPRN_TCR 0x3DA /* Timer Control Register */ -#define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ -#define WP_2_17 0 /* 2^17 clocks */ -#define WP_2_21 1 /* 2^21 clocks */ -#define WP_2_25 2 /* 2^25 clocks */ -#define WP_2_29 3 /* 2^29 clocks */ -#define TCR_WRC(x) (((x)&0x3)<<28) /* WDT Reset Control */ -#define WRC_NONE 0 /* No reset will occur */ -#define WRC_CORE 1 /* Core reset will occur */ -#define WRC_CHIP 2 /* Chip reset will occur */ -#define WRC_SYSTEM 3 /* System reset will occur */ -#define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ -#define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ -#define TCR_FP(x) (((x)&0x3)<<24) /* FIT Period */ -#define FP_2_9 0 /* 2^9 clocks */ -#define FP_2_13 1 /* 2^13 clocks */ -#define FP_2_17 2 /* 2^17 clocks */ -#define FP_2_21 3 /* 2^21 clocks */ -#define TCR_FIE 0x00800000 /* FIT Interrupt Enable */ -#define TCR_ARE 0x00400000 /* Auto Reload Enable */ -#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ -#define THRM1_TIN (1<<0) -#define THRM1_TIV (1<<1) -#define THRM1_THRES (0x7f<<2) -#define THRM1_TID (1<<29) -#define THRM1_TIE (1<<30) -#define THRM1_V (1<<31) -#define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ -#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ -#define THRM3_E (1<<31) -#define SPRN_TSR 0x3D8 /* Timer Status Register */ -#define TSR_ENW 0x80000000 /* Enable Next Watchdog */ -#define TSR_WIS 0x40000000 /* WDT Interrupt Status */ -#define TSR_WRS(x) (((x)&0x3)<<28) /* WDT Reset Status */ -#define WRS_NONE 0 /* No WDT reset occurred */ -#define WRS_CORE 1 /* WDT forced core reset */ -#define WRS_CHIP 2 /* WDT forced chip reset */ -#define WRS_SYSTEM 3 /* WDT forced system reset */ -#define TSR_PIS 0x08000000 /* PIT Interrupt Status */ -#define TSR_FIS 0x04000000 /* FIT Interrupt Status */ #define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ #define SPRN_XER 0x001 /* Fixed Point Exception Register */ -#define SPRN_ZPR 0x3B0 /* Zone Protection Register */ #define SPRN_VRSAVE 0x100 /* Vector save */ +#define SPRN_CTRLF 0x088 +#define SPRN_CTRLT 0x098 +#define CTRL_RUNLATCH 0x1 /* Performance monitor SPRs */ #define SPRN_SIAR 780 @@ -352,28 +211,19 @@ #define CTR SPRN_CTR /* Counter Register */ #define DAR SPRN_DAR /* Data Address Register */ #define DABR SPRN_DABR /* Data Address Breakpoint Register */ -#define DCMP SPRN_DCMP /* Data TLB Compare Register */ #define DEC SPRN_DEC /* Decrement Register */ -#define DMISS SPRN_DMISS /* Data TLB Miss Register */ #define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ -#define EAR SPRN_EAR /* External Address Register */ -#define HASH1 SPRN_HASH1 /* Primary Hash Address Register */ -#define HASH2 SPRN_HASH2 /* Secondary Hash Address Register */ #define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ #define MSRDORM SPRN_MSRDORM /* MSR Dormant Register */ #define NIADORM SPRN_NIADORM /* NIA Dormant Register */ #define TSC SPRN_TSC /* Thread switch control */ #define TST SPRN_TST /* Thread switch timeout */ #define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ -#define ICMP SPRN_ICMP /* Instruction TLB Compare Register */ -#define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ -#define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ #define L2CR SPRN_L2CR /* PPC 750 L2 control register */ #define __LR SPRN_LR #define PVR SPRN_PVR /* Processor Version */ #define PIR SPRN_PIR /* Processor ID */ #define PURR SPRN_PURR /* Processor Utilization of Resource Register */ -//#define RPA SPRN_RPA /* Required Physical Address Register */ #define SDR1 SPRN_SDR1 /* MMU hash base register */ #define SPR0 SPRN_SPRG0 /* Supervisor Private Registers */ #define SPR1 SPRN_SPRG1 @@ -389,10 +239,6 @@ #define TBRU SPRN_TBRU /* Time Base Read Upper Register */ #define TBWL SPRN_TBWL /* Time Base Write Lower Register */ #define TBWU SPRN_TBWU /* Time Base Write Upper Register */ -#define ICTC 1019 -#define THRM1 SPRN_THRM1 /* Thermal Management Register 1 */ -#define THRM2 SPRN_THRM2 /* Thermal Management Register 2 */ -#define THRM3 SPRN_THRM3 /* Thermal Management Register 3 */ #define XER SPRN_XER /* Processor Version Register (PVR) field extraction */ @@ -436,12 +282,6 @@ #define XGLUE(a,b) a##b #define GLUE(a,b) XGLUE(a,b) -/* iSeries CTRL register (for runlatch) */ - -#define CTRLT 0x098 -#define CTRLF 0x088 -#define RUNLATCH 0x0001 - #ifdef __ASSEMBLY__ #define _GLOBAL(name) \ @@ -656,6 +496,24 @@ static inline void prefetchw(const void *x) #define HAVE_ARCH_PICK_MMAP_LAYOUT +static inline void ppc64_runlatch_on(void) +{ + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl |= CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); +} + +static inline void ppc64_runlatch_off(void) +{ + unsigned long ctrl; + + ctrl = mfspr(SPRN_CTRLF); + ctrl &= ~CTRL_RUNLATCH; + mtspr(SPRN_CTRLT, ctrl); +} + #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc64/thread_info.h b/include/asm-ppc64/thread_info.h index 037b5e06083..48b7900e90e 100644 --- a/include/asm-ppc64/thread_info.h +++ b/include/asm-ppc64/thread_info.h @@ -96,7 +96,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_POLLING_NRFLAG 4 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_32BIT 5 /* 32 bit binary */ -#define TIF_RUN_LIGHT 6 /* iSeries run light */ +/* #define SPARE 6 */ #define TIF_ABI_PENDING 7 /* 32/64 bit switch needed */ #define TIF_SYSCALL_AUDIT 8 /* syscall auditing active */ #define TIF_SINGLESTEP 9 /* singlestepping active */ @@ -110,7 +110,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_32BIT (1<<TIF_32BIT) -#define _TIF_RUN_LIGHT (1<<TIF_RUN_LIGHT) +/* #define _SPARE (1<<SPARE) */ #define _TIF_ABI_PENDING (1<<TIF_ABI_PENDING) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h index c64f8c181df..1dc74baf03c 100644 --- a/include/asm-s390/user.h +++ b/include/asm-s390/user.h @@ -10,7 +10,7 @@ #define _S390_USER_H #include <asm/page.h> -#include <linux/ptrace.h> +#include <asm/ptrace.h> /* 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/include/asm-sparc/uaccess.h b/include/asm-sparc/uaccess.h index f461144067e..0a780e84a12 100644 --- a/include/asm-sparc/uaccess.h +++ b/include/asm-sparc/uaccess.h @@ -41,10 +41,11 @@ * No one can read/write anything from userland in the kernel space by setting * large size and address near to PAGE_OFFSET - a fault will break his intentions. */ -#define __user_ok(addr,size) ((addr) < STACK_TOP) +#define __user_ok(addr, size) ({ (void)(size); (addr) < STACK_TOP; }) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) #define __access_ok(addr,size) (__user_ok((addr) & get_fs().seg,(size))) -#define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) +#define access_ok(type, addr, size) \ + ({ (void)(type); __access_ok((unsigned long)(addr), size); }) /* this function will go away soon - use access_ok() instead */ static inline int __deprecated verify_area(int type, const void __user * addr, unsigned long size) diff --git a/include/asm-sparc64/agp.h b/include/asm-sparc64/agp.h index ba05bdf9a21..58f8cb6ae76 100644 --- a/include/asm-sparc64/agp.h +++ b/include/asm-sparc64/agp.h @@ -8,4 +8,14 @@ #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/include/asm-x86_64/agp.h b/include/asm-x86_64/agp.h index 0bb9019d58a..06c52ee9c06 100644 --- a/include/asm-x86_64/agp.h +++ b/include/asm-x86_64/agp.h @@ -19,4 +19,14 @@ 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/include/linux/acpi.h b/include/linux/acpi.h index d5a55bdb9c3..b123cc08773 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -25,6 +25,8 @@ #ifndef _LINUX_ACPI_H #define _LINUX_ACPI_H +#include <linux/config.h> + #ifdef CONFIG_ACPI #ifndef _LINUX diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 0485b256d04..004e6f09a6e 100644 --- a/include/linux/if_shaper.h +++ b/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 */ - unsigned long locked; + struct semaphore sem; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, @@ -38,7 +38,6 @@ 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/include/linux/if_tr.h b/include/linux/if_tr.h index 6688b414c52..3fba9e2f542 100644 --- a/include/linux/if_tr.h +++ b/include/linux/if_tr.h @@ -19,6 +19,8 @@ #ifndef _LINUX_IF_TR_H #define _LINUX_IF_TR_H +#include <asm/byteorder.h> /* For __be16 */ + /* IEEE 802.5 Token-Ring magic constants. The frame sizes omit the preamble and FCS/CRC (frame check sequence). */ #define TR_ALEN 6 /* Octets in one token-ring addr */ diff --git a/include/linux/libata.h b/include/linux/libata.h index e74f301e9ba..b009f801e7c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -467,12 +467,34 @@ 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) { @@ -487,6 +509,18 @@ 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); @@ -525,6 +559,18 @@ 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; @@ -544,6 +590,18 @@ 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/include/linux/netdevice.h b/include/linux/netdevice.h index 470af8c1a4a..ba5d1236aa1 100644 --- a/include/linux/netdevice.h +++ b/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) & (HH_DATA_MOD - 1))) + (HH_DATA_MOD - (((__len - 1) & (HH_DATA_MOD - 1)) + 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/include/linux/pci_ids.h b/include/linux/pci_ids.h index b0d6134e1ee..b8b4ebf9abf 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -874,6 +874,7 @@ #define PCI_DEVICE_ID_APPLE_KL_USB_P 0x0026 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 #define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d +#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA 0x0033 @@ -2382,6 +2383,8 @@ #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/include/linux/signal.h b/include/linux/signal.h index 0a98f5ec5ca..7be18b5e2fb 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -231,10 +231,8 @@ extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *); extern long do_sigpending(void __user *, unsigned long); extern int sigprocmask(int, sigset_t *, sigset_t *); -#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER struct pt_regs; extern int get_signal_to_deliver(siginfo_t *info, struct k_sigaction *return_ka, struct pt_regs *regs, void *cookie); -#endif #endif /* __KERNEL__ */ diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 23032d9d607..a17745c80a9 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -346,6 +346,7 @@ enum NET_TCP_MODERATE_RCVBUF=106, NET_TCP_TSO_WIN_DIVISOR=107, NET_TCP_BIC_BETA=108, + NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109, }; enum { diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index aa6b48bb4dc..a6b2cc530af 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -56,6 +56,36 @@ enum TCF_META_ID_TCCLASSID, TCF_META_ID_RTCLASSID, TCF_META_ID_RTIIF, + TCF_META_ID_SK_FAMILY, + TCF_META_ID_SK_STATE, + TCF_META_ID_SK_REUSE, + TCF_META_ID_SK_BOUND_IF, + TCF_META_ID_SK_REFCNT, + TCF_META_ID_SK_SHUTDOWN, + TCF_META_ID_SK_PROTO, + TCF_META_ID_SK_TYPE, + TCF_META_ID_SK_RCVBUF, + TCF_META_ID_SK_RMEM_ALLOC, + TCF_META_ID_SK_WMEM_ALLOC, + TCF_META_ID_SK_OMEM_ALLOC, + TCF_META_ID_SK_WMEM_QUEUED, + TCF_META_ID_SK_RCV_QLEN, + TCF_META_ID_SK_SND_QLEN, + TCF_META_ID_SK_ERR_QLEN, + TCF_META_ID_SK_FORWARD_ALLOCS, + TCF_META_ID_SK_SNDBUF, + TCF_META_ID_SK_ALLOCS, + TCF_META_ID_SK_ROUTE_CAPS, + TCF_META_ID_SK_HASHENT, + TCF_META_ID_SK_LINGERTIME, + TCF_META_ID_SK_ACK_BACKLOG, + TCF_META_ID_SK_MAX_ACK_BACKLOG, + TCF_META_ID_SK_PRIO, + TCF_META_ID_SK_RCVLOWAT, + TCF_META_ID_SK_RCVTIMEO, + TCF_META_ID_SK_SNDTIMEO, + TCF_META_ID_SK_SENDMSG_OFF, + TCF_META_ID_SK_WRITE_PENDING, __TCF_META_ID_MAX }; #define TCF_META_ID_MAX (__TCF_META_ID_MAX - 1) diff --git a/include/linux/usb.h b/include/linux/usb.h index 41d1a644c9d..2d1ac505853 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -796,6 +796,10 @@ 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 { @@ -803,12 +807,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/include/net/ip.h b/include/net/ip.h index 3f63992eb71..32360bbe143 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -163,6 +163,7 @@ DECLARE_SNMP_STAT(struct linux_mib, net_statistics); extern int sysctl_local_port_range[2]; extern int sysctl_ip_default_ttl; +extern int sysctl_ip_nonlocal_bind; #ifdef CONFIG_INET /* The function in 2.2 was invalid, producing wrong result for diff --git a/kernel/exit.c b/kernel/exit.c index edaa50b5bbf..2ef2ad54020 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -811,10 +811,8 @@ fastcall NORET_TYPE void do_exit(long code) acct_update_integrals(tsk); update_mem_hiwater(tsk); group_dead = atomic_dec_and_test(&tsk->signal->live); - if (group_dead) { - del_timer_sync(&tsk->signal->real_timer); + if (group_dead) acct_process(code); - } exit_mm(tsk); exit_sem(tsk); diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index fd316c27226..cabb63fc9e1 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -1197,6 +1197,7 @@ void exit_itimers(struct signal_struct *sig) tmr = list_entry(sig->posix_timers.next, struct k_itimer, list); itimer_delete(tmr); } + del_timer_sync(&sig->real_timer); } /* diff --git a/kernel/sched.c b/kernel/sched.c index 66b2ed78482..f12a0c8a7d9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3755,19 +3755,22 @@ EXPORT_SYMBOL(cond_resched); */ int cond_resched_lock(spinlock_t * lock) { + int ret = 0; + if (need_lockbreak(lock)) { spin_unlock(lock); cpu_relax(); + ret = 1; spin_lock(lock); } if (need_resched()) { _raw_spin_unlock(lock); preempt_enable_no_resched(); __cond_resched(); + ret = 1; spin_lock(lock); - return 1; } - return 0; + return ret; } EXPORT_SYMBOL(cond_resched_lock); diff --git a/mm/filemap.c b/mm/filemap.c index 1d33fec7bac..4a2fee2cb62 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1968,6 +1968,7 @@ 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 */ @@ -1982,7 +1983,10 @@ 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. */ - fault_in_pages_readable(buf, bytes); + maxlen = cur_iov->iov_len - iov_base; + if (maxlen > bytes) + maxlen = bytes; + fault_in_pages_readable(buf, maxlen); page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); if (!page) { @@ -2024,6 +2028,8 @@ 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/net/core/dev.c b/net/core/dev.c index f15a3ffff63..ab935778ce8 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1744,6 +1744,7 @@ static int process_backlog(struct net_device *backlog_dev, int *budget) struct softnet_data *queue = &__get_cpu_var(softnet_data); unsigned long start_time = jiffies; + backlog_dev->weight = weight_p; for (;;) { struct sk_buff *skb; struct net_device *dev; diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 8ec484894d6..a3eeb88e1c8 100644 --- a/net/core/ethtool.c +++ b/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->get_coalesce) + if (!dev->ethtool_ops->set_coalesce) return -EOPNOTSUPP; if (copy_from_user(&coalesce, useraddr, sizeof(coalesce))) diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 910eb4c05a4..e2137f3e489 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -185,6 +185,22 @@ static ssize_t store_tx_queue_len(struct class_device *dev, const char *buf, siz static CLASS_DEVICE_ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, store_tx_queue_len); +NETDEVICE_SHOW(weight, fmt_dec); + +static int change_weight(struct net_device *net, unsigned long new_weight) +{ + net->weight = new_weight; + return 0; +} + +static ssize_t store_weight(struct class_device *dev, const char *buf, size_t len) +{ + return netdev_store(dev, buf, len, change_weight); +} + +static CLASS_DEVICE_ATTR(weight, S_IRUGO | S_IWUSR, show_weight, + store_weight); + static struct class_device_attribute *net_class_attributes[] = { &class_device_attr_ifindex, @@ -194,6 +210,7 @@ static struct class_device_attribute *net_class_attributes[] = { &class_device_attr_features, &class_device_attr_mtu, &class_device_attr_flags, + &class_device_attr_weight, &class_device_attr_type, &class_device_attr_address, &class_device_attr_broadcast, diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index b3cb49ce5fa..03942f13394 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1181,6 +1181,7 @@ EXPORT_SYMBOL(inet_stream_connect); EXPORT_SYMBOL(inet_stream_ops); EXPORT_SYMBOL(inet_unregister_protosw); EXPORT_SYMBOL(net_statistics); +EXPORT_SYMBOL(sysctl_ip_nonlocal_bind); #ifdef INET_REFCNT_DEBUG EXPORT_SYMBOL(inet_sock_nr); diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 85bf0d3e294..cb759484979 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -207,6 +207,7 @@ int sysctl_icmp_ignore_bogus_error_responses; int sysctl_icmp_ratelimit = 1 * HZ; int sysctl_icmp_ratemask = 0x1818; +int sysctl_icmp_errors_use_inbound_ifaddr; /* * ICMP control array. This specifies what to do with each ICMP. @@ -511,8 +512,12 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) */ saddr = iph->daddr; - if (!(rt->rt_flags & RTCF_LOCAL)) - saddr = 0; + if (!(rt->rt_flags & RTCF_LOCAL)) { + if (sysctl_icmp_errors_use_inbound_ifaddr) + saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK); + else + saddr = 0; + } tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL) : diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile index a788461a40c..30e85de9fff 100644 --- a/net/ipv4/ipvs/Makefile +++ b/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_proto_icmp.o \ + ip_vs_est.o ip_vs_proto.o \ $(ip_vs_proto-objs-y) diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c index 253c46252bd..867d4e9c659 100644 --- a/net/ipv4/ipvs/ip_vs_proto.c +++ b/net/ipv4/ipvs/ip_vs_proto.c @@ -216,9 +216,6 @@ 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/net/ipv4/ipvs/ip_vs_proto_icmp.c b/net/ipv4/ipvs/ip_vs_proto_icmp.c deleted file mode 100644 index 191e94aa1c1..00000000000 --- a/net/ipv4/ipvs/ip_vs_proto_icmp.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * ip_vs_proto_icmp.c: ICMP load balancing support for IP Virtual Server - * - * Authors: Julian Anastasov <ja@ssi.bg>, 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 <linux/module.h> -#include <linux/kernel.h> -#include <linux/icmp.h> -#include <linux/netfilter.h> -#include <linux/netfilter_ipv4.h> - -#include <net/ip_vs.h> - - -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/net/ipv4/multipath_drr.c b/net/ipv4/multipath_drr.c index cf2e6bcf797..c9cf8726051 100644 --- a/net/ipv4/multipath_drr.c +++ b/net/ipv4/multipath_drr.c @@ -31,6 +31,7 @@ #include <linux/igmp.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/module.h> #include <linux/mroute.h> #include <linux/init.h> #include <net/ip.h> @@ -247,3 +248,4 @@ static void __exit drr_exit(void) module_init(drr_init); module_exit(drr_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_random.c b/net/ipv4/multipath_random.c index 805a16e47de..5249dbe7c55 100644 --- a/net/ipv4/multipath_random.c +++ b/net/ipv4/multipath_random.c @@ -31,6 +31,7 @@ #include <linux/igmp.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/module.h> #include <linux/mroute.h> #include <linux/init.h> #include <net/ip.h> @@ -126,3 +127,4 @@ static void __exit random_exit(void) module_init(random_init); module_exit(random_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_rr.c b/net/ipv4/multipath_rr.c index 061b6b25398..b6cd2870478 100644 --- a/net/ipv4/multipath_rr.c +++ b/net/ipv4/multipath_rr.c @@ -31,6 +31,7 @@ #include <linux/igmp.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/module.h> #include <linux/mroute.h> #include <linux/init.h> #include <net/ip.h> @@ -93,3 +94,4 @@ static void __exit rr_exit(void) module_init(rr_init); module_exit(rr_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index c3d2ca1a678..bd7d75b6abe 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c @@ -31,6 +31,7 @@ #include <linux/igmp.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/module.h> #include <linux/mroute.h> #include <linux/init.h> #include <net/ip.h> @@ -342,3 +343,4 @@ static void __exit wrandom_exit(void) module_init(wrandom_init); module_exit(wrandom_exit); +MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 46ca45f74d8..bc59f7b3980 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -256,6 +256,7 @@ static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos) { struct list_head *e = v; + ++*pos; e = e->next; if (e == &ip_conntrack_expect_list) diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c index 25ab9fabdcb..2d44b07688a 100644 --- a/net/ipv4/netfilter/ipt_recent.c +++ b/net/ipv4/netfilter/ipt_recent.c @@ -223,7 +223,7 @@ static int ip_recent_ctrl(struct file *file, const char __user *input, unsigned curr_table->table[count].last_seen = 0; curr_table->table[count].addr = 0; curr_table->table[count].ttl = 0; - memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(curr_table->table[count].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); curr_table->table[count].oldest_pkt = 0; curr_table->table[count].time_pos = 0; curr_table->time_info[count].position = count; @@ -502,7 +502,7 @@ match(const struct sk_buff *skb, location = time_info[curr_table->time_pos].position; hash_table[r_list[location].hash_entry] = -1; hash_table[hash_result] = location; - memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); r_list[location].time_pos = curr_table->time_pos; r_list[location].addr = addr; r_list[location].ttl = ttl; @@ -631,7 +631,7 @@ match(const struct sk_buff *skb, r_list[location].last_seen = 0; r_list[location].addr = 0; r_list[location].ttl = 0; - memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(u_int32_t)); + memset(r_list[location].last_pkts,0,ip_pkt_list_tot*sizeof(unsigned long)); r_list[location].oldest_pkt = 0; ans = !info->invert; } @@ -734,10 +734,10 @@ checkentry(const char *tablename, memset(curr_table->table,0,sizeof(struct recent_ip_list)*ip_list_tot); #ifdef DEBUG if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: Allocating %d for pkt_list.\n", - sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); + sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot); #endif - hold = vmalloc(sizeof(u_int32_t)*ip_pkt_list_tot*ip_list_tot); + hold = vmalloc(sizeof(unsigned long)*ip_pkt_list_tot*ip_list_tot); #ifdef DEBUG if(debug) printk(KERN_INFO RECENT_NAME ": checkentry: After pkt_list allocation.\n"); #endif diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 3aafb298c1c..23068bddbf0 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -23,6 +23,7 @@ extern int sysctl_ip_nonlocal_bind; extern int sysctl_icmp_echo_ignore_all; extern int sysctl_icmp_echo_ignore_broadcasts; extern int sysctl_icmp_ignore_bogus_error_responses; +extern int sysctl_icmp_errors_use_inbound_ifaddr; /* From ip_fragment.c */ extern int sysctl_ipfrag_low_thresh; @@ -396,6 +397,14 @@ ctl_table ipv4_table[] = { .proc_handler = &proc_dointvec }, { + .ctl_name = NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR, + .procname = "icmp_errors_use_inbound_ifaddr", + .data = &sysctl_icmp_errors_use_inbound_ifaddr, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { .ctl_name = NET_IPV4_ROUTE, .procname = "route", .maxlen = 0, diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index a037bafcba3..0d9a4fd5f1a 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2338,7 +2338,7 @@ void __init tcp_init(void) (tcp_bhash_size * sizeof(struct tcp_bind_hashbucket)); order++) ; - if (order > 4) { + if (order >= 4) { sysctl_local_port_range[0] = 32768; sysctl_local_port_range[1] = 61000; sysctl_tcp_max_tw_buckets = 180000; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 7744a259269..2720899d516 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -372,6 +372,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ndev->regen_timer.data = (unsigned long) ndev; if ((dev->flags&IFF_LOOPBACK) || dev->type == ARPHRD_TUNNEL || + dev->type == ARPHRD_NONE || dev->type == ARPHRD_SIT) { printk(KERN_INFO "Disabled Privacy Extensions on device %p(%s)\n", diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 8e0f569b883..ff3ec9822e3 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -277,8 +277,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, { struct inet6_dev *idev = NULL; struct ipv6hdr *hdr = skb->nh.ipv6h; - struct sock *sk = icmpv6_socket->sk; - struct ipv6_pinfo *np = inet6_sk(sk); + struct sock *sk; + struct ipv6_pinfo *np; struct in6_addr *saddr = NULL; struct dst_entry *dst; struct icmp6hdr tmp_hdr; @@ -358,6 +358,9 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, if (icmpv6_xmit_lock()) return; + sk = icmpv6_socket->sk; + np = inet6_sk(sk); + if (!icmpv6_xrlim_allow(sk, type, &fl)) goto out; @@ -423,9 +426,9 @@ out: static void icmpv6_echo_reply(struct sk_buff *skb) { - struct sock *sk = icmpv6_socket->sk; + struct sock *sk; struct inet6_dev *idev; - struct ipv6_pinfo *np = inet6_sk(sk); + struct ipv6_pinfo *np; struct in6_addr *saddr = NULL; struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw; struct icmp6hdr tmp_hdr; @@ -454,6 +457,9 @@ static void icmpv6_echo_reply(struct sk_buff *skb) if (icmpv6_xmit_lock()) return; + sk = icmpv6_socket->sk; + np = inet6_sk(sk); + if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst)) fl.oif = np->mcast_oif; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 3b1c9fa184a..ba3b0c267f7 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -882,6 +882,7 @@ ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p) t->parms.hop_limit = p->hop_limit; t->parms.encap_limit = p->encap_limit; t->parms.flowinfo = p->flowinfo; + t->parms.link = p->link; ip6ip6_tnl_link_config(t); return 0; } diff --git a/net/ipv6/ipv6_syms.c b/net/ipv6/ipv6_syms.c index 2f4c91ddc9a..5ade5a5d199 100644 --- a/net/ipv6/ipv6_syms.c +++ b/net/ipv6/ipv6_syms.c @@ -37,5 +37,4 @@ 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); diff --git a/net/sched/Kconfig b/net/sched/Kconfig index b0941186f86..b22c9beb604 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -405,7 +405,7 @@ config NET_EMATCH_STACK ---help--- Size of the local stack variable used while evaluating the tree of ematches. Limits the depth of the tree, i.e. the number of - encapsulated precedences. Every level requires 4 bytes of addtional + encapsulated precedences. Every level requires 4 bytes of additional stack space. config NET_EMATCH_CMP diff --git a/net/sched/act_api.c b/net/sched/act_api.c index cafcb084098..914c85ff8fe 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -881,7 +881,7 @@ static int __init tc_action_init(void) link_p[RTM_GETACTION-RTM_BASE].dumpit = tc_dump_action; } - printk("TC classifier action (bugs to netdev@oss.sgi.com cc " + printk("TC classifier action (bugs to netdev@vger.kernel.org cc " "hadi@cyberus.ca)\n"); return 0; } diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 0d2d4415f33..dfb300bb6ba 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -261,6 +261,9 @@ static int basic_dump(struct tcf_proto *tp, unsigned long fh, rta = (struct rtattr *) b; RTA_PUT(skb, TCA_OPTIONS, 0, NULL); + if (f->res.classid) + RTA_PUT(skb, TCA_BASIC_CLASSID, sizeof(u32), &f->res.classid); + if (tcf_exts_dump(skb, &f->exts, &basic_ext_map) < 0 || tcf_em_tree_dump(skb, &f->ematches, TCA_BASIC_EMATCHES) < 0) goto rtattr_failure; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index f1eeaf65cee..48bb23c2a35 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -32,7 +32,7 @@ * +-----------+ +-----------+ * | | * ---> meta_ops[INT][INDEV](...) | - * | | + * | | * ----------- | * V V * +-----------+ +-----------+ @@ -70,6 +70,7 @@ #include <net/dst.h> #include <net/route.h> #include <net/pkt_cls.h> +#include <net/sock.h> struct meta_obj { @@ -284,6 +285,214 @@ META_COLLECTOR(int_rtiif) } /************************************************************************** + * Socket Attributes + **************************************************************************/ + +#define SKIP_NONLOCAL(skb) \ + if (unlikely(skb->sk == NULL)) { \ + *err = -1; \ + return; \ + } + +META_COLLECTOR(int_sk_family) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_family; +} + +META_COLLECTOR(int_sk_state) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_state; +} + +META_COLLECTOR(int_sk_reuse) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_reuse; +} + +META_COLLECTOR(int_sk_bound_if) +{ + SKIP_NONLOCAL(skb); + /* No error if bound_dev_if is 0, legal userspace check */ + dst->value = skb->sk->sk_bound_dev_if; +} + +META_COLLECTOR(var_sk_bound_if) +{ + SKIP_NONLOCAL(skb); + + if (skb->sk->sk_bound_dev_if == 0) { + dst->value = (unsigned long) "any"; + dst->len = 3; + } else { + struct net_device *dev; + + dev = dev_get_by_index(skb->sk->sk_bound_dev_if); + *err = var_dev(dev, dst); + if (dev) + dev_put(dev); + } +} + +META_COLLECTOR(int_sk_refcnt) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_refcnt); +} + +META_COLLECTOR(int_sk_rcvbuf) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvbuf; +} + +META_COLLECTOR(int_sk_shutdown) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_shutdown; +} + +META_COLLECTOR(int_sk_proto) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_protocol; +} + +META_COLLECTOR(int_sk_type) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_type; +} + +META_COLLECTOR(int_sk_rmem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_rmem_alloc); +} + +META_COLLECTOR(int_sk_wmem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_wmem_alloc); +} + +META_COLLECTOR(int_sk_omem_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = atomic_read(&skb->sk->sk_omem_alloc); +} + +META_COLLECTOR(int_sk_rcv_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_receive_queue.qlen; +} + +META_COLLECTOR(int_sk_snd_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_write_queue.qlen; +} + +META_COLLECTOR(int_sk_wmem_queued) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_wmem_queued; +} + +META_COLLECTOR(int_sk_fwd_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_forward_alloc; +} + +META_COLLECTOR(int_sk_sndbuf) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndbuf; +} + +META_COLLECTOR(int_sk_alloc) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_allocation; +} + +META_COLLECTOR(int_sk_route_caps) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_route_caps; +} + +META_COLLECTOR(int_sk_hashent) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_hashent; +} + +META_COLLECTOR(int_sk_lingertime) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_lingertime / HZ; +} + +META_COLLECTOR(int_sk_err_qlen) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_error_queue.qlen; +} + +META_COLLECTOR(int_sk_ack_bl) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_ack_backlog; +} + +META_COLLECTOR(int_sk_max_ack_bl) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_max_ack_backlog; +} + +META_COLLECTOR(int_sk_prio) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_priority; +} + +META_COLLECTOR(int_sk_rcvlowat) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvlowat; +} + +META_COLLECTOR(int_sk_rcvtimeo) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_rcvtimeo / HZ; +} + +META_COLLECTOR(int_sk_sndtimeo) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndtimeo / HZ; +} + +META_COLLECTOR(int_sk_sendmsg_off) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_sndmsg_off; +} + +META_COLLECTOR(int_sk_write_pend) +{ + SKIP_NONLOCAL(skb); + dst->value = skb->sk->sk_write_pending; +} + +/************************************************************************** * Meta value collectors assignment table **************************************************************************/ @@ -293,41 +502,75 @@ struct meta_ops struct meta_value *, struct meta_obj *, int *); }; +#define META_ID(name) TCF_META_ID_##name +#define META_FUNC(name) { .get = meta_##name } + /* Meta value operations table listing all meta value collectors and * assigns them to a type and meta id. */ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [TCF_META_TYPE_VAR] = { - [TCF_META_ID_DEV] = { .get = meta_var_dev }, - [TCF_META_ID_INDEV] = { .get = meta_var_indev }, - [TCF_META_ID_REALDEV] = { .get = meta_var_realdev } + [META_ID(DEV)] = META_FUNC(var_dev), + [META_ID(INDEV)] = META_FUNC(var_indev), + [META_ID(REALDEV)] = META_FUNC(var_realdev), + [META_ID(SK_BOUND_IF)] = META_FUNC(var_sk_bound_if), }, [TCF_META_TYPE_INT] = { - [TCF_META_ID_RANDOM] = { .get = meta_int_random }, - [TCF_META_ID_LOADAVG_0] = { .get = meta_int_loadavg_0 }, - [TCF_META_ID_LOADAVG_1] = { .get = meta_int_loadavg_1 }, - [TCF_META_ID_LOADAVG_2] = { .get = meta_int_loadavg_2 }, - [TCF_META_ID_DEV] = { .get = meta_int_dev }, - [TCF_META_ID_INDEV] = { .get = meta_int_indev }, - [TCF_META_ID_REALDEV] = { .get = meta_int_realdev }, - [TCF_META_ID_PRIORITY] = { .get = meta_int_priority }, - [TCF_META_ID_PROTOCOL] = { .get = meta_int_protocol }, - [TCF_META_ID_SECURITY] = { .get = meta_int_security }, - [TCF_META_ID_PKTTYPE] = { .get = meta_int_pkttype }, - [TCF_META_ID_PKTLEN] = { .get = meta_int_pktlen }, - [TCF_META_ID_DATALEN] = { .get = meta_int_datalen }, - [TCF_META_ID_MACLEN] = { .get = meta_int_maclen }, + [META_ID(RANDOM)] = META_FUNC(int_random), + [META_ID(LOADAVG_0)] = META_FUNC(int_loadavg_0), + [META_ID(LOADAVG_1)] = META_FUNC(int_loadavg_1), + [META_ID(LOADAVG_2)] = META_FUNC(int_loadavg_2), + [META_ID(DEV)] = META_FUNC(int_dev), + [META_ID(INDEV)] = META_FUNC(int_indev), + [META_ID(REALDEV)] = META_FUNC(int_realdev), + [META_ID(PRIORITY)] = META_FUNC(int_priority), + [META_ID(PROTOCOL)] = META_FUNC(int_protocol), + [META_ID(SECURITY)] = META_FUNC(int_security), + [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), + [META_ID(PKTLEN)] = META_FUNC(int_pktlen), + [META_ID(DATALEN)] = META_FUNC(int_datalen), + [META_ID(MACLEN)] = META_FUNC(int_maclen), #ifdef CONFIG_NETFILTER - [TCF_META_ID_NFMARK] = { .get = meta_int_nfmark }, + [META_ID(NFMARK)] = META_FUNC(int_nfmark), #endif - [TCF_META_ID_TCINDEX] = { .get = meta_int_tcindex }, + [META_ID(TCINDEX)] = META_FUNC(int_tcindex), #ifdef CONFIG_NET_CLS_ACT - [TCF_META_ID_TCVERDICT] = { .get = meta_int_tcverd }, - [TCF_META_ID_TCCLASSID] = { .get = meta_int_tcclassid }, + [META_ID(TCVERDICT)] = META_FUNC(int_tcverd), + [META_ID(TCCLASSID)] = META_FUNC(int_tcclassid), #endif #ifdef CONFIG_NET_CLS_ROUTE - [TCF_META_ID_RTCLASSID] = { .get = meta_int_rtclassid }, + [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), #endif - [TCF_META_ID_RTIIF] = { .get = meta_int_rtiif } + [META_ID(RTIIF)] = META_FUNC(int_rtiif), + [META_ID(SK_FAMILY)] = META_FUNC(int_sk_family), + [META_ID(SK_STATE)] = META_FUNC(int_sk_state), + [META_ID(SK_REUSE)] = META_FUNC(int_sk_reuse), + [META_ID(SK_BOUND_IF)] = META_FUNC(int_sk_bound_if), + [META_ID(SK_REFCNT)] = META_FUNC(int_sk_refcnt), + [META_ID(SK_RCVBUF)] = META_FUNC(int_sk_rcvbuf), + [META_ID(SK_SNDBUF)] = META_FUNC(int_sk_sndbuf), + [META_ID(SK_SHUTDOWN)] = META_FUNC(int_sk_shutdown), + [META_ID(SK_PROTO)] = META_FUNC(int_sk_proto), + [META_ID(SK_TYPE)] = META_FUNC(int_sk_type), + [META_ID(SK_RMEM_ALLOC)] = META_FUNC(int_sk_rmem_alloc), + [META_ID(SK_WMEM_ALLOC)] = META_FUNC(int_sk_wmem_alloc), + [META_ID(SK_OMEM_ALLOC)] = META_FUNC(int_sk_omem_alloc), + [META_ID(SK_WMEM_QUEUED)] = META_FUNC(int_sk_wmem_queued), + [META_ID(SK_RCV_QLEN)] = META_FUNC(int_sk_rcv_qlen), + [META_ID(SK_SND_QLEN)] = META_FUNC(int_sk_snd_qlen), + [META_ID(SK_ERR_QLEN)] = META_FUNC(int_sk_err_qlen), + [META_ID(SK_FORWARD_ALLOCS)] = META_FUNC(int_sk_fwd_alloc), + [META_ID(SK_ALLOCS)] = META_FUNC(int_sk_alloc), + [META_ID(SK_ROUTE_CAPS)] = META_FUNC(int_sk_route_caps), + [META_ID(SK_HASHENT)] = META_FUNC(int_sk_hashent), + [META_ID(SK_LINGERTIME)] = META_FUNC(int_sk_lingertime), + [META_ID(SK_ACK_BACKLOG)] = META_FUNC(int_sk_ack_bl), + [META_ID(SK_MAX_ACK_BACKLOG)] = META_FUNC(int_sk_max_ack_bl), + [META_ID(SK_PRIO)] = META_FUNC(int_sk_prio), + [META_ID(SK_RCVLOWAT)] = META_FUNC(int_sk_rcvlowat), + [META_ID(SK_RCVTIMEO)] = META_FUNC(int_sk_rcvtimeo), + [META_ID(SK_SNDTIMEO)] = META_FUNC(int_sk_sndtimeo), + [META_ID(SK_SENDMSG_OFF)] = META_FUNC(int_sk_sendmsg_off), + [META_ID(SK_WRITE_PENDING)] = META_FUNC(int_sk_write_pend), } }; @@ -396,9 +639,9 @@ static int meta_int_compare(struct meta_obj *a, struct meta_obj *b) /* Let gcc optimize it, the unlikely is not really based on * some numbers but jump free code for mismatches seems * more logical. */ - if (unlikely(a == b)) + if (unlikely(a->value == b->value)) return 0; - else if (a < b) + else if (a->value < b->value) return -1; else return 1; diff --git a/net/sctp/input.c b/net/sctp/input.c index b719a77d66b..fffc880a646 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -178,6 +178,37 @@ int sctp_rcv(struct sk_buff *skb) asoc = __sctp_rcv_lookup(skb, &src, &dest, &transport); + if (!asoc) + ep = __sctp_rcv_lookup_endpoint(&dest); + + /* Retrieve the common input handling substructure. */ + rcvr = asoc ? &asoc->base : &ep->base; + sk = rcvr->sk; + + /* + * If a frame arrives on an interface and the receiving socket is + * bound to another interface, via SO_BINDTODEVICE, treat it as OOTB + */ + if (sk->sk_bound_dev_if && (sk->sk_bound_dev_if != af->skb_iif(skb))) + { + sock_put(sk); + if (asoc) { + sctp_association_put(asoc); + asoc = NULL; + } else { + sctp_endpoint_put(ep); + ep = NULL; + } + sk = sctp_get_ctl_sock(); + ep = sctp_sk(sk)->ep; + sctp_endpoint_hold(ep); + sock_hold(sk); + rcvr = &ep->base; + } + + if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf) + goto discard_release; + /* * RFC 2960, 8.4 - Handle "Out of the blue" Packets. * An SCTP packet is called an "out of the blue" (OOTB) @@ -187,22 +218,12 @@ int sctp_rcv(struct sk_buff *skb) * packet belongs. */ if (!asoc) { - ep = __sctp_rcv_lookup_endpoint(&dest); if (sctp_rcv_ootb(skb)) { SCTP_INC_STATS_BH(SCTP_MIB_OUTOFBLUES); goto discard_release; } } - /* Retrieve the common input handling substructure. */ - rcvr = asoc ? &asoc->base : &ep->base; - sk = rcvr->sk; - - if ((sk) && (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)) { - goto discard_release; - } - - /* SCTP seems to always need a timestamp right now (FIXME) */ if (skb->stamp.tv_sec == 0) { do_gettimeofday(&skb->stamp); @@ -265,13 +286,11 @@ discard_it: discard_release: /* Release any structures we may be holding. */ - if (asoc) { - sock_put(asoc->base.sk); + sock_put(sk); + if (asoc) sctp_association_put(asoc); - } else { - sock_put(ep->base.sk); + else sctp_endpoint_put(ep); - } goto discard_it; } diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index c9d9ea06473..c7e42d125b9 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -812,26 +812,23 @@ static int sctp_inet6_bind_verify(struct sctp_sock *opt, union sctp_addr *addr) if (addr->sa.sa_family != AF_INET6) af = sctp_get_af_specific(addr->sa.sa_family); else { - struct sock *sk; int type = ipv6_addr_type(&addr->v6.sin6_addr); - sk = sctp_opt2sk(opt); + struct net_device *dev; + if (type & IPV6_ADDR_LINKLOCAL) { - /* Note: Behavior similar to af_inet6.c: - * 1) Overrides previous bound_dev_if - * 2) Destructive even if bind isn't successful. - */ - - if (addr->v6.sin6_scope_id) - sk->sk_bound_dev_if = addr->v6.sin6_scope_id; - if (!sk->sk_bound_dev_if) + if (!addr->v6.sin6_scope_id) + return 0; + dev = dev_get_by_index(addr->v6.sin6_scope_id); + if (!dev) return 0; + dev_put(dev); } af = opt->pf->af; } return af->available(addr, opt); } -/* Verify that the provided sockaddr looks bindable. Common verification, +/* Verify that the provided sockaddr looks sendable. Common verification, * has already been taken care of. */ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) @@ -842,19 +839,16 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr) if (addr->sa.sa_family != AF_INET6) af = sctp_get_af_specific(addr->sa.sa_family); else { - struct sock *sk; int type = ipv6_addr_type(&addr->v6.sin6_addr); - sk = sctp_opt2sk(opt); + struct net_device *dev; + if (type & IPV6_ADDR_LINKLOCAL) { - /* Note: Behavior similar to af_inet6.c: - * 1) Overrides previous bound_dev_if - * 2) Destructive even if bind isn't successful. - */ - - if (addr->v6.sin6_scope_id) - sk->sk_bound_dev_if = addr->v6.sin6_scope_id; - if (!sk->sk_bound_dev_if) + if (!addr->v6.sin6_scope_id) + return 0; + dev = dev_get_by_index(addr->v6.sin6_scope_id); + if (!dev) return 0; + dev_put(dev); } af = opt->pf->af; } diff --git a/net/sctp/proc.c b/net/sctp/proc.c index e42fd8c2916..98d49ec9b74 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c @@ -132,14 +132,25 @@ void sctp_snmp_proc_exit(void) static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) { struct list_head *pos; + struct sctp_association *asoc; struct sctp_sockaddr_entry *laddr; - union sctp_addr *addr; + struct sctp_transport *peer; + union sctp_addr *addr, *primary = NULL; struct sctp_af *af; + if (epb->type == SCTP_EP_TYPE_ASSOCIATION) { + asoc = sctp_assoc(epb); + peer = asoc->peer.primary_path; + primary = &peer->saddr; + } + list_for_each(pos, &epb->bind_addr.address_list) { laddr = list_entry(pos, struct sctp_sockaddr_entry, list); addr = (union sctp_addr *)&laddr->a; af = sctp_get_af_specific(addr->sa.sa_family); + if (primary && af->cmp_addr(addr, primary)) { + seq_printf(seq, "*"); + } af->seq_dump_addr(seq, addr); } } @@ -149,17 +160,54 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa { struct list_head *pos; struct sctp_transport *transport; - union sctp_addr *addr; + union sctp_addr *addr, *primary; struct sctp_af *af; + primary = &(assoc->peer.primary_addr); list_for_each(pos, &assoc->peer.transport_addr_list) { transport = list_entry(pos, struct sctp_transport, transports); addr = (union sctp_addr *)&transport->ipaddr; af = sctp_get_af_specific(addr->sa.sa_family); + if (af->cmp_addr(addr, primary)) { + seq_printf(seq, "*"); + } af->seq_dump_addr(seq, addr); } } +static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) +{ + if (*pos > sctp_ep_hashsize) + return NULL; + + if (*pos < 0) + *pos = 0; + + if (*pos == 0) + seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); + + ++*pos; + + return (void *)pos; +} + +static void sctp_eps_seq_stop(struct seq_file *seq, void *v) +{ + return; +} + + +static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + if (*pos > sctp_ep_hashsize) + return NULL; + + ++*pos; + + return pos; +} + + /* Display sctp endpoints (/proc/net/sctp/eps). */ static int sctp_eps_seq_show(struct seq_file *seq, void *v) { @@ -167,38 +215,50 @@ static int sctp_eps_seq_show(struct seq_file *seq, void *v) struct sctp_ep_common *epb; struct sctp_endpoint *ep; struct sock *sk; - int hash; - - seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT LADDRS\n"); - for (hash = 0; hash < sctp_ep_hashsize; hash++) { - head = &sctp_ep_hashtable[hash]; - read_lock(&head->lock); - for (epb = head->chain; epb; epb = epb->next) { - ep = sctp_ep(epb); - sk = epb->sk; - seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d ", ep, sk, - sctp_sk(sk)->type, sk->sk_state, hash, - epb->bind_addr.port); - sctp_seq_dump_local_addrs(seq, epb); - seq_printf(seq, "\n"); - } - read_unlock(&head->lock); + int hash = *(int *)v; + + if (hash > sctp_ep_hashsize) + return -ENOMEM; + + head = &sctp_ep_hashtable[hash-1]; + sctp_local_bh_disable(); + read_lock(&head->lock); + for (epb = head->chain; epb; epb = epb->next) { + ep = sctp_ep(epb); + sk = epb->sk; + seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, + sctp_sk(sk)->type, sk->sk_state, hash-1, + epb->bind_addr.port, + sock_i_uid(sk), sock_i_ino(sk)); + + sctp_seq_dump_local_addrs(seq, epb); + seq_printf(seq, "\n"); } + read_unlock(&head->lock); + sctp_local_bh_enable(); return 0; } +static struct seq_operations sctp_eps_ops = { + .start = sctp_eps_seq_start, + .next = sctp_eps_seq_next, + .stop = sctp_eps_seq_stop, + .show = sctp_eps_seq_show, +}; + + /* Initialize the seq file operations for 'eps' object. */ static int sctp_eps_seq_open(struct inode *inode, struct file *file) { - return single_open(file, sctp_eps_seq_show, NULL); + return seq_open(file, &sctp_eps_ops); } static struct file_operations sctp_eps_seq_fops = { .open = sctp_eps_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; /* Set up the proc fs entry for 'eps' object. */ @@ -221,6 +281,40 @@ void sctp_eps_proc_exit(void) remove_proc_entry("eps", proc_net_sctp); } + +static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) +{ + if (*pos > sctp_assoc_hashsize) + return NULL; + + if (*pos < 0) + *pos = 0; + + if (*pos == 0) + seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " + "RPORT LADDRS <-> RADDRS\n"); + + ++*pos; + + return (void *)pos; +} + +static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) +{ + return; +} + + +static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) +{ + if (*pos > sctp_assoc_hashsize) + return NULL; + + ++*pos; + + return pos; +} + /* Display sctp associations (/proc/net/sctp/assocs). */ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) { @@ -228,43 +322,57 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) struct sctp_ep_common *epb; struct sctp_association *assoc; struct sock *sk; - int hash; - - seq_printf(seq, " ASSOC SOCK STY SST ST HBKT LPORT RPORT " - "LADDRS <-> RADDRS\n"); - for (hash = 0; hash < sctp_assoc_hashsize; hash++) { - head = &sctp_assoc_hashtable[hash]; - read_lock(&head->lock); - for (epb = head->chain; epb; epb = epb->next) { - assoc = sctp_assoc(epb); - sk = epb->sk; - seq_printf(seq, - "%8p %8p %-3d %-3d %-2d %-4d %-5d %-5d ", - assoc, sk, sctp_sk(sk)->type, sk->sk_state, - assoc->state, hash, epb->bind_addr.port, - assoc->peer.port); - sctp_seq_dump_local_addrs(seq, epb); - seq_printf(seq, "<-> "); - sctp_seq_dump_remote_addrs(seq, assoc); - seq_printf(seq, "\n"); - } - read_unlock(&head->lock); + int hash = *(int *)v; + + if (hash > sctp_assoc_hashsize) + return -ENOMEM; + + head = &sctp_assoc_hashtable[hash-1]; + sctp_local_bh_disable(); + read_lock(&head->lock); + for (epb = head->chain; epb; epb = epb->next) { + assoc = sctp_assoc(epb); + sk = epb->sk; + seq_printf(seq, + "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", + assoc, sk, sctp_sk(sk)->type, sk->sk_state, + assoc->state, hash-1, assoc->assoc_id, + (sk->sk_rcvbuf - assoc->rwnd), + assoc->sndbuf_used, + sock_i_uid(sk), sock_i_ino(sk), + epb->bind_addr.port, + assoc->peer.port); + + seq_printf(seq, " "); + sctp_seq_dump_local_addrs(seq, epb); + seq_printf(seq, "<-> "); + sctp_seq_dump_remote_addrs(seq, assoc); + seq_printf(seq, "\n"); } + read_unlock(&head->lock); + sctp_local_bh_enable(); return 0; } +static struct seq_operations sctp_assoc_ops = { + .start = sctp_assocs_seq_start, + .next = sctp_assocs_seq_next, + .stop = sctp_assocs_seq_stop, + .show = sctp_assocs_seq_show, +}; + /* Initialize the seq file operations for 'assocs' object. */ static int sctp_assocs_seq_open(struct inode *inode, struct file *file) { - return single_open(file, sctp_assocs_seq_show, NULL); + return seq_open(file, &sctp_assoc_ops); } static struct file_operations sctp_assocs_seq_fops = { .open = sctp_assocs_seq_open, .read = seq_read, .llseek = seq_lseek, - .release = single_release, + .release = seq_release, }; /* Set up the proc fs entry for 'assocs' object. */ diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 2e1f9c3556f..5135e1a25d2 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -378,10 +378,13 @@ static int sctp_v4_available(union sctp_addr *addr, struct sctp_sock *sp) { int ret = inet_addr_type(addr->v4.sin_addr.s_addr); - /* FIXME: ip_nonlocal_bind sysctl support. */ - if (addr->v4.sin_addr.s_addr != INADDR_ANY && ret != RTN_LOCAL) + if (addr->v4.sin_addr.s_addr != INADDR_ANY && + ret != RTN_LOCAL && + !sp->inet.freebind && + !sysctl_ip_nonlocal_bind) return 0; + return 1; } diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0b338eca6dc..2a3c0e08a09 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4686,6 +4686,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, struct sctp_endpoint *newep = newsp->ep; struct sk_buff *skb, *tmp; struct sctp_ulpevent *event; + int flags = 0; /* Migrate socket buffer sizes and all the socket level options to the * new socket. @@ -4707,6 +4708,17 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, sctp_sk(newsk)->bind_hash = pp; inet_sk(newsk)->num = inet_sk(oldsk)->num; + /* Copy the bind_addr list from the original endpoint to the new + * endpoint so that we can handle restarts properly + */ + if (assoc->peer.ipv4_address) + flags |= SCTP_ADDR4_PEERSUPP; + if (assoc->peer.ipv6_address) + flags |= SCTP_ADDR6_PEERSUPP; + sctp_bind_addr_copy(&newsp->ep->base.bind_addr, + &oldsp->ep->base.bind_addr, + SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags); + /* Move any messages in the old socket's receive queue that are for the * peeled off association to the new socket's receive queue. */ diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c index 84b0bbddbd2..aae66144d41 100644 --- a/sound/usb/usbaudio.c +++ b/sound/usb/usbaudio.c @@ -3289,7 +3289,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr) } usb_chip[chip->index] = NULL; up(®ister_mutex); - snd_card_free_in_thread(card); + snd_card_free(card); } else { up(®ister_mutex); } diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c index b06a267e5da..89ee8b73201 100644 --- a/sound/usb/usx2y/usbusx2y.c +++ b/sound/usb/usx2y/usbusx2y.c @@ -1,6 +1,11 @@ /* * usbusy2y.c - ALSA USB US-428 Driver * +2005-04-14 Karsten Wiese + Version 0.8.7.2: + Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. + Tested ok with kernel 2.6.12-rc2. + 2004-12-14 Karsten Wiese Version 0.8.7.1: snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open. @@ -143,7 +148,7 @@ MODULE_AUTHOR("Karsten Wiese <annabellesgarden@yahoo.de>"); -MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.1"); +MODULE_DESCRIPTION("TASCAM "NAME_ALLCAPS" Version 0.8.7.2"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{TASCAM(0x1604), "NAME_ALLCAPS"(0x8001)(0x8005)(0x8007) }}"); @@ -430,8 +435,6 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) if (ptr) { usX2Ydev_t* usX2Y = usX2Y((snd_card_t*)ptr); struct list_head* p; - if (usX2Y->chip_status == USX2Y_STAT_CHIP_HUP) // on 2.6.1 kernel snd_usbmidi_disconnect() - return; // calls us back. better leave :-) . usX2Y->chip.shutdown = 1; usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; usX2Y_unlinkSeq(&usX2Y->AS04); @@ -443,7 +446,7 @@ static void usX2Y_usb_disconnect(struct usb_device* device, void* ptr) } if (usX2Y->us428ctls_sharedmem) wake_up(&usX2Y->us428ctls_wait_queue_head); - snd_card_free_in_thread((snd_card_t*)ptr); + snd_card_free((snd_card_t*)ptr); } } |