diff --git a/[refs] b/[refs] index b61109e136fa..31fa097f6537 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 30902dc3cb0ea1cfc7ac2b17bcf478ff98420d74 +refs/heads/master: c9df406f3138265193f5e8d7b7fe85dfbbbd3ac4 diff --git a/trunk/Documentation/SubmittingPatches b/trunk/Documentation/SubmittingPatches index 118ca6e9404f..9c93a03ea33b 100644 --- a/trunk/Documentation/SubmittingPatches +++ b/trunk/Documentation/SubmittingPatches @@ -327,52 +327,6 @@ Some people also put extra tags at the end. They'll just be ignored for now, but you can do this to mark internal company procedures or just point out some special detail about the sign-off. -If you are a subsystem or branch maintainer, sometimes you need to slightly -modify patches you receive in order to merge them, because the code is not -exactly the same in your tree and the submitters'. If you stick strictly to -rule (c), you should ask the submitter to rediff, but this is a totally -counter-productive waste of time and energy. Rule (b) allows you to adjust -the code, but then it is very impolite to change one submitter's code and -make him endorse your bugs. To solve this problem, it is recommended that -you add a line between the last Signed-off-by header and yours, indicating -the nature of your changes. While there is nothing mandatory about this, it -seems like prepending the description with your mail and/or name, all -enclosed in square brackets, is noticeable enough to make it obvious that -you are responsible for last-minute changes. Example : - - Signed-off-by: Random J Developer - [lucky@maintainer.example.org: struct foo moved from foo.c to foo.h] - Signed-off-by: Lucky K Maintainer - -This practise is particularly helpful if you maintain a stable branch and -want at the same time to credit the author, track changes, merge the fix, -and protect the submitter from complaints. Note that under no circumstances -can you change the author's identity (the From header), as it is the one -which appears in the changelog. - -Special note to back-porters: It seems to be a common and useful practise -to insert an indication of the origin of a patch at the top of the commit -message (just after the subject line) to facilitate tracking. For instance, -here's what we see in 2.6-stable : - - Date: Tue May 13 19:10:30 2008 +0000 - - SCSI: libiscsi regression in 2.6.25: fix nop timer handling - - commit 4cf1043593db6a337f10e006c23c69e5fc93e722 upstream - -And here's what appears in 2.4 : - - Date: Tue May 13 22:12:27 2008 +0200 - - wireless, airo: waitbusy() won't delay - - [backport of 2.6 commit b7acbdfbd1f277c1eb23f344f899cfa4cd0bf36a] - -Whatever the format, this information provides a valuable help to people -tracking your trees, and to people trying to trouble-shoot bugs in your -tree. - 13) When to use Acked-by: and Cc: diff --git a/trunk/Documentation/cciss.txt b/trunk/Documentation/cciss.txt index 63e59b8847c5..e65736c6b8bc 100644 --- a/trunk/Documentation/cciss.txt +++ b/trunk/Documentation/cciss.txt @@ -21,11 +21,6 @@ This driver is known to work with the following cards: * SA E200 * SA E200i * SA E500 - * SA P212 - * SA P410 - * SA P410i - * SA P411 - * SA P812 Detecting drive failures: ------------------------- diff --git a/trunk/Documentation/cpusets.txt b/trunk/Documentation/cpusets.txt index d803c5c68ab5..fb7b361e6eea 100644 --- a/trunk/Documentation/cpusets.txt +++ b/trunk/Documentation/cpusets.txt @@ -199,7 +199,7 @@ using the sched_setaffinity, mbind and set_mempolicy system calls. The following rules apply to each cpuset: - Its CPUs and Memory Nodes must be a subset of its parents. - - It can't be marked exclusive unless its parent is. + - It can only be marked exclusive if its parent is. - If its cpu or memory is exclusive, they may not overlap any sibling. These rules, and the natural hierarchy of cpusets, enable efficient @@ -345,7 +345,7 @@ is modified to perform an inline check for this PF_SPREAD_PAGE task flag, and if set, a call to a new routine cpuset_mem_spread_node() returns the node to prefer for the allocation. -Similarly, setting 'memory_spread_slab' turns on the flag +Similarly, setting 'memory_spread_cache' turns on the flag PF_SPREAD_SLAB, and appropriately marked slab caches will allocate pages from the node returned by cpuset_mem_spread_node(). @@ -709,10 +709,7 @@ Now you want to do something with this cpuset. In this directory you can find several files: # ls -cpu_exclusive memory_migrate mems tasks -cpus memory_pressure notify_on_release -mem_exclusive memory_spread_page sched_load_balance -mem_hardwall memory_spread_slab sched_relax_domain_level +cpus cpu_exclusive mems mem_exclusive mem_hardwall tasks Reading them will give you information about the state of this cpuset: the CPUs and Memory Nodes it can use, the processes that are using diff --git a/trunk/Documentation/filesystems/ext4.txt b/trunk/Documentation/filesystems/ext4.txt index 0c5086db8352..560f88dc7090 100644 --- a/trunk/Documentation/filesystems/ext4.txt +++ b/trunk/Documentation/filesystems/ext4.txt @@ -139,16 +139,8 @@ commit=nrsec (*) Ext4 can be told to sync all its data and metadata Setting it to very large values will improve performance. -barrier=<0|1(*)> This enables/disables the use of write barriers in - the jbd code. barrier=0 disables, barrier=1 enables. - This also requires an IO stack which can support - barriers, and if jbd gets an error on a barrier - write, it will disable again with a warning. - Write barriers enforce proper on-disk ordering - of journal commits, making volatile disk write caches - safe to use, at some performance penalty. If - your disks are battery-backed in one way or another, - disabling barriers may safely improve performance. +barrier=1 This enables/disables barriers. barrier=0 disables + it, barrier=1 enables it. orlov (*) This enables the new Orlov block allocator. It is enabled by default. diff --git a/trunk/Documentation/kernel-doc-nano-HOWTO.txt b/trunk/Documentation/kernel-doc-nano-HOWTO.txt index 0bd32748a467..2075c0658bf5 100644 --- a/trunk/Documentation/kernel-doc-nano-HOWTO.txt +++ b/trunk/Documentation/kernel-doc-nano-HOWTO.txt @@ -1,105 +1,6 @@ kernel-doc nano-HOWTO ===================== -How to format kernel-doc comments ---------------------------------- - -In order to provide embedded, 'C' friendly, easy to maintain, -but consistent and extractable documentation of the functions and -data structures in the Linux kernel, the Linux kernel has adopted -a consistent style for documenting functions and their parameters, -and structures and their members. - -The format for this documentation is called the kernel-doc format. -It is documented in this Documentation/kernel-doc-nano-HOWTO.txt file. - -This style embeds the documentation within the source files, using -a few simple conventions. The scripts/kernel-doc perl script, some -SGML templates in Documentation/DocBook, and other tools understand -these conventions, and are used to extract this embedded documentation -into various documents. - -In order to provide good documentation of kernel functions and data -structures, please use the following conventions to format your -kernel-doc comments in Linux kernel source. - -We definitely need kernel-doc formatted documentation for functions -that are exported to loadable modules using EXPORT_SYMBOL. - -We also look to provide kernel-doc formatted documentation for -functions externally visible to other kernel files (not marked -"static"). - -We also recommend providing kernel-doc formatted documentation -for private (file "static") routines, for consistency of kernel -source code layout. But this is lower priority and at the -discretion of the MAINTAINER of that kernel source file. - -Data structures visible in kernel include files should also be -documented using kernel-doc formatted comments. - -The opening comment mark "/**" is reserved for kernel-doc comments. -Only comments so marked will be considered by the kernel-doc scripts, -and any comment so marked must be in kernel-doc format. Do not use -"/**" to be begin a comment block unless the comment block contains -kernel-doc formatted comments. The closing comment marker for -kernel-doc comments can be either "*/" or "**/". - -Kernel-doc comments should be placed just before the function -or data structure being described. - -Example kernel-doc function comment: - -/** - * foobar() - short function description of foobar - * @arg1: Describe the first argument to foobar. - * @arg2: Describe the second argument to foobar. - * One can provide multiple line descriptions - * for arguments. - * - * A longer description, with more discussion of the function foobar() - * that might be useful to those using or modifying it. Begins with - * empty comment line, and may include additional embedded empty - * comment lines. - * - * The longer description can have multiple paragraphs. - **/ - -The first line, with the short description, must be on a single line. - -The @argument descriptions must begin on the very next line following -this opening short function description line, with no intervening -empty comment lines. - -Example kernel-doc data structure comment. - -/** - * struct blah - the basic blah structure - * @mem1: describe the first member of struct blah - * @mem2: describe the second member of struct blah, - * perhaps with more lines and words. - * - * Longer description of this structure. - **/ - -The kernel-doc function comments describe each parameter to the -function, in order, with the @name lines. - -The kernel-doc data structure comments describe each structure member -in the data structure, with the @name lines. - -The longer description formatting is "reflowed", losing your line -breaks. So presenting carefully formatted lists within these -descriptions won't work so well; derived documentation will lose -the formatting. - -See the section below "How to add extractable documentation to your -source files" for more details and notes on how to format kernel-doc -comments. - -Components of the kernel-doc system ------------------------------------ - Many places in the source tree have extractable documentation in the form of block comments above functions. The components of this system are: diff --git a/trunk/Documentation/kernel-docs.txt b/trunk/Documentation/kernel-docs.txt index 28cdc2af2131..5a4ef48224ae 100644 --- a/trunk/Documentation/kernel-docs.txt +++ b/trunk/Documentation/kernel-docs.txt @@ -715,14 +715,14 @@ * Name: "Gary's Encyclopedia - The Linux Kernel" Author: Gary (I suppose...). - URL: http://slencyclopedia.berlios.de/index.html - Keywords: linux, community, everything! + URL: http://www.lisoleg.net/cgi-bin/lisoleg.pl?view=kernel.htm + Keywords: links, not found here?. Description: Gary's Encyclopedia exists to allow the rapid finding of documentation and other information of interest to GNU/Linux users. It has about 4000 links to external pages in 150 major categories. This link is for kernel-specific links, documents, - sites... This list is now hosted by developer.Berlios.de, - but seems not to have been updated since sometime in 1999. + sites... Look there if you could not find here what you were + looking for. * Name: "The home page of Linux-MM" Author: The Linux-MM team. diff --git a/trunk/Documentation/kobject.txt b/trunk/Documentation/kobject.txt index 51a8021ee532..bf3256e04027 100644 --- a/trunk/Documentation/kobject.txt +++ b/trunk/Documentation/kobject.txt @@ -305,7 +305,7 @@ should not be manipulated by any other user. A kset keeps its children in a standard kernel linked list. Kobjects point back to their containing kset via their kset field. In almost all cases, -the kobjects belonging to a kset have that kset (or, strictly, its embedded +the kobjects belonging to a ket have that kset (or, strictly, its embedded kobject) in their parent. As a kset contains a kobject within it, it should always be dynamically diff --git a/trunk/Documentation/laptops/thinkpad-acpi.txt b/trunk/Documentation/laptops/thinkpad-acpi.txt index 64b3f146e4b0..01c6c3d8a7e3 100644 --- a/trunk/Documentation/laptops/thinkpad-acpi.txt +++ b/trunk/Documentation/laptops/thinkpad-acpi.txt @@ -503,7 +503,7 @@ generate input device EV_KEY events. In addition to the EV_KEY events, thinkpad-acpi may also issue EV_SW events for switches: -SW_RFKILL_ALL T60 and later hardare rfkill rocker switch +SW_RADIO T60 and later hardare rfkill rocker switch SW_TABLET_MODE Tablet ThinkPads HKEY events 0x5009 and 0x500A Non hot-key ACPI HKEY event map: diff --git a/trunk/Documentation/networking/arcnet.txt b/trunk/Documentation/networking/arcnet.txt index 796012540386..770fc41a78e8 100644 --- a/trunk/Documentation/networking/arcnet.txt +++ b/trunk/Documentation/networking/arcnet.txt @@ -46,7 +46,7 @@ These are the ARCnet drivers for Linux. This new release (2.91) has been put together by David Woodhouse -, in an attempt to tidy up the driver after adding support +, in an attempt to tidy up the driver after adding support for yet another chipset. Now the generic support has been separated from the individual chipset drivers, and the source files aren't quite so packed with #ifdefs! I've changed this file a bit, but kept it in the first person from diff --git a/trunk/Documentation/networking/mac80211_hwsim/README b/trunk/Documentation/networking/mac80211_hwsim/README deleted file mode 100644 index 2ff8ccb8dc37..000000000000 --- a/trunk/Documentation/networking/mac80211_hwsim/README +++ /dev/null @@ -1,67 +0,0 @@ -mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 -Copyright (c) 2008, Jouni Malinen - -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. - - -Introduction - -mac80211_hwsim is a Linux kernel module that can be used to simulate -arbitrary number of IEEE 802.11 radios for mac80211. It can be used to -test most of the mac80211 functionality and user space tools (e.g., -hostapd and wpa_supplicant) in a way that matches very closely with -the normal case of using real WLAN hardware. From the mac80211 view -point, mac80211_hwsim is yet another hardware driver, i.e., no changes -to mac80211 are needed to use this testing tool. - -The main goal for mac80211_hwsim is to make it easier for developers -to test their code and work with new features to mac80211, hostapd, -and wpa_supplicant. The simulated radios do not have the limitations -of real hardware, so it is easy to generate an arbitrary test setup -and always reproduce the same setup for future tests. In addition, -since all radio operation is simulated, any channel can be used in -tests regardless of regulatory rules. - -mac80211_hwsim kernel module has a parameter 'radios' that can be used -to select how many radios are simulated (default 2). This allows -configuration of both very simply setups (e.g., just a single access -point and a station) or large scale tests (multiple access points with -hundreds of stations). - -mac80211_hwsim works by tracking the current channel of each virtual -radio and copying all transmitted frames to all other radios that are -currently enabled and on the same channel as the transmitting -radio. Software encryption in mac80211 is used so that the frames are -actually encrypted over the virtual air interface to allow more -complete testing of encryption. - -A global monitoring netdev, hwsim#, is created independent of -mac80211. This interface can be used to monitor all transmitted frames -regardless of channel. - - -Simple example - -This example shows how to use mac80211_hwsim to simulate two radios: -one to act as an access point and the other as a station that -associates with the AP. hostapd and wpa_supplicant are used to take -care of WPA2-PSK authentication. In addition, hostapd is also -processing access point side of association. - -Please note that the current Linux kernel does not enable AP mode, so a -simple patch is needed to enable AP mode selection: -http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch - - -# Build mac80211_hwsim as part of kernel configuration - -# Load the module -modprobe mac80211_hwsim - -# Run hostapd (AP) for wlan0 -hostapd hostapd.conf - -# Run wpa_supplicant (station) for wlan1 -wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf diff --git a/trunk/Documentation/networking/mac80211_hwsim/hostapd.conf b/trunk/Documentation/networking/mac80211_hwsim/hostapd.conf deleted file mode 100644 index 08cde7e35f2e..000000000000 --- a/trunk/Documentation/networking/mac80211_hwsim/hostapd.conf +++ /dev/null @@ -1,11 +0,0 @@ -interface=wlan0 -driver=nl80211 - -hw_mode=g -channel=1 -ssid=mac80211 test - -wpa=2 -wpa_key_mgmt=WPA-PSK -wpa_pairwise=CCMP -wpa_passphrase=12345678 diff --git a/trunk/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf b/trunk/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf deleted file mode 100644 index 299128cff035..000000000000 --- a/trunk/Documentation/networking/mac80211_hwsim/wpa_supplicant.conf +++ /dev/null @@ -1,10 +0,0 @@ -ctrl_interface=/var/run/wpa_supplicant - -network={ - ssid="mac80211 test" - psk="12345678" - key_mgmt=WPA-PSK - proto=WPA2 - pairwise=CCMP - group=CCMP -} diff --git a/trunk/Documentation/video4linux/CARDLIST.cx88 b/trunk/Documentation/video4linux/CARDLIST.cx88 index 7cf5685d3645..543957346469 100644 --- a/trunk/Documentation/video4linux/CARDLIST.cx88 +++ b/trunk/Documentation/video4linux/CARDLIST.cx88 @@ -60,7 +60,7 @@ 59 -> DViCO FusionHDTV 5 PCI nano [18ac:d530] 60 -> Pinnacle Hybrid PCTV [12ab:1788] 61 -> Winfast TV2000 XP Global [107d:6f18] - 62 -> PowerColor RA330 [14f1:ea3d] + 62 -> PowerColor Real Angel 330 [14f1:ea3d] 63 -> Geniatech X8000-MT DVBT [14f1:8852] 64 -> DViCO FusionHDTV DVB-T PRO [18ac:db30] 65 -> DViCO FusionHDTV 7 Gold [18ac:d610] diff --git a/trunk/Documentation/video4linux/cx18.txt b/trunk/Documentation/video4linux/cx18.txt index 6842c262890f..077d56ec3f3d 100644 --- a/trunk/Documentation/video4linux/cx18.txt +++ b/trunk/Documentation/video4linux/cx18.txt @@ -1,9 +1,7 @@ Some notes regarding the cx18 driver for the Conexant CX23418 MPEG encoder chip: -1) The only hardware currently supported is the Hauppauge HVR-1600 - card and the Compro VideoMate H900 (note that this card only - supports analog input, it has no digital tuner!). +1) The only hardware currently supported is the Hauppauge HVR-1600. 2) Some people have problems getting the i2c bus to work. Cause unknown. The symptom is that the eeprom cannot be read and the card is diff --git a/trunk/Documentation/vm/pagemap.txt b/trunk/Documentation/vm/pagemap.txt deleted file mode 100644 index ce72c0fe6177..000000000000 --- a/trunk/Documentation/vm/pagemap.txt +++ /dev/null @@ -1,77 +0,0 @@ -pagemap, from the userspace perspective ---------------------------------------- - -pagemap is a new (as of 2.6.25) set of interfaces in the kernel that allow -userspace programs to examine the page tables and related information by -reading files in /proc. - -There are three components to pagemap: - - * /proc/pid/pagemap. This file lets a userspace process find out which - physical frame each virtual page is mapped to. It contains one 64-bit - value for each virtual page, containing the following data (from - fs/proc/task_mmu.c, above pagemap_read): - - * Bits 0-55 page frame number (PFN) if present - * Bits 0-4 swap type if swapped - * Bits 5-55 swap offset if swapped - * Bits 55-60 page shift (page size = 1<node == &ssp_list) + if (ssp->port_id != port) return NULL; return ssp; diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index ab4a9f579913..c2cbd66db814 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -467,8 +467,8 @@ static struct platform_device *devices[] __initdata = { static void tosa_poweroff(void) { - gpio_direction_output(TOSA_GPIO_ON_RESET, 0); - gpio_set_value(TOSA_GPIO_ON_RESET, 1); + pxa_gpio_mode(TOSA_GPIO_ON_RESET | GPIO_OUT); + GPSR(TOSA_GPIO_ON_RESET) = GPIO_bit(TOSA_GPIO_ON_RESET); mdelay(1000); arm_machine_restart('h'); diff --git a/trunk/arch/blackfin/kernel/traps.c b/trunk/arch/blackfin/kernel/traps.c index f061f5181623..7bfbd958980c 100644 --- a/trunk/arch/blackfin/kernel/traps.c +++ b/trunk/arch/blackfin/kernel/traps.c @@ -67,7 +67,7 @@ void __init trap_init(void) CSYNC(); } -unsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; +void *saved_icplb_fault_addr, *saved_dcplb_fault_addr; int kstack_depth_to_print = 48; @@ -366,7 +366,7 @@ asmlinkage void trap_c(struct pt_regs *fp) info.si_code = ILL_CPLB_MULHIT; sig = SIGSEGV; #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO - if (saved_dcplb_fault_addr < FIXED_CODE_START) + if (saved_dcplb_fault_addr < (void *)FIXED_CODE_START) printk(KERN_NOTICE "NULL pointer access\n"); else #endif @@ -421,7 +421,7 @@ asmlinkage void trap_c(struct pt_regs *fp) info.si_code = ILL_CPLB_MULHIT; sig = SIGSEGV; #ifdef CONFIG_DEBUG_HUNT_FOR_ZERO - if (saved_icplb_fault_addr < FIXED_CODE_START) + if (saved_icplb_fault_addr < (void *)FIXED_CODE_START) printk(KERN_NOTICE "Jump to NULL address\n"); else #endif @@ -939,6 +939,8 @@ void panic_cplb_error(int cplb_panic, struct pt_regs *fp) oops_in_progress = 1; + printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", saved_dcplb_fault_addr); + printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", saved_icplb_fault_addr); dump_bfin_process(fp); dump_bfin_mem(fp); show_regs(fp); diff --git a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c index 5958eecefcf1..fa4f4e833e84 100644 --- a/trunk/arch/blackfin/mach-bf527/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf527/boards/ezkit.c @@ -451,6 +451,9 @@ static struct platform_device net2272_bfin_device = { }; #endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) static struct mtd_partition bfin_spi_flash_partitions[] = { @@ -673,7 +676,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #endif }; -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI controller data */ static struct bfin5xx_spi_master bfin_spi0_info = { .num_chipselect = 8, @@ -1016,7 +1018,10 @@ static int __init stamp_init(void) #endif platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; diff --git a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c b/trunk/arch/blackfin/mach-bf533/boards/ezkit.c index 079389cbd859..9d28415163ea 100644 --- a/trunk/arch/blackfin/mach-bf533/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf533/boards/ezkit.c @@ -87,6 +87,9 @@ static struct platform_device smc91x_device = { }; #endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + #if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) static struct mtd_partition bfin_spi_flash_partitions[] = { { @@ -186,7 +189,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #endif }; -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI (0) */ static struct resource bfin_spi0_resource[] = { [0] = { @@ -423,7 +425,9 @@ static int __init ezkit_init(void) { printk(KERN_INFO "%s(): registering device resources\n", __func__); platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; diff --git a/trunk/arch/blackfin/mach-bf533/boards/stamp.c b/trunk/arch/blackfin/mach-bf533/boards/stamp.c index 13ae49515f73..ec05b236dc3f 100644 --- a/trunk/arch/blackfin/mach-bf533/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf533/boards/stamp.c @@ -161,6 +161,9 @@ static struct platform_device stamp_flash_device = { }; #endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + #if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE) static struct mtd_partition bfin_spi_flash_partitions[] = { { @@ -317,7 +320,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #endif }; -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI (0) */ static struct resource bfin_spi0_resource[] = { [0] = { @@ -624,8 +626,10 @@ static int __init stamp_init(void) SSYNC(); #endif - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); - +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; #endif diff --git a/trunk/arch/blackfin/mach-bf537/boards/stamp.c b/trunk/arch/blackfin/mach-bf537/boards/stamp.c index 671f9d67f23a..9a756d1f3d73 100644 --- a/trunk/arch/blackfin/mach-bf537/boards/stamp.c +++ b/trunk/arch/blackfin/mach-bf537/boards/stamp.c @@ -400,6 +400,9 @@ static struct platform_device stamp_flash_device = { }; #endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ + #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) static struct mtd_partition bfin_spi_flash_partitions[] = { @@ -626,7 +629,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #endif }; -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI controller data */ static struct bfin5xx_spi_master bfin_spi0_info = { .num_chipselect = 8, @@ -937,7 +939,10 @@ static int __init stamp_init(void) #endif platform_add_devices(stamp_devices, ARRAY_SIZE(stamp_devices)); - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; diff --git a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c index af7c211a580e..d1682bb37509 100644 --- a/trunk/arch/blackfin/mach-bf548/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf548/boards/ezkit.c @@ -412,6 +412,8 @@ static struct platform_device ezkit_flash_device = { }; #endif +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) +/* all SPI peripherals info goes here */ #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) /* SPI flash chip (m25p16) */ @@ -479,7 +481,7 @@ static struct bfin5xx_spi_chip spidev_chip_info = { }; #endif -static struct spi_board_info bfin_spi_board_info[] __initdata = { +static struct spi_board_info bf54x_spi_board_info[] __initdata = { #if defined(CONFIG_MTD_M25P80) \ || defined(CONFIG_MTD_M25P80_MODULE) { @@ -525,7 +527,6 @@ static struct spi_board_info bfin_spi_board_info[] __initdata = { #endif }; -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI (0) */ static struct resource bfin_spi0_resource[] = { [0] = { @@ -799,7 +800,10 @@ static int __init ezkit_init(void) platform_add_devices(ezkit_devices, ARRAY_SIZE(ezkit_devices)); - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bf54x_spi_board_info, + ARRAY_SIZE(bf54x_spi_board_info)); +#endif return 0; } diff --git a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c b/trunk/arch/blackfin/mach-bf561/boards/ezkit.c index bc6feded8569..61d8f7648b24 100644 --- a/trunk/arch/blackfin/mach-bf561/boards/ezkit.c +++ b/trunk/arch/blackfin/mach-bf561/boards/ezkit.c @@ -280,6 +280,7 @@ static struct platform_device ezkit_flash_device = { }; #endif +#ifdef CONFIG_SPI_BFIN #if defined(CONFIG_SND_BLACKFIN_AD1836) \ || defined(CONFIG_SND_BLACKFIN_AD1836_MODULE) static struct bfin5xx_spi_chip ad1836_spi_chip_info = { @@ -294,8 +295,8 @@ static struct bfin5xx_spi_chip spidev_chip_info = { .bits_per_word = 8, }; #endif +#endif -#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) /* SPI (0) */ static struct resource bfin_spi0_resource[] = { [0] = { @@ -326,7 +327,6 @@ static struct platform_device bfin_spi0_device = { .platform_data = &bfin_spi0_info, /* Passed to driver */ }, }; -#endif static struct spi_board_info bfin_spi_board_info[] __initdata = { #if defined(CONFIG_SND_BLACKFIN_AD1836) \ @@ -537,7 +537,10 @@ static int __init ezkit_init(void) SSYNC(); #endif - spi_register_board_info(bfin_spi_board_info, ARRAY_SIZE(bfin_spi_board_info)); +#if defined(CONFIG_SPI_BFIN) || defined(CONFIG_SPI_BFIN_MODULE) + spi_register_board_info(bfin_spi_board_info, + ARRAY_SIZE(bfin_spi_board_info)); +#endif #if defined(CONFIG_PATA_PLATFORM) || defined(CONFIG_PATA_PLATFORM_MODULE) irq_desc[PATA_INT].status |= IRQ_NOAUTOEN; diff --git a/trunk/arch/frv/kernel/cmode.S b/trunk/arch/frv/kernel/cmode.S index 53deeb5d7e87..81ba28ad2207 100644 --- a/trunk/arch/frv/kernel/cmode.S +++ b/trunk/arch/frv/kernel/cmode.S @@ -1,7 +1,7 @@ /* cmode.S: clock mode management * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. - * Written by David Woodhouse (dwmw2@infradead.org) + * Written by David Woodhouse (dwmw2@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/trunk/arch/frv/kernel/sleep.S b/trunk/arch/frv/kernel/sleep.S index f67bf73cd2cc..c9b2d51ab9ad 100644 --- a/trunk/arch/frv/kernel/sleep.S +++ b/trunk/arch/frv/kernel/sleep.S @@ -1,7 +1,7 @@ /* sleep.S: power saving mode entry * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. - * Written by David Woodhouse (dwmw2@infradead.org) + * Written by David Woodhouse (dwmw2@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c index 64ee58d748be..4985466b1a7c 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c +++ b/trunk/arch/frv/mb93090-mb00/pci-dma-nommu.c @@ -1,7 +1,7 @@ /* pci-dma-nommu.c: Dynamic DMA mapping support for the FRV * * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. - * Written by David Woodhouse (dwmw2@infradead.org) + * Written by David Woodhouse (dwmw2@redhat.com) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/trunk/arch/ia64/kernel/acpi.c b/trunk/arch/ia64/kernel/acpi.c index 43687cc60dfb..853d1f11be00 100644 --- a/trunk/arch/ia64/kernel/acpi.c +++ b/trunk/arch/ia64/kernel/acpi.c @@ -465,6 +465,7 @@ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) printk(KERN_ERR "ACPI 2.0 SLIT: size mismatch: %d expected, %d actual\n", len, slit->header.length); + memset(numa_slit, 10, sizeof(numa_slit)); return; } slit_table = slit; @@ -573,14 +574,8 @@ void __init acpi_numa_arch_fixup(void) printk(KERN_INFO "Number of memory chunks in system = %d\n", num_node_memblks); - if (!slit_table) { - for (i = 0; i < MAX_NUMNODES; i++) - for (j = 0; j < MAX_NUMNODES; j++) - node_distance(i, j) = i == j ? LOCAL_DISTANCE : - REMOTE_DISTANCE; + if (!slit_table) return; - } - memset(numa_slit, -1, sizeof(numa_slit)); for (i = 0; i < slit_table->locality_count; i++) { if (!pxm_bit_test(i)) diff --git a/trunk/arch/ia64/kvm/mmio.c b/trunk/arch/ia64/kvm/mmio.c index 7f1a858bc69f..351bf70da463 100644 --- a/trunk/arch/ia64/kvm/mmio.c +++ b/trunk/arch/ia64/kvm/mmio.c @@ -159,8 +159,7 @@ static void mmio_access(struct kvm_vcpu *vcpu, u64 src_pa, u64 *dest, if (p->u.ioreq.state == STATE_IORESP_READY) { if (dir == IOREQ_READ) - /* it's necessary to ensure zero extending */ - *dest = p->u.ioreq.data & (~0UL >> (64-(s*8))); + *dest = p->u.ioreq.data; } else panic_vm(vcpu); out: diff --git a/trunk/arch/m68k/configs/amiga_defconfig b/trunk/arch/m68k/configs/amiga_defconfig index 8e2a0f5faf53..dca50da9ffd0 100644 --- a/trunk/arch/m68k/configs/amiga_defconfig +++ b/trunk/arch/m68k/configs/amiga_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:41 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/apollo_defconfig b/trunk/arch/m68k/configs/apollo_defconfig index e2d511e2a1d1..c3cd5b749d2c 100644 --- a/trunk/arch/m68k/configs/apollo_defconfig +++ b/trunk/arch/m68k/configs/apollo_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:42 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/atari_defconfig b/trunk/arch/m68k/configs/atari_defconfig index 6e20d656adaf..073ae4bbe264 100644 --- a/trunk/arch/m68k/configs/atari_defconfig +++ b/trunk/arch/m68k/configs/atari_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:43 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/bvme6000_defconfig b/trunk/arch/m68k/configs/bvme6000_defconfig index a0a9b30bb502..0789ede2e9ee 100644 --- a/trunk/arch/m68k/configs/bvme6000_defconfig +++ b/trunk/arch/m68k/configs/bvme6000_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:45 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/hp300_defconfig b/trunk/arch/m68k/configs/hp300_defconfig index 6778041de262..3e140bf49b22 100644 --- a/trunk/arch/m68k/configs/hp300_defconfig +++ b/trunk/arch/m68k/configs/hp300_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:46 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/mac_defconfig b/trunk/arch/m68k/configs/mac_defconfig index 7cd375740348..ba3a91792cbf 100644 --- a/trunk/arch/m68k/configs/mac_defconfig +++ b/trunk/arch/m68k/configs/mac_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:47 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/multi_defconfig b/trunk/arch/m68k/configs/multi_defconfig index 0747fa3984df..4d23f99227f9 100644 --- a/trunk/arch/m68k/configs/multi_defconfig +++ b/trunk/arch/m68k/configs/multi_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:42:31 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/mvme147_defconfig b/trunk/arch/m68k/configs/mvme147_defconfig index e7a8246840b5..188847fed824 100644 --- a/trunk/arch/m68k/configs/mvme147_defconfig +++ b/trunk/arch/m68k/configs/mvme147_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:49 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/mvme16x_defconfig b/trunk/arch/m68k/configs/mvme16x_defconfig index ab536eb172bb..983e53d990c8 100644 --- a/trunk/arch/m68k/configs/mvme16x_defconfig +++ b/trunk/arch/m68k/configs/mvme16x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:50 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/q40_defconfig b/trunk/arch/m68k/configs/q40_defconfig index e05be687b500..7707f3fb0a70 100644 --- a/trunk/arch/m68k/configs/q40_defconfig +++ b/trunk/arch/m68k/configs/q40_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:51 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/sun3_defconfig b/trunk/arch/m68k/configs/sun3_defconfig index 296340d2b315..a765f6f15d2c 100644 --- a/trunk/arch/m68k/configs/sun3_defconfig +++ b/trunk/arch/m68k/configs/sun3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:53 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68k/configs/sun3x_defconfig b/trunk/arch/m68k/configs/sun3x_defconfig index 8d3a416c92bf..431513937498 100644 --- a/trunk/arch/m68k/configs/sun3x_defconfig +++ b/trunk/arch/m68k/configs/sun3x_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Wed May 28 22:47:35 2008 +# Linux kernel version: 2.6.26-rc2 +# Sun May 18 14:44:54 2008 # CONFIG_M68K=y CONFIG_MMU=y @@ -59,7 +59,7 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_ANON_INODES=y diff --git a/trunk/arch/m68knommu/platform/coldfire/timers.c b/trunk/arch/m68knommu/platform/coldfire/timers.c index 454f25493491..ba5a9f32ebd4 100644 --- a/trunk/arch/m68knommu/platform/coldfire/timers.c +++ b/trunk/arch/m68knommu/platform/coldfire/timers.c @@ -111,13 +111,7 @@ void hw_timer_init(void) __raw_writew(MCFTIMER_TMR_DISABLE, TA(MCFTIMER_TMR)); mcftmr_cycles_per_jiffy = FREQ / HZ; - /* - * The coldfire timer runs from 0 to TRR included, then 0 - * again and so on. It counts thus actually TRR + 1 steps - * for 1 tick, not TRR. So if you want n cycles, - * initialize TRR with n - 1. - */ - __raw_writetrr(mcftmr_cycles_per_jiffy - 1, TA(MCFTIMER_TRR)); + __raw_writetrr(mcftmr_cycles_per_jiffy, TA(MCFTIMER_TRR)); __raw_writew(MCFTIMER_TMR_ENORI | MCFTIMER_TMR_CLK16 | MCFTIMER_TMR_RESTART | MCFTIMER_TMR_ENABLE, TA(MCFTIMER_TMR)); diff --git a/trunk/arch/mips/au1000/common/clocks.c b/trunk/arch/mips/au1000/common/clocks.c index 043429d17c5f..46f8ee0e2657 100644 --- a/trunk/arch/mips/au1000/common/clocks.c +++ b/trunk/arch/mips/au1000/common/clocks.c @@ -45,7 +45,6 @@ unsigned int get_au1x00_speed(void) { return au1x00_clock; } -EXPORT_SYMBOL(get_au1x00_speed); /* * The UART baud base is not known at compile time ... if diff --git a/trunk/arch/mips/au1000/common/dbdma.c b/trunk/arch/mips/au1000/common/dbdma.c index 601ee9180ee4..42d555236de1 100644 --- a/trunk/arch/mips/au1000/common/dbdma.c +++ b/trunk/arch/mips/au1000/common/dbdma.c @@ -216,17 +216,6 @@ u32 au1xxx_ddma_add_device(dbdev_tab_t *dev) } EXPORT_SYMBOL(au1xxx_ddma_add_device); -void au1xxx_ddma_del_device(u32 devid) -{ - dbdev_tab_t *p = find_dbdev_id(devid); - - if (p != NULL) { - memset(p, 0, sizeof(dbdev_tab_t)); - p->dev_id = ~0; - } -} -EXPORT_SYMBOL(au1xxx_ddma_del_device); - /* Allocate a channel and return a non-zero descriptor if successful. */ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, void (*callback)(int, void *), void *callparam) diff --git a/trunk/arch/mips/kernel/Makefile b/trunk/arch/mips/kernel/Makefile index 65e46a6d4178..cc0244036aec 100644 --- a/trunk/arch/mips/kernel/Makefile +++ b/trunk/arch/mips/kernel/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R3000) += r2300_fpu.o r2300_switch.o +obj-$(CONFIG_CPU_R4000) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4300) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R4X00) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_R5000) += r4k_fpu.o r4k_switch.o diff --git a/trunk/arch/mips/kernel/traps.c b/trunk/arch/mips/kernel/traps.c index f9165d1a17bf..cb8b0e2c7954 100644 --- a/trunk/arch/mips/kernel/traps.c +++ b/trunk/arch/mips/kernel/traps.c @@ -88,17 +88,15 @@ static void show_raw_backtrace(unsigned long reg29) #ifdef CONFIG_KALLSYMS printk("\n"); #endif - while (!kstack_end(sp)) { - unsigned long __user *p = - (unsigned long __user *)(unsigned long)sp++; - if (__get_user(addr, p)) { - printk(" (Bad stack address)"); - break; +#define IS_KVA01(a) ((((unsigned int)a) & 0xc0000000) == 0x80000000) + if (IS_KVA01(sp)) { + while (!kstack_end(sp)) { + addr = *sp++; + if (__kernel_text_address(addr)) + print_ip_sym(addr); } - if (__kernel_text_address(addr)) - print_ip_sym(addr); + printk("\n"); } - printk("\n"); } #ifdef CONFIG_KALLSYMS diff --git a/trunk/arch/mips/mips-boards/generic/time.c b/trunk/arch/mips/mips-boards/generic/time.c index fe2cac1b4514..008fd82b5840 100644 --- a/trunk/arch/mips/mips-boards/generic/time.c +++ b/trunk/arch/mips/mips-boards/generic/time.c @@ -58,8 +58,27 @@ static int mips_cpu_timer_irq; static int mips_cpu_perf_irq; extern int cp0_perfcount_irq; +DEFINE_PER_CPU(unsigned int, tickcount); +#define tickcount_this_cpu __get_cpu_var(tickcount) +static unsigned long ledbitmask; + static void mips_timer_dispatch(void) { +#if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_ATLAS) + /* + * Yes, this is very tacky, won't work as expected with SMTC and + * dyntick will break it, + * but it gives me a nice warm feeling during debug + */ +#define LEDBAR 0xbf000408 + if (tickcount_this_cpu++ >= HZ) { + tickcount_this_cpu = 0; + change_bit(smp_processor_id(), &ledbitmask); + smp_wmb(); /* Make sure every one else sees the change */ + /* This will pick up any recent changes made by other CPU's */ + *(unsigned int *)LEDBAR = ledbitmask; + } +#endif do_IRQ(mips_cpu_timer_irq); } diff --git a/trunk/arch/mips/mm/page.c b/trunk/arch/mips/mm/page.c index cab81f42eee5..d827d6144369 100644 --- a/trunk/arch/mips/mm/page.c +++ b/trunk/arch/mips/mm/page.c @@ -310,8 +310,8 @@ void __cpuinit build_clear_page(void) if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) uasm_i_lui(&buf, AT, 0xa000); - off = cache_line_size ? min(8, pref_bias_clear_store / cache_line_size) - * cache_line_size : 0; + off = min(8, pref_bias_clear_store / cache_line_size) * + cache_line_size; while (off) { build_clear_pref(&buf, -off); off -= cache_line_size; @@ -454,14 +454,12 @@ void __cpuinit build_copy_page(void) if (R4600_V2_HIT_CACHEOP_WAR && cpu_is_r4600_v2_x()) uasm_i_lui(&buf, AT, 0xa000); - off = cache_line_size ? min(8, pref_bias_copy_load / cache_line_size) * - cache_line_size : 0; + off = min(8, pref_bias_copy_load / cache_line_size) * cache_line_size; while (off) { build_copy_load_pref(&buf, -off); off -= cache_line_size; } - off = cache_line_size ? min(8, pref_bias_copy_load / cache_line_size) * - cache_line_size : 0; + off = min(8, pref_bias_copy_store / cache_line_size) * cache_line_size; while (off) { build_copy_store_pref(&buf, -off); off -= cache_line_size; diff --git a/trunk/arch/mips/mm/tlbex.c b/trunk/arch/mips/mm/tlbex.c index 76da73a5ab3c..382738ca8a0b 100644 --- a/trunk/arch/mips/mm/tlbex.c +++ b/trunk/arch/mips/mm/tlbex.c @@ -224,9 +224,8 @@ static u32 final_handler[64] __cpuinitdata; static void __cpuinit __maybe_unused build_tlb_probe_entry(u32 **p) { switch (current_cpu_type()) { - /* Found by experiment: R4600 v2.0/R4700 needs this, too. */ + /* Found by experiment: R4600 v2.0 needs this, too. */ case CPU_R4600: - case CPU_R4700: case CPU_R5000: case CPU_R5000A: case CPU_NEVADA: diff --git a/trunk/arch/mips/pci/ops-bridge.c b/trunk/arch/mips/pci/ops-bridge.c index b46b3e211775..1fa09929cd7a 100644 --- a/trunk/arch/mips/pci/ops-bridge.c +++ b/trunk/arch/mips/pci/ops-bridge.c @@ -13,22 +13,6 @@ #include #include -/* - * Most of the IOC3 PCI config register aren't present - * we emulate what is needed for a normal PCI enumeration - */ -static u32 emulate_ioc3_cfg(int where, int size) -{ - if (size == 1 && where == 0x3d) - return 0x01; - else if (size == 2 && where == 0x3c) - return 0x0100; - else if (size == 4 && where == 0x3c) - return 0x00000100; - - return 0; -} - /* * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is * not really documented, so right now I can't write code which uses it. @@ -80,7 +64,7 @@ static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, * generic PCI code a chance to look at the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { - *value = emulate_ioc3_cfg(where, size); + *value = 0; return PCIBIOS_SUCCESSFUL; } @@ -143,7 +127,7 @@ static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, * generic PCI code a chance to look at the wrong register. */ if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { - *value = emulate_ioc3_cfg(where, size); + *value = 0; return PCIBIOS_SUCCESSFUL; } diff --git a/trunk/arch/mips/pci/pci-ip27.c b/trunk/arch/mips/pci/pci-ip27.c index a18516925cdd..bb64828a92fe 100644 --- a/trunk/arch/mips/pci/pci-ip27.c +++ b/trunk/arch/mips/pci/pci-ip27.c @@ -47,9 +47,6 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) static int num_bridges = 0; bridge_t *bridge; int slot; - extern int pci_probe_only; - - pci_probe_only = 1; printk("a bridge\n"); @@ -103,11 +100,6 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) */ bridge->b_wid_control |= BRIDGE_CTRL_IO_SWAP | BRIDGE_CTRL_MEM_SWAP; -#ifdef CONFIG_PAGE_SIZE_4KB - bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE; -#else /* 16kB or larger */ - bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE; -#endif /* * Hmm... IRIX sets additional bits in the address which diff --git a/trunk/arch/mips/sgi-ip27/ip27-init.c b/trunk/arch/mips/sgi-ip27/ip27-init.c index 4a500e8cd3cc..7093e7c573a4 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-init.c +++ b/trunk/arch/mips/sgi-ip27/ip27-init.c @@ -161,6 +161,27 @@ cnodeid_t get_compact_nodeid(void) return NASID_TO_COMPACT_NODEID(get_nasid()); } +/* Extracted from the IOC3 meta driver. FIXME. */ +static inline void ioc3_sio_init(void) +{ + struct ioc3 *ioc3; + nasid_t nid; + long loops; + + nid = get_nasid(); + ioc3 = (struct ioc3 *) KL_CONFIG_CH_CONS_INFO(nid)->memory_base; + + ioc3->sscr_a = 0; /* PIO mode for uarta. */ + ioc3->sscr_b = 0; /* PIO mode for uartb. */ + ioc3->sio_iec = ~0; + ioc3->sio_ies = (SIO_IR_SA_INT | SIO_IR_SB_INT); + + loops=1000000; while(loops--); + ioc3->sregs.uarta.iu_fcr = 0; + ioc3->sregs.uartb.iu_fcr = 0; + loops=1000000; while(loops--); +} + static inline void ioc3_eth_init(void) { struct ioc3 *ioc3; @@ -213,6 +234,7 @@ void __init plat_mem_setup(void) panic("Kernel compiled for N mode."); #endif + ioc3_sio_init(); ioc3_eth_init(); per_cpu_init(); diff --git a/trunk/arch/mips/sgi-ip27/ip27-memory.c b/trunk/arch/mips/sgi-ip27/ip27-memory.c index 42cd10956306..bf438d02366e 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-memory.c +++ b/trunk/arch/mips/sgi-ip27/ip27-memory.c @@ -33,6 +33,10 @@ #define SLOT_PFNSHIFT (SLOT_SHIFT - PAGE_SHIFT) #define PFN_NASIDSHFT (NASID_SHFT - PAGE_SHIFT) +#define SLOT_IGNORED 0xffff + +static short __initdata slot_lastfilled_cache[MAX_COMPACT_NODES]; +static unsigned short __initdata slot_psize_cache[MAX_COMPACT_NODES][MAX_MEM_SLOTS]; static struct bootmem_data __initdata plat_node_bdata[MAX_COMPACT_NODES]; struct node_data *__node_data[MAX_COMPACT_NODES]; @@ -263,6 +267,51 @@ static pfn_t __init slot_getbasepfn(cnodeid_t cnode, int slot) return ((pfn_t)nasid << PFN_NASIDSHFT) | (slot << SLOT_PFNSHIFT); } +/* + * Return the number of pages of memory provided by the given slot + * on the specified node. + */ +static pfn_t __init slot_getsize(cnodeid_t node, int slot) +{ + return (pfn_t) slot_psize_cache[node][slot]; +} + +/* + * Return highest slot filled + */ +static int __init node_getlastslot(cnodeid_t node) +{ + return (int) slot_lastfilled_cache[node]; +} + +/* + * Return the pfn of the last free page of memory on a node. + */ +static pfn_t __init node_getmaxclick(cnodeid_t node) +{ + pfn_t slot_psize; + int slot; + + /* + * Start at the top slot. When we find a slot with memory in it, + * that's the winner. + */ + for (slot = (MAX_MEM_SLOTS - 1); slot >= 0; slot--) { + if ((slot_psize = slot_getsize(node, slot))) { + if (slot_psize == SLOT_IGNORED) + continue; + /* Return the basepfn + the slot size, minus 1. */ + return slot_getbasepfn(node, slot) + slot_psize - 1; + } + } + + /* + * If there's no memory on the node, return 0. This is likely + * to cause problems. + */ + return 0; +} + static pfn_t __init slot_psize_compute(cnodeid_t node, int slot) { nasid_t nasid; @@ -355,13 +404,13 @@ static void __init mlreset(void) static void __init szmem(void) { pfn_t slot_psize, slot0sz = 0, nodebytes; /* Hack to detect problem configs */ - int slot; + int slot, ignore; cnodeid_t node; num_physpages = 0; for_each_online_node(node) { - nodebytes = 0; + ignore = nodebytes = 0; for (slot = 0; slot < MAX_MEM_SLOTS; slot++) { slot_psize = slot_psize_compute(node, slot); if (slot == 0) @@ -371,20 +420,21 @@ static void __init szmem(void) * kernel text. */ nodebytes += (1LL << SLOT_SHIFT); - - if (!slot_psize) - continue; - if ((nodebytes >> PAGE_SHIFT) * (sizeof(struct page)) > - (slot0sz << PAGE_SHIFT)) { + (slot0sz << PAGE_SHIFT)) + ignore = 1; + if (ignore && slot_psize) { printk("Ignoring slot %d onwards on node %d\n", slot, node); + slot_psize_cache[node][slot] = SLOT_IGNORED; slot = MAX_MEM_SLOTS; continue; } num_physpages += slot_psize; - add_active_range(node, slot_getbasepfn(node, slot), - slot_getbasepfn(node, slot) + slot_psize); + slot_psize_cache[node][slot] = + (unsigned short) slot_psize; + if (slot_psize) + slot_lastfilled_cache[node] = slot; } } } @@ -392,20 +442,18 @@ static void __init szmem(void) static void __init node_mem_init(cnodeid_t node) { pfn_t slot_firstpfn = slot_getbasepfn(node, 0); + pfn_t slot_lastpfn = slot_firstpfn + slot_getsize(node, 0); pfn_t slot_freepfn = node_getfirstfree(node); + struct pglist_data *pd; unsigned long bootmap_size; - pfn_t start_pfn, end_pfn; - - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); /* * Allocate the node data structures on the node first. */ __node_data[node] = __va(slot_freepfn << PAGE_SHIFT); - NODE_DATA(node)->bdata = &plat_node_bdata[node]; - NODE_DATA(node)->node_start_pfn = start_pfn; - NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; + pd = NODE_DATA(node); + pd->bdata = &plat_node_bdata[node]; cpus_clear(hub_data(node)->h_cpus); @@ -413,12 +461,12 @@ static void __init node_mem_init(cnodeid_t node) sizeof(struct hub_data)); bootmap_size = init_bootmem_node(NODE_DATA(node), slot_freepfn, - start_pfn, end_pfn); - free_bootmem_with_active_regions(node, end_pfn); + slot_firstpfn, slot_lastpfn); + free_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, + (slot_lastpfn - slot_firstpfn) << PAGE_SHIFT); reserve_bootmem_node(NODE_DATA(node), slot_firstpfn << PAGE_SHIFT, ((slot_freepfn - slot_firstpfn) << PAGE_SHIFT) + bootmap_size, BOOTMEM_DEFAULT); - sparse_memory_present_with_active_regions(node); } /* @@ -467,15 +515,16 @@ void __init paging_init(void) pagetable_init(); for_each_online_node(node) { - pfn_t start_pfn, end_pfn; + pfn_t start_pfn = slot_getbasepfn(node, 0); + pfn_t end_pfn = node_getmaxclick(node) + 1; - get_pfn_range_for_nid(node, &start_pfn, &end_pfn); + zones_size[ZONE_NORMAL] = end_pfn - start_pfn; + free_area_init_node(node, NODE_DATA(node), + zones_size, start_pfn, NULL); if (end_pfn > max_low_pfn) max_low_pfn = end_pfn; } - zones_size[ZONE_NORMAL] = max_low_pfn; - free_area_init_nodes(zones_size); } void __init mem_init(void) @@ -486,10 +535,34 @@ void __init mem_init(void) high_memory = (void *) __va(num_physpages << PAGE_SHIFT); for_each_online_node(node) { + unsigned slot, numslots; + struct page *end, *p; + /* * This will free up the bootmem, ie, slot 0 memory. */ totalram_pages += free_all_bootmem_node(NODE_DATA(node)); + + /* + * We need to manually do the other slots. + */ + numslots = node_getlastslot(node); + for (slot = 1; slot <= numslots; slot++) { + p = nid_page_nr(node, slot_getbasepfn(node, slot) - + slot_getbasepfn(node, 0)); + + /* + * Free valid memory in current slot. + */ + for (end = p + slot_getsize(node, slot); p < end; p++) { + /* if (!page_is_ram(pgnr)) continue; */ + /* commented out until page_is_ram works */ + ClearPageReserved(p); + init_page_count(p); + __free_page(p); + totalram_pages++; + } + } } totalram_pages -= setup_zero_pages(); /* This comes from node 0 */ diff --git a/trunk/arch/mips/sgi-ip27/ip27-smp.c b/trunk/arch/mips/sgi-ip27/ip27-smp.c index ba5cdebeaf0d..f15fc93d6b35 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-smp.c +++ b/trunk/arch/mips/sgi-ip27/ip27-smp.c @@ -176,14 +176,11 @@ static void ip27_send_ipi_mask(cpumask_t mask, unsigned int action) static void __cpuinit ip27_init_secondary(void) { per_cpu_init(); + local_irq_enable(); } static void __cpuinit ip27_smp_finish(void) { - extern void hub_rt_clock_event_init(void); - - hub_rt_clock_event_init(); - local_irq_enable(); } static void __init ip27_cpus_done(void) diff --git a/trunk/arch/mips/sgi-ip27/ip27-timer.c b/trunk/arch/mips/sgi-ip27/ip27-timer.c index 8b4e854af925..9cebc9e7da63 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-timer.c +++ b/trunk/arch/mips/sgi-ip27/ip27-timer.c @@ -160,13 +160,10 @@ static void rt_set_mode(enum clock_event_mode mode, int rt_timer_irq; -static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent); -static DEFINE_PER_CPU(char [11], hub_rt_name); - static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id) { + struct clock_event_device *cd = dev_id; unsigned int cpu = smp_processor_id(); - struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); int slice = cputoslice(cpu); /* @@ -195,7 +192,10 @@ struct irqaction hub_rt_irqaction = { #define NSEC_PER_CYCLE 800 #define CYCLES_PER_SEC (NSEC_PER_SEC / NSEC_PER_CYCLE) -void __cpuinit hub_rt_clock_event_init(void) +static DEFINE_PER_CPU(struct clock_event_device, hub_rt_clockevent); +static DEFINE_PER_CPU(char [11], hub_rt_name); + +static void __cpuinit hub_rt_clock_event_init(void) { unsigned int cpu = smp_processor_id(); struct clock_event_device *cd = &per_cpu(hub_rt_clockevent, cpu); @@ -203,16 +203,17 @@ void __cpuinit hub_rt_clock_event_init(void) int irq = rt_timer_irq; sprintf(name, "hub-rt %d", cpu); - cd->name = name; - cd->features = CLOCK_EVT_FEAT_ONESHOT; + cd->name = "HUB-RT", + cd->features = CLOCK_EVT_FEAT_ONESHOT, clockevent_set_clock(cd, CYCLES_PER_SEC); cd->max_delta_ns = clockevent_delta2ns(0xfffffffffffff, cd); cd->min_delta_ns = clockevent_delta2ns(0x300, cd); - cd->rating = 200; - cd->irq = irq; - cd->cpumask = cpumask_of_cpu(cpu); - cd->set_next_event = rt_next_event; - cd->set_mode = rt_set_mode; + cd->rating = 200, + cd->irq = irq, + cd->cpumask = cpumask_of_cpu(cpu), + cd->rating = 300, + cd->set_next_event = rt_next_event, + cd->set_mode = rt_set_mode, clockevents_register_device(cd); } @@ -260,7 +261,6 @@ void __init plat_time_init(void) { hub_rt_clocksource_init(); hub_rt_clock_event_global_init(); - hub_rt_clock_event_init(); } void __cpuinit cpu_time_init(void) @@ -281,6 +281,7 @@ void __cpuinit cpu_time_init(void) printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed); + hub_rt_clock_event_init(); set_c0_status(SRB_TIMOCLK); } diff --git a/trunk/arch/parisc/hpux/gate.S b/trunk/arch/parisc/hpux/gate.S index 38a1c1b8d4e8..f0b18ce89842 100644 --- a/trunk/arch/parisc/hpux/gate.S +++ b/trunk/arch/parisc/hpux/gate.S @@ -13,9 +13,10 @@ #include #include #include +#include .level LEVEL - .text + __HEAD .import hpux_call_table .import hpux_syscall_exit,code diff --git a/trunk/arch/parisc/hpux/wrappers.S b/trunk/arch/parisc/hpux/wrappers.S index 58c53c879c02..ccd3a50c0995 100644 --- a/trunk/arch/parisc/hpux/wrappers.S +++ b/trunk/arch/parisc/hpux/wrappers.S @@ -28,9 +28,10 @@ #include #include #include +#include .level LEVEL - .text + __HEAD /* These should probably go in a header file somewhere. * They are duplicated in kernel/wrappers.S diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index d1fa4edd2d80..5d0837458c19 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -38,6 +38,7 @@ #include #include +#include #ifdef CONFIG_64BIT .level 2.0w @@ -621,7 +622,7 @@ * the static part of the kernel address space. */ - .text + __HEAD .align PAGE_SIZE diff --git a/trunk/arch/parisc/kernel/head.S b/trunk/arch/parisc/kernel/head.S index a84e31e82876..5680a2c3b13d 100644 --- a/trunk/arch/parisc/kernel/head.S +++ b/trunk/arch/parisc/kernel/head.S @@ -33,7 +33,6 @@ ENTRY(boot_args) END(boot_args) __HEAD - .align 4 .import init_thread_union,data .import fault_vector_20,code /* IVA parisc 2.0 32 bit */ diff --git a/trunk/arch/parisc/kernel/hpmc.S b/trunk/arch/parisc/kernel/hpmc.S index 2cbf13b3ef11..068322eb8c9b 100644 --- a/trunk/arch/parisc/kernel/hpmc.S +++ b/trunk/arch/parisc/kernel/hpmc.S @@ -47,6 +47,7 @@ #include #include +#include /* * stack for os_hpmc, the HPMC handler. @@ -76,7 +77,7 @@ ENTRY(hpmc_pim_data) .block HPMC_PIM_DATA_SIZE END(hpmc_pim_data) - .text + __HEAD .import intr_save, code ENTRY(os_hpmc) diff --git a/trunk/arch/parisc/kernel/pacache.S b/trunk/arch/parisc/kernel/pacache.S index 09b77b2553c6..e3246a5ca74f 100644 --- a/trunk/arch/parisc/kernel/pacache.S +++ b/trunk/arch/parisc/kernel/pacache.S @@ -37,8 +37,9 @@ #include #include #include +#include - .text + __HEAD .align 128 ENTRY(flush_tlb_all_local) diff --git a/trunk/arch/parisc/kernel/parisc_ksyms.c b/trunk/arch/parisc/kernel/parisc_ksyms.c index 0eecfbbc59cd..5b7fc4aa044d 100644 --- a/trunk/arch/parisc/kernel/parisc_ksyms.c +++ b/trunk/arch/parisc/kernel/parisc_ksyms.c @@ -152,6 +152,3 @@ EXPORT_SYMBOL($$dyncall); EXPORT_SYMBOL(node_data); EXPORT_SYMBOL(pfnnid_map); #endif - -/* from pacache.S -- needed for copy_page */ -EXPORT_SYMBOL(copy_user_page_asm); diff --git a/trunk/arch/parisc/kernel/perf_asm.S b/trunk/arch/parisc/kernel/perf_asm.S index fa6ea99bb324..d411dfb5b6d1 100644 --- a/trunk/arch/parisc/kernel/perf_asm.S +++ b/trunk/arch/parisc/kernel/perf_asm.S @@ -43,7 +43,7 @@ ; The coprocessor only needs to be enabled when ; starting/stopping the coprocessor with the pmenb/pmdis. ; - .text + __HEAD ENTRY(perf_intrigue_enable_perf_counters) .proc diff --git a/trunk/arch/parisc/kernel/real2.S b/trunk/arch/parisc/kernel/real2.S index 7a92695d95a6..47fbdae6efd5 100644 --- a/trunk/arch/parisc/kernel/real2.S +++ b/trunk/arch/parisc/kernel/real2.S @@ -12,6 +12,7 @@ #include #include +#include .section .bss .export real_stack @@ -39,7 +40,7 @@ save_cr_end: /************************ 32-bit real-mode calls ***********************/ /* This can be called in both narrow and wide kernels */ - .text + __HEAD /* unsigned long real32_call_asm(unsigned int *sp, * unsigned int *arg0p, @@ -113,7 +114,7 @@ ENDPROC(real32_call_asm) # define PUSH_CR(r, where) mfctl r, %r1 ! STREG,ma %r1, REG_SZ(where) # define POP_CR(r, where) LDREG,mb -REG_SZ(where), %r1 ! mtctl %r1, r - .text + __HEAD save_control_regs: load32 PA(save_cr_space), %r28 PUSH_CR(%cr24, %r28) @@ -145,7 +146,7 @@ restore_control_regs: /* rfi_virt2real() and rfi_real2virt() could perhaps be adapted for * more general-purpose use by the several places which need RFIs */ - .text + __HEAD .align 128 rfi_virt2real: /* switch to real mode... */ @@ -180,7 +181,7 @@ rfi_v2r_1: bv 0(%r2) nop - .text + __HEAD .align 128 rfi_real2virt: rsm PSW_SM_I,%r0 @@ -218,7 +219,7 @@ rfi_r2v_1: /************************ 64-bit real-mode calls ***********************/ /* This is only usable in wide kernels right now and will probably stay so */ - .text + __HEAD /* unsigned long real64_call_asm(unsigned long *sp, * unsigned long *arg0p, * unsigned long fn) @@ -276,7 +277,7 @@ ENDPROC(real64_call_asm) #endif - .text + __HEAD /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html ** GCC 3.3 and later has a new function in libgcc.a for ** comparing function pointers. diff --git a/trunk/arch/parisc/kernel/signal32.c b/trunk/arch/parisc/kernel/signal32.c index fb59852006de..db94affe5c71 100644 --- a/trunk/arch/parisc/kernel/signal32.c +++ b/trunk/arch/parisc/kernel/signal32.c @@ -289,7 +289,7 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __ &sc->sc_iaoq[0], compat_reg); /* Store upper half */ - compat_reg = (compat_uint_t)(regs->gr[31] >> 32); + compat_reg = (compat_uint_t)(regs->gr[32] >> 32); err |= __put_user(compat_reg, &rf->rf_iaoq[0]); DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg); @@ -299,7 +299,7 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __ DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n", &sc->sc_iaoq[1], compat_reg); /* Store upper half */ - compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32); + compat_reg = (compat_uint_t)((regs->gr[32]+4) >> 32); err |= __put_user(compat_reg, &rf->rf_iaoq[1]); DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg); diff --git a/trunk/arch/parisc/kernel/syscall.S b/trunk/arch/parisc/kernel/syscall.S index 69b6eebc466e..ae509d8cd03f 100644 --- a/trunk/arch/parisc/kernel/syscall.S +++ b/trunk/arch/parisc/kernel/syscall.S @@ -17,6 +17,7 @@ #include #include +#include /* We fill the empty parts of the gateway page with * something that will kill the kernel or a @@ -26,7 +27,7 @@ .level LEVEL - .text + __HEAD .import syscall_exit,code .import syscall_exit_rfi,code @@ -636,7 +637,7 @@ END(sys_call_table64) All light-weight-syscall atomic operations will use this set of locks */ - .section .data + .section .data, "aw" .align PAGE_SIZE ENTRY(lws_lock_start) /* lws locks */ diff --git a/trunk/arch/parisc/kernel/vmlinux.lds.S b/trunk/arch/parisc/kernel/vmlinux.lds.S index 2e516b871752..50b4a3a25d0a 100644 --- a/trunk/arch/parisc/kernel/vmlinux.lds.S +++ b/trunk/arch/parisc/kernel/vmlinux.lds.S @@ -50,7 +50,6 @@ SECTIONS _text = .; /* Text and read-only data */ .text ALIGN(16) : { - HEAD_TEXT TEXT_TEXT SCHED_TEXT LOCK_TEXT diff --git a/trunk/arch/parisc/lib/fixup.S b/trunk/arch/parisc/lib/fixup.S index d172d4245cdc..4821ad6d5269 100644 --- a/trunk/arch/parisc/lib/fixup.S +++ b/trunk/arch/parisc/lib/fixup.S @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_SMP .macro get_fault_ip t1 t2 @@ -55,7 +56,7 @@ .level LEVEL - .text + __HEAD .section .fixup, "ax" /* get_user() fixups, store -EFAULT in r8, and 0 in r9 */ diff --git a/trunk/arch/parisc/lib/lusercopy.S b/trunk/arch/parisc/lib/lusercopy.S index 1bd23ccec17b..b0d885350846 100644 --- a/trunk/arch/parisc/lib/lusercopy.S +++ b/trunk/arch/parisc/lib/lusercopy.S @@ -33,11 +33,12 @@ */ - .text - #include #include #include +#include + + __HEAD /* * get_sr gets the appropriate space value into diff --git a/trunk/arch/parisc/mm/init.c b/trunk/arch/parisc/mm/init.c index ce0da689a89d..78fe252b92c3 100644 --- a/trunk/arch/parisc/mm/init.c +++ b/trunk/arch/parisc/mm/init.c @@ -547,7 +547,6 @@ void __init mem_init(void) } unsigned long *empty_zero_page __read_mostly; -EXPORT_SYMBOL(empty_zero_page); void show_mem(void) { diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index d53b84e761a9..f5e0b2a5af57 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -221,8 +221,8 @@ image-$(CONFIG_WARP) += cuImage.warp image-$(CONFIG_YOSEMITE) += cuImage.yosemite # Board ports in arch/powerpc/platform/8xx/Kconfig -image-$(CONFIG_MPC86XADS) += cuImage.mpc866ads -image-$(CONFIG_MPC885ADS) += cuImage.mpc885ads +image-$(CONFIG_PPC_MPC86XADS) += cuImage.mpc866ads +image-$(CONFIG_PPC_MPC885ADS) += cuImage.mpc885ads image-$(CONFIG_PPC_EP88XC) += dtbImage.ep88xc image-$(CONFIG_PPC_ADDER875) += cuImage.adder875-uboot \ dtbImage.adder875-redboot diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 30eedfc5a566..52750745edfd 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -189,7 +189,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, dev->cfg_size = pci_cfg_space_size(dev); - dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus), + sprintf(pci_name(dev), "%04x:%02x:%02x.%d", pci_domain_nr(bus), dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn)); dev->class = get_int_prop(node, "class-code", 0); dev->revision = get_int_prop(node, "revision-id", 0); diff --git a/trunk/arch/powerpc/kernel/signal_64.c b/trunk/arch/powerpc/kernel/signal_64.c index da7c058e3731..faeb8f207ea4 100644 --- a/trunk/arch/powerpc/kernel/signal_64.c +++ b/trunk/arch/powerpc/kernel/signal_64.c @@ -87,7 +87,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, #ifdef CONFIG_ALTIVEC elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful); #endif - unsigned long msr = regs->msr; long err = 0; flush_fp_to_thread(current); @@ -103,7 +102,7 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg) * contains valid data. */ - msr |= MSR_VEC; + regs->msr |= MSR_VEC; } /* We always copy to/from vrsave, it's 0 if we don't have or don't * use altivec. @@ -115,7 +114,6 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, err |= __put_user(&sc->gp_regs, &sc->regs); WARN_ON(!FULL_REGS(regs)); err |= __copy_to_user(&sc->gp_regs, regs, GP_REGS_SIZE); - err |= __put_user(msr, &sc->gp_regs[PT_MSR]); err |= __copy_to_user(&sc->fp_regs, ¤t->thread.fpr, FP_REGS_SIZE); err |= __put_user(signr, &sc->signal); err |= __put_user(handler, &sc->handler); diff --git a/trunk/arch/powerpc/kvm/44x_tlb.c b/trunk/arch/powerpc/kvm/44x_tlb.c index 75dff7cfa814..f5d7a5eab96e 100644 --- a/trunk/arch/powerpc/kvm/44x_tlb.c +++ b/trunk/arch/powerpc/kvm/44x_tlb.c @@ -116,6 +116,8 @@ static void kvmppc_44x_shadow_release(struct kvm_vcpu *vcpu, struct tlbe *stlbe = &vcpu->arch.shadow_tlb[index]; struct page *page = vcpu->arch.shadow_pages[index]; + kunmap(vcpu->arch.shadow_pages[index]); + if (get_tlb_v(stlbe)) { if (kvmppc_44x_tlbe_is_writable(stlbe)) kvm_release_page_dirty(page); @@ -142,19 +144,18 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, stlbe = &vcpu->arch.shadow_tlb[victim]; /* Get reference to new page. */ - down_read(¤t->mm->mmap_sem); + down_write(¤t->mm->mmap_sem); new_page = gfn_to_page(vcpu->kvm, gfn); if (is_error_page(new_page)) { - printk(KERN_ERR "Couldn't get guest page for gfn %lx!\n", gfn); + printk(KERN_ERR "Couldn't get guest page!\n"); kvm_release_page_clean(new_page); - up_read(¤t->mm->mmap_sem); return; } hpaddr = page_to_phys(new_page); /* Drop reference to old page. */ kvmppc_44x_shadow_release(vcpu, victim); - up_read(¤t->mm->mmap_sem); + up_write(¤t->mm->mmap_sem); vcpu->arch.shadow_pages[victim] = new_page; diff --git a/trunk/arch/powerpc/kvm/booke_guest.c b/trunk/arch/powerpc/kvm/booke_guest.c index 9c8ad850c6e3..712d89a28c46 100644 --- a/trunk/arch/powerpc/kvm/booke_guest.c +++ b/trunk/arch/powerpc/kvm/booke_guest.c @@ -227,6 +227,39 @@ void kvmppc_check_and_deliver_interrupts(struct kvm_vcpu *vcpu) } } +static int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu) +{ + enum emulation_result er; + int r; + + er = kvmppc_emulate_instruction(run, vcpu); + switch (er) { + case EMULATE_DONE: + /* Future optimization: only reload non-volatiles if they were + * actually modified. */ + r = RESUME_GUEST_NV; + break; + case EMULATE_DO_MMIO: + run->exit_reason = KVM_EXIT_MMIO; + /* We must reload nonvolatiles because "update" load/store + * instructions modify register state. */ + /* Future optimization: only reload non-volatiles if they were + * actually modified. */ + r = RESUME_HOST_NV; + break; + case EMULATE_FAIL: + /* XXX Deliver Program interrupt to guest. */ + printk(KERN_EMERG "%s: emulation failed (%08x)\n", __func__, + vcpu->arch.last_inst); + r = RESUME_HOST; + break; + default: + BUG(); + } + + return r; +} + /** * kvmppc_handle_exit * diff --git a/trunk/arch/powerpc/kvm/emulate.c b/trunk/arch/powerpc/kvm/emulate.c index 000097461283..a03fe0c80698 100644 --- a/trunk/arch/powerpc/kvm/emulate.c +++ b/trunk/arch/powerpc/kvm/emulate.c @@ -246,11 +246,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) case 31: switch (get_xop(inst)) { - case 23: /* lwzx */ - rt = get_rt(inst); - emulated = kvmppc_handle_load(run, vcpu, rt, 4, 1); - break; - case 83: /* mfmsr */ rt = get_rt(inst); vcpu->arch.gpr[rt] = vcpu->arch.msr; @@ -272,13 +267,6 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) kvmppc_set_msr(vcpu, vcpu->arch.gpr[rs]); break; - case 151: /* stwx */ - rs = get_rs(inst); - emulated = kvmppc_handle_store(run, vcpu, - vcpu->arch.gpr[rs], - 4, 1); - break; - case 163: /* wrteei */ vcpu->arch.msr = (vcpu->arch.msr & ~MSR_EE) | (inst & MSR_EE); diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 51f82d83bf14..f67e118116fa 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -151,7 +151,6 @@ int remove_memory(u64 start, u64 size) return ret; } #endif /* CONFIG_MEMORY_HOTREMOVE */ -#endif /* CONFIG_MEMORY_HOTPLUG */ /* * walk_memory_resource() needs to make sure there is no holes in a given @@ -185,6 +184,8 @@ walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg, } EXPORT_SYMBOL_GPL(walk_memory_resource); +#endif /* CONFIG_MEMORY_HOTPLUG */ + void show_mem(void) { unsigned long total = 0, reserved = 0; diff --git a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c index 8a455ebce98d..48da5dfe4856 100644 --- a/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c +++ b/trunk/arch/powerpc/platforms/52xx/mpc52xx_gpio.c @@ -100,7 +100,7 @@ static int mpc52xx_wkup_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + struct mpc52xx_gpio_wkup *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -122,7 +122,7 @@ static int mpc52xx_wkup_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpio_wkup __iomem *regs = mm_gc->regs; + struct mpc52xx_gpio_wkup *regs = mm_gc->regs; struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); unsigned long flags; @@ -150,7 +150,7 @@ static int __devinit mpc52xx_wkup_gpiochip_probe(struct of_device *ofdev, const struct of_device_id *match) { struct mpc52xx_gpiochip *chip; - struct mpc52xx_gpio_wkup __iomem *regs; + struct mpc52xx_gpio_wkup *regs; struct of_gpio_chip *ofchip; int ret; @@ -260,7 +260,7 @@ static int mpc52xx_simple_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + struct mpc52xx_gpio *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -284,7 +284,7 @@ mpc52xx_simple_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); struct mpc52xx_gpiochip *chip = container_of(mm_gc, struct mpc52xx_gpiochip, mmchip); - struct mpc52xx_gpio __iomem *regs = mm_gc->regs; + struct mpc52xx_gpio *regs = mm_gc->regs; unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -312,7 +312,7 @@ static int __devinit mpc52xx_simple_gpiochip_probe(struct of_device *ofdev, { struct mpc52xx_gpiochip *chip; struct of_gpio_chip *ofchip; - struct mpc52xx_gpio __iomem *regs; + struct mpc52xx_gpio *regs; int ret; chip = kzalloc(sizeof(*chip), GFP_KERNEL); @@ -387,7 +387,7 @@ mpc52xx_gpt_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val) static int mpc52xx_gpt_gpio_dir_in(struct gpio_chip *gc, unsigned int gpio) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct mpc52xx_gpt __iomem *regs = mm_gc->regs; + struct mpc52xx_gpt *regs = mm_gc->regs; out_be32(®s->mode, 0x04); diff --git a/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c b/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c index 0e04f8fb152a..31da84c458d2 100644 --- a/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c +++ b/trunk/arch/powerpc/platforms/cell/celleb_scc_pciex.c @@ -217,7 +217,7 @@ static u##size scc_pciex_in##name(unsigned long port) \ static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \ { \ struct iowa_bus *bus = iowa_pio_find_bus(p); \ - __le##size *dst = b; \ + u##size *dst = b; \ for (; c != 0; c--, dst++) \ *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \ scc_pciex_io_flush(bus); \ @@ -231,11 +231,10 @@ static void scc_pciex_outs##name(unsigned long p, const void *b, \ unsigned long c) \ { \ struct iowa_bus *bus = iowa_pio_find_bus(p); \ - const __le##size *src = b; \ + const u##size *src = b; \ for (; c != 0; c--, src++) \ __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \ } -#define __le8 u8 #define cpu_to_le8(x) (x) #define le8_to_cpu(x) (x) PCIEX_PIO_FUNC(8, b) diff --git a/trunk/arch/powerpc/sysdev/fsl_soc.c b/trunk/arch/powerpc/sysdev/fsl_soc.c index 019657c110b6..3a7054e2bb75 100644 --- a/trunk/arch/powerpc/sysdev/fsl_soc.c +++ b/trunk/arch/powerpc/sysdev/fsl_soc.c @@ -432,7 +432,7 @@ static struct i2c_driver_device i2c_devices[] __initdata = { {"dallas,ds1339", "ds1339"}, {"dallas,ds1340", "ds1340"}, {"stm,m41t00", "m41t00"}, - {"dallas,ds1374", "ds1374"}, + {"dallas,ds1374", "rtc-ds1374"}, }; static int __init of_find_i2c_driver(struct device_node *node, diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index 107e492cb47e..93acb3c1859d 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -304,7 +304,6 @@ config ARCH_SPARSEMEM_ENABLE def_bool y select SPARSEMEM_VMEMMAP_ENABLE select SPARSEMEM_VMEMMAP - select SPARSEMEM_STATIC if !64BIT config ARCH_SPARSEMEM_DEFAULT def_bool y diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 5d4fa4b1c74c..42b1d12ebb10 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -711,7 +711,7 @@ int __cpuinit __cpu_up(unsigned int cpu) memset(sf, 0, sizeof(struct stack_frame)); sf->gprs[9] = (unsigned long) sf; cpu_lowcore->save_area[15] = (unsigned long) sf; - __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); + __ctl_store(cpu_lowcore->cregs_save_area[0], 0, 15); asm volatile( " stam 0,15,0(%0)" : : "a" (&cpu_lowcore->access_regs_save_area) : "memory"); diff --git a/trunk/arch/s390/kvm/diag.c b/trunk/arch/s390/kvm/diag.c index a0775e1f08df..f639a152869f 100644 --- a/trunk/arch/s390/kvm/diag.c +++ b/trunk/arch/s390/kvm/diag.c @@ -20,7 +20,7 @@ static int __diag_time_slice_end(struct kvm_vcpu *vcpu) VCPU_EVENT(vcpu, 5, "%s", "diag time slice end"); vcpu->stat.diagnose_44++; vcpu_put(vcpu); - yield(); + schedule(); vcpu_load(vcpu); return 0; } diff --git a/trunk/arch/s390/kvm/interrupt.c b/trunk/arch/s390/kvm/interrupt.c index 84a7fed4cd4e..fcd1ed8015c1 100644 --- a/trunk/arch/s390/kvm/interrupt.c +++ b/trunk/arch/s390/kvm/interrupt.c @@ -339,11 +339,6 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) if (kvm_cpu_has_interrupt(vcpu)) return 0; - __set_cpu_idle(vcpu); - spin_lock_bh(&vcpu->arch.local_int.lock); - vcpu->arch.local_int.timer_due = 0; - spin_unlock_bh(&vcpu->arch.local_int.lock); - if (psw_interrupts_disabled(vcpu)) { VCPU_EVENT(vcpu, 3, "%s", "disabled wait"); __unset_cpu_idle(vcpu); @@ -371,6 +366,8 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu) no_timer: spin_lock_bh(&vcpu->arch.local_int.float_int->lock); spin_lock_bh(&vcpu->arch.local_int.lock); + __set_cpu_idle(vcpu); + vcpu->arch.local_int.timer_due = 0; add_wait_queue(&vcpu->arch.local_int.wq, &wait); while (list_empty(&vcpu->arch.local_int.list) && list_empty(&vcpu->arch.local_int.float_int->list) && diff --git a/trunk/arch/s390/kvm/kvm-s390.c b/trunk/arch/s390/kvm/kvm-s390.c index 6558b09ff579..0ac36a649eba 100644 --- a/trunk/arch/s390/kvm/kvm-s390.c +++ b/trunk/arch/s390/kvm/kvm-s390.c @@ -423,8 +423,6 @@ int kvm_arch_vcpu_ioctl_set_mpstate(struct kvm_vcpu *vcpu, return -EINVAL; /* not implemented yet */ } -extern void s390_handle_mcck(void); - static void __vcpu_run(struct kvm_vcpu *vcpu) { memcpy(&vcpu->arch.sie_block->gg14, &vcpu->arch.guest_gprs[14], 16); @@ -432,21 +430,13 @@ static void __vcpu_run(struct kvm_vcpu *vcpu) if (need_resched()) schedule(); - if (test_thread_flag(TIF_MCCK_PENDING)) - s390_handle_mcck(); - - kvm_s390_deliver_pending_interrupts(vcpu); - vcpu->arch.sie_block->icptcode = 0; local_irq_disable(); kvm_guest_enter(); local_irq_enable(); VCPU_EVENT(vcpu, 6, "entering sie flags %x", atomic_read(&vcpu->arch.sie_block->cpuflags)); - if (sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs)) { - VCPU_EVENT(vcpu, 3, "%s", "fault in sie instruction"); - kvm_s390_inject_program_int(vcpu, PGM_ADDRESSING); - } + sie64a(vcpu->arch.sie_block, vcpu->arch.guest_gprs); VCPU_EVENT(vcpu, 6, "exit sie icptcode %d", vcpu->arch.sie_block->icptcode); local_irq_disable(); @@ -485,6 +475,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) might_sleep(); do { + kvm_s390_deliver_pending_interrupts(vcpu); __vcpu_run(vcpu); rc = kvm_handle_sie_intercept(vcpu); } while (!signal_pending(current) && !rc); diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 3d98ba82ea67..5c1aea97cd12 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -254,46 +254,36 @@ void disable_noexec(struct mm_struct *mm, struct task_struct *tsk) int s390_enable_sie(void) { struct task_struct *tsk = current; - struct mm_struct *mm, *old_mm; + struct mm_struct *mm; + int rc; - /* Do we have pgstes? if yes, we are done */ + task_lock(tsk); + + rc = 0; if (tsk->mm->context.pgstes) - return 0; + goto unlock; - /* lets check if we are allowed to replace the mm */ - task_lock(tsk); + rc = -EINVAL; if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || - tsk->mm != tsk->active_mm || tsk->mm->ioctx_list) { - task_unlock(tsk); - return -EINVAL; - } - task_unlock(tsk); + tsk->mm != tsk->active_mm || tsk->mm->ioctx_list) + goto unlock; - /* we copy the mm with pgstes enabled */ - tsk->mm->context.pgstes = 1; + tsk->mm->context.pgstes = 1; /* dirty little tricks .. */ mm = dup_mm(tsk); tsk->mm->context.pgstes = 0; - if (!mm) - return -ENOMEM; - /* Now lets check again if somebody attached ptrace etc */ - task_lock(tsk); - if (!tsk->mm || atomic_read(&tsk->mm->mm_users) > 1 || - tsk->mm != tsk->active_mm || tsk->mm->ioctx_list) { - mmput(mm); - task_unlock(tsk); - return -EINVAL; - } - - /* ok, we are alone. No ptrace, no threads, etc. */ - old_mm = tsk->mm; + rc = -ENOMEM; + if (!mm) + goto unlock; + mmput(tsk->mm); tsk->mm = tsk->active_mm = mm; preempt_disable(); update_mm(mm, tsk); cpu_set(smp_processor_id(), mm->cpu_vm_mask); preempt_enable(); + rc = 0; +unlock: task_unlock(tsk); - mmput(old_mm); - return 0; + return rc; } EXPORT_SYMBOL_GPL(s390_enable_sie); diff --git a/trunk/arch/s390/mm/vmem.c b/trunk/arch/s390/mm/vmem.c index e4868bfc672f..f591188fa2c0 100644 --- a/trunk/arch/s390/mm/vmem.c +++ b/trunk/arch/s390/mm/vmem.c @@ -236,7 +236,7 @@ static int insert_memory_segment(struct memory_segment *seg) { struct memory_segment *tmp; - if (seg->start + seg->size > VMEM_MAX_PHYS || + if (seg->start + seg->size >= VMEM_MAX_PHYS || seg->start + seg->size < seg->start) return -ERANGE; diff --git a/trunk/arch/sh/Kconfig.debug b/trunk/arch/sh/Kconfig.debug index 0f4549860226..0d2ef1e9a6fd 100644 --- a/trunk/arch/sh/Kconfig.debug +++ b/trunk/arch/sh/Kconfig.debug @@ -81,7 +81,7 @@ config DEBUG_STACK_USAGE config 4KSTACKS bool "Use 4Kb for kernel stacks instead of 8Kb" - depends on DEBUG_KERNEL && (MMU || BROKEN) + depends on DEBUG_KERNEL help If you say Y here the kernel will use a 4Kb stacksize for the kernel stack attached to each process/thread. This facilitates diff --git a/trunk/arch/sh/Makefile b/trunk/arch/sh/Makefile index fb7b1b15e392..8050b03d51fc 100644 --- a/trunk/arch/sh/Makefile +++ b/trunk/arch/sh/Makefile @@ -41,8 +41,6 @@ cflags-$(CONFIG_CPU_SH5) := $(call cc-option,-m5-32media-nofpu,) cflags-$(CONFIG_CPU_BIG_ENDIAN) += -mb cflags-$(CONFIG_CPU_LITTLE_ENDIAN) += -ml -cflags-y += $(call cc-option,-mno-fdpic) - # # -Wa,-isa= tuning implies -Wa,-dsp for the versions of binutils that # support it, while -Wa,-dsp by itself limits the range of usable opcodes diff --git a/trunk/arch/sh/configs/rsk7203_defconfig b/trunk/arch/sh/configs/rsk7203_defconfig deleted file mode 100644 index a0ebd439cbd2..000000000000 --- a/trunk/arch/sh/configs/rsk7203_defconfig +++ /dev/null @@ -1,841 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Tue Jun 3 13:02:42 2008 -# -CONFIG_SUPERH=y -CONFIG_SUPERH32=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_BUG=y -CONFIG_GENERIC_FIND_NEXT_BIT=y -CONFIG_GENERIC_HWEIGHT=y -CONFIG_GENERIC_HARDIRQS=y -CONFIG_GENERIC_IRQ_PROBE=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -# CONFIG_GENERIC_TIME is not set -# CONFIG_GENERIC_CLOCKEVENTS is not set -CONFIG_STACKTRACE_SUPPORT=y -CONFIG_LOCKDEP_SUPPORT=y -# CONFIG_ARCH_HAS_ILOG2_U32 is not set -# CONFIG_ARCH_HAS_ILOG2_U64 is not set -CONFIG_ARCH_NO_VIRT_TO_BUS=y -CONFIG_ARCH_SUPPORTS_AOUT=y -CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" - -# -# General setup -# -CONFIG_EXPERIMENTAL=y -CONFIG_BROKEN_ON_SMP=y -CONFIG_INIT_ENV_ARG_LIMIT=32 -CONFIG_LOCALVERSION="" -# CONFIG_LOCALVERSION_AUTO is not set -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -# CONFIG_BSD_PROCESS_ACCT is not set -# CONFIG_TASKSTATS is not set -# CONFIG_AUDIT is not set -# CONFIG_IKCONFIG is not set -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_CGROUPS is not set -CONFIG_GROUP_SCHED=y -CONFIG_FAIR_GROUP_SCHED=y -# CONFIG_RT_GROUP_SCHED is not set -CONFIG_USER_SCHED=y -# CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y -# CONFIG_RELAY is not set -# CONFIG_NAMESPACES is not set -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SYSCTL=y -CONFIG_EMBEDDED=y -CONFIG_UID16=y -CONFIG_SYSCTL_SYSCALL=y -CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y -CONFIG_PRINTK=y -CONFIG_BUG=y -CONFIG_ELF_CORE=y -CONFIG_COMPAT_BRK=y -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_ANON_INODES=y -CONFIG_EPOLL=y -CONFIG_SIGNALFD=y -CONFIG_TIMERFD=y -CONFIG_EVENTFD=y -CONFIG_VM_EVENT_COUNTERS=y -CONFIG_SLAB=y -# CONFIG_SLUB is not set -# CONFIG_SLOB is not set -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_SLABINFO=y -CONFIG_RT_MUTEXES=y -CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -# CONFIG_MODULES is not set -CONFIG_BLOCK=y -# CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_LSF is not set -# CONFIG_BLK_DEV_BSG is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -# CONFIG_IOSCHED_AS is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -# CONFIG_DEFAULT_AS is not set -# CONFIG_DEFAULT_DEADLINE is not set -# CONFIG_DEFAULT_CFQ is not set -CONFIG_DEFAULT_NOOP=y -CONFIG_DEFAULT_IOSCHED="noop" -CONFIG_CLASSIC_RCU=y - -# -# System type -# -CONFIG_CPU_SH2=y -CONFIG_CPU_SH2A=y -# CONFIG_CPU_SUBTYPE_SH7619 is not set -CONFIG_CPU_SUBTYPE_SH7203=y -# CONFIG_CPU_SUBTYPE_SH7206 is not set -# CONFIG_CPU_SUBTYPE_SH7263 is not set -# CONFIG_CPU_SUBTYPE_MXG is not set -# CONFIG_CPU_SUBTYPE_SH7705 is not set -# CONFIG_CPU_SUBTYPE_SH7706 is not set -# CONFIG_CPU_SUBTYPE_SH7707 is not set -# CONFIG_CPU_SUBTYPE_SH7708 is not set -# CONFIG_CPU_SUBTYPE_SH7709 is not set -# CONFIG_CPU_SUBTYPE_SH7710 is not set -# CONFIG_CPU_SUBTYPE_SH7712 is not set -# CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set -# CONFIG_CPU_SUBTYPE_SH7750 is not set -# CONFIG_CPU_SUBTYPE_SH7091 is not set -# CONFIG_CPU_SUBTYPE_SH7750R is not set -# CONFIG_CPU_SUBTYPE_SH7750S is not set -# CONFIG_CPU_SUBTYPE_SH7751 is not set -# CONFIG_CPU_SUBTYPE_SH7751R is not set -# CONFIG_CPU_SUBTYPE_SH7760 is not set -# CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7723 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set -# CONFIG_CPU_SUBTYPE_SH7770 is not set -# CONFIG_CPU_SUBTYPE_SH7780 is not set -# CONFIG_CPU_SUBTYPE_SH7785 is not set -# CONFIG_CPU_SUBTYPE_SHX3 is not set -# CONFIG_CPU_SUBTYPE_SH7343 is not set -# CONFIG_CPU_SUBTYPE_SH7722 is not set -# CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set - -# -# Memory management options -# -CONFIG_QUICKLIST=y -CONFIG_PAGE_OFFSET=0x00000000 -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x01000000 -CONFIG_29BIT=y -CONFIG_ARCH_FLATMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y -CONFIG_ARCH_SPARSEMEM_DEFAULT=y -CONFIG_MAX_ACTIVE_REGIONS=1 -CONFIG_ARCH_POPULATES_NODE_MAP=y -CONFIG_ARCH_SELECT_MEMORY_MODEL=y -CONFIG_PAGE_SIZE_4KB=y -# CONFIG_PAGE_SIZE_8KB is not set -# CONFIG_PAGE_SIZE_64KB is not set -CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y -# CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y -CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y -CONFIG_SPLIT_PTLOCK_CPUS=4 -# CONFIG_RESOURCES_64BIT is not set -CONFIG_ZONE_DMA_FLAG=0 -CONFIG_NR_QUICK=2 - -# -# Cache configuration -# -# CONFIG_SH_DIRECT_MAPPED is not set -CONFIG_CACHE_WRITEBACK=y -# CONFIG_CACHE_WRITETHROUGH is not set -# CONFIG_CACHE_OFF is not set - -# -# Processor features -# -# CONFIG_CPU_LITTLE_ENDIAN is not set -CONFIG_CPU_BIG_ENDIAN=y -CONFIG_SH_FPU=y -CONFIG_CPU_HAS_FPU=y - -# -# Board support -# - -# -# Timer and clock configuration -# -CONFIG_SH_CMT=y -# CONFIG_SH_MTU2 is not set -CONFIG_SH_TIMER_IRQ=142 -CONFIG_SH_PCLK_FREQ=16670800 -CONFIG_SH_CLK_MD=0 -# CONFIG_TICK_ONESHOT is not set - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -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_POWERSAVE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set -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_ONDEMAND is not set -# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_SH_CPU_FREQ=y - -# -# DMA support -# - -# -# Companion Chips -# - -# -# Additional SuperH Device Drivers -# -CONFIG_HEARTBEAT=y -# CONFIG_PUSH_SWITCH is not set - -# -# Kernel features -# -# CONFIG_HZ_100 is not set -# CONFIG_HZ_250 is not set -# CONFIG_HZ_300 is not set -CONFIG_HZ_1000=y -CONFIG_HZ=1000 -# CONFIG_SCHED_HRTICK is not set -# CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set -CONFIG_PREEMPT_NONE=y -# CONFIG_PREEMPT_VOLUNTARY is not set -# CONFIG_PREEMPT is not set -CONFIG_GUSA=y - -# -# Boot options -# -CONFIG_ZERO_PAGE_OFFSET=0x00001000 -CONFIG_BOOT_LINK_OFFSET=0x00800000 -CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=serial ignore_loglevel" - -# -# Bus options -# -# CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set - -# -# Executable file formats -# -CONFIG_BINFMT_FLAT=y -CONFIG_BINFMT_ZFLAT=y -CONFIG_BINFMT_SHARED_FLAT=y -# CONFIG_BINFMT_MISC is not set - -# -# Networking -# -CONFIG_NET=y - -# -# Networking options -# -# CONFIG_PACKET is not set -# CONFIG_UNIX is not set -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_TCP_CONG_ADVANCED is not set -CONFIG_TCP_CONG_CUBIC=y -CONFIG_DEFAULT_TCP_CONG="cubic" -# CONFIG_TCP_MD5SIG is not set -# CONFIG_IPV6 is not set -# CONFIG_NETWORK_SECMARK is not set -# CONFIG_NETFILTER is not set -# CONFIG_IP_DCCP is not set -# CONFIG_IP_SCTP is not set -# CONFIG_TIPC is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -# CONFIG_AF_RXRPC is not set - -# -# Wireless -# -# CONFIG_CFG80211 is not set -# CONFIG_WIRELESS_EXT is not set -# CONFIG_MAC80211 is not set -# CONFIG_IEEE80211 is not set -# CONFIG_RFKILL is not set -# CONFIG_NET_9P is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -# CONFIG_STANDALONE is not set -# CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set -# CONFIG_DEBUG_DRIVER is not set -# CONFIG_DEBUG_DEVRES is not set -# CONFIG_SYS_HYPERVISOR is not set -# CONFIG_CONNECTOR is not set -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_CONCAT=y -CONFIG_MTD_PARTITIONS=y -CONFIG_MTD_REDBOOT_PARTS=y -CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 -# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set -# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLKDEVS=y -CONFIG_MTD_BLOCK=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set -# CONFIG_INFTL is not set -# CONFIG_RFD_FTL is not set -# CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -# CONFIG_MTD_CFI_ADV_OPTIONS is not set -CONFIG_MTD_MAP_BANK_WIDTH_1=y -CONFIG_MTD_MAP_BANK_WIDTH_2=y -CONFIG_MTD_MAP_BANK_WIDTH_4=y -# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -CONFIG_MTD_CFI_I1=y -CONFIG_MTD_CFI_I2=y -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -# CONFIG_MTD_CFI_INTELEXT is not set -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_CFI_STAA is not set -CONFIG_MTD_CFI_UTIL=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_COMPLEX_MAPPINGS is not set -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_PHYSMAP_START=0x20000000 -CONFIG_MTD_PHYSMAP_LEN=0x01000000 -CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -# CONFIG_MTD_UCLINUX is not set -# CONFIG_MTD_PLATRAM is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_PHRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLOCK2MTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOC2001PLUS is not set -# CONFIG_MTD_NAND is not set -# CONFIG_MTD_ONENAND is not set - -# -# UBI - Unsorted block images -# -# CONFIG_MTD_UBI is not set -# CONFIG_PARPORT is not set -CONFIG_BLK_DEV=y -# CONFIG_BLK_DEV_COW_COMMON is not set -# CONFIG_BLK_DEV_LOOP is not set -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_CDROM_PKTCDVD is not set -# CONFIG_ATA_OVER_ETH is not set -CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y -# CONFIG_IDE is not set - -# -# SCSI device support -# -# CONFIG_RAID_ATTRS is not set -# CONFIG_SCSI is not set -# CONFIG_SCSI_DMA is not set -# CONFIG_SCSI_NETLINK is not set -# CONFIG_ATA is not set -# CONFIG_MD is not set -CONFIG_NETDEVICES=y -# CONFIG_NETDEVICES_MULTIQUEUE is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_MACVLAN is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_VETH is not set -# CONFIG_PHYLIB is not set -CONFIG_NET_ETHERNET=y -CONFIG_MII=y -# CONFIG_AX88796 is not set -# CONFIG_STNIC is not set -CONFIG_SMC91X=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -CONFIG_NETDEV_1000=y -# CONFIG_E1000E_ENABLED is not set -CONFIG_NETDEV_10000=y - -# -# Wireless LAN -# -# CONFIG_WLAN_PRE80211 is not set -# CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_ISDN is not set -# CONFIG_PHONE is not set - -# -# Input device support -# -CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set -# CONFIG_INPUT_POLLDEV is not set - -# -# Userland interfaces -# -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TABLET is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -# CONFIG_SERIO is not set -# CONFIG_GAMEPORT is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_DEVKMEM=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SH_SCI=y -CONFIG_SERIAL_SH_SCI_NR_UARTS=4 -CONFIG_SERIAL_SH_SCI_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -# CONFIG_UNIX98_PTYS is not set -# CONFIG_LEGACY_PTYS is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_HW_RANDOM is not set -# CONFIG_R3964 is not set -# CONFIG_RAW_DRIVER is not set -# CONFIG_TCG_TPM is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -# CONFIG_W1 is not set -# CONFIG_POWER_SUPPLY is not set -# CONFIG_HWMON is not set -CONFIG_THERMAL=y -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set - -# -# Multifunction device drivers -# -# CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set - -# -# Multimedia devices -# - -# -# Multimedia core support -# -# CONFIG_VIDEO_DEV is not set -# CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -CONFIG_DAB=y - -# -# Graphics support -# -# CONFIG_VGASTATE is not set -CONFIG_VIDEO_OUTPUT_CONTROL=y -# CONFIG_FB is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Display device support -# -# CONFIG_DISPLAY_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set -CONFIG_HID_SUPPORT=y -CONFIG_HID=y -# CONFIG_HID_DEBUG is not set -# CONFIG_HIDRAW is not set -CONFIG_USB_SUPPORT=y -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB_ARCH_HAS_EHCI is not set -# CONFIG_USB is not set -# CONFIG_USB_OTG_WHITELIST is not set -# CONFIG_USB_OTG_BLACKLIST_HUB is not set - -# -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' -# -# CONFIG_USB_GADGET is not set -# CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set -# CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set - -# -# RTC interfaces -# -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set - -# -# SPI RTC drivers -# - -# -# Platform RTC drivers -# -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set - -# -# on-CPU RTC drivers -# -CONFIG_RTC_DRV_SH=y -# CONFIG_UIO is not set - -# -# File systems -# -# CONFIG_EXT2_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_EXT4DEV_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_FS_POSIX_ACL is not set -# CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set -# CONFIG_INOTIFY is not set -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_FUSE_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_MSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -# CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -CONFIG_ROMFS_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set -# CONFIG_DLM is not set - -# -# Kernel hacking -# -CONFIG_TRACE_IRQFLAGS_SUPPORT=y -# CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y -# CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 -CONFIG_MAGIC_SYSRQ=y -# CONFIG_UNUSED_SYMBOLS is not set -# CONFIG_DEBUG_FS is not set -# CONFIG_HEADERS_CHECK is not set -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_SHIRQ=y -CONFIG_DETECT_SOFTLOCKUP=y -CONFIG_SCHED_DEBUG=y -# CONFIG_SCHEDSTATS is not set -# CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_LOCK_ALLOC is not set -# CONFIG_PROVE_LOCKING is not set -# CONFIG_LOCK_STAT is not set -CONFIG_DEBUG_SPINLOCK_SLEEP=y -# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -# CONFIG_DEBUG_KOBJECT is not set -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_DEBUG_INFO=y -# CONFIG_DEBUG_VM is not set -# CONFIG_DEBUG_WRITECOUNT is not set -# CONFIG_DEBUG_LIST is not set -# CONFIG_DEBUG_SG is not set -CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_BACKTRACE_SELF_TEST is not set -# CONFIG_FAULT_INJECTION is not set -# CONFIG_SAMPLES is not set -# CONFIG_SH_STANDARD_BIOS is not set -CONFIG_EARLY_SCIF_CONSOLE=y -CONFIG_EARLY_SCIF_CONSOLE_PORT=0xfffe8000 -CONFIG_EARLY_PRINTK=y -CONFIG_DEBUG_BOOTMEM=y -CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_DEBUG_STACK_USAGE=y -# CONFIG_IRQSTACKS is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -# CONFIG_CRC_CCITT is not set -# CONFIG_CRC16 is not set -# CONFIG_CRC_ITU_T is not set -CONFIG_CRC32=y -# CONFIG_CRC7 is not set -# CONFIG_LIBCRC32C is not set -CONFIG_ZLIB_INFLATE=y -CONFIG_PLIST=y -CONFIG_HAS_IOMEM=y -CONFIG_HAS_IOPORT=y -CONFIG_HAS_DMA=y diff --git a/trunk/arch/sh/configs/se7206_defconfig b/trunk/arch/sh/configs/se7206_defconfig index 6b34baa26eae..0d0cda908270 100644 --- a/trunk/arch/sh/configs/se7206_defconfig +++ b/trunk/arch/sh/configs/se7206_defconfig @@ -1,10 +1,9 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.26-rc4 -# Tue Jun 3 20:27:08 2008 +# Linux kernel version: 2.6.23-rc4 +# Thu Sep 13 16:40:16 2007 # CONFIG_SUPERH=y -CONFIG_SUPERH32=y CONFIG_RWSEM_GENERIC_SPINLOCK=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_FIND_NEXT_BIT=y @@ -19,7 +18,6 @@ CONFIG_LOCKDEP_SUPPORT=y # CONFIG_ARCH_HAS_ILOG2_U32 is not set # CONFIG_ARCH_HAS_ILOG2_U64 is not set CONFIG_ARCH_NO_VIRT_TO_BUS=y -CONFIG_ARCH_SUPPORTS_AOUT=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -27,82 +25,47 @@ CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # CONFIG_EXPERIMENTAL=y CONFIG_BROKEN_ON_SMP=y -CONFIG_LOCK_KERNEL=y CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_LOCALVERSION="" -CONFIG_LOCALVERSION_AUTO=y -CONFIG_SYSVIPC=y -CONFIG_SYSVIPC_SYSCTL=y -CONFIG_POSIX_MQUEUE=y -CONFIG_BSD_PROCESS_ACCT=y -# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_SYSVIPC is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set -CONFIG_AUDIT=y -CONFIG_AUDITSYSCALL=y +# CONFIG_USER_NS is not set +# CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 -CONFIG_CGROUPS=y -CONFIG_CGROUP_DEBUG=y -CONFIG_CGROUP_NS=y -CONFIG_CGROUP_DEVICE=y -# CONFIG_GROUP_SCHED is not set -CONFIG_CGROUP_CPUACCT=y -CONFIG_RESOURCE_COUNTERS=y -CONFIG_MM_OWNER=y -CONFIG_CGROUP_MEM_RES_CTLR=y -# CONFIG_SYSFS_DEPRECATED_V2 is not set -CONFIG_RELAY=y -CONFIG_NAMESPACES=y -CONFIG_UTS_NS=y -CONFIG_IPC_NS=y -CONFIG_USER_NS=y -CONFIG_PID_NS=y -CONFIG_BLK_DEV_INITRD=y -CONFIG_INITRAMFS_SOURCE="" +CONFIG_SYSFS_DEPRECATED=y +# CONFIG_RELAY is not set +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y CONFIG_EMBEDDED=y # CONFIG_UID16 is not set # CONFIG_SYSCTL_SYSCALL is not set -CONFIG_KALLSYMS=y -CONFIG_KALLSYMS_ALL=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_HOTPLUG=y +# CONFIG_KALLSYMS is not set +# CONFIG_HOTPLUG is not set CONFIG_PRINTK=y CONFIG_BUG=y # CONFIG_ELF_CORE is not set -# CONFIG_COMPAT_BRK is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y +# CONFIG_BASE_FULL is not set +# CONFIG_FUTEX is not set CONFIG_ANON_INODES=y -CONFIG_EPOLL=y +# CONFIG_EPOLL is not set CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y -CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_VM_EVENT_COUNTERS is not set +CONFIG_SLUB_DEBUG=y # CONFIG_SLAB is not set -# CONFIG_SLUB is not set -CONFIG_SLOB=y -CONFIG_PROFILING=y -# CONFIG_MARKERS is not set -CONFIG_OPROFILE=y -CONFIG_HAVE_OPROFILE=y -# CONFIG_HAVE_KPROBES is not set -# CONFIG_HAVE_KRETPROBES is not set -# CONFIG_HAVE_DMA_ATTRS is not set -CONFIG_RT_MUTEXES=y +CONFIG_SLUB=y +# CONFIG_SLOB is not set CONFIG_TINY_SHMEM=y -CONFIG_BASE_SMALL=0 -CONFIG_MODULES=y -# CONFIG_MODULE_FORCE_LOAD is not set -CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set +CONFIG_BASE_SMALL=1 +# CONFIG_MODULES is not set CONFIG_BLOCK=y # CONFIG_LBD is not set -# CONFIG_BLK_DEV_IO_TRACE is not set # CONFIG_LSF is not set # CONFIG_BLK_DEV_BSG is not set @@ -118,7 +81,6 @@ CONFIG_IOSCHED_NOOP=y # CONFIG_DEFAULT_CFQ is not set CONFIG_DEFAULT_NOOP=y CONFIG_DEFAULT_IOSCHED="noop" -# CONFIG_CLASSIC_RCU is not set # # System type @@ -126,10 +88,7 @@ CONFIG_DEFAULT_IOSCHED="noop" CONFIG_CPU_SH2=y CONFIG_CPU_SH2A=y # CONFIG_CPU_SUBTYPE_SH7619 is not set -# CONFIG_CPU_SUBTYPE_SH7203 is not set CONFIG_CPU_SUBTYPE_SH7206=y -# CONFIG_CPU_SUBTYPE_SH7263 is not set -# CONFIG_CPU_SUBTYPE_MXG is not set # CONFIG_CPU_SUBTYPE_SH7705 is not set # CONFIG_CPU_SUBTYPE_SH7706 is not set # CONFIG_CPU_SUBTYPE_SH7707 is not set @@ -138,7 +97,6 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7710 is not set # CONFIG_CPU_SUBTYPE_SH7712 is not set # CONFIG_CPU_SUBTYPE_SH7720 is not set -# CONFIG_CPU_SUBTYPE_SH7721 is not set # CONFIG_CPU_SUBTYPE_SH7750 is not set # CONFIG_CPU_SUBTYPE_SH7091 is not set # CONFIG_CPU_SUBTYPE_SH7750R is not set @@ -147,17 +105,14 @@ CONFIG_CPU_SUBTYPE_SH7206=y # CONFIG_CPU_SUBTYPE_SH7751R is not set # CONFIG_CPU_SUBTYPE_SH7760 is not set # CONFIG_CPU_SUBTYPE_SH4_202 is not set -# CONFIG_CPU_SUBTYPE_SH7723 is not set -# CONFIG_CPU_SUBTYPE_SH7763 is not set +# CONFIG_CPU_SUBTYPE_ST40STB1 is not set +# CONFIG_CPU_SUBTYPE_ST40GX1 is not set # CONFIG_CPU_SUBTYPE_SH7770 is not set # CONFIG_CPU_SUBTYPE_SH7780 is not set # CONFIG_CPU_SUBTYPE_SH7785 is not set # CONFIG_CPU_SUBTYPE_SHX3 is not set # CONFIG_CPU_SUBTYPE_SH7343 is not set # CONFIG_CPU_SUBTYPE_SH7722 is not set -# CONFIG_CPU_SUBTYPE_SH7366 is not set -# CONFIG_CPU_SUBTYPE_SH5_101 is not set -# CONFIG_CPU_SUBTYPE_SH5_103 is not set # # Memory management options @@ -166,25 +121,23 @@ CONFIG_QUICKLIST=y CONFIG_PAGE_OFFSET=0x00000000 CONFIG_MEMORY_START=0x0c000000 CONFIG_MEMORY_SIZE=0x04000000 -CONFIG_29BIT=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_MAX_ACTIVE_REGIONS=1 CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_8KB is not set # CONFIG_PAGE_SIZE_64KB is not set CONFIG_SELECT_MEMORY_MODEL=y -CONFIG_FLATMEM_MANUAL=y +# CONFIG_FLATMEM_MANUAL is not set # CONFIG_DISCONTIGMEM_MANUAL is not set -# CONFIG_SPARSEMEM_MANUAL is not set -CONFIG_FLATMEM=y -CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM=y +CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_STATIC=y -# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set -CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_RESOURCES_64BIT is not set CONFIG_ZONE_DMA_FLAG=0 @@ -230,16 +183,13 @@ CONFIG_CPU_FREQ_TABLE=y 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_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set -# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set 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_ONDEMAND is not set # CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set -CONFIG_SH_CPU_FREQ=y +# CONFIG_SH_CPU_FREQ is not set # # DMA support @@ -263,15 +213,11 @@ CONFIG_HEARTBEAT=y # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 -# CONFIG_SCHED_HRTICK is not set -CONFIG_KEXEC=y +# CONFIG_KEXEC is not set # CONFIG_CRASH_DUMP is not set -# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set -CONFIG_PREEMPT=y -CONFIG_PREEMPT_RCU=y -CONFIG_RCU_TRACE=y -CONFIG_GUSA=y +# CONFIG_PREEMPT is not set # # Boot options @@ -279,25 +225,25 @@ CONFIG_GUSA=y CONFIG_ZERO_PAGE_OFFSET=0x00001000 CONFIG_BOOT_LINK_OFFSET=0x00800000 CONFIG_CMDLINE_BOOL=y -CONFIG_CMDLINE="console=ttySC3,115200 ignore_loglevel earlyprintk=serial" +CONFIG_CMDLINE="console=ttySC3,115200 earlyprintk=serial ignore_loglevel" # # Bus options # -CONFIG_CF_ENABLER=y -# CONFIG_CF_AREA5 is not set -CONFIG_CF_AREA6=y -CONFIG_CF_BASE_ADDR=0xb8000000 +# CONFIG_CF_ENABLER is not set # CONFIG_ARCH_SUPPORTS_MSI is not set -# CONFIG_PCCARD is not set + +# +# PCCARD (PCMCIA/CardBus) support +# # # Executable file formats # CONFIG_BINFMT_FLAT=y CONFIG_BINFMT_ZFLAT=y -CONFIG_BINFMT_SHARED_FLAT=y -CONFIG_BINFMT_MISC=y +# CONFIG_BINFMT_SHARED_FLAT is not set +# CONFIG_BINFMT_MISC is not set # # Networking @@ -307,24 +253,14 @@ CONFIG_NET=y # # Networking options # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_UNIX=y -CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_XFRM_SUB_POLICY is not set -# CONFIG_XFRM_MIGRATE is not set -# CONFIG_XFRM_STATISTICS is not set -CONFIG_NET_KEY=y -# CONFIG_NET_KEY_MIGRATE is not set +# CONFIG_PACKET is not set +# CONFIG_UNIX is not set +# CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set CONFIG_IP_FIB_HASH=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set # CONFIG_ARPD is not set @@ -337,13 +273,14 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_NETWORK_SECMARK is not set # CONFIG_NETFILTER is not set # CONFIG_IP_DCCP is not set @@ -360,6 +297,10 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# # CONFIG_NET_SCHED is not set # @@ -367,7 +308,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # CONFIG_NET_PKTGEN is not set # CONFIG_HAMRADIO is not set -# CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set @@ -389,10 +329,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic" # # Generic Driver Options # -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set # CONFIG_PREVENT_FIRMWARE_BUILD is not set -# CONFIG_FW_LOADER is not set # CONFIG_DEBUG_DRIVER is not set # CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set @@ -401,9 +339,11 @@ CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set # CONFIG_MTD_CMDLINE_PARTS is not set -# CONFIG_MTD_AR7_PARTS is not set # # User Modules And Translation Layers @@ -416,7 +356,6 @@ CONFIG_MTD_BLOCK=y # CONFIG_INFTL is not set # CONFIG_RFD_FTL is not set # CONFIG_SSFDC is not set -# CONFIG_MTD_OOPS is not set # # RAM/ROM/Flash chip drivers @@ -451,6 +390,7 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_START=0x20000000 CONFIG_MTD_PHYSMAP_LEN=0x01000000 CONFIG_MTD_PHYSMAP_BANKWIDTH=4 +# CONFIG_MTD_SOLUTIONENGINE is not set # CONFIG_MTD_UCLINUX is not set # CONFIG_MTD_PLATRAM is not set @@ -478,19 +418,13 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=4 # CONFIG_PARPORT is not set CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_BLK_DEV_RAM_SIZE=4096 -# CONFIG_BLK_DEV_XIP is not set +# CONFIG_BLK_DEV_RAM is not set # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set CONFIG_MISC_DEVICES=y -CONFIG_EEPROM_93CX6=y -# CONFIG_ENCLOSURE_SERVICES is not set -CONFIG_HAVE_IDE=y +# CONFIG_EEPROM_93CX6 is not set # CONFIG_IDE is not set # @@ -509,30 +443,23 @@ CONFIG_NETDEVICES=y # CONFIG_MACVLAN is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_VETH is not set # CONFIG_PHYLIB is not set CONFIG_NET_ETHERNET=y CONFIG_MII=y -# CONFIG_AX88796 is not set # CONFIG_STNIC is not set CONFIG_SMC91X=y -# CONFIG_IBM_NEW_EMAC_ZMII is not set -# CONFIG_IBM_NEW_EMAC_RGMII is not set -# CONFIG_IBM_NEW_EMAC_TAH is not set -# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -# CONFIG_B44 is not set -# CONFIG_NETDEV_1000 is not set -# CONFIG_NETDEV_10000 is not set +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y # # Wireless LAN # # CONFIG_WLAN_PRE80211 is not set # CONFIG_WLAN_80211 is not set -# CONFIG_IWLWIFI_LEDS is not set # CONFIG_WAN is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set +# CONFIG_SHAPER is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -542,7 +469,28 @@ CONFIG_SMC91X=y # # Input device support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +# CONFIG_INPUT_FF_MEMLESS is not set +# CONFIG_INPUT_POLLDEV is not set + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set # # Hardware I/O ports @@ -554,7 +502,6 @@ CONFIG_SMC91X=y # Character devices # # CONFIG_VT is not set -# CONFIG_DEVKMEM is not set # CONFIG_SERIAL_NONSTANDARD is not set # @@ -573,119 +520,106 @@ CONFIG_SERIAL_CORE_CONSOLE=y # CONFIG_UNIX98_PTYS is not set # CONFIG_LEGACY_PTYS is not set # CONFIG_IPMI_HANDLER is not set +# CONFIG_WATCHDOG is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set # CONFIG_RAW_DRIVER is not set # CONFIG_TCG_TPM is not set # CONFIG_I2C is not set + +# +# SPI support +# # CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set # CONFIG_W1 is not set # CONFIG_POWER_SUPPLY is not set # CONFIG_HWMON is not set -# CONFIG_THERMAL is not set -# CONFIG_WATCHDOG is not set - -# -# Sonics Silicon Backplane -# -CONFIG_SSB_POSSIBLE=y -# CONFIG_SSB is not set # # Multifunction device drivers # # CONFIG_MFD_SM501 is not set -# CONFIG_HTC_PASIC3 is not set # # Multimedia devices # - -# -# Multimedia core support -# # CONFIG_VIDEO_DEV is not set # CONFIG_DVB_CORE is not set -# CONFIG_VIDEO_MEDIA is not set - -# -# Multimedia drivers -# -# CONFIG_DAB is not set +CONFIG_DAB=y # # Graphics support # -# CONFIG_VGASTATE is not set -# CONFIG_VIDEO_OUTPUT_CONTROL is not set -# CONFIG_FB is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Display device support # # CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_VGASTATE is not set +CONFIG_VIDEO_OUTPUT_CONTROL=y +# CONFIG_FB is not set # # Sound # # CONFIG_SOUND is not set -# CONFIG_USB_SUPPORT is not set +CONFIG_HID_SUPPORT=y +CONFIG_HID=y +# CONFIG_HID_DEBUG is not set +CONFIG_USB_SUPPORT=y +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set # CONFIG_MMC is not set -# CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set -# CONFIG_ACCESSIBILITY is not set -CONFIG_RTC_LIB=y -CONFIG_RTC_CLASS=y -CONFIG_RTC_HCTOSYS=y -CONFIG_RTC_HCTOSYS_DEVICE="rtc0" -# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_CLASS is not set # -# RTC interfaces +# DMA Engine support # -CONFIG_RTC_INTF_SYSFS=y -CONFIG_RTC_INTF_PROC=y -CONFIG_RTC_INTF_DEV=y -# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -# CONFIG_RTC_DRV_TEST is not set +# CONFIG_DMA_ENGINE is not set # -# SPI RTC drivers +# DMA Clients # # -# Platform RTC drivers +# DMA Devices # -# CONFIG_RTC_DRV_DS1511 is not set -# CONFIG_RTC_DRV_DS1553 is not set -# CONFIG_RTC_DRV_DS1742 is not set -# CONFIG_RTC_DRV_STK17TA8 is not set -# CONFIG_RTC_DRV_M48T86 is not set -# CONFIG_RTC_DRV_M48T59 is not set -# CONFIG_RTC_DRV_V3020 is not set # -# on-CPU RTC drivers +# Userspace I/O # -CONFIG_RTC_DRV_SH=y # CONFIG_UIO is not set # # File systems # -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS is not set # CONFIG_EXT3_FS is not set # CONFIG_EXT4DEV_FS is not set # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set # CONFIG_XFS_FS is not set -# CONFIG_OCFS2_FS is not set -# CONFIG_DNOTIFY is not set +# CONFIG_GFS2_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=y # CONFIG_INOTIFY is not set # CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -708,11 +642,10 @@ CONFIG_EXT2_FS=y # CONFIG_PROC_FS=y CONFIG_PROC_SYSCTL=y -CONFIG_SYSFS=y -CONFIG_TMPFS=y -# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_SYSFS is not set +# CONFIG_TMPFS is not set # CONFIG_HUGETLB_PAGE is not set -CONFIG_CONFIGFS_FS=y +CONFIG_RAMFS=y # # Miscellaneous filesystems @@ -725,28 +658,18 @@ CONFIG_CONFIGFS_FS=y # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y +# CONFIG_CRAMFS is not set # CONFIG_VXFS_FS is not set -# CONFIG_MINIX_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set -CONFIG_ROMFS_FS=y # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -CONFIG_NETWORK_FILESYSTEMS=y -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -# CONFIG_NFS_V3_ACL is not set -# CONFIG_NFS_V4 is not set + +# +# Network File Systems +# +# CONFIG_NFS_FS is not set # CONFIG_NFSD is not set -CONFIG_ROOT_NFS=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=y -# CONFIG_SUNRPC_BIND34 is not set -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set @@ -758,20 +681,30 @@ CONFIG_SUNRPC=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# # CONFIG_NLS is not set -# CONFIG_DLM is not set + +# +# Distributed Lock Manager +# + +# +# Profiling support +# +CONFIG_PROFILING=y +# CONFIG_OPROFILE is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # CONFIG_PRINTK_TIME is not set -CONFIG_ENABLE_WARN_DEPRECATED=y # CONFIG_ENABLE_MUST_CHECK is not set -CONFIG_FRAME_WARN=1024 # CONFIG_MAGIC_SYSRQ is not set # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_SHIRQ is not set @@ -779,10 +712,7 @@ CONFIG_DETECT_SOFTLOCKUP=y CONFIG_SCHED_DEBUG=y # CONFIG_SCHEDSTATS is not set # CONFIG_TIMER_STATS is not set -# CONFIG_DEBUG_OBJECTS is not set -CONFIG_DEBUG_PREEMPT=y -# CONFIG_DEBUG_RT_MUTEXES is not set -# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_SLUB_DEBUG_ON=y # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_LOCK_ALLOC is not set @@ -792,123 +722,38 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y -# CONFIG_DEBUG_INFO is not set -CONFIG_DEBUG_VM=y -# CONFIG_DEBUG_WRITECOUNT is not set -CONFIG_DEBUG_LIST=y -# CONFIG_DEBUG_SG is not set +CONFIG_DEBUG_INFO=y +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_LIST is not set CONFIG_FRAME_POINTER=y -# CONFIG_BOOT_PRINTK_DELAY is not set -# CONFIG_RCU_TORTURE_TEST is not set -# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_FORCED_INLINING=y # CONFIG_FAULT_INJECTION is not set -# CONFIG_SAMPLES is not set # CONFIG_SH_STANDARD_BIOS is not set -# CONFIG_EARLY_SCIF_CONSOLE is not set +CONFIG_EARLY_SCIF_CONSOLE=y +CONFIG_EARLY_SCIF_CONSOLE_PORT=0xfffe9800 +CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_BOOTMEM is not set CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACK_USAGE=y -# CONFIG_IRQSTACKS is not set +# CONFIG_4KSTACKS is not set # # Security options # # CONFIG_KEYS is not set -# CONFIG_SECURITY is not set -# CONFIG_SECURITY_FILE_CAPABILITIES is not set -CONFIG_CRYPTO=y - -# -# Crypto core or helper -# -CONFIG_CRYPTO_ALGAPI=y -# CONFIG_CRYPTO_MANAGER is not set -# CONFIG_CRYPTO_GF128MUL is not set -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_CRYPTD is not set -# CONFIG_CRYPTO_AUTHENC is not set -# CONFIG_CRYPTO_TEST is not set - -# -# Authenticated Encryption with Associated Data -# -# CONFIG_CRYPTO_CCM is not set -# CONFIG_CRYPTO_GCM is not set -# CONFIG_CRYPTO_SEQIV is not set - -# -# Block modes -# -# CONFIG_CRYPTO_CBC is not set -# CONFIG_CRYPTO_CTR is not set -# CONFIG_CRYPTO_CTS is not set -# CONFIG_CRYPTO_ECB is not set -# CONFIG_CRYPTO_LRW is not set -# CONFIG_CRYPTO_PCBC is not set -# CONFIG_CRYPTO_XTS is not set - -# -# Hash modes -# -# CONFIG_CRYPTO_HMAC is not set -# CONFIG_CRYPTO_XCBC is not set - -# -# Digest -# -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_MD4 is not set -# CONFIG_CRYPTO_MD5 is not set -# CONFIG_CRYPTO_MICHAEL_MIC is not set -# CONFIG_CRYPTO_SHA1 is not set -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_TGR192 is not set -# CONFIG_CRYPTO_WP512 is not set - -# -# Ciphers -# -# CONFIG_CRYPTO_AES is not set -# CONFIG_CRYPTO_ANUBIS is not set -# CONFIG_CRYPTO_ARC4 is not set -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_CAMELLIA is not set -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_DES is not set -# CONFIG_CRYPTO_FCRYPT is not set -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_SALSA20 is not set -# CONFIG_CRYPTO_SEED is not set -# CONFIG_CRYPTO_SERPENT is not set -# CONFIG_CRYPTO_TEA is not set -# CONFIG_CRYPTO_TWOFISH is not set - -# -# Compression -# -CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_LZO=y -# CONFIG_CRYPTO_HW is not set +# CONFIG_CRYPTO is not set # # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set -CONFIG_CRC_CCITT=y -CONFIG_CRC16=y -CONFIG_CRC_ITU_T=y +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +# CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y -CONFIG_CRC7=y -CONFIG_LIBCRC32C=y -CONFIG_AUDIT_GENERIC=y +# CONFIG_CRC7 is not set +# CONFIG_LIBCRC32C is not set CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -CONFIG_LZO_COMPRESS=y -CONFIG_LZO_DECOMPRESS=y -CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y diff --git a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c index 79baa47af977..de45c6a3e33b 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc-sh5.c @@ -242,7 +242,6 @@ void __init plat_irq_setup(void) reg += 8; } } - } #endif /* diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index a0470f2f5479..566ce79b9abf 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -16,21 +16,6 @@ static struct plat_sci_port sci_platform_data[] = { { - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 80, 80, 80, 80 }, - },{ - .mapbase = 0xffe10000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 81, 81, 81, 81 }, - },{ - .mapbase = 0xffe20000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 82, 82, 82, 82 }, - },{ .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCI, @@ -88,35 +73,9 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct resource sh7723_usb_host_resources[] = { - [0] = { - .name = "r8a66597_hcd", - .start = 0xa4d80000, - .end = 0xa4d800ff, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = 65, - .end = 65, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct platform_device sh7723_usb_host_device = { - .name = "r8a66597_hcd", - .id = 0, - .dev = { - .dma_mask = NULL, /* not use dma */ - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(sh7723_usb_host_resources), - .resource = sh7723_usb_host_resources, -}; - static struct platform_device *sh7723_devices[] __initdata = { &sci_device, &rtc_device, - &sh7723_usb_host_device, }; static int __init sh7723_devices_setup(void) diff --git a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index f189a559462b..ae2b22219f02 100644 --- a/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/trunk/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -291,9 +291,8 @@ static struct intc_sense_reg irq_sense_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_irq_desc, "sh7763-irq", irq_vectors, - NULL, irq_mask_registers, irq_prio_registers, - irq_sense_registers); - + NULL, NULL, irq_mask_registers, irq_prio_registers, + irq_sense_registers); /* External interrupt pins in IRL mode */ static struct intc_vect irl_vectors[] __initdata = { @@ -325,10 +324,10 @@ static struct intc_mask_reg irl7654_mask_registers[] __initdata = { }; static DECLARE_INTC_DESC(intc_irl7654_desc, "sh7763-irl7654", irl_vectors, - NULL, irl7654_mask_registers, NULL, NULL); + NULL, NULL, irl7654_mask_registers, NULL, NULL); static DECLARE_INTC_DESC(intc_irl3210_desc, "sh7763-irl3210", irl_vectors, - NULL, irl3210_mask_registers, NULL, NULL); + NULL, NULL, irl3210_mask_registers, NULL, NULL); #define INTC_ICR0 0xffd00000 #define INTC_INTMSK0 0xffd00044 diff --git a/trunk/arch/sh/kernel/module.c b/trunk/arch/sh/kernel/module.c index 5482e65375a9..b3d0a03b4c76 100644 --- a/trunk/arch/sh/kernel/module.c +++ b/trunk/arch/sh/kernel/module.c @@ -30,7 +30,6 @@ #include #include #include -#include void *module_alloc(unsigned long size) { @@ -57,6 +56,34 @@ int module_frob_arch_sections(Elf_Ehdr *hdr, return 0; } +#ifdef CONFIG_SUPERH32 +#define COPY_UNALIGNED_WORD(sw, tw, align) \ +{ \ + void *__s = &(sw), *__t = &(tw); \ + unsigned short *__s2 = __s, *__t2 = __t; \ + unsigned char *__s1 = __s, *__t1 = __t; \ + switch ((align)) \ + { \ + case 0: \ + *(unsigned long *) __t = *(unsigned long *) __s; \ + break; \ + case 2: \ + *__t2++ = *__s2++; \ + *__t2 = *__s2; \ + break; \ + default: \ + *__t1++ = *__s1++; \ + *__t1++ = *__s1++; \ + *__t1++ = *__s1++; \ + *__t1 = *__s1; \ + break; \ + } \ +} +#else +/* One thing SHmedia doesn't screw up! */ +#define COPY_UNALIGNED_WORD(sw, tw, align) { (tw) = (sw); } +#endif + int apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex, @@ -69,6 +96,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, Elf32_Addr relocation; uint32_t *location; uint32_t value; + int align; pr_debug("Applying relocate section %u to %u\n", relsec, sechdrs[relsec].sh_info); @@ -81,6 +109,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, sym = (Elf32_Sym *)sechdrs[symindex].sh_addr + ELF32_R_SYM(rel[i].r_info); relocation = sym->st_value + rel[i].r_addend; + align = (int)location & 3; #ifdef CONFIG_SUPERH64 /* For text addresses, bit2 of the st_other field indicates @@ -93,15 +122,15 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, switch (ELF32_R_TYPE(rel[i].r_info)) { case R_SH_DIR32: - value = get_unaligned(location); + COPY_UNALIGNED_WORD (*location, value, align); value += relocation; - put_unaligned(value, location); + COPY_UNALIGNED_WORD (value, *location, align); break; case R_SH_REL32: relocation = (relocation - (Elf32_Addr) location); - value = get_unaligned(location); + COPY_UNALIGNED_WORD (*location, value, align); value += relocation; - put_unaligned(value, location); + COPY_UNALIGNED_WORD (value, *location, align); break; case R_SH_IMM_LOW16: *location = (*location & ~0x3fffc00) | diff --git a/trunk/arch/sparc/kernel/led.c b/trunk/arch/sparc/kernel/led.c index adaaed4ea2fb..59e9344e7a0d 100644 --- a/trunk/arch/sparc/kernel/led.c +++ b/trunk/arch/sparc/kernel/led.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -46,22 +45,21 @@ static void led_blink(unsigned long timeout) add_timer(&led_blink_timer); } -static int led_proc_show(struct seq_file *m, void *v) +static int led_read_proc(char *buf, char **start, off_t offset, int count, + int *eof, void *data) { + int len = 0; + if (get_auxio() & AUXIO_LED) - seq_puts(m, "on\n"); + len = sprintf(buf, "on\n"); else - seq_puts(m, "off\n"); - return 0; -} + len = sprintf(buf, "off\n"); -static int led_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, led_proc_show, NULL); + return len; } -static ssize_t led_proc_write(struct file *file, const char __user *buffer, - size_t count, loff_t *ppos) +static int led_write_proc(struct file *file, const char __user *buffer, + unsigned long count, void *data) { char *buf = NULL; @@ -105,15 +103,6 @@ static ssize_t led_proc_write(struct file *file, const char __user *buffer, return count; } -static const struct file_operations led_proc_fops = { - .owner = THIS_MODULE, - .open = led_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .write = led_proc_write, -}; - static struct proc_dir_entry *led; #define LED_VERSION "0.1" @@ -123,9 +112,12 @@ static int __init led_init(void) init_timer(&led_blink_timer); led_blink_timer.function = led_blink; - led = proc_create("led", 0, NULL, &led_proc_fops); + led = create_proc_entry("led", 0, NULL); if (!led) return -ENOMEM; + + led->read_proc = led_read_proc; /* reader function */ + led->write_proc = led_write_proc; /* writer function */ led->owner = THIS_MODULE; printk(KERN_INFO diff --git a/trunk/arch/um/drivers/ubd_kern.c b/trunk/arch/um/drivers/ubd_kern.c index b58fb8941d8d..44ad1607be2d 100644 --- a/trunk/arch/um/drivers/ubd_kern.c +++ b/trunk/arch/um/drivers/ubd_kern.c @@ -49,6 +49,7 @@ #include "irq_user.h" #include "irq_kern.h" #include "ubd_user.h" +#include "kern_util.h" #include "os.h" #include "mem.h" #include "mem_kern.h" diff --git a/trunk/arch/um/include/os.h b/trunk/arch/um/include/os.h index db5be46e3e18..e2716ac8889a 100644 --- a/trunk/arch/um/include/os.h +++ b/trunk/arch/um/include/os.h @@ -299,6 +299,6 @@ extern int os_arch_prctl(int pid, int code, unsigned long *addr); extern int get_pty(void); /* sys-$ARCH/task_size.c */ -extern unsigned long os_get_top_address(void); +extern unsigned long os_get_task_size(void); #endif diff --git a/trunk/arch/um/kernel/um_arch.c b/trunk/arch/um/kernel/um_arch.c index 8d84250324b3..9db85b2ce698 100644 --- a/trunk/arch/um/kernel/um_arch.c +++ b/trunk/arch/um/kernel/um_arch.c @@ -274,7 +274,7 @@ int __init linux_main(int argc, char **argv) if (have_root == 0) add_arg(DEFAULT_COMMAND_LINE); - host_task_size = os_get_top_address(); + host_task_size = os_get_task_size(); /* * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps * out diff --git a/trunk/arch/um/os-Linux/helper.c b/trunk/arch/um/os-Linux/helper.c index 30860b89ec58..74ca7aabf4e1 100644 --- a/trunk/arch/um/os-Linux/helper.c +++ b/trunk/arch/um/os-Linux/helper.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include "kern_constants.h" diff --git a/trunk/arch/um/os-Linux/skas/process.c b/trunk/arch/um/os-Linux/skas/process.c index 172ad8f72e12..6be028ca1817 100644 --- a/trunk/arch/um/os-Linux/skas/process.c +++ b/trunk/arch/um/os-Linux/skas/process.c @@ -55,7 +55,7 @@ static int ptrace_dump_regs(int pid) * Signals that are OK to receive in the stub - we'll just continue it. * SIGWINCH will happen when UML is inside a detached screen. */ -#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH)) +#define STUB_SIG_MASK (1 << SIGVTALRM) /* Signals that the stub will finish with - anything else is an error */ #define STUB_DONE_MASK (1 << SIGTRAP) diff --git a/trunk/arch/um/os-Linux/start_up.c b/trunk/arch/um/os-Linux/start_up.c index 183db26d01bf..b4b36e0f2e89 100644 --- a/trunk/arch/um/os-Linux/start_up.c +++ b/trunk/arch/um/os-Linux/start_up.c @@ -121,10 +121,8 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit) { int status, n, ret = 0; - if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) { - perror("stop_ptraced_child : ptrace failed"); - return -1; - } + if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) + fatal_perror("stop_ptraced_child : ptrace failed"); CATCH_EINTR(n = waitpid(pid, &status, 0)); if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { int exit_with = WEXITSTATUS(status); @@ -214,7 +212,7 @@ static void __init check_sysemu(void) if (n < 0) fatal_perror("check_sysemu : wait failed"); if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) - fatal("check_sysemu : expected SIGTRAP, got status = %d\n", + fatal("check_sysemu : expected SIGTRAP, got status = %d", status); if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) @@ -256,11 +254,9 @@ static void __init check_sysemu(void) if (WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))) { - if (!count) { - non_fatal("check_ptrace : SYSEMU_SINGLESTEP " - "doesn't singlestep"); - goto fail; - } + if (!count) + fatal("check_ptrace : SYSEMU_SINGLESTEP " + "doesn't singlestep"); n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); if (n < 0) @@ -270,12 +266,9 @@ static void __init check_sysemu(void) } else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) count++; - else { - non_fatal("check_ptrace : expected SIGTRAP or " - "(SIGTRAP | 0x80), got status = %d\n", - status); - goto fail; - } + else + fatal("check_ptrace : expected SIGTRAP or " + "(SIGTRAP | 0x80), got status = %d", status); } if (stop_ptraced_child(pid, 0, 0) < 0) goto fail_stopped; diff --git a/trunk/arch/um/os-Linux/sys-i386/registers.c b/trunk/arch/um/os-Linux/sys-i386/registers.c index 229f7a53d8da..b487cbead1bd 100644 --- a/trunk/arch/um/os-Linux/sys-i386/registers.c +++ b/trunk/arch/um/os-Linux/sys-i386/registers.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include "kern_constants.h" #include "longjmp.h" #include "user.h" @@ -76,7 +76,7 @@ int put_fp_registers(int pid, unsigned long *regs) void arch_init_registers(int pid) { - struct user_fpxregs_struct fpx_regs; + struct user_fxsr_struct fpx_regs; int err; err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs); diff --git a/trunk/arch/um/os-Linux/sys-i386/task_size.c b/trunk/arch/um/os-Linux/sys-i386/task_size.c index be04c1e183bf..ccb49b0aff59 100644 --- a/trunk/arch/um/os-Linux/sys-i386/task_size.c +++ b/trunk/arch/um/os-Linux/sys-i386/task_size.c @@ -63,7 +63,7 @@ static int page_ok(unsigned long page) return ok; } -unsigned long os_get_top_address(void) +unsigned long os_get_task_size(void) { struct sigaction sa, old; unsigned long bottom = 0; @@ -76,9 +76,9 @@ unsigned long os_get_top_address(void) * hosts, but shouldn't hurt otherwise. */ unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT; - unsigned long test, original; + unsigned long test; - printf("Locating the bottom of the address space ... "); + printf("Locating the top of the address space ... "); fflush(stdout); /* @@ -89,31 +89,16 @@ unsigned long os_get_top_address(void) sigemptyset(&sa.sa_mask); sa.sa_flags = SA_NODEFER; if (sigaction(SIGSEGV, &sa, &old)) { - perror("os_get_top_address"); + perror("os_get_task_size"); exit(1); } - /* Manually scan the address space, bottom-up, until we find - * the first valid page (or run out of them). - */ - for (bottom = 0; bottom < top; bottom++) { - if (page_ok(bottom)) - break; - } - - /* If we've got this far, we ran out of pages. */ - if (bottom == top) { - fprintf(stderr, "Unable to determine bottom of address " - "space.\n"); + if (!page_ok(bottom)) { + fprintf(stderr, "Address 0x%x no good?\n", + bottom << UM_KERN_PAGE_SHIFT); exit(1); } - printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT); - printf("Locating the top of the address space ... "); - fflush(stdout); - - original = bottom; - /* This could happen with a 4G/4G split */ if (page_ok(top)) goto out; @@ -129,7 +114,7 @@ unsigned long os_get_top_address(void) out: /* Restore the old SIGSEGV handling */ if (sigaction(SIGSEGV, &old, NULL)) { - perror("os_get_top_address"); + perror("os_get_task_size"); exit(1); } top <<= UM_KERN_PAGE_SHIFT; diff --git a/trunk/arch/um/os-Linux/sys-x86_64/task_size.c b/trunk/arch/um/os-Linux/sys-x86_64/task_size.c index 26a0dd1f349c..fad6f57f8ee3 100644 --- a/trunk/arch/um/os-Linux/sys-x86_64/task_size.c +++ b/trunk/arch/um/os-Linux/sys-x86_64/task_size.c @@ -1,4 +1,4 @@ -unsigned long os_get_top_address(unsigned long shift) +unsigned long os_get_task_size(unsigned long shift) { /* The old value of CONFIG_TOP_ADDR */ return 0x7fc0000000; diff --git a/trunk/arch/um/os-Linux/time.c b/trunk/arch/um/os-Linux/time.c index dec5678fc17f..bee98f466d66 100644 --- a/trunk/arch/um/os-Linux/time.c +++ b/trunk/arch/um/os-Linux/time.c @@ -106,10 +106,6 @@ static void deliver_alarm(void) unsigned long long this_tick = os_nsecs(); int one_tick = UM_NSEC_PER_SEC / UM_HZ; - /* Protection against the host's time going backwards */ - if ((last_tick != 0) && (this_tick < last_tick)) - this_tick = last_tick; - if (last_tick == 0) last_tick = this_tick - one_tick; @@ -152,9 +148,6 @@ static int after_sleep_interval(struct timespec *ts) start_usecs = usec; start_usecs -= skew / UM_NSEC_PER_USEC; - if (start_usecs < 0) - start_usecs = 0; - tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC, .tv_usec = start_usecs % UM_USEC_PER_SEC }); interval = ((struct itimerval) { { 0, usec }, tv }); diff --git a/trunk/arch/um/sys-x86_64/ksyms.c b/trunk/arch/um/sys-x86_64/ksyms.c index 1db2fce00948..6604673a849d 100644 --- a/trunk/arch/um/sys-x86_64/ksyms.c +++ b/trunk/arch/um/sys-x86_64/ksyms.c @@ -3,9 +3,5 @@ #include /*XXX: we need them because they would be exported by x86_64 */ -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 -EXPORT_SYMBOL(memcpy); -#else EXPORT_SYMBOL(__memcpy); -#endif EXPORT_SYMBOL(csum_partial); diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 52e18e6d2ba0..dcbec34154cf 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -1508,13 +1508,13 @@ config PCI_GOMMCONFIG config PCI_GODIRECT bool "Direct" +config PCI_GOANY + bool "Any" + config PCI_GOOLPC bool "OLPC" depends on OLPC -config PCI_GOANY - bool "Any" - endchoice config PCI_BIOS @@ -1531,8 +1531,9 @@ config PCI_MMCONFIG depends on X86_32 && PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY) config PCI_OLPC - def_bool y - depends on PCI && OLPC && (PCI_GOOLPC || PCI_GOANY) + bool + depends on PCI && PCI_GOOLPC + default y config PCI_DOMAINS def_bool y diff --git a/trunk/arch/x86/Kconfig.debug b/trunk/arch/x86/Kconfig.debug index 18363374d51a..ac1e31ba4795 100644 --- a/trunk/arch/x86/Kconfig.debug +++ b/trunk/arch/x86/Kconfig.debug @@ -6,19 +6,15 @@ config TRACE_IRQFLAGS_SUPPORT source "lib/Kconfig.debug" config NONPROMISC_DEVMEM - bool "Filter access to /dev/mem" + bool "Disable promiscuous /dev/mem" help - If this option is left off, you allow userspace access to all - of memory, including kernel and userspace memory. Accidental - access to this is obviously disastrous, but specific access can - be used by people debugging the kernel. - - If this option is switched on, the /dev/mem file only allows - userspace access to PCI space and the BIOS code and data regions. - This is sufficient for dosemu and X and all common users of - /dev/mem. - - If in doubt, say Y. + The /dev/mem file by default only allows userspace access to PCI + space and the BIOS code and data regions. This is sufficient for + dosemu and X and all common users of /dev/mem. With this config + option, you allow userspace access to all of memory, including + kernel and userspace memory. Accidental access to this is + obviously disasterous, but specific access can be used by people + debugging the kernel. config EARLY_PRINTK bool "Early printk" if EMBEDDED diff --git a/trunk/arch/x86/boot/a20.c b/trunk/arch/x86/boot/a20.c index e01aafd03bde..90943f83e84d 100644 --- a/trunk/arch/x86/boot/a20.c +++ b/trunk/arch/x86/boot/a20.c @@ -115,6 +115,8 @@ static void enable_a20_fast(void) int enable_a20(void) { + int loops = A20_ENABLE_LOOPS; + #if defined(CONFIG_X86_ELAN) /* Elan croaks if we try to touch the KBC */ enable_a20_fast(); @@ -126,7 +128,6 @@ int enable_a20(void) enable_a20_kbc(); return 0; #else - int loops = A20_ENABLE_LOOPS; while (loops--) { /* First, check to see if A20 is already enabled (legacy free, etc.) */ diff --git a/trunk/arch/x86/kernel/acpi/boot.c b/trunk/arch/x86/kernel/acpi/boot.c index 33c5216fd3e1..c49ebcc6c41e 100644 --- a/trunk/arch/x86/kernel/acpi/boot.c +++ b/trunk/arch/x86/kernel/acpi/boot.c @@ -242,19 +242,12 @@ static int __init acpi_parse_madt(struct acpi_table_header *table) static void __cpuinit acpi_register_lapic(int id, u8 enabled) { - unsigned int ver = 0; - if (!enabled) { ++disabled_cpus; return; } -#ifdef CONFIG_X86_32 - if (boot_cpu_physical_apicid != -1U) - ver = apic_version[boot_cpu_physical_apicid]; -#endif - - generic_processor_info(id, ver); + generic_processor_info(id, 0); } static int __init @@ -774,13 +767,8 @@ static void __init acpi_register_lapic_address(unsigned long address) mp_lapic_addr = address; set_fixmap_nocache(FIX_APIC_BASE, address); - if (boot_cpu_physical_apicid == -1U) { + if (boot_cpu_physical_apicid == -1U) boot_cpu_physical_apicid = GET_APIC_ID(read_apic_id()); -#ifdef CONFIG_X86_32 - apic_version[boot_cpu_physical_apicid] = - GET_APIC_VERSION(apic_read(APIC_LVR)); -#endif - } } static int __init early_acpi_parse_madt_lapic_addr_ovr(void) diff --git a/trunk/arch/x86/kernel/entry_32.S b/trunk/arch/x86/kernel/entry_32.S index c778e4fa55a2..2a609dc3271c 100644 --- a/trunk/arch/x86/kernel/entry_32.S +++ b/trunk/arch/x86/kernel/entry_32.S @@ -248,7 +248,6 @@ ENTRY(resume_userspace) DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret - TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx andl $_TIF_WORK_MASK, %ecx # is there any work to be done on # int/exception return? diff --git a/trunk/arch/x86/kernel/head_32.S b/trunk/arch/x86/kernel/head_32.S index f7357cc0162c..b2cc73768a9d 100644 --- a/trunk/arch/x86/kernel/head_32.S +++ b/trunk/arch/x86/kernel/head_32.S @@ -189,7 +189,7 @@ default_entry: * this stage. */ -#define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ +#define KPMDS ((0x100000000-__PAGE_OFFSET) >> 30) /* Number of kernel PMDs */ xorl %ebx,%ebx /* %ebx is kept at zero */ diff --git a/trunk/arch/x86/kernel/i387.c b/trunk/arch/x86/kernel/i387.c index eb9ddd8efb82..e03cc952f233 100644 --- a/trunk/arch/x86/kernel/i387.c +++ b/trunk/arch/x86/kernel/i387.c @@ -56,11 +56,6 @@ void __cpuinit mxcsr_feature_mask_init(void) void __init init_thread_xstate(void) { - if (!HAVE_HWFP) { - xstate_size = sizeof(struct i387_soft_struct); - return; - } - if (cpu_has_fxsr) xstate_size = sizeof(struct i387_fxsave_struct); #ifdef CONFIG_X86_32 @@ -99,7 +94,7 @@ void __cpuinit fpu_init(void) int init_fpu(struct task_struct *tsk) { if (tsk_used_math(tsk)) { - if (HAVE_HWFP && tsk == current) + if (tsk == current) unlazy_fpu(tsk); return 0; } @@ -114,15 +109,6 @@ int init_fpu(struct task_struct *tsk) return -ENOMEM; } -#ifdef CONFIG_X86_32 - if (!HAVE_HWFP) { - memset(tsk->thread.xstate, 0, xstate_size); - finit(); - set_stopped_child_used_math(tsk); - return 0; - } -#endif - if (cpu_has_fxsr) { struct i387_fxsave_struct *fx = &tsk->thread.xstate->fxsave; @@ -344,13 +330,13 @@ int fpregs_get(struct task_struct *target, const struct user_regset *regset, struct user_i387_ia32_struct env; int ret; + if (!HAVE_HWFP) + return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); + ret = init_fpu(target); if (ret) return ret; - if (!HAVE_HWFP) - return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); - if (!cpu_has_fxsr) { return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &target->thread.xstate->fsave, 0, @@ -374,15 +360,15 @@ int fpregs_set(struct task_struct *target, const struct user_regset *regset, struct user_i387_ia32_struct env; int ret; + if (!HAVE_HWFP) + return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf); + ret = init_fpu(target); if (ret) return ret; set_stopped_child_used_math(target); - if (!HAVE_HWFP) - return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf); - if (!cpu_has_fxsr) { return user_regset_copyin(&pos, &count, &kbuf, &ubuf, &target->thread.xstate->fsave, 0, -1); @@ -488,18 +474,18 @@ static int restore_i387_fxsave(struct _fpstate_ia32 __user *buf) int restore_i387_ia32(struct _fpstate_ia32 __user *buf) { int err; - struct task_struct *tsk = current; - if (HAVE_HWFP) + if (HAVE_HWFP) { + struct task_struct *tsk = current; + clear_fpu(tsk); - if (!used_math()) { - err = init_fpu(tsk); - if (err) - return err; - } + if (!used_math()) { + err = init_fpu(tsk); + if (err) + return err; + } - if (HAVE_HWFP) { if (cpu_has_fxsr) err = restore_i387_fxsave(buf); else diff --git a/trunk/arch/x86/kernel/io_apic_32.c b/trunk/arch/x86/kernel/io_apic_32.c index 4dc8600d9d20..a40d54fc1fdd 100644 --- a/trunk/arch/x86/kernel/io_apic_32.c +++ b/trunk/arch/x86/kernel/io_apic_32.c @@ -2130,10 +2130,14 @@ static inline void __init check_timer(void) { int apic1, pin1, apic2, pin2; int vector; + unsigned int ver; unsigned long flags; local_irq_save(flags); + ver = apic_read(APIC_LVR); + ver = GET_APIC_VERSION(ver); + /* * get/set the timer IRQ vector: */ @@ -2146,11 +2150,15 @@ static inline void __init check_timer(void) * mode for the 8259A whenever interrupts are routed * through I/O APICs. Also IRQ0 has to be enabled in * the 8259A which implies the virtual wire has to be - * disabled in the local APIC. + * disabled in the local APIC. Finally timer interrupts + * need to be acknowledged manually in the 8259A for + * timer_interrupt() and for the i82489DX when using + * the NMI watchdog. */ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); init_8259A(1); - timer_ack = 1; + timer_ack = !cpu_has_tsc; + timer_ack |= (nmi_watchdog == NMI_IO_APIC && !APIC_INTEGRATED(ver)); if (timer_over_8254 > 0) enable_8259A_irq(0); diff --git a/trunk/arch/x86/kernel/mfgpt_32.c b/trunk/arch/x86/kernel/mfgpt_32.c index 07c0f828f488..3cad17fe026b 100644 --- a/trunk/arch/x86/kernel/mfgpt_32.c +++ b/trunk/arch/x86/kernel/mfgpt_32.c @@ -155,7 +155,6 @@ int geode_mfgpt_toggle_event(int timer, int cmp, int event, int enable) wrmsr(msr, value, dummy); return 0; } -EXPORT_SYMBOL_GPL(geode_mfgpt_toggle_event); int geode_mfgpt_set_irq(int timer, int cmp, int irq, int enable) { @@ -223,7 +222,6 @@ int geode_mfgpt_alloc_timer(int timer, int domain) /* No timers available - too bad */ return -1; } -EXPORT_SYMBOL_GPL(geode_mfgpt_alloc_timer); #ifdef CONFIG_GEODE_MFGPT_TIMER diff --git a/trunk/arch/x86/kernel/nmi_32.c b/trunk/arch/x86/kernel/nmi_32.c index 84160f74eeb0..11b14bbaa61e 100644 --- a/trunk/arch/x86/kernel/nmi_32.c +++ b/trunk/arch/x86/kernel/nmi_32.c @@ -26,6 +26,7 @@ #include #include +#include #include "mach_traps.h" @@ -81,7 +82,7 @@ int __init check_nmi_watchdog(void) prev_nmi_count = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); if (!prev_nmi_count) - return -1; + goto error; printk(KERN_INFO "Testing NMI watchdog ... "); @@ -118,7 +119,7 @@ int __init check_nmi_watchdog(void) if (!atomic_read(&nmi_active)) { kfree(prev_nmi_count); atomic_set(&nmi_active, -1); - return -1; + goto error; } printk("OK.\n"); @@ -129,6 +130,10 @@ int __init check_nmi_watchdog(void) kfree(prev_nmi_count); return 0; +error: + timer_ack = !cpu_has_tsc; + + return -1; } static int __init setup_nmi_watchdog(char *str) diff --git a/trunk/arch/x86/kernel/pci-gart_64.c b/trunk/arch/x86/kernel/pci-gart_64.c index aa8ec928caa8..c07455d1695f 100644 --- a/trunk/arch/x86/kernel/pci-gart_64.c +++ b/trunk/arch/x86/kernel/pci-gart_64.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -549,28 +548,6 @@ static __init unsigned read_aperture(struct pci_dev *dev, u32 *size) return aper_base; } -static int gart_resume(struct sys_device *dev) -{ - return 0; -} - -static int gart_suspend(struct sys_device *dev, pm_message_t state) -{ - return -EINVAL; -} - -static struct sysdev_class gart_sysdev_class = { - .name = "gart", - .suspend = gart_suspend, - .resume = gart_resume, - -}; - -static struct sys_device device_gart = { - .id = 0, - .cls = &gart_sysdev_class, -}; - /* * Private Northbridge GATT initialization in case we cannot use the * AGP driver for some reason. @@ -581,7 +558,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info) unsigned aper_base, new_aper_base; struct pci_dev *dev; void *gatt; - int i, error; + int i; printk(KERN_INFO "PCI-DMA: Disabling AGP.\n"); aper_size = aper_base = info->aper_size = 0; @@ -629,12 +606,6 @@ static __init int init_k8_gatt(struct agp_kern_info *info) pci_write_config_dword(dev, 0x90, ctl); } - - error = sysdev_class_register(&gart_sysdev_class); - if (!error) - error = sysdev_register(&device_gart); - if (error) - panic("Could not register gart_sysdev -- would corrupt data on next suspend"); flush_gart(); printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n", diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index 6d5483356e74..f8476dfbb60d 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -649,11 +649,8 @@ struct task_struct * __switch_to(struct task_struct *prev_p, struct task_struct /* If the task has used fpu the last 5 timeslices, just do a full * restore of the math state immediately to avoid the trap; the * chances of needing FPU soon are obviously high now - * - * tsk_used_math() checks prevent calling math_state_restore(), - * which can sleep in the case of !tsk_used_math() */ - if (tsk_used_math(next_p) && next_p->fpu_counter > 5) + if (next_p->fpu_counter > 5) math_state_restore(); /* diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index ac54ff56df80..e2319f39988b 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -658,11 +658,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) /* If the task has used fpu the last 5 timeslices, just do a full * restore of the math state immediately to avoid the trap; the * chances of needing FPU soon are obviously high now - * - * tsk_used_math() checks prevent calling math_state_restore(), - * which can sleep in the case of !tsk_used_math() */ - if (tsk_used_math(next_p) && next_p->fpu_counter > 5) + if (next_p->fpu_counter>5) math_state_restore(); return prev_p; } diff --git a/trunk/arch/x86/kernel/rtc.c b/trunk/arch/x86/kernel/rtc.c index 05191bbc68b8..9615eee9b775 100644 --- a/trunk/arch/x86/kernel/rtc.c +++ b/trunk/arch/x86/kernel/rtc.c @@ -4,8 +4,6 @@ #include #include #include -#include -#include #include #include @@ -199,35 +197,3 @@ unsigned long long native_read_tsc(void) } EXPORT_SYMBOL(native_read_tsc); - -static struct resource rtc_resources[] = { - [0] = { - .start = RTC_PORT(0), - .end = RTC_PORT(1), - .flags = IORESOURCE_IO, - }, - [1] = { - .start = RTC_IRQ, - .end = RTC_IRQ, - .flags = IORESOURCE_IRQ, - } -}; - -static struct platform_device rtc_device = { - .name = "rtc_cmos", - .id = -1, - .resource = rtc_resources, - .num_resources = ARRAY_SIZE(rtc_resources), -}; - -static __init int add_rtc_cmos(void) -{ -#ifdef CONFIG_PNP - if (!pnp_platform_devices) - platform_device_register(&rtc_device); -#else - platform_device_register(&rtc_device); -#endif /* CONFIG_PNP */ - return 0; -} -device_initcall(add_rtc_cmos); diff --git a/trunk/arch/x86/kernel/smpboot.c b/trunk/arch/x86/kernel/smpboot.c index 56078d61c793..38988491c622 100644 --- a/trunk/arch/x86/kernel/smpboot.c +++ b/trunk/arch/x86/kernel/smpboot.c @@ -1190,7 +1190,6 @@ static void __init smp_cpu_index_default(void) */ void __init native_smp_prepare_cpus(unsigned int max_cpus) { - preempt_disable(); nmi_watchdog_default(); smp_cpu_index_default(); current_cpu_data = boot_cpu_data; @@ -1207,7 +1206,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) if (smp_sanity_check(max_cpus) < 0) { printk(KERN_INFO "SMP disabled\n"); disable_smp(); - goto out; + return; } preempt_disable(); @@ -1247,8 +1246,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) printk(KERN_INFO "CPU%d: ", 0); print_cpu_info(&cpu_data(0)); setup_boot_clock(); -out: - preempt_enable(); } /* * Early setup to make printk work. diff --git a/trunk/arch/x86/kernel/traps_32.c b/trunk/arch/x86/kernel/traps_32.c index 08d752de4eee..bde6f63e15d5 100644 --- a/trunk/arch/x86/kernel/traps_32.c +++ b/trunk/arch/x86/kernel/traps_32.c @@ -544,7 +544,6 @@ do_trap(int trapnr, int signr, char *str, int vm86, struct pt_regs *regs, #define DO_ERROR(trapnr, signr, str, name) \ void do_##name(struct pt_regs *regs, long error_code) \ { \ - trace_hardirqs_fixup(); \ if (notify_die(DIE_TRAP, str, regs, error_code, trapnr, signr) \ == NOTIFY_STOP) \ return; \ diff --git a/trunk/arch/x86/kvm/i8254.c b/trunk/arch/x86/kvm/i8254.c index f2f5d260874e..7c077a9d9777 100644 --- a/trunk/arch/x86/kvm/i8254.c +++ b/trunk/arch/x86/kvm/i8254.c @@ -200,6 +200,7 @@ int __pit_timer_fn(struct kvm_kpit_state *ps) atomic_inc(&pt->pending); smp_mb__after_atomic_inc(); + /* FIXME: handle case where the guest is in guest mode */ if (vcpu0 && waitqueue_active(&vcpu0->wq)) { vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE; wake_up_interruptible(&vcpu0->wq); @@ -236,19 +237,6 @@ static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) return HRTIMER_NORESTART; } -void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) -{ - struct kvm_pit *pit = vcpu->kvm->arch.vpit; - struct hrtimer *timer; - - if (vcpu->vcpu_id != 0 || !pit) - return; - - timer = &pit->pit_state.pit_timer.timer; - if (hrtimer_cancel(timer)) - hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); -} - static void destroy_pit_timer(struct kvm_kpit_timer *pt) { pr_debug("pit: execute del timer!\n"); diff --git a/trunk/arch/x86/kvm/irq.c b/trunk/arch/x86/kvm/irq.c index 76d736b5f664..ce1f583459b1 100644 --- a/trunk/arch/x86/kvm/irq.c +++ b/trunk/arch/x86/kvm/irq.c @@ -94,9 +94,3 @@ void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec) /* TODO: PIT, RTC etc. */ } EXPORT_SYMBOL_GPL(kvm_timer_intr_post); - -void __kvm_migrate_timers(struct kvm_vcpu *vcpu) -{ - __kvm_migrate_apic_timer(vcpu); - __kvm_migrate_pit_timer(vcpu); -} diff --git a/trunk/arch/x86/kvm/irq.h b/trunk/arch/x86/kvm/irq.h index 2a15be2275c0..1802134b836f 100644 --- a/trunk/arch/x86/kvm/irq.h +++ b/trunk/arch/x86/kvm/irq.h @@ -84,8 +84,6 @@ void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); -void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu); -void __kvm_migrate_timers(struct kvm_vcpu *vcpu); int pit_has_pending_timer(struct kvm_vcpu *vcpu); int apic_has_pending_timer(struct kvm_vcpu *vcpu); diff --git a/trunk/arch/x86/kvm/mmu.c b/trunk/arch/x86/kvm/mmu.c index ee3f53098f0c..7246b60afb96 100644 --- a/trunk/arch/x86/kvm/mmu.c +++ b/trunk/arch/x86/kvm/mmu.c @@ -658,7 +658,7 @@ static int is_empty_shadow_page(u64 *spt) u64 *end; for (pos = spt, end = pos + PAGE_SIZE / sizeof(u64); pos != end; pos++) - if (is_shadow_present_pte(*pos)) { + if (*pos != shadow_trap_nonpresent_pte) { printk(KERN_ERR "%s: %p %llx\n", __func__, pos, *pos); return 0; @@ -1858,7 +1858,6 @@ static void free_mmu_pages(struct kvm_vcpu *vcpu) sp = container_of(vcpu->kvm->arch.active_mmu_pages.next, struct kvm_mmu_page, link); kvm_mmu_zap_page(vcpu->kvm, sp); - cond_resched(); } free_page((unsigned long)vcpu->arch.mmu.pae_root); } diff --git a/trunk/arch/x86/kvm/paging_tmpl.h b/trunk/arch/x86/kvm/paging_tmpl.h index 934c7b619396..156fe10288ae 100644 --- a/trunk/arch/x86/kvm/paging_tmpl.h +++ b/trunk/arch/x86/kvm/paging_tmpl.h @@ -418,7 +418,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, /* mmio */ if (is_error_pfn(pfn)) { - pgprintk("gfn %lx is mmio\n", walker.gfn); + pgprintk("gfn %x is mmio\n", walker.gfn); kvm_release_pfn_clean(pfn); return 1; } diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index 6b0d5fa5bab3..ab22615eee89 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -688,7 +688,7 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) delta = vcpu->arch.host_tsc - tsc_this; svm->vmcb->control.tsc_offset += delta; vcpu->cpu = cpu; - kvm_migrate_timers(vcpu); + kvm_migrate_apic_timer(vcpu); } for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++) diff --git a/trunk/arch/x86/kvm/vmx.c b/trunk/arch/x86/kvm/vmx.c index 02efbe75f317..bfe4db11989c 100644 --- a/trunk/arch/x86/kvm/vmx.c +++ b/trunk/arch/x86/kvm/vmx.c @@ -608,7 +608,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu->cpu != cpu) { vcpu_clear(vmx); - kvm_migrate_timers(vcpu); + kvm_migrate_apic_timer(vcpu); vpid_sync_vcpu_all(vmx); } @@ -1036,7 +1036,6 @@ static void hardware_enable(void *garbage) static void hardware_disable(void *garbage) { asm volatile (ASM_VMX_VMXOFF : : : "cc"); - write_cr4(read_cr4() & ~X86_CR4_VMXE); } static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, diff --git a/trunk/arch/x86/kvm/x86.c b/trunk/arch/x86/kvm/x86.c index 00acf1301a15..21338bdb28ff 100644 --- a/trunk/arch/x86/kvm/x86.c +++ b/trunk/arch/x86/kvm/x86.c @@ -2758,7 +2758,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) if (vcpu->requests) { if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) - __kvm_migrate_timers(vcpu); + __kvm_migrate_apic_timer(vcpu); if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, &vcpu->requests)) { kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; diff --git a/trunk/arch/x86/kvm/x86_emulate.c b/trunk/arch/x86/kvm/x86_emulate.c index 932f216d890c..8a96320ab071 100644 --- a/trunk/arch/x86/kvm/x86_emulate.c +++ b/trunk/arch/x86/kvm/x86_emulate.c @@ -1727,8 +1727,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) if (rc) goto done; - /* Let the processor re-execute the fixed hypercall */ - c->eip = ctxt->vcpu->arch.rip; + kvm_emulate_hypercall(ctxt->vcpu); /* Disable writeback. */ c->dst.type = OP_NONE; break; diff --git a/trunk/arch/x86/lib/delay_32.c b/trunk/arch/x86/lib/delay_32.c index d710f2d167bb..4535e6d147ad 100644 --- a/trunk/arch/x86/lib/delay_32.c +++ b/trunk/arch/x86/lib/delay_32.c @@ -44,36 +44,13 @@ static void delay_loop(unsigned long loops) static void delay_tsc(unsigned long loops) { unsigned long bclock, now; - int cpu; - preempt_disable(); - cpu = smp_processor_id(); + preempt_disable(); /* TSC's are per-cpu */ rdtscl(bclock); - for (;;) { - rdtscl(now); - if ((now - bclock) >= loops) - break; - - /* Allow RT tasks to run */ - preempt_enable(); + do { rep_nop(); - preempt_disable(); - - /* - * It is possible that we moved to another CPU, and - * since TSC's are per-cpu we need to calculate - * that. The delay must guarantee that we wait "at - * least" the amount of time. Being moved to another - * CPU could make the wait longer but we just need to - * make sure we waited long enough. Rebalance the - * counter for this CPU. - */ - if (unlikely(cpu != smp_processor_id())) { - loops -= (now - bclock); - cpu = smp_processor_id(); - rdtscl(bclock); - } - } + rdtscl(now); + } while ((now-bclock) < loops); preempt_enable(); } diff --git a/trunk/arch/x86/lib/delay_64.c b/trunk/arch/x86/lib/delay_64.c index 4c441be92641..bbc610518516 100644 --- a/trunk/arch/x86/lib/delay_64.c +++ b/trunk/arch/x86/lib/delay_64.c @@ -31,36 +31,14 @@ int __devinit read_current_timer(unsigned long *timer_value) void __delay(unsigned long loops) { unsigned bclock, now; - int cpu; - preempt_disable(); - cpu = smp_processor_id(); + preempt_disable(); /* TSC's are pre-cpu */ rdtscl(bclock); - for (;;) { + do { + rep_nop(); rdtscl(now); - if ((now - bclock) >= loops) - break; - - /* Allow RT tasks to run */ - preempt_enable(); - rep_nop(); - preempt_disable(); - - /* - * It is possible that we moved to another CPU, and - * since TSC's are per-cpu we need to calculate - * that. The delay must guarantee that we wait "at - * least" the amount of time. Being moved to another - * CPU could make the wait longer but we just need to - * make sure we waited long enough. Rebalance the - * counter for this CPU. - */ - if (unlikely(cpu != smp_processor_id())) { - loops -= (now - bclock); - cpu = smp_processor_id(); - rdtscl(bclock); - } } + while ((now-bclock) < loops); preempt_enable(); } EXPORT_SYMBOL(__delay); diff --git a/trunk/arch/x86/math-emu/fpu_entry.c b/trunk/arch/x86/math-emu/fpu_entry.c index c7b06feb139b..6e38d877ea77 100644 --- a/trunk/arch/x86/math-emu/fpu_entry.c +++ b/trunk/arch/x86/math-emu/fpu_entry.c @@ -30,7 +30,6 @@ #include #include #include -#include #include "fpu_system.h" #include "fpu_emu.h" @@ -147,13 +146,6 @@ asmlinkage void math_emulate(long arg) unsigned long code_limit = 0; /* Initialized to stop compiler warnings */ struct desc_struct code_descriptor; - if (!used_math()) { - if (init_fpu(current)) { - do_group_exit(SIGKILL); - return; - } - } - #ifdef RE_ENTRANT_CHECKING if (emulating) { printk("ERROR: wm-FPU-emu is not RE-ENTRANT!\n"); @@ -161,6 +153,11 @@ asmlinkage void math_emulate(long arg) RE_ENTRANT_CHECK_ON; #endif /* RE_ENTRANT_CHECKING */ + if (!used_math()) { + finit(); + set_used_math(); + } + SETUP_DATA_AREA(arg); FPU_ORIG_EIP = FPU_EIP; diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 8bcb6f40ccb6..fd7e1798c75a 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -497,11 +497,6 @@ static int vmalloc_fault(unsigned long address) unsigned long pgd_paddr; pmd_t *pmd_k; pte_t *pte_k; - - /* Make sure we are in vmalloc area */ - if (!(address >= VMALLOC_START && address < VMALLOC_END)) - return -1; - /* * Synchronize this task's top level page-table * with the 'reference' page table. diff --git a/trunk/arch/x86/mm/init_64.c b/trunk/arch/x86/mm/init_64.c index 156e6d7b0e32..32ba13b0f818 100644 --- a/trunk/arch/x86/mm/init_64.c +++ b/trunk/arch/x86/mm/init_64.c @@ -206,7 +206,7 @@ void __init cleanup_highmap(void) pmd_t *last_pmd = pmd + PTRS_PER_PMD; for (; pmd < last_pmd; pmd++, vaddr += PMD_SIZE) { - if (pmd_none(*pmd)) + if (!pmd_present(*pmd)) continue; if (vaddr < (unsigned long) _text || vaddr > end) set_pmd(pmd, __pmd(0)); @@ -506,7 +506,7 @@ early_param("memtest", parse_memtest); static void __init early_memtest(unsigned long start, unsigned long end) { - u64 t_start, t_size; + unsigned long t_start, t_size; unsigned pattern; if (!memtest_pattern) @@ -525,7 +525,7 @@ static void __init early_memtest(unsigned long start, unsigned long end) if (t_start + t_size > end) t_size = end - t_start; - printk(KERN_CONT "\n %016llx - %016llx pattern %d", + printk(KERN_CONT "\n %016lx - %016lx pattern %d", t_start, t_start + t_size, pattern); memtest(t_start, t_size, pattern); diff --git a/trunk/arch/x86/mm/ioremap.c b/trunk/arch/x86/mm/ioremap.c index 2b2bb3f9b683..71bb3159031a 100644 --- a/trunk/arch/x86/mm/ioremap.c +++ b/trunk/arch/x86/mm/ioremap.c @@ -593,11 +593,10 @@ void __init early_iounmap(void *addr, unsigned long size) unsigned long offset; unsigned int nrpages; enum fixed_addresses idx; - int nesting; + unsigned int nesting; nesting = --early_ioremap_nested; - if (WARN_ON(nesting < 0)) - return; + WARN_ON(nesting < 0); if (early_ioremap_debug) { printk(KERN_INFO "early_iounmap(%p, %08lx) [%d]\n", addr, diff --git a/trunk/arch/x86/mm/pat.c b/trunk/arch/x86/mm/pat.c index 06b7a1c90fb8..de3a99812450 100644 --- a/trunk/arch/x86/mm/pat.c +++ b/trunk/arch/x86/mm/pat.c @@ -34,7 +34,7 @@ void __cpuinit pat_disable(char *reason) printk(KERN_INFO "%s\n", reason); } -static int __init nopat(char *str) +static int nopat(char *str) { pat_disable("PAT support disabled."); return 0; @@ -151,33 +151,32 @@ static int pat_x_mtrr_type(u64 start, u64 end, unsigned long prot, unsigned long pat_type; u8 mtrr_type; + mtrr_type = mtrr_type_lookup(start, end); + if (mtrr_type == 0xFF) { /* MTRR not enabled */ + *ret_prot = prot; + return 0; + } + if (mtrr_type == 0xFE) { /* MTRR match error */ + *ret_prot = _PAGE_CACHE_UC; + return -1; + } + if (mtrr_type != MTRR_TYPE_UNCACHABLE && + mtrr_type != MTRR_TYPE_WRBACK && + mtrr_type != MTRR_TYPE_WRCOMB) { /* MTRR type unhandled */ + *ret_prot = _PAGE_CACHE_UC; + return -1; + } + pat_type = prot & _PAGE_CACHE_MASK; prot &= (~_PAGE_CACHE_MASK); - /* - * We return the PAT request directly for types where PAT takes - * precedence with respect to MTRR and for UC_MINUS. - * Consistency checks with other PAT requests is done later - * while going through memtype list. - */ + /* Currently doing intersection by hand. Optimize it later. */ if (pat_type == _PAGE_CACHE_WC) { *ret_prot = prot | _PAGE_CACHE_WC; - return 0; } else if (pat_type == _PAGE_CACHE_UC_MINUS) { *ret_prot = prot | _PAGE_CACHE_UC_MINUS; - return 0; - } else if (pat_type == _PAGE_CACHE_UC) { - *ret_prot = prot | _PAGE_CACHE_UC; - return 0; - } - - /* - * Look for MTRR hint to get the effective type in case where PAT - * request is for WB. - */ - mtrr_type = mtrr_type_lookup(start, end); - - if (mtrr_type == MTRR_TYPE_UNCACHABLE) { + } else if (pat_type == _PAGE_CACHE_UC || + mtrr_type == MTRR_TYPE_UNCACHABLE) { *ret_prot = prot | _PAGE_CACHE_UC; } else if (mtrr_type == MTRR_TYPE_WRCOMB) { *ret_prot = prot | _PAGE_CACHE_WC; @@ -234,12 +233,14 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, if (req_type == -1) { /* - * Call mtrr_lookup to get the type hint. This is an - * optimization for /dev/mem mmap'ers into WB memory (BIOS - * tools and ACPI tools). Use WB request for WB memory and use - * UC_MINUS otherwise. + * Special case where caller wants to inherit from mtrr or + * existing pat mapping, defaulting to UC_MINUS in case of + * no match. */ u8 mtrr_type = mtrr_type_lookup(start, end); + if (mtrr_type == 0xFE) { /* MTRR match error */ + err = -1; + } if (mtrr_type == MTRR_TYPE_WRBACK) { req_type = _PAGE_CACHE_WB; diff --git a/trunk/arch/x86/mm/srat_64.c b/trunk/arch/x86/mm/srat_64.c index 99649dccad28..3890234e5b26 100644 --- a/trunk/arch/x86/mm/srat_64.c +++ b/trunk/arch/x86/mm/srat_64.c @@ -97,9 +97,36 @@ static __init inline int srat_disabled(void) return numa_off || acpi_numa < 0; } +/* + * A lot of BIOS fill in 10 (= no distance) everywhere. This messes + * up the NUMA heuristics which wants the local node to have a smaller + * distance than the others. + * Do some quick checks here and only use the SLIT if it passes. + */ +static __init int slit_valid(struct acpi_table_slit *slit) +{ + int i, j; + int d = slit->locality_count; + for (i = 0; i < d; i++) { + for (j = 0; j < d; j++) { + u8 val = slit->entry[d*i + j]; + if (i == j) { + if (val != LOCAL_DISTANCE) + return 0; + } else if (val <= LOCAL_DISTANCE) + return 0; + } + } + return 1; +} + /* Callback for SLIT parsing */ void __init acpi_numa_slit_init(struct acpi_table_slit *slit) { + if (!slit_valid(slit)) { + printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); + return; + } acpi_slit = slit; } diff --git a/trunk/arch/x86/pci/init.c b/trunk/arch/x86/pci/init.c index b821f4462d99..e70b9c57b88e 100644 --- a/trunk/arch/x86/pci/init.c +++ b/trunk/arch/x86/pci/init.c @@ -15,8 +15,7 @@ static __init int pci_access_init(void) pci_mmcfg_early_init(); #ifdef CONFIG_PCI_OLPC - if (!pci_olpc_init()) - return 0; /* skip additional checks if it's an XO */ + pci_olpc_init(); #endif #ifdef CONFIG_PCI_BIOS pci_pcbios_init(); diff --git a/trunk/arch/x86/pci/irq.c b/trunk/arch/x86/pci/irq.c index ca8df9c260bc..0908fca901bf 100644 --- a/trunk/arch/x86/pci/irq.c +++ b/trunk/arch/x86/pci/irq.c @@ -621,13 +621,6 @@ static __init int via_router_probe(struct irq_router *r, */ device = PCI_DEVICE_ID_VIA_8235; break; - case PCI_DEVICE_ID_VIA_8237: - /** - * Asus a7v600 bios wrongly reports 8237 - * as 586-compatible - */ - device = PCI_DEVICE_ID_VIA_8237; - break; } } diff --git a/trunk/arch/x86/pci/olpc.c b/trunk/arch/x86/pci/olpc.c index e11e9e803d5f..5e7636558c02 100644 --- a/trunk/arch/x86/pci/olpc.c +++ b/trunk/arch/x86/pci/olpc.c @@ -302,13 +302,12 @@ static struct pci_raw_ops pci_olpc_conf = { .write = pci_olpc_write, }; -int __init pci_olpc_init(void) +void __init pci_olpc_init(void) { if (!machine_is_olpc() || olpc_has_vsa()) - return -ENODEV; + return; printk(KERN_INFO "PCI: Using configuration type OLPC\n"); raw_pci_ops = &pci_olpc_conf; is_lx = is_geode_lx(); - return 0; } diff --git a/trunk/arch/x86/pci/pci.h b/trunk/arch/x86/pci/pci.h index 720c4c554534..f3972b12c60a 100644 --- a/trunk/arch/x86/pci/pci.h +++ b/trunk/arch/x86/pci/pci.h @@ -101,7 +101,7 @@ extern struct pci_raw_ops pci_direct_conf1; extern int pci_direct_probe(void); extern void pci_direct_init(int type); extern void pci_pcbios_init(void); -extern int pci_olpc_init(void); +extern void pci_olpc_init(void); /* pci-mmconfig.c */ diff --git a/trunk/arch/x86/xen/time.c b/trunk/arch/x86/xen/time.c index 52b2e3856980..c39e1a5aa241 100644 --- a/trunk/arch/x86/xen/time.c +++ b/trunk/arch/x86/xen/time.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -151,7 +150,11 @@ static void do_stolen_accounting(void) if (stolen < 0) stolen = 0; - ticks = iter_div_u64_rem(stolen, NS_PER_TICK, &stolen); + ticks = 0; + while (stolen >= NS_PER_TICK) { + ticks++; + stolen -= NS_PER_TICK; + } __get_cpu_var(residual_stolen) = stolen; account_steal_time(NULL, ticks); @@ -163,7 +166,11 @@ static void do_stolen_accounting(void) if (blocked < 0) blocked = 0; - ticks = iter_div_u64_rem(blocked, NS_PER_TICK, &blocked); + ticks = 0; + while (blocked >= NS_PER_TICK) { + ticks++; + blocked -= NS_PER_TICK; + } __get_cpu_var(residual_blocked) = blocked; account_steal_time(idle_task(smp_processor_id()), ticks); } diff --git a/trunk/block/blktrace.c b/trunk/block/blktrace.c index 8d3a27780260..7ae87cc4a163 100644 --- a/trunk/block/blktrace.c +++ b/trunk/block/blktrace.c @@ -79,17 +79,16 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) { int n; va_list args; - unsigned long flags; char *buf; - local_irq_save(flags); + preempt_disable(); buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); va_start(args, fmt); n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args); va_end(args); trace_note(bt, 0, BLK_TN_MESSAGE, buf, n); - local_irq_restore(flags); + preempt_enable(); } EXPORT_SYMBOL_GPL(__trace_note_message); @@ -159,7 +158,10 @@ void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, /* * A word about the locking here - we disable interrupts to reserve * some space in the relay per-cpu buffer, to prevent an irq - * from coming in and stepping on our toes. + * from coming in and stepping on our toes. Once reserved, it's + * enough to get preemption disabled to prevent read of this data + * before we are through filling it. get_cpu()/put_cpu() does this + * for us */ local_irq_save(flags); diff --git a/trunk/block/genhd.c b/trunk/block/genhd.c index b922d4801c87..129ad939f9dd 100644 --- a/trunk/block/genhd.c +++ b/trunk/block/genhd.c @@ -660,8 +660,6 @@ dev_t blk_lookup_devt(const char *name, int part) mutex_lock(&block_class_lock); list_for_each_entry(dev, &block_class.devices, node) { - if (dev->type != &disk_type) - continue; if (strcmp(dev->bus_id, name) == 0) { struct gendisk *disk = dev_to_disk(dev); diff --git a/trunk/drivers/acpi/bay.c b/trunk/drivers/acpi/bay.c index 26038c2a2a71..d2fc94161848 100644 --- a/trunk/drivers/acpi/bay.c +++ b/trunk/drivers/acpi/bay.c @@ -301,20 +301,16 @@ static int bay_add(acpi_handle handle, int id) */ pdev->dev.uevent_suppress = 0; - /* register for events on this device */ - status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - bay_notify, new_bay); - if (ACPI_FAILURE(status)) { - printk(KERN_INFO PREFIX "Error installing bay notify handler\n"); + if (acpi_bay_add_fs(new_bay)) { platform_device_unregister(new_bay->pdev); goto bay_add_err; } - if (acpi_bay_add_fs(new_bay)) { - acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, - bay_notify); - platform_device_unregister(new_bay->pdev); - goto bay_add_err; + /* register for events on this device */ + status = acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + bay_notify, new_bay); + if (ACPI_FAILURE(status)) { + printk(KERN_ERR PREFIX "Error installing bay notify handler\n"); } /* if we are on a dock station, we should register for dock diff --git a/trunk/drivers/acpi/dispatcher/dsfield.c b/trunk/drivers/acpi/dispatcher/dsfield.c index f988a5e7d2b4..c78078315be9 100644 --- a/trunk/drivers/acpi/dispatcher/dsfield.c +++ b/trunk/drivers/acpi/dispatcher/dsfield.c @@ -450,6 +450,10 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, return_ACPI_STATUS(AE_BAD_PARAMETER); } + if (!arg) { + return_ACPI_STATUS(AE_AML_NO_OPERAND); + } + /* Creating new namespace node(s), should not already exist */ flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | @@ -463,7 +467,6 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, /* * Walk the list of entries in the field_list - * Note: field_list can be of zero length. In this case, Arg will be NULL. */ while (arg) { /* diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 96c542f7fded..fa44fb96fc34 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -834,7 +834,7 @@ static int dock_add(acpi_handle handle) goto dock_add_err; } - printk(KERN_INFO PREFIX "%s\n", ACPI_DOCK_DRIVER_DESCRIPTION); + printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION); return 0; diff --git a/trunk/drivers/acpi/ec.c b/trunk/drivers/acpi/ec.c index 5622aee996b2..0924992187e8 100644 --- a/trunk/drivers/acpi/ec.c +++ b/trunk/drivers/acpi/ec.c @@ -194,7 +194,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) while (time_before(jiffies, delay)) { if (acpi_ec_check_status(ec, event)) return 0; - msleep(1); + udelay(ACPI_EC_UDELAY); } } pr_err(PREFIX "acpi_ec_wait timeout, status = 0x%2.2x, event = %s\n", diff --git a/trunk/drivers/acpi/executer/exconfig.c b/trunk/drivers/acpi/executer/exconfig.c index 39d742190584..24da921d13e3 100644 --- a/trunk/drivers/acpi/executer/exconfig.c +++ b/trunk/drivers/acpi/executer/exconfig.c @@ -375,15 +375,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc, goto cleanup; } - /* - * Add the table to the namespace. - * - * Note: We load the table objects relative to the root of the namespace. - * This appears to go against the ACPI specification, but we do it for - * compatibility with other ACPI implementations. - */ status = - acpi_ex_add_table(table_index, acpi_gbl_root_node, &ddb_handle); + acpi_ex_add_table(table_index, walk_state->scope_info->scope.node, + &ddb_handle); if (ACPI_FAILURE(status)) { /* On error, table_ptr was deallocated above */ diff --git a/trunk/drivers/acpi/glue.c b/trunk/drivers/acpi/glue.c index 2808dc60fd67..06f8634fe58b 100644 --- a/trunk/drivers/acpi/glue.c +++ b/trunk/drivers/acpi/glue.c @@ -272,12 +272,6 @@ static u32 rtc_handler(void *context) static inline void rtc_wake_setup(void) { acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); - /* - * After the RTC handler is installed, the Fixed_RTC event should - * be disabled. Only when the RTC alarm is set will it be enabled. - */ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); } static void rtc_wake_on(struct device *dev) diff --git a/trunk/drivers/acpi/hardware/hwsleep.c b/trunk/drivers/acpi/hardware/hwsleep.c index dba3cfbe8cba..d9937e05ec6a 100644 --- a/trunk/drivers/acpi/hardware/hwsleep.c +++ b/trunk/drivers/acpi/hardware/hwsleep.c @@ -223,17 +223,15 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) break; } - /* - * Set the system indicators to show the desired sleep state. - * _SST is an optional method (return no error if not found) - */ + /* Set the system indicators to show the desired sleep state. */ + status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL); if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { ACPI_EXCEPTION((AE_INFO, status, "While executing method _SST")); } - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(status); } ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) diff --git a/trunk/drivers/acpi/numa.c b/trunk/drivers/acpi/numa.c index 658e5f3abae0..5d59cb33b1a5 100644 --- a/trunk/drivers/acpi/numa.c +++ b/trunk/drivers/acpi/numa.c @@ -140,42 +140,19 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header) } } -/* - * A lot of BIOS fill in 10 (= no distance) everywhere. This messes - * up the NUMA heuristics which wants the local node to have a smaller - * distance than the others. - * Do some quick checks here and only use the SLIT if it passes. - */ -static __init int slit_valid(struct acpi_table_slit *slit) -{ - int i, j; - int d = slit->locality_count; - for (i = 0; i < d; i++) { - for (j = 0; j < d; j++) { - u8 val = slit->entry[d*i + j]; - if (i == j) { - if (val != LOCAL_DISTANCE) - return 0; - } else if (val <= LOCAL_DISTANCE) - return 0; - } - } - return 1; -} - static int __init acpi_parse_slit(struct acpi_table_header *table) { struct acpi_table_slit *slit; + u32 localities; if (!table) return -EINVAL; slit = (struct acpi_table_slit *)table; - if (!slit_valid(slit)) { - printk(KERN_INFO "ACPI: SLIT table looks invalid. Not used.\n"); - return -EINVAL; - } + /* downcast just for %llu vs %lu for i386/ia64 */ + localities = (u32) slit->locality_count; + acpi_numa_slit_init(slit); return 0; diff --git a/trunk/drivers/acpi/parser/psargs.c b/trunk/drivers/acpi/parser/psargs.c index e94463778845..f1e8bf65e24e 100644 --- a/trunk/drivers/acpi/parser/psargs.c +++ b/trunk/drivers/acpi/parser/psargs.c @@ -268,7 +268,7 @@ acpi_ps_get_next_namepath(struct acpi_walk_state *walk_state, */ if (ACPI_SUCCESS(status) && possible_method_call && (node->type == ACPI_TYPE_METHOD)) { - if (walk_state->opcode == AML_UNLOAD_OP) { + if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { /* * acpi_ps_get_next_namestring has increased the AML pointer, * so we need to restore the saved AML pointer for method call. @@ -691,7 +691,7 @@ acpi_ps_get_next_arg(struct acpi_walk_state *walk_state, /* To support super_name arg of Unload */ - if (walk_state->opcode == AML_UNLOAD_OP) { + if (walk_state->op->common.aml_opcode == AML_UNLOAD_OP) { status = acpi_ps_get_next_namepath(walk_state, parser_state, arg, diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 9dd0fa93b9e1..386e5aa48834 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -86,6 +86,7 @@ static int acpi_processor_info_open_fs(struct inode *inode, struct file *file); static void acpi_processor_notify(acpi_handle handle, u32 event, void *data); static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu); static int acpi_processor_handle_eject(struct acpi_processor *pr); +extern int acpi_processor_tstate_has_changed(struct acpi_processor *pr); static const struct acpi_device_id processor_device_ids[] = { diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 556ee1585192..2dd2c1f3a01c 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -1669,7 +1669,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) return -EINVAL; } - dev->cpu = pr->id; for (i = 0; i < CPUIDLE_STATE_MAX; i++) { dev->states[i].name[0] = '\0'; dev->states[i].desc[0] = '\0'; @@ -1739,7 +1738,7 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) int acpi_processor_cst_has_changed(struct acpi_processor *pr) { - int ret = 0; + int ret; if (boot_option_idle_override) return 0; @@ -1757,10 +1756,8 @@ int acpi_processor_cst_has_changed(struct acpi_processor *pr) cpuidle_pause_and_lock(); cpuidle_disable_device(&pr->power.dev); acpi_processor_get_power_info(pr); - if (pr->flags.power) { - acpi_processor_setup_cpuidle(pr); - ret = cpuidle_enable_device(&pr->power.dev); - } + acpi_processor_setup_cpuidle(pr); + ret = cpuidle_enable_device(&pr->power.dev); cpuidle_resume_and_unlock(); return ret; @@ -1816,6 +1813,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, if (pr->flags.power) { #ifdef CONFIG_CPU_IDLE acpi_processor_setup_cpuidle(pr); + pr->power.dev.cpu = pr->id; if (cpuidle_register_device(&pr->power.dev)) return -EIO; #endif @@ -1852,7 +1850,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr, return 0; #ifdef CONFIG_CPU_IDLE - cpuidle_unregister_device(&pr->power.dev); + if (pr->flags.power) + cpuidle_unregister_device(&pr->power.dev); #endif pr->flags.power_setup_done = 0; diff --git a/trunk/drivers/acpi/sleep/proc.c b/trunk/drivers/acpi/sleep/proc.c index 224c57c03381..8a5fe8710513 100644 --- a/trunk/drivers/acpi/sleep/proc.c +++ b/trunk/drivers/acpi/sleep/proc.c @@ -495,12 +495,6 @@ static int __init acpi_sleep_proc_init(void) acpi_root_dir, &acpi_system_alarm_fops); acpi_install_fixed_event_handler(ACPI_EVENT_RTC, rtc_handler, NULL); - /* - * Disable the RTC event after installing RTC handler. - * Only when RTC alarm is set will it be enabled. - */ - acpi_clear_event(ACPI_EVENT_RTC); - acpi_disable_event(ACPI_EVENT_RTC, 0); #endif /* HAVE_ACPI_LEGACY_ALARM */ /* 'wakeup device' [R/W] */ diff --git a/trunk/drivers/acpi/system.c b/trunk/drivers/acpi/system.c index 5bd2dec9a7ac..769f24855eb6 100644 --- a/trunk/drivers/acpi/system.c +++ b/trunk/drivers/acpi/system.c @@ -77,6 +77,7 @@ static ssize_t acpi_table_show(struct kobject *kobj, container_of(bin_attr, struct acpi_table_attr, attr); struct acpi_table_header *table_header = NULL; acpi_status status; + ssize_t ret_count = count; status = acpi_get_table(table_attr->name, table_attr->instance, @@ -84,8 +85,18 @@ static ssize_t acpi_table_show(struct kobject *kobj, if (ACPI_FAILURE(status)) return -ENODEV; - return memory_read_from_buffer(buf, count, &offset, - table_header, table_header->length); + if (offset >= table_header->length) { + ret_count = 0; + goto end; + } + + if (offset + ret_count > table_header->length) + ret_count = table_header->length - offset; + + memcpy(buf, ((char *)table_header) + offset, ret_count); + + end: + return ret_count; } static void acpi_table_attr_init(struct acpi_table_attr *table_attr, diff --git a/trunk/drivers/acpi/tables/tbinstal.c b/trunk/drivers/acpi/tables/tbinstal.c index 5336ce88f89f..402f93e1ff20 100644 --- a/trunk/drivers/acpi/tables/tbinstal.c +++ b/trunk/drivers/acpi/tables/tbinstal.c @@ -123,13 +123,24 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, } } - /* - * Originally, we checked the table signature for "SSDT" or "PSDT" here. - * Next, we added support for OEMx tables, signature "OEM". - * Valid tables were encountered with a null signature, so we've just - * given up on validating the signature, since it seems to be a waste - * of code. The original code was removed (05/2008). - */ + /* The table must be either an SSDT or a PSDT or an OEMx */ + + if (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_PSDT)&& + !ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)&& + strncmp(table_desc->pointer->signature, "OEM", 3)) { + /* Check for a printable name */ + if (acpi_ut_valid_acpi_name( + *(u32 *) table_desc->pointer->signature)) { + ACPI_ERROR((AE_INFO, "Table has invalid signature " + "[%4.4s], must be SSDT or PSDT", + table_desc->pointer->signature)); + } else { + ACPI_ERROR((AE_INFO, "Table has invalid signature " + "(0x%8.8X), must be SSDT or PSDT", + *(u32 *) table_desc->pointer->signature)); + } + return_ACPI_STATUS(AE_BAD_SIGNATURE); + } (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); diff --git a/trunk/drivers/acpi/tables/tbxface.c b/trunk/drivers/acpi/tables/tbxface.c index 0e319604d3e7..fb57b93c2495 100644 --- a/trunk/drivers/acpi/tables/tbxface.c +++ b/trunk/drivers/acpi/tables/tbxface.c @@ -540,7 +540,7 @@ static acpi_status acpi_tb_load_namespace(void) acpi_tb_print_table_header(0, table); if (no_auto_ssdt == 0) { - printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n"); + printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\""); } } diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 84c795fb9b1e..504385b1f211 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -364,17 +364,10 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) if (flag & ACPI_TRIPS_CRITICAL) { status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tz->trips.critical.temperature); - /* - * Treat freezing temperatures as invalid as well; some - * BIOSes return really low values and cause reboots at startup. - * Below zero (Celcius) values clearly aren't right for sure.. - * ... so lets discard those as invalid. - */ - if (ACPI_FAILURE(status) || - tz->trips.critical.temperature <= 2732) { + if (ACPI_FAILURE(status)) { tz->trips.critical.flags.valid = 0; ACPI_EXCEPTION((AE_INFO, status, - "No or invalid critical threshold")); + "No critical threshold")); return -ENODEV; } else { tz->trips.critical.flags.valid = 1; diff --git a/trunk/drivers/acpi/utilities/utmisc.c b/trunk/drivers/acpi/utilities/utmisc.c index 1f057b71db1a..e4ba7192cd15 100644 --- a/trunk/drivers/acpi/utilities/utmisc.c +++ b/trunk/drivers/acpi/utilities/utmisc.c @@ -1048,7 +1048,6 @@ acpi_ut_exception(char *module_name, va_start(args, format); acpi_os_vprintf(format, args); acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); - va_end(args); } EXPORT_SYMBOL(acpi_ut_exception); @@ -1064,6 +1063,7 @@ acpi_ut_warning(char *module_name, u32 line_number, char *format, ...) acpi_os_vprintf(format, args); acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); va_end(args); + va_end(args); } void ACPI_INTERNAL_VAR_XFACE diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 966ab401e523..544b7d6c617c 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -89,7 +89,6 @@ enum { board_ahci_sb600 = 3, board_ahci_mv = 4, board_ahci_sb700 = 5, - board_ahci_mcp65 = 6, /* global controller registers */ HOST_CAP = 0x00, /* host capabilities */ @@ -191,7 +190,6 @@ enum { AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ - AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ /* ap->flags bits */ @@ -255,8 +253,6 @@ static void ahci_pmp_attach(struct ata_port *ap); static void ahci_pmp_detach(struct ata_port *ap); static int ahci_softreset(struct ata_link *link, unsigned int *class, unsigned long deadline); -static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, - unsigned long deadline); static int ahci_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, @@ -333,12 +329,6 @@ static struct ata_port_operations ahci_p5wdh_ops = { .hardreset = ahci_p5wdh_hardreset, }; -static struct ata_port_operations ahci_sb600_ops = { - .inherits = &ahci_ops, - .softreset = ahci_sb600_softreset, - .pmp_softreset = ahci_sb600_softreset, -}; - #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) static const struct ata_port_info ahci_port_info[] = { @@ -369,11 +359,11 @@ static const struct ata_port_info ahci_port_info[] = { { AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | - AHCI_HFLAG_SECT255), + AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, - .port_ops = &ahci_sb600_ops, + .port_ops = &ahci_ops, }, /* board_ahci_mv */ { @@ -387,15 +377,8 @@ static const struct ata_port_info ahci_port_info[] = { }, /* board_ahci_sb700 */ { - AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), - .flags = AHCI_FLAG_COMMON, - .pio_mask = 0x1f, /* pio0-4 */ - .udma_mask = ATA_UDMA6, - .port_ops = &ahci_sb600_ops, - }, - /* board_ahci_mcp65 */ - { - AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), + AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | + AHCI_HFLAG_NO_PMP), .flags = AHCI_FLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = ATA_UDMA6, @@ -455,14 +438,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ /* NVIDIA */ - { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ - { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ + { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ @@ -641,12 +624,6 @@ static void ahci_save_initial_config(struct pci_dev *pdev, cap &= ~HOST_CAP_NCQ; } - if (!(cap & HOST_CAP_NCQ) && (hpriv->flags & AHCI_HFLAG_YES_NCQ)) { - dev_printk(KERN_INFO, &pdev->dev, - "controller can do NCQ, turning on CAP_NCQ\n"); - cap |= HOST_CAP_NCQ; - } - if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { dev_printk(KERN_INFO, &pdev->dev, "controller can't do PMP, turning off CAP_PMP\n"); @@ -1285,11 +1262,19 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, return 0; } -static int ahci_do_softreset(struct ata_link *link, unsigned int *class, - int pmp, unsigned long deadline, - int (*check_ready)(struct ata_link *link)) +static int ahci_check_ready(struct ata_link *link) +{ + void __iomem *port_mmio = ahci_port_base(link->ap); + u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; + + return ata_check_ready(status); +} + +static int ahci_softreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) { struct ata_port *ap = link->ap; + int pmp = sata_srst_pmp(link); const char *reason = NULL; unsigned long now, msecs; struct ata_taskfile tf; @@ -1327,7 +1312,7 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); /* wait for link to become ready */ - rc = ata_wait_after_reset(link, deadline, check_ready); + rc = ata_wait_after_reset(link, deadline, ahci_check_ready); /* link occupied, -ENODEV too is an error */ if (rc) { reason = "device not ready"; @@ -1343,72 +1328,6 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class, return rc; } -static int ahci_check_ready(struct ata_link *link) -{ - void __iomem *port_mmio = ahci_port_base(link->ap); - u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; - - return ata_check_ready(status); -} - -static int ahci_softreset(struct ata_link *link, unsigned int *class, - unsigned long deadline) -{ - int pmp = sata_srst_pmp(link); - - DPRINTK("ENTER\n"); - - return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); -} - -static int ahci_sb600_check_ready(struct ata_link *link) -{ - void __iomem *port_mmio = ahci_port_base(link->ap); - u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; - u32 irq_status = readl(port_mmio + PORT_IRQ_STAT); - - /* - * There is no need to check TFDATA if BAD PMP is found due to HW bug, - * which can save timeout delay. - */ - if (irq_status & PORT_IRQ_BAD_PMP) - return -EIO; - - return ata_check_ready(status); -} - -static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, - unsigned long deadline) -{ - struct ata_port *ap = link->ap; - void __iomem *port_mmio = ahci_port_base(ap); - int pmp = sata_srst_pmp(link); - int rc; - u32 irq_sts; - - DPRINTK("ENTER\n"); - - rc = ahci_do_softreset(link, class, pmp, deadline, - ahci_sb600_check_ready); - - /* - * Soft reset fails on some ATI chips with IPMS set when PMP - * is enabled but SATA HDD/ODD is connected to SATA port, - * do soft reset again to port 0. - */ - if (rc == -EIO) { - irq_sts = readl(port_mmio + PORT_IRQ_STAT); - if (irq_sts & PORT_IRQ_BAD_PMP) { - ata_link_printk(link, KERN_WARNING, - "failed due to HW bug, retry pmp=0\n"); - rc = ahci_do_softreset(link, class, 0, deadline, - ahci_check_ready); - } - } - - return rc; -} - static int ahci_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline) { @@ -2199,8 +2118,7 @@ static void ahci_p5wdh_workaround(struct ata_host *host) static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; - unsigned int board_id = ent->driver_data; - struct ata_port_info pi = ahci_port_info[board_id]; + struct ata_port_info pi = ahci_port_info[ent->driver_data]; const struct ata_port_info *ppi[] = { &pi, NULL }; struct device *dev = &pdev->dev; struct ahci_host_priv *hpriv; @@ -2249,11 +2167,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return -ENOMEM; hpriv->flags |= (unsigned long)pi.private_data; - /* MCP65 revision A1 and A2 can't do MSI */ - if (board_id == board_ahci_mcp65 && - (pdev->revision == 0xa1 || pdev->revision == 0xa2)) - hpriv->flags |= AHCI_HFLAG_NO_MSI; - if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) pci_intx(pdev, 1); diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 81b7ae376951..3548ee7014ca 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -574,8 +574,6 @@ static const struct ich_laptop ich_laptop[] = { { 0x27DF, 0x1043, 0x1267 }, /* ICH7 on Asus W5F */ { 0x27DF, 0x103C, 0x30A1 }, /* ICH7 on HP Compaq nc2400 */ { 0x24CA, 0x1025, 0x0061 }, /* ICH4 on ACER Aspire 2023WLMi */ - { 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */ - { 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */ { 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */ /* end marker */ { 0, } diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index 3ff8b14420d9..dbf6ca781f66 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -118,62 +118,12 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) ap->pflags |= ATA_PFLAG_INIT_GTM_VALID; } -static void ata_acpi_eject_device(acpi_handle handle) -{ - struct acpi_object_list arg_list; - union acpi_object arg; - - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - if (ACPI_FAILURE(acpi_evaluate_object(handle, "_EJ0", - &arg_list, NULL))) - printk(KERN_ERR "Failed to evaluate _EJ0!\n"); -} - -/* @ap and @dev are the same as ata_acpi_handle_hotplug() */ -static void ata_acpi_detach_device(struct ata_port *ap, struct ata_device *dev) -{ - if (dev) - dev->flags |= ATA_DFLAG_DETACH; - else { - struct ata_link *tlink; - struct ata_device *tdev; - - ata_port_for_each_link(tlink, ap) - ata_link_for_each_dev(tdev, tlink) - tdev->flags |= ATA_DFLAG_DETACH; - } - - ata_port_schedule_eh(ap); -} - -/** - * ata_acpi_handle_hotplug - ACPI event handler backend - * @ap: ATA port ACPI event occurred - * @dev: ATA device ACPI event occurred (can be NULL) - * @event: ACPI event which occurred - * @is_dock_event: boolean indicating whether the event was a dock one - * - * All ACPI bay / device realted events end up in this function. If - * the event is port-wide @dev is NULL. If the event is specific to a - * device, @dev points to it. - * - * Hotplug (as opposed to unplug) notification is always handled as - * port-wide while unplug only kills the target device on device-wide - * event. - * - * LOCKING: - * ACPI notify handler context. May sleep. - */ -static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, - u32 event, int is_dock_event) +static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device + *dev, u32 event) { char event_string[12]; char *envp[] = { event_string, NULL }; - struct ata_eh_info *ehi = &ap->link.eh_info; + struct ata_eh_info *ehi; struct kobject *kobj = NULL; int wait = 0; unsigned long flags; @@ -181,100 +131,87 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev, unsigned long sta; acpi_status status; - if (dev) { - if (dev->sdev) - kobj = &dev->sdev->sdev_gendev.kobj; + if (!ap) + ap = dev->link->ap; + ehi = &ap->link.eh_info; + + spin_lock_irqsave(ap->lock, flags); + + if (dev) handle = dev->acpi_handle; - } else { - kobj = &ap->dev->kobj; + else handle = ap->acpi_handle; - } status = acpi_get_handle(handle, "_EJ0", &tmphandle); - if (ACPI_FAILURE(status)) - /* This device does not support hotplug */ + if (ACPI_FAILURE(status)) { + /* This device is not ejectable */ + spin_unlock_irqrestore(ap->lock, flags); return; + } - spin_lock_irqsave(ap->lock, flags); + status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + if (ACPI_FAILURE(status)) { + printk ("Unable to determine bay status\n"); + spin_unlock_irqrestore(ap->lock, flags); + return; + } switch (event) { case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: ata_ehi_push_desc(ehi, "ACPI event"); - - status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); - if (ACPI_FAILURE(status)) { - ata_port_printk(ap, KERN_ERR, - "acpi: failed to determine bay status (0x%x)\n", - status); - break; - } - - if (sta) { + if (!sta) { + /* Device has been unplugged */ + if (dev) + dev->flags |= ATA_DFLAG_DETACH; + else { + struct ata_link *tlink; + struct ata_device *tdev; + + ata_port_for_each_link(tlink, ap) { + ata_link_for_each_dev(tdev, tlink) { + tdev->flags |= + ATA_DFLAG_DETACH; + } + } + } + ata_port_schedule_eh(ap); + wait = 1; + } else { ata_ehi_hotplugged(ehi); ata_port_freeze(ap); - } else { - /* The device has gone - unplug it */ - ata_acpi_detach_device(ap, dev); - wait = 1; } - break; - case ACPI_NOTIFY_EJECT_REQUEST: - ata_ehi_push_desc(ehi, "ACPI event"); - - if (!is_dock_event) - break; - - /* undock event - immediate unplug */ - ata_acpi_detach_device(ap, dev); - wait = 1; - break; } - /* make sure kobj doesn't go away while ap->lock is released */ - kobject_get(kobj); - spin_unlock_irqrestore(ap->lock, flags); - if (wait) { + if (wait) ata_port_wait_eh(ap); - ata_acpi_eject_device(handle); - } - if (kobj && !is_dock_event) { + if (dev) { + if (dev->sdev) + kobj = &dev->sdev->sdev_gendev.kobj; + } else + kobj = &ap->dev->kobj; + + if (kobj) { sprintf(event_string, "BAY_EVENT=%d", event); kobject_uevent_env(kobj, KOBJ_CHANGE, envp); } - - kobject_put(kobj); -} - -static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data) -{ - struct ata_device *dev = data; - - ata_acpi_handle_hotplug(dev->link->ap, dev, event, 1); -} - -static void ata_acpi_ap_notify_dock(acpi_handle handle, u32 event, void *data) -{ - struct ata_port *ap = data; - - ata_acpi_handle_hotplug(ap, NULL, event, 1); } static void ata_acpi_dev_notify(acpi_handle handle, u32 event, void *data) { struct ata_device *dev = data; - ata_acpi_handle_hotplug(dev->link->ap, dev, event, 0); + ata_acpi_handle_hotplug(NULL, dev, event); } static void ata_acpi_ap_notify(acpi_handle handle, u32 event, void *data) { struct ata_port *ap = data; - ata_acpi_handle_hotplug(ap, NULL, event, 0); + ata_acpi_handle_hotplug(ap, NULL, event); } /** @@ -315,7 +252,7 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_ap_notify, ap); /* we might be on a docking station */ register_hotplug_dock_device(ap->acpi_handle, - ata_acpi_ap_notify_dock, ap); + ata_acpi_ap_notify, ap); } for (j = 0; j < ata_link_max_devices(&ap->link); j++) { @@ -327,7 +264,7 @@ void ata_acpi_associate(struct ata_host *host) ata_acpi_dev_notify, dev); /* we might be on a docking station */ register_hotplug_dock_device(dev->acpi_handle, - ata_acpi_dev_notify_dock, dev); + ata_acpi_dev_notify, dev); } } } diff --git a/trunk/drivers/ata/libata-sff.c b/trunk/drivers/ata/libata-sff.c index 215d18672a5a..3c2d2289f85e 100644 --- a/trunk/drivers/ata/libata-sff.c +++ b/trunk/drivers/ata/libata-sff.c @@ -247,7 +247,7 @@ u8 ata_sff_check_status(struct ata_port *ap) * LOCKING: * Inherited from caller. */ -static u8 ata_sff_altstatus(struct ata_port *ap) +u8 ata_sff_altstatus(struct ata_port *ap) { if (ap->ops->sff_check_altstatus) return ap->ops->sff_check_altstatus(ap); @@ -255,93 +255,6 @@ static u8 ata_sff_altstatus(struct ata_port *ap) return ioread8(ap->ioaddr.altstatus_addr); } -/** - * ata_sff_irq_status - Check if the device is busy - * @ap: port where the device is - * - * Determine if the port is currently busy. Uses altstatus - * if available in order to avoid clearing shared IRQ status - * when finding an IRQ source. Non ctl capable devices don't - * share interrupt lines fortunately for us. - * - * LOCKING: - * Inherited from caller. - */ -static u8 ata_sff_irq_status(struct ata_port *ap) -{ - u8 status; - - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { - status = ata_sff_altstatus(ap); - /* Not us: We are busy */ - if (status & ATA_BUSY) - return status; - } - /* Clear INTRQ latch */ - status = ap->ops->sff_check_status(ap); - return status; -} - -/** - * ata_sff_sync - Flush writes - * @ap: Port to wait for. - * - * CAUTION: - * If we have an mmio device with no ctl and no altstatus - * method this will fail. No such devices are known to exist. - * - * LOCKING: - * Inherited from caller. - */ - -static void ata_sff_sync(struct ata_port *ap) -{ - if (ap->ops->sff_check_altstatus) - ap->ops->sff_check_altstatus(ap); - else if (ap->ioaddr.altstatus_addr) - ioread8(ap->ioaddr.altstatus_addr); -} - -/** - * ata_sff_pause - Flush writes and wait 400nS - * @ap: Port to pause for. - * - * CAUTION: - * If we have an mmio device with no ctl and no altstatus - * method this will fail. No such devices are known to exist. - * - * LOCKING: - * Inherited from caller. - */ - -void ata_sff_pause(struct ata_port *ap) -{ - ata_sff_sync(ap); - ndelay(400); -} - -/** - * ata_sff_dma_pause - Pause before commencing DMA - * @ap: Port to pause for. - * - * Perform I/O fencing and ensure sufficient cycle delays occur - * for the HDMA1:0 transition - */ - -void ata_sff_dma_pause(struct ata_port *ap) -{ - if (ap->ops->sff_check_altstatus || ap->ioaddr.altstatus_addr) { - /* An altstatus read will cause the needed delay without - messing up the IRQ status */ - ata_sff_altstatus(ap); - return; - } - /* There are no DMA controllers without ctl. BUG here to ensure - we never violate the HDMA1:0 transition timing and risk - corruption. */ - BUG(); -} - /** * ata_sff_busy_sleep - sleep until BSY clears, or timeout * @ap: port containing status register to be polled @@ -829,7 +742,7 @@ static void ata_pio_sectors(struct ata_queued_cmd *qc) } else ata_pio_sector(qc); - ata_sff_sync(qc->ap); /* flush */ + ata_sff_altstatus(qc->ap); /* flush */ } /** @@ -850,9 +763,8 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc) WARN_ON(qc->dev->cdb_len < 12); ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1); - ata_sff_sync(ap); - /* FIXME: If the CDB is for DMA do we need to do the transition delay - or is bmdma_start guaranteed to do it ? */ + ata_sff_altstatus(ap); /* flush */ + switch (qc->tf.protocol) { case ATAPI_PROT_PIO: ap->hsm_task_state = HSM_ST; @@ -993,7 +905,7 @@ static void atapi_pio_bytes(struct ata_queued_cmd *qc) if (unlikely(__atapi_pio_bytes(qc, bytes))) goto err_out; - ata_sff_sync(ap); /* flush */ + ata_sff_altstatus(ap); /* flush */ return; @@ -1577,12 +1489,16 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap, goto idle_irq; } - - /* check main status, clearing INTRQ if needed */ - status = ata_sff_irq_status(ap); + /* check altstatus */ + status = ata_sff_altstatus(ap); if (status & ATA_BUSY) goto idle_irq; + /* check main status, clearing INTRQ */ + status = ap->ops->sff_check_status(ap); + if (unlikely(status & ATA_BUSY)) + goto idle_irq; + /* ack bmdma irq events */ ap->ops->sff_irq_clear(ap); @@ -2114,7 +2030,7 @@ void ata_sff_error_handler(struct ata_port *ap) ap->ops->bmdma_stop(qc); } - ata_sff_sync(ap); /* FIXME: We don't need this */ + ata_sff_altstatus(ap); ap->ops->sff_check_status(ap); ap->ops->sff_irq_clear(ap); @@ -2287,7 +2203,7 @@ void ata_bmdma_stop(struct ata_queued_cmd *qc) mmio + ATA_DMA_CMD); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_sff_dma_pause(ap); + ata_sff_altstatus(ap); /* dummy read */ } /** @@ -2806,8 +2722,7 @@ EXPORT_SYMBOL_GPL(ata_sff_qc_prep); EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep); EXPORT_SYMBOL_GPL(ata_sff_dev_select); EXPORT_SYMBOL_GPL(ata_sff_check_status); -EXPORT_SYMBOL_GPL(ata_sff_dma_pause); -EXPORT_SYMBOL_GPL(ata_sff_pause); +EXPORT_SYMBOL_GPL(ata_sff_altstatus); EXPORT_SYMBOL_GPL(ata_sff_busy_sleep); EXPORT_SYMBOL_GPL(ata_sff_wait_ready); EXPORT_SYMBOL_GPL(ata_sff_tf_load); diff --git a/trunk/drivers/ata/pata_icside.c b/trunk/drivers/ata/pata_icside.c index cf9e9848f8b5..17138436423d 100644 --- a/trunk/drivers/ata/pata_icside.c +++ b/trunk/drivers/ata/pata_icside.c @@ -270,7 +270,7 @@ static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc) disable_dma(state->dma); /* see ata_bmdma_stop */ - ata_sff_dma_pause(ap); + ata_sff_altstatus(ap); } static u8 pata_icside_bmdma_status(struct ata_port *ap) diff --git a/trunk/drivers/ata/pata_rb532_cf.c b/trunk/drivers/ata/pata_rb532_cf.c index f8b3ffc8ae9e..a108d259f19d 100644 --- a/trunk/drivers/ata/pata_rb532_cf.c +++ b/trunk/drivers/ata/pata_rb532_cf.c @@ -57,9 +57,7 @@ static inline void rb532_pata_finish_io(struct ata_port *ap) struct ata_host *ah = ap->host; struct rb532_cf_info *info = ah->private_data; - /* FIXME: Keep previous delay. If this is merely a fence then - ata_sff_sync might be sufficient. */ - ata_sff_dma_pause(ap); + ata_sff_altstatus(ap); ndelay(RB500_CF_IO_DELAY); set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH); diff --git a/trunk/drivers/ata/pata_scc.c b/trunk/drivers/ata/pata_scc.c index bbf5aa345e68..e965b251ca24 100644 --- a/trunk/drivers/ata/pata_scc.c +++ b/trunk/drivers/ata/pata_scc.c @@ -726,7 +726,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc) in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START); /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ - ata_sff_dma_pause(ap); /* dummy read */ + ata_sff_altstatus(ap); /* dummy read */ } /** @@ -747,8 +747,7 @@ static u8 scc_bmdma_status (struct ata_port *ap) return host_stat; /* errata A252,A308 workaround: Step4 */ - if ((scc_check_altstatus(ap) & ATA_ERR) - && (int_status & INTSTS_INTRQ)) + if ((ata_sff_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ)) return (host_stat | ATA_DMA_INTR); /* errata A308 workaround Step5 */ diff --git a/trunk/drivers/ata/sata_mv.c b/trunk/drivers/ata/sata_mv.c index 60391e9a84db..acf347f71a2f 100644 --- a/trunk/drivers/ata/sata_mv.c +++ b/trunk/drivers/ata/sata_mv.c @@ -224,11 +224,6 @@ enum { PHY_MODE3 = 0x310, PHY_MODE4 = 0x314, - PHY_MODE4_CFG_MASK = 0x00000003, /* phy internal config field */ - PHY_MODE4_CFG_VALUE = 0x00000001, /* phy internal config field */ - PHY_MODE4_RSVD_ZEROS = 0x5de3fffa, /* Gen2e always write zeros */ - PHY_MODE4_RSVD_ONES = 0x00000005, /* Gen2e always write ones */ - PHY_MODE2 = 0x330, SATA_IFCTL_OFS = 0x344, SATA_TESTCTL_OFS = 0x348, @@ -2568,16 +2563,17 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio, m3 &= ~0x1c; if (fix_phy_mode4) { - u32 m4 = readl(port_mmio + PHY_MODE4); - /* - * Enforce reserved-bit restrictions on GenIIe devices only. - * For earlier chipsets, force only the internal config field - * (workaround for errata FEr SATA#10 part 1). - */ + u32 m4; + + m4 = readl(port_mmio + PHY_MODE4); + + /* workaround for errata FEr SATA#10 (part 1) */ + m4 = (m4 & ~(1 << 1)) | (1 << 0); + + /* enforce bit restrictions on GenIIe devices */ if (IS_GEN_IIE(hpriv)) - m4 = (m4 & ~PHY_MODE4_RSVD_ZEROS) | PHY_MODE4_RSVD_ONES; - else - m4 = (m4 & ~PHY_MODE4_CFG_MASK) | PHY_MODE4_CFG_VALUE; + m4 = (m4 & ~0x5DE3FFFC) | (1 << 2); + writel(m4, port_mmio + PHY_MODE4); } /* diff --git a/trunk/drivers/atm/Kconfig b/trunk/drivers/atm/Kconfig index f197a193633a..b554edac1ced 100644 --- a/trunk/drivers/atm/Kconfig +++ b/trunk/drivers/atm/Kconfig @@ -294,7 +294,7 @@ config ATM_HORIZON_DEBUG config ATM_IA tristate "Interphase ATM PCI x575/x525/x531" - depends on PCI + depends on PCI && !64BIT ---help--- This is a driver for the Interphase (i)ChipSAR adapter cards which include a variety of variants in term of the size of the @@ -325,22 +325,81 @@ config ATM_IA_DEBUG speed of the driver, and the size of your syslog files! When inactive, they will have only a modest impact on performance. -config ATM_FORE200E +config ATM_FORE200E_MAYBE tristate "FORE Systems 200E-series" - depends on (PCI || SBUS) - select FW_LOADER + depends on PCI || SBUS ---help--- This is a driver for the FORE Systems 200E-series ATM adapter cards. It simultaneously supports PCA-200E and SBA-200E models on PCI and SBUS hosts. Say Y (or M to compile as a module named fore_200e) here if you have one of these ATM adapters. + Note that the driver will actually be compiled only if you + additionally enable the support for PCA-200E and/or SBA-200E + cards. + See the file for further details. +config ATM_FORE200E_PCA + bool "PCA-200E support" + depends on ATM_FORE200E_MAYBE && PCI + help + Say Y here if you want your PCA-200E cards to be probed. + +config ATM_FORE200E_PCA_DEFAULT_FW + bool "Use default PCA-200E firmware (normally enabled)" + depends on ATM_FORE200E_PCA + help + Use the default PCA-200E firmware data shipped with the driver. + + Normal users do not have to deal with the firmware stuff, so + they should say Y here. + +config ATM_FORE200E_PCA_FW + string "Pathname of user-supplied binary firmware" + depends on ATM_FORE200E_PCA && !ATM_FORE200E_PCA_DEFAULT_FW + default "" + help + This defines the pathname of an alternative PCA-200E binary + firmware image supplied by the user. This pathname may be + absolute or relative to the drivers/atm directory. + + The driver comes with an adequate firmware image, so normal users do + not have to supply an alternative one. They just say Y to "Use + default PCA-200E firmware" instead. + +config ATM_FORE200E_SBA + bool "SBA-200E support" + depends on ATM_FORE200E_MAYBE && SBUS + help + Say Y here if you want your SBA-200E cards to be probed. + +config ATM_FORE200E_SBA_DEFAULT_FW + bool "Use default SBA-200E firmware (normally enabled)" + depends on ATM_FORE200E_SBA + help + Use the default SBA-200E firmware data shipped with the driver. + + Normal users do not have to deal with the firmware stuff, so + they should say Y here. + +config ATM_FORE200E_SBA_FW + string "Pathname of user-supplied binary firmware" + depends on ATM_FORE200E_SBA && !ATM_FORE200E_SBA_DEFAULT_FW + default "" + help + This defines the pathname of an alternative SBA-200E binary + firmware image supplied by the user. This pathname may be + absolute or relative to the drivers/atm directory. + + The driver comes with an adequate firmware image, so normal users do + not have to supply an alternative one. They just say Y to "Use + default SBA-200E firmware", above. + config ATM_FORE200E_USE_TASKLET bool "Defer interrupt work to a tasklet" - depends on ATM_FORE200E + depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA) default n help This defers work to be done by the interrupt handler to a @@ -349,7 +408,7 @@ config ATM_FORE200E_USE_TASKLET config ATM_FORE200E_TX_RETRY int "Maximum number of tx retries" - depends on ATM_FORE200E + depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA) default "16" ---help--- Specifies the number of times the driver attempts to transmit @@ -366,7 +425,7 @@ config ATM_FORE200E_TX_RETRY config ATM_FORE200E_DEBUG int "Debugging level (0-3)" - depends on ATM_FORE200E + depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA) default "0" help Specifies the level of debugging messages issued by the driver. @@ -377,6 +436,12 @@ config ATM_FORE200E_DEBUG the performances of the driver, and the size of your syslog files! Keep the debugging level to 0 during normal operations. +config ATM_FORE200E + tristate + depends on (PCI || SBUS) && (ATM_FORE200E_PCA || ATM_FORE200E_SBA) + default m if ATM_FORE200E_MAYBE!=y + default y if ATM_FORE200E_MAYBE=y + config ATM_HE tristate "ForeRunner HE Series" depends on PCI diff --git a/trunk/drivers/atm/Makefile b/trunk/drivers/atm/Makefile index 0bfb31748ecf..e4fa99658699 100644 --- a/trunk/drivers/atm/Makefile +++ b/trunk/drivers/atm/Makefile @@ -3,6 +3,14 @@ # fore_200e-objs := fore200e.o +hostprogs-y := fore200e_mkfirm + +# Files generated that shall be removed upon make clean +clean-files := atmsar11.bin atmsar11.bin1 atmsar11.bin2 pca200e.bin \ + pca200e.bin1 pca200e.bin2 pca200e_ecd.bin pca200e_ecd.bin1 \ + pca200e_ecd.bin2 sba200e_ecd.bin sba200e_ecd.bin1 sba200e_ecd.bin2 +# Firmware generated that shall be removed upon make clean +clean-files += fore200e_pca_fw.c fore200e_sba_fw.c obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o obj-$(CONFIG_ATM_NICSTAR) += nicstar.o @@ -28,7 +36,38 @@ obj-$(CONFIG_ATM_TCP) += atmtcp.o obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o obj-$(CONFIG_ATM_LANAI) += lanai.o +ifeq ($(CONFIG_ATM_FORE200E_PCA),y) + fore_200e-objs += fore200e_pca_fw.o + # guess the target endianess to choose the right PCA-200E firmware image + ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) + byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h + CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(KBUILD_CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) + endif +endif + +ifeq ($(CONFIG_ATM_FORE200E_SBA),y) + fore_200e-objs += fore200e_sba_fw.o + ifeq ($(CONFIG_ATM_FORE200E_SBA_DEFAULT_FW),y) + CONFIG_ATM_FORE200E_SBA_FW := $(obj)/sba200e_ecd.bin2 + endif +endif obj-$(CONFIG_ATM_HE) += he.o ifeq ($(CONFIG_ATM_HE_USE_SUNI),y) obj-$(CONFIG_ATM_HE) += suni.o endif + +# FORE Systems 200E-series firmware magic +$(obj)/fore200e_pca_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_PCA_FW)) \ + $(obj)/fore200e_mkfirm + $(obj)/fore200e_mkfirm -k -b _fore200e_pca_fw \ + -i $(CONFIG_ATM_FORE200E_PCA_FW) -o $@ + +$(obj)/fore200e_sba_fw.c: $(patsubst "%", %, $(CONFIG_ATM_FORE200E_SBA_FW)) \ + $(obj)/fore200e_mkfirm + $(obj)/fore200e_mkfirm -k -b _fore200e_sba_fw \ + -i $(CONFIG_ATM_FORE200E_SBA_FW) -o $@ + +# deal with the various suffixes of the binary firmware images +$(obj)/%.bin $(obj)/%.bin1 $(obj)/%.bin2: $(src)/%.data + objcopy -Iihex $< -Obinary $@.gz + gzip -n -df $@.gz diff --git a/trunk/drivers/atm/eni.h b/trunk/drivers/atm/eni.h index e4c9525e60b3..d04fefb0841f 100644 --- a/trunk/drivers/atm/eni.h +++ b/trunk/drivers/atm/eni.h @@ -18,6 +18,7 @@ #include "midway.h" +#define KERNEL_OFFSET 0xC0000000 /* kernel 0x0 is at phys 0xC0000000 */ #define DEV_LABEL "eni" #define UBR_BUFFER (128*1024) /* UBR buffer size */ diff --git a/trunk/drivers/atm/fore200e.c b/trunk/drivers/atm/fore200e.c index d5c1bbfbe79d..432181ed7bb5 100644 --- a/trunk/drivers/atm/fore200e.c +++ b/trunk/drivers/atm/fore200e.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,7 @@ #include #include -#ifdef CONFIG_SBUS +#ifdef CONFIG_ATM_FORE200E_SBA #include #include #include @@ -383,6 +382,9 @@ fore200e_shutdown(struct fore200e* fore200e) case FORE200E_STATE_START_FW: /* nothing to do for that state */ + case FORE200E_STATE_LOAD_FW: + /* nothing to do for that state */ + case FORE200E_STATE_RESET: /* nothing to do for that state */ @@ -403,7 +405,7 @@ fore200e_shutdown(struct fore200e* fore200e) } -#ifdef CONFIG_PCI +#ifdef CONFIG_ATM_FORE200E_PCA static u32 fore200e_pca_read(volatile u32 __iomem *addr) { @@ -656,10 +658,10 @@ fore200e_pca_proc_read(struct fore200e* fore200e, char *page) pci_dev->bus->number, PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn)); } -#endif /* CONFIG_PCI */ +#endif /* CONFIG_ATM_FORE200E_PCA */ -#ifdef CONFIG_SBUS +#ifdef CONFIG_ATM_FORE200E_SBA static u32 fore200e_sba_read(volatile u32 __iomem *addr) @@ -905,7 +907,7 @@ fore200e_sba_proc_read(struct fore200e* fore200e, char *page) return sprintf(page, " SBUS slot/device:\t\t%d/'%s'\n", sbus_dev->slot, sbus_dev->prom_name); } -#endif /* CONFIG_SBUS */ +#endif /* CONFIG_ATM_FORE200E_SBA */ static void @@ -2550,53 +2552,13 @@ fore200e_monitor_puts(struct fore200e* fore200e, char* str) while (fore200e_monitor_getc(fore200e) >= 0); } -#ifdef __LITTLE_ENDIAN -#define FW_EXT ".bin" -#else -#define FW_EXT "_ecd.bin2" -#endif static int __devinit -fore200e_load_and_start_fw(struct fore200e* fore200e) -{ - const struct firmware *firmware; - struct device *device; - struct fw_header *fw_header; - u32 *fw_data, fw_size; - u32 __iomem *load_addr; - char buf[48]; - int err = -ENODEV; - - if (strcmp(fore200e->bus->model_name, "PCA-200E") == 0) - device = &((struct pci_dev *) fore200e->bus_dev)->dev; -#ifdef CONFIG_SBUS - else if (strcmp(fore200e->bus->model_name, "SBA-200E") == 0) - device = &((struct sbus_dev *) fore200e->bus_dev)->ofdev.dev; -#endif - else - return err; - - sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); - if (request_firmware(&firmware, buf, device) == 1) { - printk(FORE200E "missing %s firmware image\n", fore200e->bus->model_name); - return err; - } - - fw_data = (u32 *) firmware->data; - fw_size = firmware->size / sizeof(u32); - fw_header = (struct fw_header *) firmware->data; - load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset); - - DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n", - fore200e->name, load_addr, fw_size); - - if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) { - printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name); - goto release; - } - - for (; fw_size--; fw_data++, load_addr++) - fore200e->bus->write(le32_to_cpu(*fw_data), load_addr); +fore200e_start_fw(struct fore200e* fore200e) +{ + int ok; + char cmd[ 48 ]; + struct fw_header* fw_header = (struct fw_header*) fore200e->bus->fw_data; DPRINTK(2, "device %s firmware being started\n", fore200e->name); @@ -2605,22 +2567,46 @@ fore200e_load_and_start_fw(struct fore200e* fore200e) fore200e_spin(100); #endif - sprintf(buf, "\rgo %x\r", le32_to_cpu(fw_header->start_offset)); - fore200e_monitor_puts(fore200e, buf); + sprintf(cmd, "\rgo %x\r", le32_to_cpu(fw_header->start_offset)); - if (fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000) == 0) { + fore200e_monitor_puts(fore200e, cmd); + + ok = fore200e_io_poll(fore200e, &fore200e->cp_monitor->bstat, BSTAT_CP_RUNNING, 1000); + if (ok == 0) { printk(FORE200E "device %s firmware didn't start\n", fore200e->name); - goto release; + return -ENODEV; } printk(FORE200E "device %s firmware started\n", fore200e->name); fore200e->state = FORE200E_STATE_START_FW; - err = 0; + return 0; +} -release: - release_firmware(firmware); - return err; + +static int __devinit +fore200e_load_fw(struct fore200e* fore200e) +{ + __le32* fw_data = (__le32*) fore200e->bus->fw_data; + u32 fw_size = (u32) *fore200e->bus->fw_size / sizeof(u32); + + struct fw_header* fw_header = (struct fw_header*) fw_data; + + u32 __iomem *load_addr = fore200e->virt_base + le32_to_cpu(fw_header->load_offset); + + DPRINTK(2, "device %s firmware being loaded at 0x%p (%d words)\n", + fore200e->name, load_addr, fw_size); + + if (le32_to_cpu(fw_header->magic) != FW_HEADER_MAGIC) { + printk(FORE200E "corrupted %s firmware image\n", fore200e->bus->model_name); + return -ENODEV; + } + + for (; fw_size--; fw_data++, load_addr++) + fore200e->bus->write(le32_to_cpu(*fw_data), load_addr); + + fore200e->state = FORE200E_STATE_LOAD_FW; + return 0; } @@ -2666,7 +2652,10 @@ fore200e_init(struct fore200e* fore200e) if (fore200e_reset(fore200e, 1) < 0) return -ENODEV; - if (fore200e_load_and_start_fw(fore200e) < 0) + if (fore200e_load_fw(fore200e) < 0) + return -ENODEV; + + if (fore200e_start_fw(fore200e) < 0) return -ENODEV; if (fore200e_initialize(fore200e) < 0) @@ -2700,7 +2689,7 @@ fore200e_init(struct fore200e* fore200e) return 0; } -#ifdef CONFIG_PCI +#ifdef CONFIG_ATM_FORE200E_PCA static int __devinit fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) { @@ -2815,7 +2804,7 @@ fore200e_module_init(void) } } -#ifdef CONFIG_PCI +#ifdef CONFIG_ATM_FORE200E_PCA if (!pci_register_driver(&fore200e_pca_driver)) return 0; #endif @@ -2832,7 +2821,7 @@ fore200e_module_cleanup(void) { struct fore200e *fore200e, *next; -#ifdef CONFIG_PCI +#ifdef CONFIG_ATM_FORE200E_PCA pci_unregister_driver(&fore200e_pca_driver); #endif @@ -3151,9 +3140,19 @@ static const struct atmdev_ops fore200e_ops = }; +#ifdef CONFIG_ATM_FORE200E_PCA +extern const unsigned char _fore200e_pca_fw_data[]; +extern const unsigned int _fore200e_pca_fw_size; +#endif +#ifdef CONFIG_ATM_FORE200E_SBA +extern const unsigned char _fore200e_sba_fw_data[]; +extern const unsigned int _fore200e_sba_fw_size; +#endif + static const struct fore200e_bus fore200e_bus[] = { -#ifdef CONFIG_PCI +#ifdef CONFIG_ATM_FORE200E_PCA { "PCA-200E", "pca200e", 32, 4, 32, + _fore200e_pca_fw_data, &_fore200e_pca_fw_size, fore200e_pca_read, fore200e_pca_write, fore200e_pca_dma_map, @@ -3174,8 +3173,9 @@ static const struct fore200e_bus fore200e_bus[] = { fore200e_pca_proc_read, }, #endif -#ifdef CONFIG_SBUS +#ifdef CONFIG_ATM_FORE200E_SBA { "SBA-200E", "sba200e", 32, 64, 32, + _fore200e_sba_fw_data, &_fore200e_sba_fw_size, fore200e_sba_read, fore200e_sba_write, fore200e_sba_dma_map, diff --git a/trunk/drivers/atm/fore200e.h b/trunk/drivers/atm/fore200e.h index 5c6e7adcb19c..8dd4aa76c3bd 100644 --- a/trunk/drivers/atm/fore200e.h +++ b/trunk/drivers/atm/fore200e.h @@ -754,6 +754,7 @@ typedef enum fore200e_state { FORE200E_STATE_CONFIGURE, /* bus interface configured */ FORE200E_STATE_MAP, /* board space mapped in host memory */ FORE200E_STATE_RESET, /* board resetted */ + FORE200E_STATE_LOAD_FW, /* firmware loaded */ FORE200E_STATE_START_FW, /* firmware started */ FORE200E_STATE_INITIALIZE, /* initialize command successful */ FORE200E_STATE_INIT_CMDQ, /* command queue initialized */ @@ -802,6 +803,8 @@ typedef struct fore200e_bus { int descr_alignment; /* tpd/rpd/rbd DMA alignment requirement */ int buffer_alignment; /* rx buffers DMA alignment requirement */ int status_alignment; /* status words DMA alignment requirement */ + const unsigned char* fw_data; /* address of firmware data start */ + const unsigned int* fw_size; /* address of firmware data size */ u32 (*read)(volatile u32 __iomem *); void (*write)(u32, volatile u32 __iomem *); u32 (*dma_map)(struct fore200e*, void*, int, int); diff --git a/trunk/drivers/atm/fore200e_firmware_copyright b/trunk/drivers/atm/fore200e_firmware_copyright new file mode 100644 index 000000000000..d58e6490836e --- /dev/null +++ b/trunk/drivers/atm/fore200e_firmware_copyright @@ -0,0 +1,31 @@ + +These microcode data are placed under the terms of the GNU General Public License. + +We would prefer you not to distribute modified versions of it and not to ask +for assembly or other microcode source. + +Copyright (c) 1995-2000 FORE Systems, Inc., as an unpublished work. This +notice does not imply unrestricted or public access to these materials which +are a trade secret of FORE Systems, Inc. or its subsidiaries or affiliates +(together referred to as "FORE"), and which may not be reproduced, used, sold +or transferred to any third party without FORE's prior written consent. All +rights reserved. + +U.S. Government Restricted Rights. If you are licensing the Software on +behalf of the U.S. Government ("Government"), the following provisions apply +to you. If the software is supplied to the Department of Defense ("DoD"), it +is classified as "Commercial Computer Software" under paragraph 252.227-7014 +of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any +successor regulations) and the Government is acquiring only the license +rights granted herein (the license rights customarily provided to non-Government +users). If the Software is supplied to any unit or agency of the Government +other than the DoD, it is classified as "Restricted Computer Software" and +the Government's rights in the Software are defined in paragraph 52.227-19 of +the Federal Acquisition Regulations ("FAR") (or any successor regulations) or, +in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR +(or any successor regulations). + +FORE Systems is a registered trademark, and ForeRunner, ForeRunnerLE, and +ForeThought are trademarks of FORE Systems, Inc. All other brands or product +names are trademarks or registered trademarks of their respective holders. + diff --git a/trunk/drivers/atm/fore200e_mkfirm.c b/trunk/drivers/atm/fore200e_mkfirm.c new file mode 100644 index 000000000000..520e14b488ff --- /dev/null +++ b/trunk/drivers/atm/fore200e_mkfirm.c @@ -0,0 +1,154 @@ +/* + mkfirm.c: generates a C readable file from a binary firmware image + + Christophe Lizzi (lizzi@{csti.fr, cnam.fr}), June 1999. + + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. +*/ + +#include +#include +#include +#include + +char* default_basename = "pca200e"; /* was initially written for the PCA-200E firmware */ +char* default_infname = ""; +char* default_outfname = ""; + +char* progname; +int verbose = 0; +int inkernel = 0; + + +void usage(void) +{ + fprintf(stderr, + "%s: [-v] [-k] [-b basename ] [-i firmware.bin] [-o firmware.c]\n", + progname); + exit(-1); +} + + +int main(int argc, char** argv) +{ + time_t now; + char* infname = NULL; + char* outfname = NULL; + char* basename = NULL; + FILE* infile; + FILE* outfile; + unsigned firmsize; + int c; + + progname = *(argv++); + + while (argc > 1) { + if ((*argv)[0] == '-') { + switch ((*argv)[1]) { + case 'i': + if (argc-- < 3) + usage(); + infname = *(++argv); + break; + case 'o': + if (argc-- < 3) + usage(); + outfname = *(++argv); + break; + case 'b': + if (argc-- < 3) + usage(); + basename = *(++argv); + break; + case 'v': + verbose = 1; + break; + case 'k': + inkernel = 1; + break; + default: + usage(); + } + } + else { + usage(); + } + argc--; + argv++; + } + + if (infname != NULL) { + infile = fopen(infname, "r"); + if (infile == NULL) { + fprintf(stderr, "%s: can't open %s for reading\n", + progname, infname); + exit(-2); + } + } + else { + infile = stdin; + infname = default_infname; + } + + if (outfname) { + outfile = fopen(outfname, "w"); + if (outfile == NULL) { + fprintf(stderr, "%s: can't open %s for writing\n", + progname, outfname); + exit(-3); + } + } + else { + outfile = stdout; + outfname = default_outfname; + } + + if (basename == NULL) + basename = default_basename; + + if (verbose) { + fprintf(stderr, "%s: input file = %s\n", progname, infname ); + fprintf(stderr, "%s: output file = %s\n", progname, outfname ); + fprintf(stderr, "%s: firmware basename = %s\n", progname, basename ); + } + + time(&now); + fprintf(outfile, "/*\n generated by %s from %s on %s" + " DO NOT EDIT!\n*/\n\n", + progname, infname, ctime(&now)); + + if (inkernel) + fprintf(outfile, "#include \n\n" ); + + /* XXX force 32 bit alignment? */ + fprintf(outfile, "const unsigned char%s %s_data[] = {\n", + inkernel ? " __initdata" : "", basename ); + + c = getc(infile); + fprintf(outfile,"\t0x%02x", c); + firmsize = 1; + + while ((c = getc(infile)) >= 0) { + + if (firmsize++ % 8) + fprintf(outfile,", 0x%02x", c); + else + fprintf(outfile,",\n\t0x%02x", c); + } + + fprintf(outfile, "\n};\n\n"); + + fprintf(outfile, "const unsigned int%s %s_size = %u;\n", + inkernel ? " __initdata" : "", basename, firmsize ); + + if (infile != stdin) + fclose(infile); + if (outfile != stdout) + fclose(outfile); + + if(verbose) + fprintf(stderr, "%s: firmware size = %u\n", progname, firmsize); + + exit(0); +} diff --git a/trunk/drivers/atm/he.c b/trunk/drivers/atm/he.c index bdbad7edf682..ffc4a5a41946 100644 --- a/trunk/drivers/atm/he.c +++ b/trunk/drivers/atm/he.c @@ -75,8 +75,14 @@ #include #include +#define USE_TASKLET #undef USE_SCATTERGATHER #undef USE_CHECKSUM_HW /* still confused about this */ +#define USE_RBPS +#undef USE_RBPS_POOL /* if memory is tight try this */ +#undef USE_RBPL_POOL /* if memory is tight try this */ +#define USE_TPD_POOL +/* #undef CONFIG_ATM_HE_USE_SUNI */ /* #undef HE_DEBUG */ #include "he.h" @@ -382,7 +388,9 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) he_dev->atm_dev->dev_data = he_dev; atm_dev->dev_data = he_dev; he_dev->number = atm_dev->number; +#ifdef USE_TASKLET tasklet_init(&he_dev->tasklet, he_tasklet, (unsigned long) he_dev); +#endif spin_lock_init(&he_dev->global_lock); if (he_start(atm_dev)) { @@ -779,13 +787,23 @@ he_init_group(struct he_dev *he_dev, int group) { int i; +#ifdef USE_RBPS /* small buffer pool */ +#ifdef USE_RBPS_POOL he_dev->rbps_pool = pci_pool_create("rbps", he_dev->pci_dev, CONFIG_RBPS_BUFSIZE, 8, 0); if (he_dev->rbps_pool == NULL) { hprintk("unable to create rbps pages\n"); return -ENOMEM; } +#else /* !USE_RBPS_POOL */ + he_dev->rbps_pages = pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPS_SIZE * CONFIG_RBPS_BUFSIZE, &he_dev->rbps_pages_phys); + if (he_dev->rbps_pages == NULL) { + hprintk("unable to create rbps page pool\n"); + return -ENOMEM; + } +#endif /* USE_RBPS_POOL */ he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys); @@ -800,9 +818,14 @@ he_init_group(struct he_dev *he_dev, int group) dma_addr_t dma_handle; void *cpuaddr; +#ifdef USE_RBPS_POOL cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle); if (cpuaddr == NULL) return -ENOMEM; +#else + cpuaddr = he_dev->rbps_pages + (i * CONFIG_RBPS_BUFSIZE); + dma_handle = he_dev->rbps_pages_phys + (i * CONFIG_RBPS_BUFSIZE); +#endif he_dev->rbps_virt[i].virt = cpuaddr; he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF); @@ -821,14 +844,30 @@ he_init_group(struct he_dev *he_dev, int group) RBP_QSIZE(CONFIG_RBPS_SIZE - 1) | RBP_INT_ENB, G0_RBPS_QI + (group * 32)); +#else /* !USE_RBPS */ + he_writel(he_dev, 0x0, G0_RBPS_S + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_T + (group * 32)); + he_writel(he_dev, 0x0, G0_RBPS_QI + (group * 32)); + he_writel(he_dev, RBP_THRESH(0x1) | RBP_QSIZE(0x0), + G0_RBPS_BS + (group * 32)); +#endif /* USE_RBPS */ /* large buffer pool */ +#ifdef USE_RBPL_POOL he_dev->rbpl_pool = pci_pool_create("rbpl", he_dev->pci_dev, CONFIG_RBPL_BUFSIZE, 8, 0); if (he_dev->rbpl_pool == NULL) { hprintk("unable to create rbpl pool\n"); return -ENOMEM; } +#else /* !USE_RBPL_POOL */ + he_dev->rbpl_pages = (void *) pci_alloc_consistent(he_dev->pci_dev, + CONFIG_RBPL_SIZE * CONFIG_RBPL_BUFSIZE, &he_dev->rbpl_pages_phys); + if (he_dev->rbpl_pages == NULL) { + hprintk("unable to create rbpl pages\n"); + return -ENOMEM; + } +#endif /* USE_RBPL_POOL */ he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys); @@ -843,9 +882,14 @@ he_init_group(struct he_dev *he_dev, int group) dma_addr_t dma_handle; void *cpuaddr; +#ifdef USE_RBPL_POOL cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle); if (cpuaddr == NULL) return -ENOMEM; +#else + cpuaddr = he_dev->rbpl_pages + (i * CONFIG_RBPL_BUFSIZE); + dma_handle = he_dev->rbpl_pages_phys + (i * CONFIG_RBPL_BUFSIZE); +#endif he_dev->rbpl_virt[i].virt = cpuaddr; he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF); @@ -1431,6 +1475,7 @@ he_start(struct atm_dev *dev) he_init_tpdrq(he_dev); +#ifdef USE_TPD_POOL he_dev->tpd_pool = pci_pool_create("tpd", he_dev->pci_dev, sizeof(struct he_tpd), TPD_ALIGNMENT, 0); if (he_dev->tpd_pool == NULL) { @@ -1439,6 +1484,20 @@ he_start(struct atm_dev *dev) } INIT_LIST_HEAD(&he_dev->outstanding_tpds); +#else + he_dev->tpd_base = (void *) pci_alloc_consistent(he_dev->pci_dev, + CONFIG_NUMTPDS * sizeof(struct he_tpd), &he_dev->tpd_base_phys); + if (!he_dev->tpd_base) + return -ENOMEM; + + for (i = 0; i < CONFIG_NUMTPDS; ++i) { + he_dev->tpd_base[i].status = (i << TPD_ADDR_SHIFT); + he_dev->tpd_base[i].inuse = 0; + } + + he_dev->tpd_head = he_dev->tpd_base; + he_dev->tpd_end = &he_dev->tpd_base[CONFIG_NUMTPDS - 1]; +#endif if (he_init_group(he_dev, 0) != 0) return -ENOMEM; @@ -1483,8 +1542,7 @@ he_start(struct atm_dev *dev) /* initialize framer */ #ifdef CONFIG_ATM_HE_USE_SUNI - if (he_isMM(he_dev)) - suni_init(he_dev->atm_dev); + suni_init(he_dev->atm_dev); if (he_dev->atm_dev->phy && he_dev->atm_dev->phy->start) he_dev->atm_dev->phy->start(he_dev->atm_dev); #endif /* CONFIG_ATM_HE_USE_SUNI */ @@ -1496,7 +1554,6 @@ he_start(struct atm_dev *dev) val = he_phy_get(he_dev->atm_dev, SUNI_TPOP_APM); val = (val & ~SUNI_TPOP_APM_S) | (SUNI_TPOP_S_SDH << SUNI_TPOP_APM_S_SHIFT); he_phy_put(he_dev->atm_dev, val, SUNI_TPOP_APM); - he_phy_put(he_dev->atm_dev, SUNI_TACP_IUCHP_CLP, SUNI_TACP_IUCHP); } /* 5.1.12 enable transmit and receive */ @@ -1547,7 +1604,9 @@ he_stop(struct he_dev *he_dev) gen_cntl_0 &= ~(INT_PROC_ENBL | INIT_ENB); pci_write_config_dword(pci_dev, GEN_CNTL_0, gen_cntl_0); +#ifdef USE_TASKLET tasklet_disable(&he_dev->tasklet); +#endif /* disable recv and transmit */ @@ -1577,6 +1636,7 @@ he_stop(struct he_dev *he_dev) he_dev->hsp, he_dev->hsp_phys); if (he_dev->rbpl_base) { +#ifdef USE_RBPL_POOL int i; for (i = 0; i < CONFIG_RBPL_SIZE; ++i) { @@ -1585,14 +1645,22 @@ he_stop(struct he_dev *he_dev) pci_pool_free(he_dev->rbpl_pool, cpuaddr, dma_handle); } +#else + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE + * CONFIG_RBPL_BUFSIZE, he_dev->rbpl_pages, he_dev->rbpl_pages_phys); +#endif pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE * sizeof(struct he_rbp), he_dev->rbpl_base, he_dev->rbpl_phys); } +#ifdef USE_RBPL_POOL if (he_dev->rbpl_pool) pci_pool_destroy(he_dev->rbpl_pool); +#endif +#ifdef USE_RBPS if (he_dev->rbps_base) { +#ifdef USE_RBPS_POOL int i; for (i = 0; i < CONFIG_RBPS_SIZE; ++i) { @@ -1601,12 +1669,20 @@ he_stop(struct he_dev *he_dev) pci_pool_free(he_dev->rbps_pool, cpuaddr, dma_handle); } +#else + pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE + * CONFIG_RBPS_BUFSIZE, he_dev->rbps_pages, he_dev->rbps_pages_phys); +#endif pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE * sizeof(struct he_rbp), he_dev->rbps_base, he_dev->rbps_phys); } +#ifdef USE_RBPS_POOL if (he_dev->rbps_pool) pci_pool_destroy(he_dev->rbps_pool); +#endif + +#endif /* USE_RBPS */ if (he_dev->rbrq_base) pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), @@ -1620,8 +1696,14 @@ he_stop(struct he_dev *he_dev) pci_free_consistent(he_dev->pci_dev, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), he_dev->tpdrq_base, he_dev->tpdrq_phys); +#ifdef USE_TPD_POOL if (he_dev->tpd_pool) pci_pool_destroy(he_dev->tpd_pool); +#else + if (he_dev->tpd_base) + pci_free_consistent(he_dev->pci_dev, CONFIG_NUMTPDS * sizeof(struct he_tpd), + he_dev->tpd_base, he_dev->tpd_base_phys); +#endif if (he_dev->pci_dev) { pci_read_config_word(he_dev->pci_dev, PCI_COMMAND, &command); @@ -1636,6 +1718,7 @@ he_stop(struct he_dev *he_dev) static struct he_tpd * __alloc_tpd(struct he_dev *he_dev) { +#ifdef USE_TPD_POOL struct he_tpd *tpd; dma_addr_t dma_handle; @@ -1650,6 +1733,27 @@ __alloc_tpd(struct he_dev *he_dev) tpd->iovec[2].addr = 0; tpd->iovec[2].len = 0; return tpd; +#else + int i; + + for (i = 0; i < CONFIG_NUMTPDS; ++i) { + ++he_dev->tpd_head; + if (he_dev->tpd_head > he_dev->tpd_end) { + he_dev->tpd_head = he_dev->tpd_base; + } + + if (!he_dev->tpd_head->inuse) { + he_dev->tpd_head->inuse = 1; + he_dev->tpd_head->status &= TPD_MASK; + he_dev->tpd_head->iovec[0].addr = 0; he_dev->tpd_head->iovec[0].len = 0; + he_dev->tpd_head->iovec[1].addr = 0; he_dev->tpd_head->iovec[1].len = 0; + he_dev->tpd_head->iovec[2].addr = 0; he_dev->tpd_head->iovec[2].len = 0; + return he_dev->tpd_head; + } + } + hprintk("out of tpds -- increase CONFIG_NUMTPDS (%d)\n", CONFIG_NUMTPDS); + return NULL; +#endif } #define AAL5_LEN(buf,len) \ @@ -1698,9 +1802,11 @@ he_service_rbrq(struct he_dev *he_dev, int group) RBRQ_CON_CLOSED(he_dev->rbrq_head) ? " CON_CLOSED" : "", RBRQ_HBUF_ERR(he_dev->rbrq_head) ? " HBUF_ERR" : ""); +#ifdef USE_RBPS if (RBRQ_ADDR(he_dev->rbrq_head) & RBP_SMALLBUF) rbp = &he_dev->rbps_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; else +#endif rbp = &he_dev->rbpl_base[RBP_INDEX(RBRQ_ADDR(he_dev->rbrq_head))]; buf_len = RBRQ_BUFLEN(he_dev->rbrq_head) * 4; @@ -1779,10 +1885,12 @@ he_service_rbrq(struct he_dev *he_dev, int group) for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) { +#ifdef USE_RBPS if (iov->iov_base & RBP_SMALLBUF) memcpy(skb_put(skb, iov->iov_len), he_dev->rbps_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); else +#endif memcpy(skb_put(skb, iov->iov_len), he_dev->rbpl_virt[RBP_INDEX(iov->iov_base)].virt, iov->iov_len); } @@ -1827,9 +1935,11 @@ he_service_rbrq(struct he_dev *he_dev, int group) for (iov = he_vcc->iov_head; iov < he_vcc->iov_tail; ++iov) { +#ifdef USE_RBPS if (iov->iov_base & RBP_SMALLBUF) rbp = &he_dev->rbps_base[RBP_INDEX(iov->iov_base)]; else +#endif rbp = &he_dev->rbpl_base[RBP_INDEX(iov->iov_base)]; rbp->status &= ~RBP_LOANED; @@ -1865,7 +1975,9 @@ he_service_tbrq(struct he_dev *he_dev, int group) he_dev->hsp->group[group].tbrq_tail); struct he_tpd *tpd; int slot, updated = 0; +#ifdef USE_TPD_POOL struct he_tpd *__tpd; +#endif /* 2.1.6 transmit buffer return queue */ @@ -1877,6 +1989,7 @@ he_service_tbrq(struct he_dev *he_dev, int group) TBRQ_TPD(he_dev->tbrq_head), TBRQ_EOS(he_dev->tbrq_head) ? " EOS" : "", TBRQ_MULTIPLE(he_dev->tbrq_head) ? " MULTIPLE" : ""); +#ifdef USE_TPD_POOL tpd = NULL; list_for_each_entry(__tpd, &he_dev->outstanding_tpds, entry) { if (TPD_ADDR(__tpd->status) == TBRQ_TPD(he_dev->tbrq_head)) { @@ -1891,6 +2004,9 @@ he_service_tbrq(struct he_dev *he_dev, int group) TBRQ_TPD(he_dev->tbrq_head)); goto next_tbrq_entry; } +#else + tpd = &he_dev->tpd_base[ TPD_INDEX(TBRQ_TPD(he_dev->tbrq_head)) ]; +#endif if (TBRQ_EOS(he_dev->tbrq_head)) { HPRINTK("wake_up(tx_waitq) cid 0x%x\n", @@ -1920,8 +2036,12 @@ he_service_tbrq(struct he_dev *he_dev, int group) } next_tbrq_entry: +#ifdef USE_TPD_POOL if (tpd) pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); +#else + tpd->inuse = 0; +#endif he_dev->tbrq_head = (struct he_tbrq *) ((unsigned long) he_dev->tbrq_base | TBRQ_MASK(++he_dev->tbrq_head)); @@ -1964,6 +2084,7 @@ he_service_rbpl(struct he_dev *he_dev, int group) he_writel(he_dev, RBPL_MASK(he_dev->rbpl_tail), G0_RBPL_T); } +#ifdef USE_RBPS static void he_service_rbps(struct he_dev *he_dev, int group) { @@ -1990,6 +2111,7 @@ he_service_rbps(struct he_dev *he_dev, int group) if (moved) he_writel(he_dev, RBPS_MASK(he_dev->rbps_tail), G0_RBPS_T); } +#endif /* USE_RBPS */ static void he_tasklet(unsigned long data) @@ -2000,7 +2122,9 @@ he_tasklet(unsigned long data) int updated = 0; HPRINTK("tasklet (0x%lx)\n", data); +#ifdef USE_TASKLET spin_lock_irqsave(&he_dev->global_lock, flags); +#endif while (he_dev->irq_head != he_dev->irq_tail) { ++updated; @@ -2015,7 +2139,9 @@ he_tasklet(unsigned long data) case ITYPE_RBRQ_TIMER: if (he_service_rbrq(he_dev, group)) { he_service_rbpl(he_dev, group); +#ifdef USE_RBPS he_service_rbps(he_dev, group); +#endif /* USE_RBPS */ } break; case ITYPE_TBRQ_THRESH: @@ -2028,7 +2154,9 @@ he_tasklet(unsigned long data) he_service_rbpl(he_dev, group); break; case ITYPE_RBPS_THRESH: +#ifdef USE_RBPS he_service_rbps(he_dev, group); +#endif /* USE_RBPS */ break; case ITYPE_PHY: HPRINTK("phy interrupt\n"); @@ -2056,7 +2184,9 @@ he_tasklet(unsigned long data) he_service_rbrq(he_dev, 0); he_service_rbpl(he_dev, 0); +#ifdef USE_RBPS he_service_rbps(he_dev, 0); +#endif /* USE_RBPS */ he_service_tbrq(he_dev, 0); break; default: @@ -2078,7 +2208,9 @@ he_tasklet(unsigned long data) IRQ_TAIL(he_dev->irq_tail), IRQ0_HEAD); (void) he_readl(he_dev, INT_FIFO); /* 8.1.2 controller errata; flush posted writes */ } +#ifdef USE_TASKLET spin_unlock_irqrestore(&he_dev->global_lock, flags); +#endif } static irqreturn_t @@ -2110,7 +2242,11 @@ he_irq_handler(int irq, void *dev_id) if (he_dev->irq_head != he_dev->irq_tail) { handled = 1; +#ifdef USE_TASKLET tasklet_schedule(&he_dev->tasklet); +#else + he_tasklet((unsigned long) he_dev); +#endif he_writel(he_dev, INT_CLEAR_A, INT_FIFO); /* clear interrupt */ (void) he_readl(he_dev, INT_FIFO); /* flush posted writes */ } @@ -2167,14 +2303,23 @@ __enqueue_tpd(struct he_dev *he_dev, struct he_tpd *tpd, unsigned cid) dev_kfree_skb_any(tpd->skb); atomic_inc(&tpd->vcc->stats->tx_err); } +#ifdef USE_TPD_POOL pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status)); +#else + tpd->inuse = 0; +#endif return; } } /* 2.1.5 transmit packet descriptor ready queue */ +#ifdef USE_TPD_POOL list_add_tail(&tpd->entry, &he_dev->outstanding_tpds); he_dev->tpdrq_tail->tpd = TPD_ADDR(tpd->status); +#else + he_dev->tpdrq_tail->tpd = he_dev->tpd_base_phys + + (TPD_INDEX(tpd->status) * sizeof(struct he_tpd)); +#endif he_dev->tpdrq_tail->cid = cid; wmb(); @@ -2364,8 +2509,13 @@ he_open(struct atm_vcc *vcc) goto open_failed; } +#ifdef USE_RBPS rsr1 = RSR1_GROUP(0); rsr4 = RSR4_GROUP(0); +#else /* !USE_RBPS */ + rsr1 = RSR1_GROUP(0)|RSR1_RBPL_ONLY; + rsr4 = RSR4_GROUP(0)|RSR4_RBPL_ONLY; +#endif /* USE_RBPS */ rsr0 = vcc->qos.rxtp.traffic_class == ATM_UBR ? (RSR0_EPD_ENABLE|RSR0_PPD_ENABLE) : 0; @@ -2694,15 +2844,10 @@ he_ioctl(struct atm_dev *atm_dev, unsigned int cmd, void __user *arg) if (copy_from_user(®, arg, sizeof(struct he_ioctl_reg))) return -EFAULT; - + spin_lock_irqsave(&he_dev->global_lock, flags); switch (reg.type) { case HE_REGTYPE_PCI: - if (reg.addr < 0 || reg.addr >= HE_REGMAP_SIZE) { - err = -EINVAL; - break; - } - reg.val = he_readl(he_dev, reg.addr); break; case HE_REGTYPE_RCM: diff --git a/trunk/drivers/atm/he.h b/trunk/drivers/atm/he.h index c2983e0d4ec1..fe6cd15a78a4 100644 --- a/trunk/drivers/atm/he.h +++ b/trunk/drivers/atm/he.h @@ -51,6 +51,8 @@ #define CONFIG_IRQ_SIZE 128 #define CONFIG_IRQ_THRESH (CONFIG_IRQ_SIZE/2) +#define CONFIG_NUMTPDS 256 + #define CONFIG_TPDRQ_SIZE 512 #define TPDRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1)) @@ -138,7 +140,12 @@ struct he_tpd { struct sk_buff *skb; struct atm_vcc *vcc; +#ifdef USE_TPD_POOL struct list_head entry; +#else + u32 inuse; + char padding[32 - sizeof(u32) - (2*sizeof(void*))]; +#endif }; #define TPD_ALIGNMENT 64 @@ -260,7 +267,13 @@ struct he_dev { char prod_id[30]; char mac_addr[6]; - int media; + int media; /* + * 0x26 = HE155 MM + * 0x27 = HE622 MM + * 0x46 = HE155 SM + * 0x47 = HE622 SM + */ + unsigned int vcibits, vpibits; unsigned int cells_per_row; @@ -284,9 +297,16 @@ struct he_dev { volatile unsigned *irq_tailoffset; int irq_peak; +#ifdef USE_TASKLET struct tasklet_struct tasklet; +#endif +#ifdef USE_TPD_POOL struct pci_pool *tpd_pool; struct list_head outstanding_tpds; +#else + struct he_tpd *tpd_head, *tpd_base, *tpd_end; + dma_addr_t tpd_base_phys; +#endif dma_addr_t tpdrq_phys; struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head; @@ -297,13 +317,25 @@ struct he_dev { struct he_rbrq *rbrq_base, *rbrq_head; int rbrq_peak; +#ifdef USE_RBPL_POOL struct pci_pool *rbpl_pool; +#else + void *rbpl_pages; + dma_addr_t rbpl_pages_phys; +#endif dma_addr_t rbpl_phys; struct he_rbp *rbpl_base, *rbpl_tail; struct he_virt *rbpl_virt; int rbpl_peak; +#ifdef USE_RBPS +#ifdef USE_RBPS_POOL struct pci_pool *rbps_pool; +#else + void *rbps_pages; + dma_addr_t rbps_pages_phys; +#endif +#endif dma_addr_t rbps_phys; struct he_rbp *rbps_base, *rbps_tail; struct he_virt *rbps_virt; @@ -360,7 +392,6 @@ struct he_vcc #define HE_DEV(dev) ((struct he_dev *) (dev)->dev_data) #define he_is622(dev) ((dev)->media & 0x1) -#define he_isMM(dev) ((dev)->media & 0x20) #define HE_REGMAP_SIZE 0x100000 @@ -845,8 +876,8 @@ struct he_vcc #define M_SN 0x3a /* integer */ #define MEDIA 0x3e /* integer */ #define HE155MM 0x26 -#define HE622MM 0x27 -#define HE155SM 0x46 +#define HE155SM 0x27 +#define HE622MM 0x46 #define HE622SM 0x47 #define MAC_ADDR 0x42 /* char[] */ diff --git a/trunk/drivers/atm/iphase.c b/trunk/drivers/atm/iphase.c index 24df73ad326d..5c28ca7380ff 100644 --- a/trunk/drivers/atm/iphase.c +++ b/trunk/drivers/atm/iphase.c @@ -65,7 +65,12 @@ #include "iphase.h" #include "suni.h" #define swap(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8)) - +struct suni_priv { + struct k_sonet_stats sonet_stats; /* link diagnostics */ + unsigned char loop_mode; /* loopback mode */ + struct atm_dev *dev; /* device back-pointer */ + struct suni_priv *next; /* next SUNI */ +}; #define PRIV(dev) ((struct suni_priv *) dev->phy_data) static unsigned char ia_phy_get(struct atm_dev *dev, unsigned long addr); @@ -89,6 +94,10 @@ module_param(IADebugFlag, uint, 0644); MODULE_LICENSE("GPL"); +#if BITS_PER_LONG != 32 +# error FIXME: this driver only works on 32-bit platforms +#endif + /**************************** IA_LIB **********************************/ static void ia_init_rtn_q (IARTN_Q *que) @@ -1402,6 +1411,7 @@ static int rx_init(struct atm_dev *dev) struct abr_vc_table *abr_vc_table; u16 *vc_table; u16 *reass_table; + u16 *ptr16; int i,j, vcsize_sel; u_short freeq_st_adr; u_short *freeq_start; @@ -1416,15 +1426,14 @@ static int rx_init(struct atm_dev *dev) printk(KERN_ERR DEV_LABEL "can't allocate DLEs\n"); goto err_out; } - iadev->rx_dle_q.start = (struct dle *)dle_addr; + iadev->rx_dle_q.start = (struct dle*)dle_addr; iadev->rx_dle_q.read = iadev->rx_dle_q.start; iadev->rx_dle_q.write = iadev->rx_dle_q.start; - iadev->rx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES); + iadev->rx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES); /* the end of the dle q points to the entry after the last DLE that can be used. */ /* write the upper 20 bits of the start address to rx list address register */ - /* We know this is 32bit bus addressed so the following is safe */ writel(iadev->rx_dle_dma & 0xfffff000, iadev->dma + IPHASE5575_RX_LIST_ADDR); IF_INIT(printk("Tx Dle list addr: 0x%08x value: 0x%0x\n", @@ -1578,12 +1587,11 @@ static int rx_init(struct atm_dev *dev) Set Packet Aging Interval count register to overflow in about 4 us */ writew(0xF6F8, iadev->reass_reg+PKT_TM_CNT ); - - i = (j >> 6) & 0xFF; - j += 2 * (j - 1); - i |= ((j << 2) & 0xFF00); + ptr16 = (u16*)j; + i = ((u32)ptr16 >> 6) & 0xff; + ptr16 += j - 1; + i |=(((u32)ptr16 << 2) & 0xff00); writew(i, iadev->reass_reg+TMOUT_RANGE); - /* initiate the desc_tble */ for(i=0; inum_tx_desc;i++) iadev->desc_tbl[i].timestamp = 0; @@ -1906,7 +1914,7 @@ static int tx_init(struct atm_dev *dev) iadev->tx_dle_q.start = (struct dle*)dle_addr; iadev->tx_dle_q.read = iadev->tx_dle_q.start; iadev->tx_dle_q.write = iadev->tx_dle_q.start; - iadev->tx_dle_q.end = (struct dle*)((unsigned long)dle_addr+sizeof(struct dle)*DLE_ENTRIES); + iadev->tx_dle_q.end = (struct dle*)((u32)dle_addr+sizeof(struct dle)*DLE_ENTRIES); /* write the upper 20 bits of the start address to tx list address register */ writel(iadev->tx_dle_dma & 0xfffff000, @@ -2554,11 +2562,17 @@ static int __devinit ia_start(struct atm_dev *dev) error = suni_init(dev); if (error) goto err_free_rx; - if (dev->phy->start) { - error = dev->phy->start(dev); - if (error) - goto err_free_rx; - } + /* + * Enable interrupt on loss of signal + * SUNI_RSOP_CIE - 0x10 + * SUNI_RSOP_CIE_LOSE - 0x04 + */ + ia_phy_put(dev, ia_phy_get(dev, 0x10) | 0x04, 0x10); +#ifndef MODULE + error = dev->phy->start(dev); + if (error) + goto err_free_rx; +#endif /* Get iadev->carrier_detect status */ IaFrontEndIntr(iadev); } @@ -2899,7 +2913,7 @@ static int ia_pkt_tx (struct atm_vcc *vcc, struct sk_buff *skb) { dev_kfree_skb_any(skb); return 0; } - if ((unsigned long)skb->data & 3) { + if ((u32)skb->data & 3) { printk("Misaligned SKB\n"); if (vcc->pop) vcc->pop(vcc, skb); @@ -3184,8 +3198,6 @@ static int __devinit ia_init_one(struct pci_dev *pdev, IF_INIT(printk("dev_id = 0x%x iadev->LineRate = %d \n", (u32)dev, iadev->LineRate);) - pci_set_drvdata(pdev, dev); - ia_dev[iadev_count] = iadev; _ia_dev[iadev_count] = dev; iadev_count++; @@ -3207,6 +3219,8 @@ static int __devinit ia_init_one(struct pci_dev *pdev, iadev->next_board = ia_boards; ia_boards = dev; + pci_set_drvdata(pdev, dev); + return 0; err_out_deregister_dev: @@ -3224,14 +3238,9 @@ static void __devexit ia_remove_one(struct pci_dev *pdev) struct atm_dev *dev = pci_get_drvdata(pdev); IADEV *iadev = INPH_IA_DEV(dev); - /* Disable phy interrupts */ - ia_phy_put(dev, ia_phy_get(dev, SUNI_RSOP_CIE) & ~(SUNI_RSOP_CIE_LOSE), - SUNI_RSOP_CIE); + ia_phy_put(dev, ia_phy_get(dev,0x10) & ~(0x4), 0x10); udelay(1); - if (dev->phy && dev->phy->stop) - dev->phy->stop(dev); - /* De-register device */ free_irq(iadev->irq, dev); iadev_count--; diff --git a/trunk/drivers/atm/pca200e.data b/trunk/drivers/atm/pca200e.data new file mode 100644 index 000000000000..e78e83becd95 --- /dev/null +++ b/trunk/drivers/atm/pca200e.data @@ -0,0 +1,850 @@ +:150000001F8B0808AB5A10380203706361323030652E62696E4D +:150015007D00E43A0D7014D7796FA5BDE84EC86211A7333020EE +:15002A00AD89C00A23EA83AA589C7E7C38D8152EB887477677D3 +:15003F0095C39C3DB2AB388CA324C4A509352BFBB085BBD0C73F +:150054007210B903C92991CCD1B1C242255BCCD81EA5C34C6826 +:1500690006271AC6D36A3A31B976D4A9A683DB4B07BB38265C56 +:15007E00BFEFBDB7777BA7030B2733994C35737AFBBEF7BDEFE7 +:15009300EF7DDFF7BEF7769FFEEAD79F221221E1ED844C3E4677 +:1500A8007EA3BFF036F827CF8597C3AF0C7E920B16595BCE5AA8 +:1500BD00296B6483D83E9F7DBE8FF50BE74A0B45FB1F274FAA79 +:1500D200D82E2867139DF637FD937EF1D55FB0769FE8678BDAFB +:1500E7007D9BD8885451515172FE27E4138E9FC9949CBFF026BC +:1500FC00741DF83ECE59823FF23BF89346493F6B4F17C1B3A7CE +:15011100B3B79C97D3275B5ABFEC3CF9579457703B3CBFEFD600 +:15012600FC38236CA91B5E347EDBFA67F7ED4397956EA4D3C5F4 +:15013B007CE6A567799EFFF5CFC4FF7BDF938BF83E83EDE59F02 +:15015000FEAC24BF8A3C3F2FF9FDFF933CF51EF2FFEC2FEBFA11 +:150165002341C38CBC5F4EAA265F5EAF04BC51F0059FD1419ED8 +:15017A00063493D465A2384E66A0171C30231F40AB5CB5646FC8 +:15018F005CBFB633DECCC614D2DAF622F15D3189EFEA3EE28B83 +:1501A4007D99F8DABE4D7C2418A438AF3129015D7507F1032EBA +:1501B900E174827F46C82229AE2BC63A9D50E9253960EC005FCA +:1501CE00F2EDFE0AF12A9D5EBD6A35F1B5AC441A49BAD94F22C6 +:1501E300DECB544F180D1A51FACD8C4A7C034B93DAFD6455A8F9 +:1501F8009AAC5AB74C9542EF11E23DB0946A0F1B0DA10BF0CC0C +:15020D00F9A4A8097BCA1D751474A02FEC02593C75C9E870D176 +:15022200B8CF352EC3783C379E1C2893C98017C6A57B3CDD0E4D +:15023700CE32426A9CB99F03FC2E81BF46AD0D06544FD0190B08 +:15024C00C0580B8E897EFDF490DE08FD652E9CFAE911DD5F24FE +:15026100CF832469DAB1116BE0F3C437B686F8D275C437AC9220 +:150276000542BFF6CC0320B22AB7237E1F5B97A4E927A397490C +:15028B0064C43AFF0CD8ACCE8886D37F632A7F4C16005E289CAF +:1502A0003E491DDAFB083513C6B0A6B8E4929626F531E0877479 +:1502B50082E58C9E2503DDD45DC4777E3BF1051F253E09684E42 +:1502CA00C3BAC26825AC39F5225F6598EE23B366227C52ABFC3A +:1502DF00BC2754E61BD1FFEBAE6DCDFE8D49AAEA38EE89A35A1B +:1502F4009DF0DCF4254234681BBB09E98536033F2F3C5F835F24 +:15030900107E147E1AE8AA0406A36989DB63C95ADE9F9272EBA7 +:15031E00C17C6131AC4519193457028723BE118D0433D6F063E5 +:150333005C6E1C77EC2981FD118663B2FA3A455F8D11A2D66BC0 +:15034800AFE9B096E6D4A38454D70D004ECA8235541117C7A5F2 +:15035D002D26F8E4B07D3848BA956402FC7BF8EC956CB6B6D35F +:1503720091EB21B280C218CAB04122B5957583D126189B7D88FF +:15038700FB2BDA46560F52056C867C6CE85FF1135F19E0C948D1 +:15039C0023873342916798F3A6E45FA58C9021887DB9A8DF9307 +:1503B1002EECF7421F693AB054DE6F73F4FDF414E83A6B66B2C0 +:1503C6000B11C3BA0E45D0D1074E3318C92C24FE074FF267E847 +:1503DB00E03AE67193D635C40D9FD66A65B471CABA5AC66D9C17 +:1503F00081B68DE4F5200AEA316B3E3EF5F8D4CAF0C902BFBC6E +:1504050003FD12ED00BE39F8E7C4E765F2A6F8BCC8083DA6B648 +:15041A00335DAAA0AFC4DEA66A6CDC8418EA26910FAD6A0821BE +:15042F0012B4A9C269D1DDAC9DB05A98BD06B91D807702D6021B +:15044400F02CA479BF88CD3D82BE3F92D49137C262E0EB5969BB +:15045900D6AC8DA4F4A3A0EB808FEB8570E6F34897F9F77CE4C2 +:15046E0071E4E07C73F2C0FC256AC3208B2D5C834D43BA3F060F +:15048300F39566B386103FC611E321E23D02F1168A79426C3DFD +:15049800E159DA32AAA34C083FBA62DC2474847A94BF031D86A2 +:1504AD00ACE5EAEB969CDC4FF3F3216F03DE5414FD8ED3DA3050 +:1504C2005F5AC953795A804F2146D05612811C0DB6A0BC0E67DE +:1504D7007C6E471FC3A5CFA04B06639EFA201E11FA182E7D3E53 +:1504EC009556913E89227D129F511FDBA5CF05970CF63CF54199 +:15050100BCE097B83EB64B9F4FA555A4CF60913E839F511F752A +:1505160026AF4FCB4C5E0684CF471FC48B75737DF079C37C69B3 +:15052B0015E973BC489FE32E7DC231AFD997FEF15925301975DC +:150540007CBC5E33F5D918F2E53E82FD69D1B745FF82E8237F22 +:15055500EC4FB07ED2A4626FD8C3F7363321FA29D11F14FD6938 +:15056A00D13F2EFA9D40678FFA1ACBD131181B507F88FBA8451E +:15057F00E179507D8362EC4FC2734A7D8786D5D526CF431356CC +:1505940010E6D51152BB2CE6690F243DED35694FBB17D6017487 +:1505A900B251C766F514A3D3037337AB67189D043C77A9E728AB +:1505BE00CE3FCFE5A0C8B347ED17F9CDB09A812EE4A09AFBC861 +:1505D30005F3ECCE1F76B0B8059C6AD51342D87777BEC16093F7 +:1505E8002ED82B3BDF613094C9813DB7F3A50E87FE6A95AF1F58 +:1505FD00D259C69E53B447F047991EAA1FDDE8D0747091968332 +:15061200EBC88AB2D5095CA4FB07AA87ED030961D37494DB348F +:15062700C27225D77D497EBF32958271CE6F8DA0D12CF612E37F +:15063C00718ED32568206F3FDF874C7B477EAC4DD8310AE35B40 +:15065100C17E683B139EA3EA6178A6D65B4CA65926E72EF555F4 +:150666007A82D977D06A9A610E58F3D80D4F6BFDF4DDFAC37506 +:15067B00E7D67D672AA93DD881720C301B55C6E4D0860EB97506 +:150690007D5DFF3A0A636BD898CDE4AD4C7A42CBDE915B037587 +:1506A50087D7593056DDC1E5477B55429CDCF8B5DCFAAB15AFBD +:1506BA00AE3B0263FFD3EE69AF8C5584FEF3FD0FDA90E6BFADE7 +:1506CF0030DB70FEBF9C186B43DC4BEFBFDE4682BD8C27C86F5A +:1506E400B3BC185CC264063DED086BF730DA2418B655D6F63110 +:1506F900394850B53126EEFCD1AC2EBD1B83F83B6D56056C5662 +:15070E0027F079B3565739DFC3A2AC8D591AB48B37FD4097B6BD +:150723007D4527CA41F38E00D6C48665887A30CEDA5E6BA09CE8 +:15073800EF7568CF8A7EC03FF80DC05F6B56078280AFB25C86D9 +:15074D00F863ACEDB32658DBC26CBEE04780FFEEB7017F9BB98C +:15076200301001FCB0C5E54E5A0DD0BEC8D6618FD53893DFDBC0 +:15077700489D0A781A5B9B27616DFAD4435409C08E179C365B01 +:15078C00B86D2C5EB34E5BCDD0CEC0B98106CBBA25A29A87AEC7 +:1507A100676BD0977601BC4A7DCDC2BA15ED575E1DD7B78610CF +:1507B6008FC715EE954F0A5CB4B78837139F9F079E8AEFA21E32 +:1507CB00DF9814679714AB9163E99F59FEBDE3263A704FFA4DF8 +:1507E0000BFAD400D9FCE1115DF1C541C7772D591DB7BA1C7929 +:1507F500D4BBCC1B9F701EC761BE22E4A1429EB736E6E5C1BDA9 +:15080A00EE92C09D74C933790B79222E79BA401EE8535A429E39 +:15081F00F3ABF2F23C2B785CC43812F24C0A799A5CF2E05E759D +:15083400BFC0457F73E4C1E79BC91376C9B319E4813E4D9690D5 +:15084900A7D925CFE55F711E6D33B8A771799007CA73BC252F86 +:15085E000FEE3567392EE35506B935DE3E625D87B3AC9363DDC5 +:15087300675D387B325FEEC53DCA370CF1D064D2707F1F9E1BAD +:15088800BCCC7732962CFCB60AF76B17AFD80C1694A4D6EBDAB7 +:15089D0047E58DFC1CEB75E1E10563311E21B6794C95704FA00C +:1508B20031EEBF8BC93DD0270326EC0F8A54674771FCCEF0B040 +:1508C7007E67F81CD864D8EA401CC819480FE1811DBC76E5FDFE +:1508DC00733A83FDD508D6AA24406D9DCF3FA75FCC66FD65D592 +:1508F100FDFAEE7BF332F5F0FDC225936D769033AD01550A3A24 +:15090600BCF12CBF86F184F305E007567C68E59EDB3FCCF1498D +:15091B00D79F692B73E8803CC25E4CAEDA152370463A4A2DE42F +:15093000AB34998BC0DE1BD01C0AA7C5715314ED0FC74F4B510E +:150945005ED2BDC9319893001F18B3A2AE734B17D4E2CFA89EB1 +:15095A00D6B7245E6394E2F350520E95A6DD6079943780F65B70 +:15096F00507B1C857AE36D0B6B12491D8133EA88E6D41A72B92A +:15098400A835607E52D421448C255D7548EE0F723FD656E84744 +:15099900CA3D28974DE33C4751AF90CFEB9603D61BE545BA8197 +:1509AE00906D2A44D446CA190BE550DE5F85B273DF637264CCC1 +:1509C300C15E487501388B928C8974B4ED9C4E8FD80F395D9B32 +:1509D800D9A7F6FDFD5482B3B6141B358F92514D3A30CEEA2EE8 +:1509ED003EC7B6108744E478BE6ECB98555F46FA54D0E77A23D8 +:150A0200FDE876AE1FE7932AE0C3EC226CC2EC98E676BC7347DE +:150A1700DC0A446C361675F3A48267306C72595A4C85D9A5D310 +:150A2C006467AB60D0E4761AA00C1E19A6CFDE057584F27DAC4C +:150A4100810A64F09F5845DD6B073896ACC05936324E1D3FC1D0 +:150A56001C843796C7485C2391FD168998CC2EAC0E807119F419 +:150A6B00A52D86899716E555719D1E5CABF77860FDA686D87D2E +:150A8000881FD74839ABCBEADB34C06AE6FC196F49F9DC3367A7 +:150A9500FF9653FCBCE83E774E9DC198FD9433E7203F734E0EF2 +:150AAA00E7CE9BECEC19F9BEE5F8961C30A2634DFCFEA0D0B70D +:150ABF00B82FA14CBDC23E6C6D4249E6574419B2081DA247F1E2 +:150AD400AE02FC0A7D81D9CC00FA74C84ADCC82E72F9336B3524 +:150AE90075186487D8A757CCC5B06FE37D56B5BAAAF912D674D6 +:150AFE0012F13EA3AE0D5D83985C9FF6B7B3DAEE31CEB713DA06 +:150B130045E420F33B90DB12700BE117C47D4058E0468A700568 +:150B2800DC42F87111EF0EFD1E316777D11C01B710DE2BE8F75C +:150B3D000A5CA30857C02D84B709FA2B05FD06818B78F8BCDCC9 +:150B5200956F1A5D63F88C67293C4379C18FCAAB46C037862CF0 +:150B6700B497ACBCA2E37A07D5613B00F6AA091FED901553AFF3 +:150B7C00EDBFA257A9A7AC65C6076D814DFFADCBB131EB44D2FC +:150B9100D3ED8D9966269B5D0C355EAB1CBB62393E5B09B92DA1 +:150BA6007D3DEB73C7C0B7A0CE95599D4AE7C4A388AF5C5E4121 +:150BBB001ACAA1213D513EACA16C353B1A2C279ED9DA634E30EB +:150BD0002027A4DFC63C22E273C22A8E67F405C61362C61D27AE +:150BE5002FDE11D7C365DC0F1591D33E2D4E5E82FD3B17230768 +:150BFA008634CC078AD84F31565642CAC2B3E0D3AC9E17310500 +:150C0F00F1F318F89BA8DF73B0FBC5B9E2E6B1D4226269A8F448 +:150C2400FD8D2B9E7ABEF0DBCFD57473E2296C3D2DEC7EBCF2E1 +:150C3900AE00DF13950DDEA802CFB7FA713CC25A35E0ECA52AC3 +:150C4E00D412F544A96ED2E3655F78CA23E0B4C678CA19C73BC6 +:150C63007A25DCF084ECD008279EA8719E37E5E1B9FD8ADDB182 +:150C78000DC0764CD423AADC4D73B519BFDF7C84EDF7B3589BA5 +:150C8D002978178F2324729206D4F666ACDF181C6C7FFDBEF62F +:150CA2003F04FFB4091D3E8BEDE2C8A08EF7A1481361354A427E +:150CB700BF0075C79CFD52F0EFBA09FFF58CFF80C9F2281DB6EB +:150CCC00918E943ECEE946809780E173BA047D6A637DC3E9E326 +:150CE100FD30D41426ABD5A0BF066353F5B7AD57AB426111E732 +:150CF6002175793BD0A435CA01DD9101E36E51513FF72CF85916 +:150D0B00533FD0D6AB0F846AD4079A03EAAAD056276FA94F71C2 +:150D2000DA82A6E43B3E87AEF48FB786AD4E2F6F75EEA36584E2 +:150D3500837D8F64208743DE10F7CD8B56A7E5565C0F7627CD82 +:150D4A0071E811C84132E2404C200ECA9A85BA8E1AFB35425244 +:150D5F00980BCDECDF9F97C1AF71CF55D02E2C2EA660BF823D2D +:150D74006135190E61FC6476BEDEE1BEA7FD9C787F107F84E908 +:150D89005860EF2C9930495D2A9AA76D08DAB6C1624F81FD644F +:150D9E0072445B638C94A45D2168373E42BCEE7D285F5F65CC2D +:150DB300E4D7B03E3172F5C9FCF381CDF301E856321F28AE3A51 +:150DC80028771E688C4A5BD641CD07B107B58A72379C210E6DFD +:150DDD00D477415EF648712D0AAD1C4846132A3F977C1772DDE5 +:150DF200B1E4C7CDE4EA10BDF6B5FC7B8D3D5FFFDDFEA623C476 +:150E070037F149D60767196DF37D72BB73D787F76764B77176CD +:150E1C0012DFEDED4E9E9D62ED24C612B4E9B319F6CE0FCEC553 +:150E310060A795E28EC5592B49ACD55EA03DFBA77C1F408D2F19 +:150E4600C19925111ED61AB1FD22D431CC768DCC76686BC46913 +:150E5B00025948755C5BFE89B05F4C62F603E3079A805E15C03F +:150E70007F7E9F7C2F5BCFEDA2BE82166B17AC59900EF6BB59E8 +:150E85003D95F781473ED50706C49DFE70491F5072FB7DC6422E +:150E9A009DC136B6B08D2D6C630BDBD8689B72C8E56E9F99AF8B +:150EAF003DF1DD13D451C14A757F10CEF8BE3C6C2DC00E06535C +:150EC40005B03F02D8D1E09803AB42582DC056042711C6EE3D4A +:150ED900B87DDFFB18EC09763DFFF15CBBBEF730F18D7D8C764C +:150EEE006DB877BE7ACD579F7809FF2813FE1105BE17B615CA1F +:150F0300D922135F23C8E20159979490B511E67899AC4DF7DEFF +:150F1800CE1ACC57DEDE12F2960B795F0759976C9BEBCF06FAC8 +:150F2D004B095F8E5DCBFACA408FC8B5B97AC4804EF81AEAE194 +:150F4200BFF7767DE976F4E929A18F2CF4F9F956E2EB84DF675D +:150F5700E1BFF97F4127B5812A6A1365EFE620074AB029B701EC +:150F6C001CFB32E934357C0E6AA60AD659AEEA96A26EFA5B76F9 +:150F8100970E79676B6C88BD2B8E7D53DCF73CC76A5433FD0D60 +:150F9600A89D643847E33B55DC9401EF62EC9455F5C419EBC295 +:150FAB00479C3601BAD9858639057D89F7BD631F15CA33267057 +:150FC000DF83B68B244DBFCAF9118DF3433EC8CFDE5DC86F3932 +:150FD500E0553D71CADA0AFC3441837EC4F9C5043FE87BDDF609 +:150FEA0054843DCD3FE1EFB8AF3E440AC61789F15D62FCBDA29D +:150FFF00F11A31BE558C8F158D2F16E34D623CC1C63366D79E29 +:15101400FC793F0B3A5202FB37ECD5DEE52452707687BF81A5FC +:15102900B646E14C41EA923BF0AC5963EC5F87EFF53591D70ED8 +:15103E002C9DD53AC22F873A5DF7E92F4C3CF113B4D573BB2F35 +:1510530075045DF0CBAFFEF57584B7EEF84987FBFE7DFA8D6F83 +:151068009D40F893FFF0E30EC2BE871834E3FFFC179BFC0163E8 +:15107D0047B297F8269F24BE3972BAEE17827F59B87FCB380E23 +:15109200F9167388548D39197231C24AECC74EAE81B351FBEE40 +:1510A7002DE2DE07700F6C19D52A638F065F811671F66EE7672C +:1510BC003C1C73CE320C5644AF8EDFF7F1EF332E0FE8F683F8F2 +:1510D1001D01FB1640C47E8ADD2918BE51B6571056CB2419BE69 +:1510E6005F39CDEE52768B7B1784A9EA283B4BED71C18202D67F +:1510FB00E7823509D8DE99FCB707866B1CED4B26086954472D8C +:15111000370CBF436C2882554932692E84518A67BFD838550E10 +:151125008DEA2D3826F4C6EF6508BD9BD99D8AF91FDC58F453B2 +:15113A002F9B9FF345D18A7E649C4A07F09C0338ECFD3DE713EE +:15114F005647E93EA827B19EC2F3EE65F0B7441FE9C6F74ED3D0 +:15116400397FE1B66DACE2760DA74FE6E40CA74FD3FE2DE3DA2C +:151179006675DC72D37C79E98086FB33D28C15ECEFA3ECEE6226 +:15118E00AB80ED1132EE113206605F6732E27B2576864DE1DED8 +:1511A300CF6A05B6F78BB51C106B298B6F2998CDA06605DE16C5 +:1511B8007EFF9280338317CFA17866127A7845AB14B5176F64D1 +:1511CD000BEA546EDF93EC5E0EF76903F4C3332E3E3B30F2F086 +:1511E2005C58991BC6EAE794D509272B493C6F56381C6C66A124 +:1511F700DD6A33CCCE0143C8C160013B1AD89812E727389FC223 +:15120C009C5A03D60DD688B591717321D2A3A356297C52029F42 +:15122100E4F0DFE4F605183C5B7B9DCFF944FCBD20F4E4B19C55 +:1512360062758BE4E804CF57A514F3F7A03F3FFEF296FCB8034D +:15124B007BA9044C7E782ECCE386B9623AE7DF22A69C7875C78E +:15126000727F512C633B25C66E36C72831C7196BC4F68BF9B97C +:151275009590BB8DBBC902278FA04D5E747C0E9EEBA7E37AAC39 +:15128A00687CC1E594CE69A4CC1648B68998A71B7CAC06F7016D +:15129F0073733E27A17F605C38637DEE31F6ED1BA7C35A178D76 +:1512B400CE221A8E0DB80F7298510C037A2F38307F1E66948027 +:1512C900555617C250A7FD2E9D1D58BC04ACBCDA0D334CBB4EC1 +:1512DE0026E1D5C23EB08F60CEC0B8F483CF634D85DFE4B17ECD +:1512F3002015AD75BD4B225584BD3342FFF533FF1D311D3FAFDB +:151308003C84DF1BD87400BFB50BF35C568A8672DB34600CF7B2 +:15131D00176514F12C2D1717498AF91CF3E12ECC25D0C77907C1 +:1513320097A634461F7DC54F6829B8E2829B6EFC25A5E10AC018 +:151347007B9DEFDEEA788E75DB6BAB74137BF94BEBBAE0B20DCC +:15135C0067E4D1BE83504BB03C301FBBFD1669A19EB75A03F3CC +:1513710076E4FACCB40AD7D51679DED9AB793E2EB475613E2E11 +:15138600210BCCE1B2A44CD602ED85480F6ABE927628814F729C +:15139B00F885F2ED75F91DC6AF543D37BE49F5DCF82EAB9E1BB7 +:1513B000CBA404EC15DFDCF8F654CF8D65B90886F847DC73F32E +:1513C500EF3C2B79FD8531CEF706B469BD6BEF83D6D825BEDF9F +:1513DA0020AEBD50291A935D63FEA231AF6B6C49D158956B6C58 +:1513EF00B922F611E52D4A1493CAEA307BCFC4BF63A4F41A6BD3 +:1514040007E9F532BEE765581B34A1A82072F5889E30C635FCEE +:151419005676B13CA21F2B1FD78E854735AC55BE639CD3BC1730 +:15142E003FD0192E201F360E68CA5653AF81BC5CE97AFF8BDFE1 +:151443008FCAE638833F17AB0ACDB8D613DFFBFFD37DFC7B9AE7 +:1514580058EEDB1B80CFF0335F65F2D7CDCB92DFC4EF4EC4B7BF +:15146D003313ECBB277E5F3EC1BF8D080E50FEBD0C1538830C25 +:15148200A7D7F57E03DF9F3F2BF84CCEE17347011FFE7DCD0460 +:15149700FB7ECAE1630B3E5D820FC719345551A725A13D119479 +:1514AC00BA2B0E8DE8FEF02AFD353C9FC4EE6E0BC42A425745A7 +:1514C1007C5D8ADD139A85672FD8BF5E8BEBD433DA5719F3B4AB +:1514D600E33A292ABE8B033BBE097935297577A9A72C388AD66C +:1514EB00C8CA5A88EB03B42E7CB0ED30665CA5DFC46F5D37FF53 +:151500003B9CEB22BFB41AD45F5ACEFBE836F58015560F5BFEA9 +:15151500F408FDBFF6BE3E3A8AEBCAF355AB5A6A498DA816ADA6 +:15152A0046C2209588708447715A422648964C43182F78306934 +:15153F00639CAD12C26EDB644C1C26A3DD61E7704E58BB255AC4 +:1515540020E10729D548462638B4B064E30938322B123C47248E +:1515690062E275F02C61B48CC390C4269D19C626332456BC4A65 +:15157E0086CD38F4DEDFABAAEE9210FE9839B367FF58D5D1A9A8 +:15159300EA57EFE3BE7BEFBBEFDEF7EEBB657887B6D5087BF17D +:1515A800081FA63A83A941B22B5F3491CE945E0EDF6E779BEBA1 +:1515BD00BF3ED0EC2E5FA1FD996EDA75A02C9E5157FCDBF00DF9 +:1515D200AF6E8D4C2B5F4CE523EA336693FA8A5DBE77C6F2D17B +:1515E700E31818D5AD80254CEF6AD47623AC7673ACFB9A2CD1D0 +:1515FC00A6A93F37BD12FC228E7293F5B5C9B184594CF2CC8307 +:151611007DE9E8A0E98BF59AFED8A869EDDBB8F9F8A4CDC7F152 +:15162600297C9CE1DFB1214D71F16F51CCDB98E151EC1B61AFE5 +:15163B008478348FE466095BA45B7DABB6FA16196876F3735093 +:15165000ED364231F94E6BBFC1E0F0E51DF97BAC8FC45BA1DF9D +:15166500AF6E60F987CA929AA22E16B459053AC0F5491D31629D +:15167A00EA5123A26EE04A68756B1FE9A75864EF1B7F41737C57 +:15168F00777BEDF1DB6FF95B14BBFD285AA9BF3945A7743575DF +:1516A4008C67CB1C31B9ED0FE7E415FB9AE349AD9878DC5D3E9C +:1516B900AAF61A1BA87D8DE0D0D483F47FD56853AB8CED6A8D70 +:1516CE001157EB8D2EB5C930D45544BB477493FD595B754AEC79 +:1516E3009FB6F553FEA43A6A1C51B9D1F7EC515EC28EE97336A4 +:1516F8003DCB17BC759527367D92772E58CC776DAAE5BB9F6D89 +:15170D00E05D6FADE04F2F38CEB166F2B91FC0892426ECBAFDF3 +:15172200CF9EE2FED387F59EB7F6F262B677A91B2E3205F38BA3 +:15173700D455CD99B46807AF92587EB13B4D74A083F39BA4BF13 +:15174C0071217D43BA16EB3032FB606FDDF89E191DFCFD821912 +:15176100EA235E1B79279D5F953C6C88B1053FE0CB37DAD7F014 +:151776008388129F788B3A85AE7290F2BC1FCCFA9DF8A6FB9DCA +:15178B0010AF1E14B65E3B7C7A4CE13F4D63DF4B32A32F49FA86 +:1517A0006CD3104F596B5EA6DF3A5F31A744D87D9326DEAB6A39 +:1517B500027BA94167BC63FD5E8B55124FE0EC483B8FBBDA56CD +:1517CA0066F0C3F1C5A85D3127C44DEC57F6A9528B323AC0AF33 +:1517DF00D96D627F734A9BF4DE37ADCDE9FB071B5CED3357FB1F +:1517F400EA0CEDCBAEF6E7CFD07ED5C76C1FFE3589863077601A +:15180900010C3BE65830CCA7B6A6B7AF8CBE28DA526303A46BCC +:15181E000CB732A5D384EF8F4CB67188DA9D1F1B309E5EF06B13 +:15183300E1D331E9F6F371EDCFAC7D2AEB3F22E52774A9ECA464 +:15184800BE7EACB3D1B78E0B5D46B92FA995EC18E1511F8B60C6 +:15185D007C96EC18E4317A866F01F21B296F0B337E6D62EF18A4 +:15187200699E6969D4D712C77F24188AB5865929DFD939B88DCC +:15188700190F70F08FFA790234A4B5FACEEDA1F64EF292D096AF +:15189C00D6B93B8EF208B5118C5B3A33F2083F10E3707FF1B807 +:1518B10021F67738C13277473D27B9DDD6B177ADF0F3098696FE +:1518C600B576DCFB29FD3CE1E9B598E74ECFA5FF20CE4084AD8B +:1518DB00730562BF0D739DBD9F2CF6434331A9B94059AFA36E52 +:1518F00094654A3397A5C37AA7381BF0B258170EC2C732BA3C2A +:15190500B35621C717E9589F484C785A426F35F0D08A7B74362A +:15191A003E6286562CB6FD5AC4BA96B557611C3597624F3D3A72 +:15192F0018BF4DDDB4043693D88735068633FFCA603C4875F9B3 +:15194400F32BF52BE974E08DE57AD3E34F7A9A1C5A5DA0BEB02D +:15195900F0761BEEB69BC2EDB954A1CBA79337C21E5E6686ED09 +:15196E00F593E9F04346032FE883D59719FA30FE0D731DFA6039 +:151983003C175F29FA10113028D1B80EF80D35A70577C08F3B83 +:15199800F15EC92CCC25E37BF8E0EFD285428F540EC7C7976FC2 +:1519AD00AA1FA5BEADA2BE39EF77FCCE75D410FE24048BAFE8E2 +:1519C200A8E085B93B4EF00999C598B16838A00CEA993335F4F6 +:1519D7005B8D25E8FD31FE3EDEC37710FB414A3B6C06E386DFF9 +:1519EC006E7FA97D597EF71525048FB3FA041F233316FB9D6202 +:151A0100BF69D883FD6A137BBB57D3E950D6FF89C6CBBFB17C5F +:151A1600625F767D5894CF961DB6FF8DCCFFB4F5E2B6988F27FD +:151A2B0053DF3715E2733535305C1CDA4EF56CE1C154A5312B41 +:151A400095D3B22AB5D80884DA88DE63A2CE10CDC92CFAFBFC5E +:151A55003519FBF21A87AF8EFCFA2384C752BE16FABD021FF809 +:151A6A00A8F0B5EA8DD7697F1EA96DBE47F5349FF75EE1A1C844 +:151A7F002797826E1BD2E9C249C9B193BA8D3CD02D2AEF32DA11 +:151A9400E013B89683D6C85743F9CEDAF9C2A91554EF6A739572 +:151AA900C573C38286F6BD26760FEF16FB8295246F5682A68619 +:151ABE0045C3A9F70E09EB8657787A391C7107881F3FAD4DE607 +:151AD30058F517F101FD41755663B13AABF6A5CA924673E18293 +:151AE800C657F18EE018BC9E2E5CA84A8D024E85F4B072A3D58F +:151AFD00C7FAF9E51FA7F333E7F1C60F5B7B8DE387CD4365D585 +:151B12001AF58C63BFABD7AE9FCA37A32E8DEA72F23AF9B6524A +:151B27009E7D6B06B45D34C6D0875B49E64D6F6BFB8FAD3D8A0C +:151B3C00522AFFAA64C185737B5D180BE37163BE7F500FFE6E98 +:151B5100BF8101BE3AF5A2619DD34A3333F282D647F5CEF3D710 +:151B6600E8A42B97C0D7BC865DE189C837DB70F62E89B1BB66B3 +:151B7B00B16E12AD72D990EE25FEC7DE506364A89129CF59B491 +:151B9000B1F5378C6159F0994A70455A05FCCA73E69B3F4AE70C +:151BA5001FF558FD5C49B46E9A81A6B751DBD3FB34F8A3B4D82E +:151BBA0013443D5BEDF2F36252A3779C6440740FF7F8137A2424 +:151BCF00B59F375D4AE73B6573699CE02CDDA88D779CE714B2F2 +:151BE40080F0E0E4E9A777E2D9788AC77F98B6CE3F529E37DF4D +:151BF9009F8A7BF0E04CB012FE4B4A53ED46FD050BE783D3CA28 +:151C0E008D02FFE07371566D0F77708D3371AB530326C73E7BDE +:151C2300785ABF5957A6DF472F5AFD06ED515F1BD55763D34CAD +:151C3800F0E6A0C59BF04B97D6FCBE1EA5F7B73AFC67D3C2C2FA +:151C4D0063B60EEDA2056B1BF1C4C8BF583C31CF5FAF8706A432 +:151C6200468737B662BC5BE73B6DDE209D3F32A42D64279AC1E8 +:151C770017C18661C10F667CA1E6EB7E519769AE5C68F381E5DB +:151C8C00F73A95EEA493FA42CA61E2F9765E447C116CAFD595EC +:151CA100376C7C3BE3C15506F6D44CF8BE1DE39DF203E737B4A5 +:151CB60043E3E928D5E9F8D3E4BA78631BF186FAA6C51B12E1DB +:151CCB0057B67963EDDF5AF8157B568493CBBFCDD20FF5CD8A7C +:151CE0006ED1B59F7CA99E649C599D5A6356A5569824E74C9214 +:151CF50083C60CFB4DE21C33F4143FD901C2276E063F6FD2937B +:151D0A00785E51B7DE06BF4CD2DFA09749F9033AF6B5BAEC73CC +:151D1F000BF02D7B50F8330D0B5B4AF877E34C34D94F87CA4E3B +:151D34006ACC1812BEDE4AB2D384BDBB2A794AE877F1E410782A +:151D4900728EA2769AABD453A641F712E388FEAA6ABD67954398 +:151D5E00FCF24DF43FD8438150B4750FE66FA58A17939CAF263F +:151D73003BE676F8E23B7633D96915DA55BD27B2BF0DF8F35FD4 +:151D8800C8DACDADEA7DE6DB3F93EE94957BF52A7505AF225DD7 +:151D9D00FE92EA6D0ED2FD5BF04514E36C0F2F3D9FCE7FAD5214 +:151DB2006E249BDC207BD698C78EDD15211B50B6694D76AC01A8 +:151DC70059D9E44A433E25146EA53ACD2ED5DFECF8589692BDD0 +:151DDC009BC72C3D0DBF8F52DDBB95A7DAA08F55CF618580CB48 +:151DF1006D67BA6DCCE80FAD71D029F257F36BC5AC9029EF99AF +:151E0600412A0399E186C9E2BF7A7E3BCD0B800F7004D5970D68 +:151E1B00F4218F781FEBE76C7C31749E6068C5A774F41D7A90B7 +:151E3000F774834E6085AAA82E21038C1E1E559FE1AFCE26DABE +:151E45002BC46754DE6907766090F41F4A33DD6DDE934E8B36D0 +:151E5A00855EA51C364748472B8FD9B22C6AC939D4D9361BEBFD +:151E6F00F6614A3B2CE0F2B2BD7A0FE08AEE3121A71CBA396BC1 +:151E84001ED13740BBF704ED707E5C55498F573A877DEA1DA687 +:151E99007705E940D1BDA26EE8F5D0E9FDEAB366CD75A929AB9C +:151EAE00CF583470F0EDA6C360C0F2BFBCD97B1E60856E7A0042 +:151EC3009EB1BFA139D2A117E495526526D6701D7AD4E49355C5 +:151ED800774DE7D7A87D9E2F9E7AC72C095D6CCD49922D7DFE54 +:151EED000A8D8D2FF00AED4FF425B16FF37D9D27DAC43E90ED91 +:151F0200971EA6BBB087B08608C28CC1C77DD80C8BB3DCDF30DF +:151F1700E684CE50BB3F249952DAEA8B3D493AED72CC2B66C792 +:151F2C00BD0F918E7BBFD171EFBD7A774A024E857E9B87392E76 +:151F41001CB5F5DB2ECB2F8FC66CCCF6B31F16F76ADB0638627B +:151F56008CDC073B2B4265B6087D3A2D7C44525C444EC819E394 +:151F6B00E1582D9F9DCC69093CBB9E074EB7E852F2040F40BFA2 +:151F8000879E7C1F7CD25F163EB87DEC9B1ACABD4FCA53DF677C +:151F9500BF69EDA7517DFBD97734B6ED1847F4903EF66D0DBA40 +:151FAA0018E4771F7B4D832F2DE089920E87FC80E55689059E76 +:151FBF00227915185BA9DF4DFDF12B8FE8B2FA9C81BE3A7E50F6 +:151FD4002C7A9FD931EB5EE1039C4F3031638DD9C70632FE501A +:151FE90028CFA2CF99AF125FFACE8DE86CA4D384FD04FA0FDB39 +:151FFE007BCC68ABE8524AEFCD7941E8F56BB1AE3C72CC1C63DA +:15201300225F1CFA3CFCE2B0B78867D80758AF213917C7BC7364 +:15202800ADE27073B9EA69F49D233DBCFE18A7726DED852B5BE4 +:15203D00A05F930D5A124DBD635468DFD3674BCF0B9DD8E33F85 +:15205200A1236F09FC1BEA87903F7270672FCD457DC236050FD3 +:15206700887764234E923CF49D3BA8CF3BF79CCE2607054C382D +:15207C00EF437C2564FC1FC6D6365978F986E13BFD72960F9219 +:15209100DE0C1F84C007842787F6BEC82ABDABCD63D111F4336D +:1520A600BA4D879E4FB31735879E2CFA0D73103ABACD2B53F1A0 +:1520BB0067E1EDABAFFF9186337253717644E0ACA44DF848DBB0 +:1520D000381B06CE026CFC581CBEDAD79EBC7789A80FB6CCA84C +:1520E5008533165D346CFD77F65B733B1B9E3B7A42E047AC7FA6 +:1520FA0019C7CC02E8C5935FE16F104B127F9414A53CCDC0ED45 +:15210F00E39E2796FE69CA736728E66976F30978C373E91DDDF8 +:1521240027BDA077AB599C04A78C0DCBF6035D2D7EB6C60AF085 +:1521390094E1F5E9769FBDEF6EAAEBEFF49DBBAAC367D9EAA701 +:15214E00C1710644E83FE1301778D9F669AB7FCA401C6BEB2D2E +:15216300EA034BB0FFE1659D7A70C75745FFD8E6E778EFD81756 +:15217800493E7CD174D93BFDC2D6C19E36E18245474CA78E203C +:15218D00D951852E5C8C117F2797AF6FBA7EDDC2C76FCA9FA8EE +:1521A200DD40FA96859FBFD7EBA4273F003FDF27FC3CFFEF82DF +:1521B7009F97809F7577E98E6D9E6661CE267F6EE1836CE6DE14 +:1521CC0038EC050B1F0BD8223DF8FE62818F9C68A95E1E2F6F3A +:1521E100BE45CC71FB782CF5AEB9ED97B0974B5BE9D9807CB1CE +:1521F600EC1FC21BFBE32C0F2A583310FF84BB0117EE5E369D99 +:15220B00F6A6E3AE9770B78D70F77736EE2E12EED07EC8D5FE2D +:15222000B55F586D4F6DF7056D5FFE505666DC5C56CC71C98A24 +:15223500A64C3EEBEC74667C2CC4BAEEBAE7333244D8E7E3545F +:15224A002E3EA44D2EF70AD8204B204722A4E3418E604D0A67B3 +:15225F002050EEE9944B9EE4BCA461FF0FE736F05EBCB3E449EC +:15227400896FDD4BFA016A5BC8946D4362CC627D0A7D2E76F53C +:1522890059A63EBB65CD74FFA551F8E6285C2FBA64E801D20F34 +:15229E00FA9232F547354EDE27F4CA906B8F8C063EE99034B72D +:1522B3000357276DFE4079DF42962F8FEFD495F33BB5A9FEFC1E +:1522C80086B0357697F56B42B7945917703526D65C86E20BB10B +:1522DD00A743632327752C2EA74EC47D7ED27308BF05F1A1C669 +:1522F200E2A841F301E73D29B94556137CAEF217382B182AC2CA +:1523070019BA0C4C5161776CC799BBF2D5ADD0B1587958D821CF +:15231C00D095271EB07C67AFE15EBE8CE6DDDF3F207CF7C2EA17 +:15233100F1D40333FB731B87B07ED12FD62F76931E5C34D629A3 +:15234600D609D8B89C301A8E58B04787E245F06FB4D33DB1A12D +:15235B00B8D2302CFAD7C3F66A384FE85B47F3883104BD08739A +:152370008C41735BA67FC591C146A7ACB58F9B79BE019E6B8741 +:15238500B2EB31BBCB86B5A2B80D8F711378285D215B1AB0B83F +:15239A00DB94ACFD988ECC5A8DBD3F8FBD68567ED2DAF7B4FD65 +:1523AF00110977167EACB5F4A978543A0F4CF12FA27110BF1F74 +:1523C4007D305A31164897E928B77CA2E21D94DE1B4D6ABE22CE +:1523D9004B2F4B114C5772E258F32AC4FBE87ACB96C1DAC1428D +:1523EE00DB8F6AB5E09123F1FBE89D03BB809BF26BEBC51EA3A5 +:15240300D8075C6BE7D35DF956A45EE8A0FF38D28DF558CFF983 +:15241800761CF31EFA82FD4FC0D1BB73480B8ED9F050BAD3EE10 +:15242D0016BBBE9E19DAED77B5BBD5CEF78C2BDF4A6A17F99220 +:15244200AE7C6D76BE8119E05B99FA661C67108E0818BF1BC70A +:152457001ED815824521F89E16BC734CF8CDF47E8F6065D6BA3B +:15246C00E01517ACDBECBA5F9C01D661170CDBED7C2FCF00EB9F +:152481004957BE1D76BE573E0056D0D881F5EA87C07AD5056B9E +:15249600CAAEBBFDFE1B61EDBA3F0BC3653B5FF7FD37A1E7FD24 +:1524AB00597A5EBE093D2FBBDABDE2D0738676FB5DED5E75E845 +:1524C000799376B76CC0F81A050E8C0977BBE8AFBD7E8F74875A +:1524D500E71FA7FCFBD95086E737782D9E7F5FB2783EB621DB46 +:1524EA0076D46BB5FDF0860F681BFBA576BB4E7B93AE7E6EB0F7 +:1524FF00EBF8E2CC751818B38E6FCEB5E9328FE4CBE5C1ACBCF8 +:1525140013E359ACCD22E69421FC099832624057F1F93BF5DD6E +:152529006586A6D0FCA0AC3DA597F213FA3E9A12DC32E809EAA9 +:15253E00D74CB2C729179286B4FDA437825F2CFFC7BD644B24A5 +:152553003BE0EFBD52D4959D1BEAA82E0FCD0B19B94A7A896F04 +:15256800DD9090A9429E3AF3451CF27448C853650DC14F725439 +:15257D00723D4F9D8FB0DFDBAF4965869EC61A18F6DAADB37498 +:15259200F6DC346CB56FD8F234DA678A35D5F121C3EACBA0069B +:1525A7007F17EC0B189897C85E99ABBCA2FB48E7C6DC34E37C24 +:1525BC0032945D0FC73A1CF6944270D7856FBEFD9BE6F339D379 +:1525D100D7C2AD75DCA3864CF348A0419C756301E917FA933497 +:1525E600B72D10BAC911331264D1D7688EF6150D0A9F0E2B1601 +:1525FB0058B5D807DA5DA66AAC7E2F6F13FB0B3D64EF579AE254 +:152610004CDCFFEDFFC3BD1C30B36DEFF238D159C0EE7ABF99F3 +:15262500F4B6E5F4FECBEC1F9722C609FAB0ABEC88735E5915B9 +:15263A007D237D48F44321BBE2E3FE0FF4F29215EFEAD9B4A1AD +:15264F00E175B1F412A7AD0ACDB2D53F4A5BF1E48D7535C6BE43 +:152664002BEA8A7E40F918952B5D33B5DCEDB18796587433CC8C +:15267900D5A09B5D2E4C79FDD3F2D6C52AECBC2A17FB43365DAB +:15268E006591AFC75C3061C77B237CE26C5D5D2CAF51ECBDC060 +:1526A3007F53E44F7092F13109F989A7113746B6E2C319880F2E +:1526B80027CE3F132F89B399E383A67B3FA9F5886B3F087BA603 +:1526CD00DB388F603F272A6C1B71BE5251E0FF613FAB3807990B +:1526E200DD0FEA75955F18931B9D3D21D421AFE17A8F589B1E44 +:1526F7001C9E74EDA33AECEF63A3F96FC977E57CD9F39EF47519 +:15270C00E951E9335250BAC6FE8EFD35FB2E7B990DB1AF319314 +:1527210075B30EB683FD2929DA5F628FB147D9436C23D3D8036A +:152736006C3DFB1CBB97FD015BCDEE66ABD84AB6822D67CDACF0 +:15274B008935B206B68C2D6577B07AB684D5B15A16669F66B73C +:15276000B34FB11ABA7E8FDDC616D355CD3E49D7AD6C115D55E8 +:15277500747D82AE857455D2A5D25521AE72BA16886BBEB86E5A +:15278A0011D73CFB2A1357A97DCDCD5C21FB2AC95C41D735C7EC +:15279F0075154FB902D32EE5866BF60D57D18CD7AC9B5EFE0F7A +:1527B400BC0A3FF42AF8C857FE875E3E26CE181FB7D6B754E111 +:1527C9008B4EBA3DE9F151A61E475A15A519F673353D8FDBCFB4 +:1527DE0035F4AC48F48C35BEF26ACA1FE1065BCDC7C95E5024A0 +:1527F3008D2BEAC2E34A8CFE93F49F5A785C8C2BB11E522DF667 +:15280800DB55D54ECBB7D3244A8BD96905769A87D292765AA167 +:15281D009D964369A88FDA14B02B2C1AB6EB825F60D8AE037E98 +:152832008061BB2CFCFEC254262AC16651F9F04B5828BD8D33C0 +:1528470075E1016F6899A8272AE2EED41AC549A9CE776631CD9E +:15285C006B95077C671A843C887FC0BBE10F78073F38BC2BA2B2 +:1528710077946E225D7EBD41176D8F2F361DDC3938473FC66D43 +:15288600189561411343153E7661037E200CFD1465C2ADC02FED +:15289B0070A878ACFCA96FDBEF99CA9BD485A661D7C35EB1D235 +:1528B000A3942F8A754A65A129FBC8A6BFC93D2A65F38CBB9EA0 +:1528C500154FF6D9B0D345FD63E9D988ED64F947AA7C42ACE7CD +:1528DA00A8563C48B12EAA8A5891B9F6B3F043F310AF617D2323 +:1528EF00BC8C477FE16109CF32332FA4B6CA91067DA2B241C487 +:15290400A998F8AEF70EE004BFE12B3046E5FC6C19CEE49A35C6 +:15291900840B529EB84FAD33F3D86D04FB6DA63714691D9F2168 +:15292E004D91AC34A6BE67C2BEAACE99AE9FA98648037FD3FD64 +:152943004155AA9389664ABCBD4E86FF8C5209F9ED634A2D354B +:15295800B9CCA81171196A4DA6002E55C012F594521B8B0DB4AE +:15296D002F9F29D595F8E27ADC7DF1C575B847D1D7F1B090F94B +:15298200C82BF818F29DF489B81813CB7844F8D946901E4BCFE8 +:152997005E4D79A2464CAC776BF659FC188F88B5932DD699FCEB +:1529AC00709B75469E6DB7E3F076D9677810F764360195205DD9 +:1529C1002461182CA141FFC1EFF796CB77B0F10EC3AFCA752C4C +:1529D600BAD39844BFC655C35A07B2CE2DD7A472EA449D549F2D +:1529EB00386783E768AFD15516D72431FFF59A9973E3D1FFDE24 +:152A00008FFECD579F3664F575D21913464495EF78E9A197A820 +:152A1500FED7FA918EB41A4A3B302DAD94D2764D4BDBB69CE0E0 +:152A2A0052DEEEFFF243EFD49262C6FDEA25633B3BC3E7AF7812 +:152A3F00476FA9F869EDD7965DB17DA5E362BD6D41FC027C739B +:152A5400845EB160C5395D4E0E1A9EF223ADAAFAAD7E664C9A2E +:152A6900BEAE5EA193637EF68DF52D0D618EA47698F10DF3161F +:152A7E00E91D1D7828603FAD1D7EE8974B0906A2E92582EB9C07 +:152A930021F17DFAD736BDCD6F89D05CACEC330967F1EBCB57B1 +:152AA800D5FABAA9BDE8CE617624176BE5C33E1F7483DD077C9B +:152ABD00ABDFA1F4FD07ACDF2FD8BFBF7DE00CCDB7C9EBD3C29B +:152AD20060477FD89FF09C3180B7ED6C8CC7BF935BF7C413B97E +:152AE70075581F3830FE356DDEF9FD5ACEB937F4BBD985DA799A +:152AFC0063A774C41685FE62AD2F8E8BBE96287FAE4F3E7CC918 +:152B11009C27BD46EF2F98BEF8B1A5D88342DD130F9F337CC974 +:152B2600DCBA912773EF10671887451C98E3090FD90CCA090325 +:152B3B007DF9EDA1CEFAD069AA5BF9078EFE28803BFABD611FD5 +:152B5000620529BB8F2B02FEEF1F7F9BC66081BAB70B6BB57987 +:152B65006A67BC27CE3589F49389CA1F1AD05192A4777CD58762 +:152B7A00F83ABC6BA2F2D726E5DDF34BB5E68E28E5DF115B5586 +:152B8F0007BB4A8C2DE59821279F2519E9AD8B8D1DAD63C60920 +:152BA4006302BC47EF317ED653BA9C3C46FCD3297C13ABEDD81E +:152BB9006D62AC197BC53E47B5186706F725F7D2388B73996858 +:152BCE00AB305E8FBB8FF13ADC113FCA97ECA33AC68C36EC2BC0 +:152BE300261386E4231C85C74CFC061F627C9CF92EDE0D923EE6 +:152BF800493A7F3261DE16E7227D8CD2F11BFBC81395DCF0C751 +:152C0D00E4BA00E96B1827139583E63CB22746AF7BEF205C9AE6 +:152C220067DE4FFB1482A789DAB8807115EEE71324839BA85E80 +:152C3700963C68BE91F1E7EE32FC8481300177A193D733E374C9 +:152C4C00BFF0632179D61D39A7FDE51772EBFA59A7D61FEFD3ED +:152C61007E5925DFD14FF6DADC44AFDEB3936B3D0D17C55EB4FD +:152C7600927ABAFFB645E59F11BA5B383E8C9824810509C4C806 +:152C8B0032E627459FAC182F3EE8A37111C3A55AC6DEFBDB8611 +:152CA000B41AF18A5F357BC6B806FF415FF22095DB0D3C8B58F6 +:152CB50057A5A9A7CDF9A9AF9BD5849BF9D4D7642EF634778BAF +:152CCA00F159ADEE16BEF1A20E85236E9FAF54FDAA217CF63673 +:152CDF00714EE50CC806393662D4A7BE437977D358E9A579EE05 +:152CF400A08E3A3D6787442CE5B6BF60AC0CF62FD980885722D7 +:152D0900AFDBA5539F0E78D6EDD3B7E4B1A9E3631CB16EBAF850 +:152D1E0057DE92BFFFB424E82262000553F033EA177E46C029AE +:152D3300E2FE045942AC5F8A78669FB77CBF906E8EF56AA5A9CF +:152D48005DFDE1D4F3496505D77DA403E7ACE5BAAC72D3EF4371 +:152D5D008CB783BC3AD2B714EBBE25EDC43FEA102F8DE3F709B1 +:152D72003364FF464C0D4BEE937D9AF2D7210DEBC2BE8CFF7CCB +:152D8700BF8881E3016EC67B8D2A4107EB8CA2447637CEE55AC6 +:152D9C006713AD3DBD37A92E896000ED413FA9EB981E5AD069C0 +:152DB100EE8F58E7DA104346FA032EF47445D0D1107E6A8AE003 +:152DC600EBE78E5F1636449788B723A748868D4F0A3C07C84604 +:152DDB00F60B1F837E116FC72362565BBE6BCC78CA443C46C088 +:152DF00029A5BEC2AB539FA875CB76C874D04FC8F58C4C27F975 +:152E0500BE25B72598FA8D29E22C1E07FFED32F7FC2E5D520F81 +:152E1A003F3B9B06C07130B5CFF0F05E3DD068C5BCF3906C4040 +:152E2F00DC763FEB5DE2271E99C77A6B41BFAD2EDEDC6AD1C9B0 +:152E4400D88E7BF99556C15B4437FC96C5B982B888E3047A8367 +:152E5900BE22361FC632D1733A2D6551D6A2C387E1F623D3083F +:152E6E003470E3DEA1C7C7A04181A041BF1DE7284B8B0FA58182 +:152E83006B6E75F03FF62DC4A72C0ABB69511CFB64ADB04BA3BE +:152E9800EDC3D79EFCE452259647F368BB01DB13B28A7F25B730 +:152EAD00EEE2BF38F2C79217A544ABE205DC94A84FA01DFA68E6 +:152EC200C53AB2DA407BA83B130F23A31F59F42873D1628780A9 +:152ED700A7CB3AB740EF11574B49ED33253521F808BF35D77979 +:152EEC00E0A0AB7CF0F399F8E022AE783F1B12FB163ED0BC7DCA +:152F010048F3AB5E218B15F007C99EB288257B32E38EFA2C6D48 +:152F1600C1FC4BF735E7040E689C06FB7F6BF53735EDB313D89E +:152F2B00A3290D75B596D1DCAFB2E4F1301B3B1E61A9E3D72E7F +:152F4000A4F3E93E4CBF87297D58B3CBDF2CFF9137A7E6AFB6EC +:152F5500F3631E1FFD8DDBFF14F32C8BBACB8AB8C362CF8D1B4F +:152F6A00D79F94EF6882BF8B3A1AFFEA99535A2E9917B2DADB5D +:152F7F0085B84805EAAB5D38FF68F9838F8933508A3A42764A45 +:152F9400C2F0A716D5C97F93CE071ECE5E4AE74FAFD30D9B3808 +:152FA9003B48659BD4678CC99F71D2890C1173C9E2C33F330520 +:152FBE00EF5AB19D267A483FAC233DE8E3F0E6C4CF7A8D84A7CE +:152FD300CB6047E496899F7133E1E9379BD41EF337D7313EE251 +:152FE800B62DD26E5E86EE13361CBDD48AEB6E1C34A0034B3494 +:152FFD006E003BFD3677FC17D2FBC25113FAAE83B39387B2F8C4 +:153012006EFD7516BFF3110B22544A7A79BB7196E0DECE629CE6 +:15302700A5C2FDD88FF2A7AA8DDCD3B5FAB7E28B6B3B972D9B72 +:15303C00A22BE631F8892E13FA539EF428C98F35869A8AF63372 +:15305100E557A6CF57A9C3D7D4D213172E2D205BC453AE8936F5 +:15306600105F167AB6B7BD562F8AD4D617509B472BEE5C3A3F3C +:15307B00A5D25C576D94A6C286E46FD43B9FADE5DE31B2FBC612 +:153090009799CE1E37621B0A5D5D6927FDB1AA56C65E6AF49146 +:1530A50061663C7CC0D785F301FF49DC53CB3D7764D7834AED9C +:1530BA00B882D5B69C0A939C5AA6414F9FA74A61118F54C869C1 +:1530CF00B241A83FB22B2695357F3E3F5C3676502FB3D7338382 +:1530E400340F63BE65E3AF9801E9B25E5759F419567EA695B16D +:1530F9002B5C61FFB03428BDABEF53BD75D005C32413E74B43AF +:15310E007A49E864AB2FF20F4BE6D3DD73AE4FF8AD601D6FEEF2 +:153123000AC4C23B69FBC7C4F9159AD78BE327F4C07CD24B94E8 +:153138008EE18FFA3F97746FDCFB97E7D517C7F2C82679C5604B +:15314D00A9E78FBF41E3687EEA6903B24AC411A0FE07683EBE55 +:153162005AD6BB2442BA0CE69B07BC86D05F7EFC0CAF75749694 +:15317700ABBF4BDF546719FEDFE99BEA2CCB6EA6B344DFE129A5 +:15318C00E7FC27640CE1CA57F985A505620F0F783BB53478FAFC +:1531A1001754FF29BE9E70B77F99E19CA917780AC54732780A6C +:1531B600A516D5FAAE604FB963587EFD14E473685E6A562DFD13 +:1531CB00368A5325E25E905A20EE06C9F199FA4FF369BD67F568 +:1531E000BBFAE56B691FF080BED6D87D9F78DFEAFBFC19FA8E7C +:1531F50032C3D73E7EFF1710DD4B2147A33DFD6DBF9966BF5070 +:15320A001FC55AAA8B9E6BDD79A27DC63DAC9F6F201D3DF78709 +:15321F00BD4B54F5345920295E2C91DEA55C3083365FCA381F10 +:15323400A4FCC4DCCE2EF280745587DCBB65C5BB7A78EC3BF5FD +:15324900B73458F8BC85BD63F975517BB7C05E095F143805CF3D +:15325E00C1BF133EA2E5296F9D9367EEE94B19BCCFA5B28ADA53 +:15327300DE1F2F4CB420EF56ECE54447FA117B31E7CC29BC3BCF +:15328800E0397B4A37D26427D1FB6AF50B4B71073C93CBF3EE4B +:15329D00D8F6D04F491FFC89E1535F3E50A3FEC85C3669F73195 +:1532B200BA6BD88FF8AAC9F5DC7A86ADB46BF8CA72ABFC49C28D +:1532C7005BD0AEEBDAF2C796DECE5EA813B68E2B2FCAA20E77B1 +:1532DC00B9B394A7E3A90B5A58FD8F4B908EF99154E5CFE1F98C +:1532F10019CC91D15D49E89F285B803D65C225BE1F33BFE7B062 +:15330600C0EB3C957402BBFEA229CF736B3DD6737F813ABB967E +:15331B00EE86A7C8D2CB51BFE7EB7B74A1037C876405E9576696 +:15333000E4794D8924F4529A3B443C16C53A83F361FF34A7745C +:15334500495DEB75F8193265A7987794129A3FEC7947CC41785F +:15335A00F731E61F67EEB1E7A119E71FCC3D9883EAC599FBCC51 +:15336F005CC3D5316BAEB1DA5159A9FA2B730E74099A977C6AF3 +:15338400B7B9E5BDB4AF20C9BB0A08EEFA48A2CEB1FF4A691EE8 +:15339900439ED5EF39F4EE349AEA2CBB716254BC37F03E4CF834 +:1533AE00417996BC6C486557881F39D98D5D3C37998817533BB2 +:1533C3004A72A41F632E27758AA34EF01A78AE5AFDD901F0D4A9 +:1533D800C5F71DFDCC8699607DA3E7591AC3EDC6D65F58F3BB94 +:1533ED005897A5B6467F951D5F8190E5EFE1B3CF1924432C9F18 +:1534020074CFFC2B01EB77DCCBF23748AC707B0ECBC77986F8A2 +:15341700D8D46F3B4DFC2D4D4C1711129DBA46FF6DF46FD0FFC6 +:15342C0030FD8FD3FF04FD2B3FA2F73FB2F28ABD83A0EAC46896 +:15344100E467C7F0E1884A1DB1F06F555B97B0FA5F755EA47C51 +:1534560015FDCF100EAE926CBE6AB2FA761EFB4B7B9DAD7E8045 +:15346B0027E9B947F5B62834AEC7DE465F470DC4BC14E73EEA46 +:15348000BB39DAA977F43BCA1FA7FCB7B2BDCDE299DA539A5FFA +:15349500340CF4433961C0BF36B4E298CE627B39DEA3EC7EF867 +:1534AA0063217634D5592CEA7C45B429621B7D601DC77851E412 +:1534BF005433F2A3CDB9A11BFDA9597082F7B2ECFEADF0DF0892 +:1534D40066CFECBF799A1AA43993D59FE216AEE1DB316CF5B34B +:1534E9007E888B36C73B0DAC81948C1DD3156AB7247E54878F79 +:1534FE009EAC4E4DC31A888FD202E35D7ACF84A7C5FDCE47EF92 +:1535130042CA7FD3FD64878E601FD4D97725F8FCCC155F697AF0 +:153528000CA57FE37B9C131A0922364775EB55BA7B953A1D3188 +:15353D0072FDB14A3397CA5C0BB142F9BFB61B56BC617917D2C3 +:153552000629CD1F1BA03967917E71B9749757E9D0C7290DF1AC +:153567004BBB903F5669E07C8D8A73A29426C706CC61A4D3B355 +:15357C00417C7B9164217CFC6BE63271C68307B23609CE1C5FF6 +:15359100F558F1B2B6219DE007C079471077F45DAE9C7F464330 +:1535A6003F4AE11BA48C709FFF98BE8E6CB339AADC92973A2800 +:1535BB00E2B610FCC5A114F2EFED90BA7B853F27CE18DE966C99 +:1535D0005AA2F82D5F0BC466982DEA1C3AE0A33C3E2B4FB034D1 +:1535E500292F918EDC589645F304DE0C9AF7AAE658DF8082FF11 +:1535FA00BDC3E7E373E0979EC8F887C9EAA4D95A427822B92460 +:15360F00137EA2F4CC66F0E72F25BC5BDF3CF96B737BEA6F0F36 +:15362400C897DAF5CBC553EBC7F744DAECFABDA1B156CA6B50E9 +:15363900DE7ED4B58764E75A196B3AED343E2254FF6AEE53F13D +:15364E001C6D853FB7447A2EE9C2A65FD5CDB504838C33722494 +:15366300A7F17D95F96A3B87DCDC537646C37AECAAD43F13CFF4 +:15367800FEC05C4DF724F1C25ABAAF4E7DA61FB410FEE76AEDB5 +:15368D00011FD5514FF59706587E581DE0169C5FE8079C388F73 +:1536A200BD92F475D8309EF258EB9EB2360DF23E42EDC4A82EF4 +:1536B700CA773C4AF7CDF41FA1FA733167184D7C436AB919A3B7 +:1536CC0076A2A9FDFD38F3B09ADA89AA3D070E521E8DDA3AAA9F +:1536E100D8676C4987403B84C0923D6549AD551D306304D7662A +:1536F600AA7F82F07335C00A7D54E632DD714E9EF8CFBC46CFF7 +:15370B00ABA88E8900CE1924F8167A7E35007E575BDFA4FB6AE1 +:153720004A93296D989EFD418B46D371ECA697F7525CDF4C7926 +:153735008B55B939C745CFB03A48B8867F31F68427699C0F9A63 +:15374A008A4A73DA349A875F9B2AAFE12FA284734806776564EA +:15375F00301C123057DF4DD38107E71CB78D7051CE386594ECF6 +:1537740018B4E4DCB663960C8AEE35E0D33217320A6B58888D3C +:1537890019957765DADD3669CBEF1E9249581B3C684A65713D24 +:15379E00E37F4678A0692F9FE62E23389BE5E3AC06D9408DFDF8 +:1537B30012CB273E32A89F8D7E1AC705EA82CFACCA63F9F3E96C +:1537C80019DF929195DDFA28F169BFC20ABFCCAA1A494008FC7C +:1537DD003E42CF09C5C26B39AB6A8EDA721FB240C04675602E4B +:1537F20088501E12E685CBE8AE282FEA997874341F5FA8686FF7 +:1538070084CFA788BD46F7ABCBBDCD0AE5DB5A7CE31872C60954 +:15381C00F6CC300E2798F50D3C278F9FF860A7FD9DBA72D5DBD0 +:153831005C4DF5E4975F213A1D9A820B85FA73167CA3DC26CE74 +:15384600D0EC8AE13B033DC613915ED1FFFC4FD3FC46F800FFDC +:15385B002D25B4416F7FB508E30EFD7AD1C01CD1C83A455EA932 +:153870002CAC77E663AD63C0AC72FAA5741B32E916D5E0BD40AC +:1538850017740503FE7E0AD581323EF5457AFF2B33BFC82AC7C6 +:15389A0094174DE0783BE5CF75CD5B6AD1D4F59B6B45AC3048CA +:1538AF0079268AC0F35546428C936A314EE0DF0499FBE6F5749D +:1538C4003EFC750AE289466FB45A57D54AE3CA72A97994CAD023 +:1538D900382EF4BAEA2FB6CFD665ED55D598781B01B576EAA8ED +:1538EE005B39FF7B22D6307CB5B09624931C95A9BE2292F7E8B6 +:15390300C7C44303F50FD2337CAD64711EC8D603E0E3F536F634 +:15391800F82CF8E5D810C9A4170D712EDDD255D3C53407E3FBCC +:15392D0055B2FA8C69CB9300BE0D09F926C33FC2FEFEC424D5C1 +:15394200F3E318F1606CC85E334EA7FF6A6CB0D14FBF713687E5 +:1539570045DBF9F642969F5B4934B4EBFE2DF5DDE90BD67050D7 +:15396C008785AB230257F0FB0DB1458D4E7F0AA80F93158B9A3D +:1539810071CE7372162BACB8981D3F326414D96517C986FC2802 +:15399600FDC4FE9B809FF409C0E21D233B3B3A4A750D4057248D +:1539AB003C7467FC45BC946FB480E5DFA30276AB6F778D250892 +:1539C000B735A60337F611FFC7B19F1CC5FA83A82F84B58C55BA +:1539D50007A03FE3BD903D36BEEAA7ED4F59E36515B7F15B828E +:1539EA00FD0F3FE5298EC9CD9B73B26347C9AFC1B7BB047ED1E3 +:1539FF00D6BCB141D2A306B1A79816E71AE9AF3CF242E3453F3E +:153A140070F373DD194F23F6F95EE80781F1A7F4C0F9255AB02E +:153A2900BD419F97929A049F19DD7C07CDEFBE50360E0960AEE7 +:153A3E00639F6A862E3096EFD0CDEAFB6FD177AA0BF97136C947 +:153A53001FB3E28A20CDDBB448C46C9745DC120BA6BF2298E058 +:153A6800DF081AECC7593A9A0333F44D791BA103CAA9534601AC +:153A7D007BA57132ED6D9E97F23607A7F58164880F78925343FB +:153A920037A72BE1183038FCE84F9D30FA52DE9650D3908009B9 +:153AA7007066F4D570B5A08B22F42AC0FD29EC41091CCD8B0F3C +:153ABC00D43B78D94C32D76BD3CD473A5451A5D468F5CDC2C5E5 +:153AD10075C1E30306C64D89DDCE3F52F98FD3DF85D4DFAA4288 +:153AE600F437ABCF839FB723662FF1815F75F529F6B2D117930E +:153AFB00B27D52AD3E59F850459F9CF3D2363D44BF0CD798284B +:153B100076E10E7A01F0E6F4674EE84A2BC9419A7F7F6EE6B539 +:153B2500D3F852F6F0373C969E087C6C60D9710F19B839730EAD +:153B3A00D7D28BC4B96ABBDC412A071E49A28C4B9E857F379504 +:153B4F00FFFDEA51923983FC4F2343B5CA8E11D12F5FB2D374B5 +:153B6400FA0C79017E2F16B1E59F35DDB20973899C7CD6EC230E +:153B79005D5321FB3E4032DF9F841CE3A6D5CFE12C9D934346AA +:153B8E00A8E984C04788FA60AF6F171440BE8AF1C5752BEEFC13 +:153BA30015D1DEC2152FB8C697859FA2D38322FE2F70F7C8C3D1 +:153BB80096BF2BEAFF0EDB4B7C3068049A3A6DFE1FCCF0FF61C9 +:153BCD00E27FC0073B05EB7C820F62E003C3E683D10CDFCFCFB8 +:153BE2009FCAF747057F0E66E9AF8E18A82BCBD3832EFA774D11 +:153BF700A33FE0D96BF537293763ECB8C70C7ECB49C4324A1863 +:153C0C004F936CB360B6FAB98BF8DAE1E110C1574C7CEBC07AA5 +:153C21008D602D2758DB7C37F2ECABBF01BFBAE08D11BC311723 +:153C3600BCAA1B5E4B36BAF502A5A953C0EBC8216B6EE8123030 +:153C4B00CB31CB87CF8824DA8A5C7362EADA541EC4B91256DF0C +:153C60006BE0FB53B01DB5FF952ECCF01FD92E6F2256C061F98F +:153C75004E2566D92FC591A33AA972C52595724BE07CBFE6913D +:153C8A0058600EDE8D8F18CAF9A426930D739CE055C8E6958910 +:153C9F00C7B0AEE5F321561CE721A2A74AB64FFCA9DE960EA415 +:153CB40077FD33E6910EDFD953629FF44AC5DE3BD8F8A8618648 +:153CC900A516D4539ED88B98C1C1B988EF41E9896EEC77ED3513 +:153CDE0065AA0F7B61E237B52B8BB5FABDA62887B68CBD387FDC +:153CF3003CA73C2937B65B653AE26413E16C936F2DD785BF237A +:153D08007C526C9B08B0A2FE9DABB996B36E528FD370E9FD2C8B +:153D1D00D7D06799CA94278E6D02FC98CF010B60036F2E2318BE +:153D32004ACE9FD4E662CE7FFD59BD98719A2F92DAB7302FD91C +:153D470075E2FB086DD4579473FABE8BEAEFDA7742F851827F75 +:153D5C0044DEE84887AFFB9FF51460A33EA12F6CF220CE5EA6C6 +:153D71008107D29D39F0B9142C4BEF1D5C5CCCE0C16A2B830789 +:153D8600ACDF8D5B78087D576EEC5A873DC921DE4EE9BD185FB6 +:153D9B008413A4C13644AC330BDE538483631AEACF59F76B7D0D +:153DB00087C0C3312D40FD030E149C3BC6DA3BF4326A0B310BAB +:153DC500C3D47E39C941271EA1751E24CED93B8CED29EBD2DED5 +:153DDA0023DD754198FD61952ADFE5C45B1FFEBC88472874DE64 +:153DEF00D5C2AE5A7420286268EE16DF804059E2EB7CFA3D8C92 +:153E04007DC0F17F72C5B3251B113184845E087F7AF8A685976F +:153E190071863C4ADD01D249C6E2D5DE16C957A3CB91C5FA20AF +:153E2E00C18AF80B48AFD0FA750573907A6FA34FFDA346457D70 +:153E4300A0598EAA3ADEA54847C77DB3388FF4E722966149836F +:153E58006A5AF51E860E34B68CDE5568861E8E0F36D6501DD54A +:153E6D00544795FA40A35347A9783FB58DCBCB1F10F5FA45BD41 +:153E8200BFEA70F25ABF0F1B89E57D778A33DA0D13565B510BB7 +:153E97007EE0EAACF0EFAF36A3948E39F62A6385D2EAC5BA120B +:153EAC00818E68F793F20D8A7C61BE01E58DC526F28ECD90178A +:153EC1006D6F07ED92569E8337C9B30163D3CEB3FD2679C294B6 +:153ED600C76FE7D9302D4FAE522FBE37847CE095ADCB7F762708 +:153EEB006425FA21533F719F43F2DCA79AE64CEB596166FBCB27 +:153F0000638C2A8363D86F147A0B3DE34CAD88371B8D0BDE2D37 +:153F1500B1CECE67D68424C9E2B74CBD549FEAAC1F093F34B224 +:153F2A004F7F90C3B07E029FEF94A06FB6BC150BEB8881746A9C +:153F3F00D3AA9FDE958C3FA707CF3FA7C1462DA1B1126C1A1181 +:153F54006397F836A0B013F598673FF7560E53E3234B133497BD +:153F6900FBC9362A461F146E5A3E6FC233A400318BFDF1634B40 +:153F7E00A04B237F10F53B700839DE65C11749D48BEFFDD9F533 +:153F9300CE8F0F2EAD99566FC60EA6B941949F617DE61FEDF10C +:153FA800877EC15626788B2F63DC2855D9F2EE785B347E71160F +:153FBD00EB9F662877745A391A9F379C27B4CA1FE23F9FA1FCAC +:153FD200D68F50FEDD19CAD57F28BC87F89519CABDCF3EBCBDF5 +:153FE700D434FD0AFC1274F31FD6D5FFC9F54DBA19DEC7AF7EC8 +:153FFC00F0FB890F7BFFEF5DFFB4F77EF778F8A0F5D6FFFFFE71 +:154011005FF55E71E1BF789A7CFA7F077E9B3FA69D399A78FFE4 +:15402600C6F1F061F5B9F94D2A3BA2F779129B3F2ABF61BCCE52 +:15403B009155FE79711EAABAB553896D5E49C3DA1FF8828EF8BF +:1540500077F80EB8FFEE6E1D631E3A823FB0459FB5AA5B57D5B8 +:154065002FF15977B7EBC1755CF34B957AB0A8524F90CE66CB4D +:15407A00874DD7482F5102D53AEAFBD7D675680DD786E173B5CB +:15408F00AE4A877F33BC776435A7E57192F925FE4ABD605D8D23 +:1540A400FEF5358BB58A758BB5907FB3DE99F37B1AF6A316C828 +:1540B90031C4C70922AF2C7D4217EB40ABDA850C822CAA284A4F +:1540CE0068F08372DE178BF78B756F202EF4DA8A07E3BAF0CFA1 +:1540E3002438CFCED0FE4ABBFD426AFF10B55FE26A1BED9653F3 +:1540F800FBC827EAA5FADD6D5FB3EB9D70D59B4EFF34ED474C7B +:15410D00C55AD6B29E4C18D41DCF8971E022CDACBA6EA7297B4C +:154122002EE1C54F6DE6AF5D4CF8A9D416F86BF4F99F965BBC93 +:15413700AC7D63C51FCB2D87662704FEB12E457378106BA2B712 +:15414C0009DD240BBB881D01FD90C59F147D2398CEDA308DA2A4 +:15416100EFFE0D7AC5BEF5BA54E4C096BEEEC0D648B095FA2B21 +:15417600457A9C14638756F94535BA5FC0D4AD2D284AE83D3BB9 +:15418B00F764F80078FE6D3A6DC3C0443F71F6CEDA779D78128F +:1541A000ED8EDB7048655DF8269C6F36B76008ECABD203D41E5E +:1541B500FAD662FBB8C3394CE0252F8B970AE29BC2B54D7AC9E4 +:1541CA00BA7A01CFEE9C6EAD80F052E84FE8B92CB1718FCD975C +:1541DF000B45DFB3ED5EA1B60C7A17207C11DD8B1D1840FB8A9B +:1541F400D51B34D8DC15EB3668D3E94F83275020CE13B2828A7C +:154209003307C57BE95C8D5EF2604C97D997F45994E780C44203 +:15421E005EFB791F3D17AE23F8884F0A8BEA75FEBD06EDD0EB49 +:154233000D5AE1B9B57A09A7B47DAB74FED97B88DFEFD140FB92 +:1542480012C265C55A0B07724C6A51D9165E4F38F34A0FEBFE75 +:15425D00580E62F807F3B15753BEBA7596F4A8EE9757EAFE153F +:15427200D4D6DD8FEBFE55F7E87B73566A5823975764F3E7852A +:15428700AC3324227FA2D6CAFFDA1775FFAB0DFADE9DB59A97C5 +:15429C00E6ECC0F7366B159FCE69C177627CF1DA8DF9630D1B06 +:1542B1009FC6B78679AD5E71EE615D3ADBA073CA2BF9B2F8DF16 +:1542C60086311D12674E362176B4AF9DCA9D6ED828ECDA65ACCF +:1542DB00253710DE981758B6B1A26BBDB69B6401E982C5BBE8C3 +:1542F000FE879031FFF331DDBFAB41870DA1AA8F72B16F98F838 +:15430500A22EADFD922EDEBDD640EF6BF5BD842FD01C7C0DFB89 +:15431A00ABE09B524BC539C21F6FD74BCE7D512F3CDB2DE8DE86 +:15432F0043749F45F42E88F08D6E39045A835EC25FD7A623F818 +:15434400F06E82A505F0138E11377A1D3D2772B66AB3A81DC03C +:15435900DFB9D37ABEFB7ABA0472C8F98DBC34AF6C3A4869289B +:15436E000B7E36C98C04FE20E7C8BE9CE3F0D276CA237CAB09C3 +:1543830086ADF41CF8DE7CADE26C29E1B3549F896F7EC9B27C78 +:15439800F377CCE21BE0BD80F826E4DF2A70F1759B77C03725B1 +:1543AD009CD2A6F14E77FCBEC70A425B8826B1D66EF6E863B372 +:1543C20042D156C9FFB8EEFC2E8C3CFA186833AB7DFD46F67A95 +:1543D700CB46E75EF1AE477C1FA220BE7E63E158CB46299FE89F +:1543EC00FC894AEE25DC5F277A0367B70BFC7B5A0A7907E1FE98 +:1544010071C2FD1E21B7DDF8CFB1F19FB0BE4B11947C9FA0B6CC +:15441600A39BCE085A8057A29B46A7D102DF6D7BD0A605C9D76D +:15442B00E2F52E5ADCEAA2C57BC287303B8677D2F8ED75D106C1 +:15444000EB55A03BD277D8F4394FB471E8B1659AFFE787D1E3D1 +:15445500828B1E7F65D30363B8C4A6C50D7420DAB86991177966 +:15446A00E4B1DCC8FAC7D876D6E21F7B64E32C65CBC63CF69F69 +:15447F001F2B88FFC946FFD8A3E277C51F8B315AEC67F43BF207 +:15449400258177794725F7908CBD9E17E5050EDE696C16FA775A +:1544A900929CBB5F2F5CFBD414BC17CC84F7AE85A0B90BEF3177 +:1544BE008177A7BF6EFC936C2FBEDBC63FD67C30361CFC17BBB3 +:1544D300F0EF116B37167E7B6DFC164136D13BEC33BBF9DE2957 +:1544E800FF4B21FF2D9AA19C887B69D3C1C279FD14589E408C43 +:1544FD00AAA4D48273D5099237B954C72304C3A17B37EB15EBF0 +:154512009A34256789969773A7061EF693BC61AF376C3CF4031B +:154527007A776EAD569CF3592D3FE70FAC77D2CA8D6CCD3D1BF6 +:15453C0077C73C2D806B2170522ED6B603B9AA47CC8548473C72 +:1545510037C7A641FBD89BCA71E6687B9E403EF80E03AEB7C9AB +:15456600ECA43C99F1FE1A8D77CC5117D26905EB41D003684EA5 +:15457B000BBE6AE7FF163D57BC2BE35E7CD2EA77C1FF01EF9849 +:06459000C0E6B892000035 +:00000001FF diff --git a/trunk/drivers/atm/pca200e_ecd.data b/trunk/drivers/atm/pca200e_ecd.data new file mode 100644 index 000000000000..eca84aa7e0c0 --- /dev/null +++ b/trunk/drivers/atm/pca200e_ecd.data @@ -0,0 +1,906 @@ +:150000001F8B0808AC5A10380203706361323030655F65636428 +:150015002E62696E327D00DC3A0D7054459AFD261333136278A4 +:15002A00192663E02479728060A10E9063213F64F0700F3DE05E +:15003F009E6CDC7B2F3514B35EF0A28B9A5A731E554B91474C5C +:1500540034E11AB6692618B7609D8404A2121CA8648D7551435D +:150069009DA578A56C8AF276A9AB829DF3AC92DD52CC5EB177A0 +:15007E00D4CA32F77DDD6F665E263FA25B775B7753D5E9F7BEA8 +:15009300FEFAFBEBEFFBFAEB7E79F4A91F6C270A21A1870849C1 +:1500A8007C974CFA8536C11F37B9A99FFEAD9C49302569258321 +:1500BD00D8EF4EEE6E14EF59E3B3EDFED3E3C735EC67E50822CC +:1500D200A9FE0FFD29BF7CEA97A26F4EC993D537AF13234A5E2D +:1500E7005EDE94F3BF245F4AFCF1F129E7CF9E866E0ADE2C3919 +:1500FC002BF0237F849F3240F688FEB5EC75792D39E3BCB43E9B +:15011100C9A9F54BDE24FFBC9C3C6987DDCD33F3938CB0674E4E +:1501260078D6F8D7D63FD9DC8CEEABDC4824B2F9DC949E391965 +:15013B00FED7BF11FF975E7267F17D1CFB4BE77E3625BFBC0C26 +:150150003F0FF9BFFF5372CB72671A1F3D3EF99DF51312ECCF0D +:15016500C070095C0E5FF8FFFE4B3A7E246851FDD31C5230FA46 +:15017A00FC0A35E009832F79ADB5E45140A3A4743C8CE3E39F62 +:15018F00C35BB09DEAFF05BD7A95BB3DADE6B56DADE538465425 +:1501A40052C90E11EF08B4773A8857FB013CB7112F090619CEAC +:1501B9005B125380AEB695F80197D874FE9A9022A5D554ADE572 +:1501CE002661CA73EE80B5F5F26AE22D7F9A78FC814838484AB5 +:1501E300E8B36DBD4D843D4C4930CE42B06FCC091861CFB9BDAD +:1501F8002621C3B438D010BE6DD7091AF29090DFEA334930C6AA +:15020D001187E86D9CB09E2EDF18033C8DD220A9BB6D57390DB4 +:1502220011D2D8B26F23C02CEA0FAC0EB76CBADB3C4F48F1BBF2 +:150237001157A5EBD25FC0FCCB804A3412ECA211D133EA167DD2 +:15024C003B8518510311A53A5FDD62226D9C4BD46AEA567ACCA9 +:15026100362DB78EE8A7683E21017F201E4E927EEAB6169944DB +:15027600AFE1ADE3AEBAC0C53534B0EE4194CF8AC2FE47C6065E +:15028B007960DD5253D1FA6834346000BC45C0D909BE0A681025 +:1502A000BDD7BA4BDBBA12ED8A7C09EB8EA79BDA6BF9816681AC +:1502B500F70EF3723259F4518D59F578B3AB0A66E7A3597F0E69 +:1502CA00BA90E04E5BEEC669E5765D2A33DD6762936427C1D5C0 +:1502DF005CDA40CA8A7AA03EA807AC0147BBA02E52A72974180E +:1502F4007B956F461DD851EB3EA14348C8A0EA9689F2332DA72B +:150309000E7B941FFB00D8FFD6801526637B69AB8FCC22A5F03C +:15031E00ACF65863355BCB4740B7F5A05B6A3CEC239954156CC1 +:15033300E7B09E9AA7F084F085DB760DD171378910B6285EA406 +:15034800F64A5F403DE05D8BB4C2F800BD8EE3418BAF06B8AA3D +:15035D00EE81F5E96393DE6D3B92E0385D564748698085091946 +:15037200A79EC256E0D34F49792B1D759310AC032BD6FBCDCEAF +:1503870038D845EFE5456A87F95932097ABB5B050D98BFE30F8A +:15039C009CDF2BE6B767E667E6C6EDC6D24DB7E7A56AA4888777 +:1503B1003626DE3B6D253EE5C5810BE19CD8095A7CFEB241D8BF +:1503C600765A663C6DAE8CBC4EF7B70D35420264F51833C16105 +:1503DB00A6438F32018C232C303A64E29A23DCADBDCAE604CE52 +:1503F000C2DAFC0BE48392B027D20C3E546386122FF0964DDB3D +:15040500C0A7BEC35A366D323B120AE8B357F8531ECA1ED46DF0 +:15041A007F6AE732A6800FFA49302E6321B8C48EB97E560BEFE0 +:15042F00458110CC6910FE9B84D825C10415992A67940623CBF7 +:15044400E9EC584E5DD1912DB4E84C9DA9C486689188ABB8F0F0 +:15045900BD43E494A124DEA49DE43503E75D87B4D6F9E7F81CCD +:15046E00E748EF05F296419A062866F84EF23AC04791363CBF24 +:150483000BCFC31CE5D213EF71C44759162BA4E81F2077148DF9 +:15049800DE677E1BF429501F117ABAB5A3E037FD527EFD21DE68 +:1504AD0072EB2653890C502FC844D803BC937403BD7E2113CE66 +:1504C20027FA51FE0EC4AAE7DCA04906DB38E62BF04FDB0E52E9 +:1504D700EFC24B09339A731CE3886F2C203A191CE0A344E0591A +:1504EC00183F514DC49F88258C471F213EC2FAAC68A8CFB85650 +:15050100D6535DAAB92A3CE7C0EFCB0728CC6BDC33EBBE3AF4E9 +:15051600E76BC964B19EF8949519FF64CE568E091F74150C995D +:15052B00885B1C83D82FEF43FCD0E167A306513B39C4E31CF4C7 +:150540000131A6FE965F4D26FD9E7387CD79E78E9AE46AAF90F1 +:1505550009FC2A0E7E2562E5D1C8C62AB40BFA87E7CCA98C1F9A +:15056A00E07CDB0F02E0079ED07A136DD5DEE892EB27D74DDAA8 +:15057F009075F0D47A1E222F1BA9F524FAABBC1763C2F6998923 +:15059400F69376FBD1FB4F007E4396CDFA85CD8A1BD166C3B678 +:1505A900CDE268B322323660755A03C6B5E64D2B053DCC1D2390 +:1505BE00D266445F1497ADAD0B68E03E15BF6D6448D8278AEB56 +:1505D300C80678BEF73EB0C30FE947E092E01FC585095735DAFE +:1505E800F671D7EE55CF245C958188AB5ADA037C046D01BEE121 +:1505FD00BAF4A9E9518E9B1D5AC626FE09B121732DAEABB48BBB +:150612008C15B459DAD7B3F32CC428FA34D7B6547ACE7D067369 +:15062700345B4F0631B39A266B102748855D9AEE95FAA9DD5677 +:15063C00D4EA35EAB4875792D2583897B499FE5D3F12FA91FA31 +:15065100A3343AFA18E487C7B823BF7489DC027E87B620FA20D5 +:150666004FD1F043DE9AE5B0C528F877AC664BD58D1BD21EFFFA +:15067B0059BA7B79AD423CD23EFF6EAE509A67B0CF7B609F6360 +:15069000FF23F63989F6D9BCD64CED8550E85072F557D21EB076 +:1506A5004745AD6EE339DB1EF3C922D37F7DA9B0478E5E629653 +:1506BA005AA5D57F827B8FBE9F46125FF04F66E1FE5412866761 +:1506CF0086F945D818ED469ECAF8A08A7BB46860BB6E87ED4EC3 +:1506E400F114BF6CDB45C1764D60BB8F6DDB5D00DB21FF8083E0 +:1506F9007F83CD7B22DFE3C67E6F5F26674C9F2BE638724555DF +:15070E001A0F7DDA111F0B20A778361F4BE710B11F8EC13CAB3F +:15072300CFB85A932B64C35C82792494788F611E51E60E9B4A3C +:1507380007E413987728E1C8273927219F0C603EF1E1B81893A8 +:15074D00F9A4D8B3F9A4F963E02D724A539F88D97980873AFBA5 +:150762001C3A37E59359CE5C33A1781D3BC1DC9B7BCDA235ED12 +:15077700A29E2C523E379B4988CE17BAF7F3909FE8EF821F7925 +:15078C000AB11608D25AE1474B445DF7FC5CCD20E5FB68A3A870 +:1507A100170E70A2DF010DFCFD7FBBF54429CA4C9ABEA016F86E +:1507B6008190DD315E0F7E5103E34F925FAF825A94A30ECFCD41 +:1507CB00EDC7BD45FA3FEA06F6167AA890B7BE6EEB8ED2E275F7 +:1507E0005F9819585F7C7324B932C5ABCC90B5C0CDF0B262939A +:1507F500695544DE16B4F419E647605EC90313E7DD13D9B652B6 +:15080A00AE1BE31B70DDEC7941C02DC8C25D1129B371352AEAA4 +:15081F003D7B5DDD02EF009F3F4EEA549887F684FAAA68452469 +:15083400AF42D45290DF570BFC56BA0BF015C4D73BF911F04B90 +:1508490037E243DE03FC62DCA7D1977CA206EDE5CEFA7063BDC6 +:15085E00A3BEDB4CC197290D617DA68BDC791A7B55055EA967AE +:150873000D7A477DD7EA98BF20E2AE48D57848C3FD00350F601C +:150888007C421EC69849CFB37FEA060FC6604F20B001CE496318 +:15089D00F45BB141FAE3B6A126DC2B99A8E7346641AFCCBD0C5D +:1508B200FC9F80B3D24E383761AD1C83FDE1320F41BEF0EFBA70 +:1508C7005F9C89FC501BE39EAAC2D98AE8F5D48775DE582DD4FD +:1508DC0079C130D653FB649EE04837404E899AD0B2CF592B7220 +:1508F10048F13F47DC707EFA7B13EB3699AF0DFBFCA4DB755C24 +:150906003B75477AA046AD605EF541B3E5D6BBCD36A0A978FFF8 +:15091B00C6DC8B750C9CBB3007DDB2E7553337827B40B7D80387 +:150930008A033190A792DF42FECCF4C379E3167106B1EBAEB1A5 +:150945001EEEC7F307D45D9DA1DE74BD05671CBE429CA18E43BC +:15095A00BE5B682CD0CC95E2ACA1F6C4DD381FFA828EE5E21D9F +:15096F00CF4F17DE36CBDB9B95EA476A72D279D11F53A6CF9FA5 +:150984002F7597077ACCF25BD6C49886A7633517D785EC80E7CC +:15099900C4DF12320AAD0BDA4E683AB425D008B40B301E87C6CB +:1509AE00A0E9625E4FDC6EB04FF43059BBFD16CF2CA13DDE56FB +:1509C30043BEDBB50EF83FC2317F3629F20C3409C7410F71268F +:1509D8008F2F88CBF60A4BF1D9381D5E9ADF82B8362D3FA475C3 +:1509ED00BA4BD293F8E3643ABE8067E39C2533D1CBD03A3C13A1 +:150A02009E8DD33425BF89326D9C964E46A68553D2C9D040BBF7 +:150A17007F55C31A995C3D2CF1C7A25CE40D8CB1E29881790360 +:150A2C00623586F12B629A58F412FA289C3F647C34424C9608E5 +:150A41007F9B2E4E5E8138715DFA8579CB9E939363247D66979D +:150A5600B181F1823501C620C60CC64E3A56ACA39958518FC96B +:150A6B00B3FA18D457D69F1A6B2156F09CCE223913E224153FF3 +:150A80001F431E9A8D7990EDA5175CF2ACFE817D7D38027114D6 +:150A950081380A7D8D38DA6CC751C3639938FA009E23DF07232E +:150AAA004223D0128F43850E8D416B8016825602ED1AE0753D49 +:150ABF0036318EC41D03C412CAEFD9DF938E27E09B965B03B992 +:150AD400F7BCFF8A21C70726C557AA05537E9F8DEBE047317E33 +:150AE900DEEF81F157441D23C75BE2B2C13A3649FEF5022F9BEF +:150AFE004E8B23CE5AE21F91E9F8B54C8AB35E320D3D874FEF6F +:150B13009A915E86969EC69B420F382B230E9D92DF4499668A69 +:150B28008D7A32959D60BE4D7FE194E3683F394E74A0F3154D74 +:150B3D00CE4DE17F988EBFD4BA8B38D4FBB846C8AC542C4EA83B +:150B520027713FDF91D98F156FABA86DB78CB65588BD1DFC5798 +:150B67007D286614EF1AA4BA479E078B77F5D28847D6AE88CF94 +:150B7C00B0C665526784B9B260E38E7DBC445B88674CB6E10A5C +:150B910021EE75DDA61F635A2DC718F12B780796AE33FA999E1D +:150BA60043484524B702756A8067E58101519721BC73FE108595 +:150BBB009862B92AE8AF77F3DBB513DC1D6B73DC635914F1AC84 +:150BD00087F12E56D25A75B3B4622F6768017E1CF67CBF1E338F +:150BE50015C85F985FE2F23B9EE0F375F4B11CFA743964B06EE9 +:150BFA00521FC48BD74A7D2C873E5F492B4B9FC12C7D06BFA10A +:150C0F003E71873E671D32C46F521FC44B7C47EA1377E8F3954C +:150C2400B4B2F419CED267F81BEAA35EC9E8B3E44A460684DF02 +:150C39008C3E88A7DAFAE0F3AA9BA595A5CF48963E230E7D4207 +:150C4E00F6FDA61A180DA77CBCCCA066BB897CA58FE0FB4EFBF0 +:150C63003D6EBF37D8EFC81FDF0DF11EA3C29781C7CE1CD1D360 +:150C780041FBBDDF7E1FB6DF2FD8EF23F6FB6AA0B3533BC6C47E +:150C8D007E0B63EDDA49BC1BE40C9EBBB49FE2F99F8FC273BFE6 +:150CA200F6160B698BA97DE6E61ACC2B857D695E24B73A10CB76 +:150CB700ADF62572AB3DB00E78DE451DCBB597059D7A98BB5EAC +:150CCC003B25E844E1B9567B83E1FC77A41C0C79D66B7B98A408 +:150CE1006BF18540B710724F0D394B4F6F3BB916715096422D36 +:150CF600B702613FD9F653011B75C0F66E7B4BC050A614EC99A4 +:150D0B006DCFAD4DD15FACC9F5433AF3C4733FABB7F9A34C0FC4 +:150D2000960DAC49D14CE122AD146E4A5694ADD4C645BAF768FE +:150D3500B9D5381EB56DAA3D216D1ABA22EF6F904789BD3FE19D +:150D4A00B8BEC3392EF9DD65D358286174F44989B3DEA681BC57 +:150D5F00FD4803C6C69FC88C55D9760CC3F846B01FDA8EC2739B +:150D7400583BC0F0DC392264BA2CE4DCA1BDC88E08FB76F1DBED +:150D8900AF0807F47DF7466E65D9853BCDCDA56F2C7F612C6631 +:150D9E007C7B2DCAD12E6C940F67B9556BDD952B4AF72C6730C3 +:150DB3007697188B0B79F363B915F3DE7257064A0F2CE7305641 +:150DC800B856CA8FF6CA8738B9F17B77E5EFE6BFB8FC208CFDBE +:150DDD0047756E753E9C577F7DF1F32AA4F9F17C5A85F3FFF557 +:150DF200C86015E29EBF78026AAD06C113E48F5BA22F113283A0 +:150E07009E715DF43B056D120CC555D1370A39E07C18C798B8BB +:150E1C00EDCC6553F93002F1F71A2D10DF7F625CCEBBCC6B45C5 +:150E31002F6D4482116E403F67DD5153D9F47DA8B3F6D15B712C +:150E4600AF04BB49BE31DE2AFA06DE2EFA2E61CFBC3D80BFEF5E +:150E5B0069C0BF9B16068280AF895C26F2ADE81BF9B0E8570B92 +:150E70009BCF3A03F81FFE10F037D1D9011DF0435CCA1DE37EDB +:150E8500E89F15EBB093975CC9EC6DA454033C43ACCD23B0367D +:150E9A008DDA7EA606C6007681AE96B6E141D15FE0E5D037AD30 +:150EAF00245E1674D52944A3FBAF277DE84B3B005EA01D83BA29 +:150EC400C112F6CB81B3F8ED77209E8C2BDC2B1FB171D1DE7613 +:150ED900BC517CDE0D3C55EF0766EB9A98FD6DB39F22BF48E2BF +:150EEE0067DCBF6B08EB5F529F789DC33BB340367FA8CF54BDFC +:150F0300782FF021776B43FC9315B63CDA1DF4C69792C76198CC +:150F1800AFDAF2305B1EAA65E4C1BDEEBC8D3BEA9067740679E9 +:150F2D0074873CB5200FBC3336853CB50E799EB4797C807164D6 +:150F4200CB336ACB73BD2C230FEE55F7D9B8E86F2979F0793A72 +:150F570079420E79D6833CF0CE6253C8F3CEF28C3C977E277943 +:150F6C002CBB827B9A940779A03C3B1CF2E05E735AE20A5E2E36 +:150F8100C8ADADD57DFC7A32994CE55867F917D10659443B01F6 +:150F960039BA96AA810DE1CE35FD14FF4FA873ECB821758973F1 +:150FAB00DDCE291BAFE0A505F1791CFB6658EB6539856F9A5A59 +:150FC00002CE58E939FD7C839D8F53B806E04521B67D901B9DD8 +:150FD500F3752DCA6A81BF017218DA61689FB1466D21DBA92DFB +:150FEA00039F2967ED5A15ACD57A56663C627272B07149A28F90 +:150FFF0046ADBEC62EC08F6923AC5FA3ACF3C8095A4C06CC398E +:151014005B8FD0F9173FA3AD5BEFA46DF397D2E7B62EA7CF1F57 +:151029005943DB2FAEA387E69FA6783FF357BFC8C198A6F8BFCB +:15103E00542F1C7993169CE9310F5CDC07F5C0BE554EB9CEDE5D +:1510530043BC85DAFAEA344C6FA1E5F712AFCF09130AB4D0C3DD +:15106800D3C06BAF2527C18D480BC37C89F6F12F9E621E6BA1D1 +:15107D00CBD64C01875AE093F9C4BB30D6C3704D312FD45EC9C3 +:15109200D405E99F3AC2884A995B13DF2FD855FCC78E2063D72D +:1510A70044DFC5AEBB64AD33EE92DF494812EAA2C23E336A0D67 +:1510BC0019F87D638EBBCF3C9433641C0A0D189DB0962F586F8B +:1510D100189E0F3E1777C9F825E280D561A81BA9897E90EF9079 +:1510E6000FCFF76E3A24E0CF440A2A3E49FD7B8D9D377E5E23CE +:1510FB00F7C7487A2F8D31947F01EC63F9B1DF97CF8BFD1DEE8E +:1511100023F65E382CEA18B97F0DCB5C073693FB1FB371BA04B5 +:151125004E43669F14F1F0A4CD6774129F5B27F091FBE5B0A8F2 +:15113A0087527CE2369FF5361F89D345651EEE67B171428E04DB +:15114F0095BABCFD7DA63FB4C83C06BAFA2277560560AFBA7A78 +:1511640043EA7B3E726FC56578F680FDCB0C3807E50E34C29EFD +:1511790055AD94F687550DBF8B04E9D8DB9027624A5DADF6326D +:15118E00DED9F9DCEADDB00F75B0D2D0BEAA0324DA48D43DD4DD +:1511A30055DA15762F851A4DFF0D5FA8FD86BB6C5B57691D3C31 +:1511B800A41DE0FE441F63B97D4DCBB46E8E79C51A053D12BD56 +:1511CD004C059A08276A94C281CBE3E4B9E527DDD5CEF965C6B7 +:1511E2004193DB34702E3E232D1D68B94B97844359F37D303FCA +:1511F700A4BDC8A186B0E747A79CAFFE23EE4D4BC2284B10C611 +:15120C0096419D11D43AC45D3427AD8D86F62B9EAB609E3B411A +:1512210039E96C74475AB90FF66017D6BB7A2FF744A2BC2032BB +:1512360022EE9C27FAF1B0EDC7D6043F4EFBEF689FA13AFCB79B +:15124B00106A85B48F821FE0FAA18FE6ED1F308BC92253EAB616 +:1512600044EA16EAAE76FAB35FEB608188BBD28DE768C2A807ED +:15127500D6A3E94EE2C5F7E7E7B61B259B89F7A5B93143D596FA +:15128A008AB5598FEB0073D9FAE876EC73578BFF21CABF23206C +:15129F0069AAAB3C61159E676A128F885E0BA4E4D620EECA880B +:1512B4005AB8CC6C752DDD9E6BC399CFDA9E1AC7FF6352430BCD +:1512C900BFE74ED10845BFE74B3DAFCBC0459C801EF81D11EF02 +:1512DE00CD0E6AEE3A96DE9BE4BDD916BCABB2EFA5314E08DEDD +:1512F300AFE9C75940AB2EC7B51570BD8F5DAFA95E29EEFB990A +:15130800BCE39FA37799F8BD016922CCA746CDB3C9A47F527EA9 +:15131D00B2F9D74EE2DF6EDF9D4B39EE127766BD71A4A3240E38 +:151332004BBA3A7E4790307C4E4C419FC571FF91F4D500F0620B +:1513470094E2BE68D3F4F9347FD50AADA02264E78D0AEDF66A05 +:15135C00A0C97C6A47FAEE1068B3A2ACF7F4B3CD8F8F1D355654 +:1513710068F757F8B4FBCB03DAA28AD47DEB0A6DBBA46DD35490 +:15138600BC8727D155DE9F19B638717B25D610F8EC4638D8F716 +:15139B00207ECF8950FC3E731ABFE72C4EB82B713D104791385F +:1513B000EC20E660C4D1FB38E2A0ACA501AC11A1B67B88903162 +:1513C5000236FE4BE255C5DD690CCF9BEA79D24FF15ED2F20E35 +:1513DA0088EF6B44AC7B4CE0FBD5D7E47730FBDC81304D1BA0C3 +:1513EF00E28CE280056D58A303B6CC8635E0D9B754F0E33B1C7E +:15140400E3E2FF0C865D648936C09D30DC971766C188CB4DCA55 +:1514190027C2583DF46A6488A910CBABB3C712CAF87016AC0146 +:15142E0060235930F7BF29E3A3593002B0771066AFF37F13F3E9 +:1514430084C1511569F6242F3203617CC0644C280C0F0C1AF656 +:15145800229960D0640871E2A297502C37025AEFB141264ADC60 +:15146D00E0A1CC4156D92DEE7CC144126CB07926122DDD9DB8D3 +:1514820099327844070F14B7425DEE8E73BD2D6A2B6559B7D497 +:151497009D52B355DE15578538BAE8B2559C73DFD7DD6FE6CDD5 +:1514AC006450F1F6EA7E4CBD37DDFDBEEFEBAFBFFEBEAFFBFBA7 +:1514C100BA31DE44D82DB80EE738919E4FBE9AF31B37FF6E8C0B +:1514D600D97D8E4A1BC19FE113CC3500EB7D15DAA8986B25E05C +:1514EB0087B471F62449D02133CEFDA473208FA0ED37A19F74B0 +:151500003663C7C458757D99E6E3144ABE9AA12F947C9BF50CD4 +:151515008CEBAB1D34234CD447180B4298111E57823AA4431D81 +:15152A006768C3D7CAB2AD92C6AD92463FE63CA91C16DF3FF7EC +:15153F00E1FF709CDAB90469291BFD5236446E9DE415D833C0CF +:151554000DBEEBAB6C10E61C105FC6F58DEC875B3ED5BCE799CF +:15156900AF3269B70EFEBE8AB2C2569792B0D97682E72DADE6FD +:15157E00717D5146D64D2F2B7296012DDCE704CDE492EFAB5527 +:15159300511E4ABE0134BEC1CA529CCF7E53D2C1CBC0E6F81BA9 +:1515A800C7A4FE495015BE293361DC608CF8337C825E8FF0D8F6 +:1515BD00B855A83D29D09E64DABF2DF80B65F06EEDC9F843208F +:1515D200770BC03B94FDC477DE271FD06EF709DE2FB9C6F8FCD9 +:1515E70009F8B2F5FBDAB2F576D9D305CA9475D3CB4A9C65796F +:1515FC00F1542EDF728EDAF3DFA91B7AF274033EA764DDD5BE7C +:15161100310B7C63D755E3F3FBD96FD1EE4ECD27B36CBD843CC7 +:1516260079CA9639785F78B6D748E4D5CF3A3766081863B4A142 +:15163B001CFCA948C92615F7A301D6853FCFEA38940F9C17769B +:15165000DD94B30E78E19670F8D301632C0F86CD032183A2CC22 +:15166500CC2F03787BED325FB6CC2C5036D39B5B867DEA73F4B0 +:15167A00D92EEB2D5056EC7596993451A9105621F9436214752A +:15168F0006CE4B1FC83CC6CA306EC2FFFBC7DACB1C6B51524A3A +:1516A400F89A13E5D7C7E5374E6D399F7910F72B13AC1DE6BA33 +:1516B9003F2474592118EA35C380BA700CDFB19DA53BD60968C7 +:1516CE001F501F6E475D02FFF1BB0315633A878FB2E223AC503C +:1516E300B9EA28A7CEF6E585CB5528EF92712E94FB7C7E617C84 +:1516F800B820BF7C85FB3AEB5CC21832C7A3072A123AD703DF1D +:15170D00866F7F4258D8CFAF1B037A2D747D6758B9E39A907AAE +:15172200DEB6FD421FE7F23A571F17A005BE11B48C51FE04D841 +:15173700D7233CF06F0AF2A1407B92699F4BDF1E87DCE1FC7519 +:15174C0079A7CF6FE29D3EBF8BBCD3E7322950B6DF337D7E97A8 +:1517610078A7CF6525AF0CDB3FE7FC36BB26E13ABB92CF716123 +:151776001B90A70B1DB60FE3E0DD72AF86386CA19A57A738EAD9 +:15178B007C79756E475D795E5DA9A36E812AED48204577F72309 +:1517A0005D268F1F667D8F380BDA7BE6DCDF88338C69E058640C +:1517B500FD8D98217C8BDCDC45A266737E547F75BBABAD8E9F57 +:1517CA0067C09C7AF516428A0E361AC9CFD31E5843EA53F054F3 +:1517DF00802798FB87FB643F03997A3EF6C77A726984BDD79F79 +:1517F4008DAFB70EFCFFFECEB7104F0DD0CA423DFAEA3B9555D3 +:1518090076EC09E339A4DB7C7312CFA274C7DE9CE2CF495CDB6C +:15181E00C033F9668A9F5101FFF25EB157E2F039A98B8C9F43E4 +:151833007E52807D39C4E339D2CEF6839D1D053B0BCFEF8FEA65 +:151848008277D59C77B6CD8D7D96F6106FAFCE3E93FC8BB8384D +:15185D00FF50FF35013C13CA3FBC53B903F1EDB957CC93DDF0B5 +:15187200447F12734E79CC08FEAFCFF137E36CCD771C7335E3A0 +:15188700FFA62CEC2BF024217992903C49489E249027C5B09E3B +:15189C00BE16FEE15CF26A4B0233B5BEC04BC58257A2EC562824 +:1518B1003B1018CB295B01654381E3765929969541D98D8149CF +:1518C6002CE3FBEE829F7A0AF8077C6C4D4DE7E3A53B89A721F4 +:1518DB00857CACBAE34FDD9FFE02F25024E5610FE03DDF9C4B45 +:1518F0006783423C473F853903B4BEF4E9745A5BE11BFA29D2CB +:151905005AF3AD69B5E391DF86DEED05E82D96F49E015A1B9ABF +:15191A00A7CBAF8939BE0564F7E38B694F11F4E3838BD3FB616C +:15192F00029CD317B11FBE6BEA47E63CEEB7EC4F5781FE28B23F +:151944003F5756114F17FCBE0BFEF73E813E69554CD56A18D73C +:15195900FDA0F35CCB09998472FCAF9056FA21BE0774AA017723 +:15196E00166886A56A2D2F22FE08E899B511DC0F8C51DC35426B +:151983009B98A262AD12DB0FB65831C11EF6F3FD2C0AEDCE4436 +:151998008E58A51DC7ACB512762F3CD3D79B74233C5DE2BFBBA6 +:1519AD00218F9E06D95687E746F0357D9AC04774810FF120BED8 +:1519C200E833B9F81640BBD28E23D65AC0F7E10501C327F17D8A +:1519D7007C41E083FF6E273F55C9CFA34D44D437919CFA39B6C6 +:1519EC00FE93F59756E6D6CF95F5DB65FD0779F5F364FD5A59A5 +:151A01007F9CD7A7A8EFD9ECF9A334F491913E1DF790DC68A32C +:151A1600F3CE1BF5833FC4F0CC47656C7333EE2F997D75959A13 +:151A2B0012D4A53E1BA838AF3787F6055B1DF1DCBD273B7E8D0B +:151A4000BC7ABCFBFDE680A3FCDC0BCF5CC1F2959B7FDDEC8CD9 +:151A5500FF9E7DEBA72F63F983FFF8AB665289B1C761DAFBDB56 +:151A6A00275A7C7E7373EC87C433761FF14CA3D391AF9B7A36C9 +:151A7F00D73E0B5F2365A10E7179C53A8C97A9B97DB3FD236C72 +:151A94003713647D3028721BB0ED40DBB83E33725F607F1BD7AA +:151AA900E5CCB47539D4719D0F3079591E3C5C6F52B02D5D5C15 +:151ABE0086ED35183306CD2A1DF7BDC16FF4F457C4F4BBC89216 +:151AD300A0972CA99BAFB98298233650C1F4756655F0BD0C5F2F +:151AE800C6F83EC46CCE0FB6177D9412F0F546F3EA3D8E7A059E +:151AFD00EA7BB37CED2F5248BF1BEA5DB5307EB2CD7C6ECFC40A +:151B1200B7D741FB8DB2FDF740FFFBB592805DE787BA0622E42F +:151B270009FF2F3C3B6254C3FFF98E360BCFC60D5F1E3DF7C0A8 +:151B3C0038252271CB0DBAB6FECBB4277625EDD9FA557A96EC0C +:151B5100DFAA49D0D3203F397AC527E574B491F079134A3E4B1F +:151B660093256416CA19FAC136EC27619E610C4775D0E5AA8842 +:151B7B0019C723DCFED2808C3FEF01B8D5C0FFDE45C493AA12E9 +:151B9000B27FB20160CB7D72226DF99364980E4E8EEA336F4273 +:151BA5009B1EA0C297D5E43E6D35C576459EB8F1AF8B7E50EF22 +:151BBA006B8CB1062BEB6F45E0BD669090283C1B9E23C484E70C +:151BCF0065F895C3FB65F885E0C79E13FB5D08A7F53FD29ED399 +:151BE400B82693FFDDE7D39EE3F89F8DB079303E181BA8E47B6F +:151BF9000929EBF4FD843C87B6818D58367FED75C669919FC22E +:151C0E0061281AC6285EC77C7A9ABA8F102FEA228C9B711FF33D +:151C230088E56AA306EE2763EC8AE7CAAB23B8B75AD6E4A0E3B9 +:151C3800AC9BCCC2D82AE2C7734FB857B100EAC73CD25E713CCB +:151C4D000798CA7535A326FC5FF05F609F501F89FC8B0C2D99AC +:151C6200B39958F63B570AF0F17D3CC5F18E7B97F63BEE59F2DD +:151C7700B80FFC1F73C4B96C783E76C4405D904A5FCFE71EC6BA +:151C8C004486FEF9282F23A9EB89EFDD51F10E7F701CB36D6341 +:151CA10016C65186268FEA650ADF43B1447C2566613CA5C94103 +:151CB600B7D8BF1CA60F4C3D30B5787234472E67A35C227D20D4 +:151CCB009BBB6F271E1EAF0C1F61E8F7EDD7560510861B73A2DD +:151CE00022A798163941FDFC9CD3179697E700279862EF075FF5 +:151CF50014F916FC5C82DAC3F74C791C397CCC7A5CCEC76BF51C +:151D0A00279B1CFCFA661A246E3CAB84F80BCC81F25560EBE5AC +:151D1F00FC60B8F7AC522E5764B288801D328662CA263C7B40E5 +:151D3400EFE5716FBFBD6E9B43460CD46BC85B2AE9C3EFCFDEF8 +:151D4900463CCAD45386FAFE53BA5347E2792466821EE76BBC5A +:151D5E007E9AFEBBD30AC626152EFBA6581F4D017FCCB87E3379 +:151D7300190DE299C5D496A3CDCE71B94EEA8BEE159C0779F150 +:151D8800175CBFD9704D0E374D4ED2CC99447594611CED7B66CF +:151D9D00BC20EC191276F90A92B38F9B858F79A4FD745FC5B0E0 +:151DB200CECFC7838E45FA63FCEC42DC5C8CEB03C0519C1C3729 +:151DC70095E409D35D1A37704F7026E09B1B66862B42E9A1A492 +:151DDC00B249D17AE90DEA2F8D33E9B4DF1B5382D9757098A279 +:151DF1005FBBDB85BAB015CAAAF9790D9EAE8B3EC3FD620D515C +:151E06008ECFCA06983B77BFC8D75A01ED4D727F017AC13E46AC +:151E1B000EA37D1CE6F6715FC549DD3BD9773BC737A5F4B2C6FC +:151E300031417B386E7AD1DF93E54591B8A9362678FF0E9103BC +:151E4500BA05F2EA5E07F38DC5AD9BC51955E68A8C67FA3737FD +:151E5A00341AB4BF15FA2AF33E8D9EF70E67F371F7817FE13540 +:151E6F00253DEC2AF440B90AFA176971E2748978EADE9C3334E2 +:151E8400A82741C648E549B18F20FD33E09DE08FC82DC8E5A33C +:151E9900DAF762CE7E3DCCBDC806EC036BC7791A4A1EDE5B29A3 +:151EAE00D681E683503E188EE96EAFD86B4B024DE78B4D3CA3AA +:151EC3003E0BEB03EB458E0CDAB0C572EDD8CA6564CCAC833ABB +:151ED8009B764E37B46F58CFFD6C1EC75F2BDB353ADAB5245FE1 +:151EED00DD0B3F13CBA3EB798CC4C43831F605D7AA48C7E05399 +:151F020071DD3729F704A1DCC6DB25E1FD5501BCBB1D78B7CB1C +:151F1700763F71B4BB0BF0623BD3D12E2ADBF514A0EFAEE41B6C +:151F2C0026CEB17E4EE3DF9B685FDC408B0AF43DCF65679CEF03 +:151F4100430FFE13D04AC4397EB783D66E097BA000ADCC41C374 +:151F56006ED9EE50015A871DEDF6C8762F7C0DAD38C636ADA5E6 +:151F6B00DF406BA983D6A484DDB1613AAD5D1BB2347C2CDB6D89 +:151F8000DB7095F1DC901D4FE52AE3A938F09EB7C7B300DEDD56 +:151F95000EBC17ECF1BC0ADED68D38BF2690074C75E2C5FECA8E +:151FAA00FB36B0DC96F935D0FE308967647E638990F92B2E21E2 +:151FBF00F3A18D59DCE11281BB65E3D7E006BC3E89D7C6E77309 +:151FD400F473A384D1561806C3396BEF7597E7EB3CD02FC75F90 +:151FE900CAEA3B3E9FF95D0A4719B767784F8E7A9CA11FE92EF7 +:151FFE00ED33F6815FAA826D53D79E32CAE909E32021739C3A1C +:15201300E86FA05F85748FFD9DDF15D70F9BE33ACA8B88271E8C +:15202800D0613DBC17D7BF77715859DBB01C6015815DC8E8D5B4 +:15203D00D0B8EE5E17E73A95EB53DB5E98A84FE35C9FAA6D40B2 +:152052003FE85197E33DA7BF9598AF31ACBB2A9881E7F178AE2F +:152067008CB0F9D23625047E26F5697848F8946063455F46F90A +:15207C00F9097E3E08ED52641CECD23B863B7682A26D2A684F28 +:152091005ECEAE1F193FC7D46BF8319C8E7B15F2FFA5747A5E1E +:1520A600FE5A52EC77F278BD359C02FDEA81B915AEA12CD41386 +:1520BB00455DEC2E163A59917E7C293CA37F486772FF588AE7B0 +:1520D000E79539F3C6944671EF4CABA31D5EF893DF0E6DC2F3A4 +:1520E5001A9E5B3AC910CE83987F510BFF8167E877BB2A13EDD1 +:1520FA00587F4368D4B821F40ECA8CD5CC7345C618C2C372FF1D +:15210F00E6B895FDFF8EC1CBFE3A8E3E0BF1B38421BE7F076D69 +:15212400BAAFC8DB631CFF324BD3608AFB4D0E9A12B4991C5B1C +:15213900E9D75C011B37DEBDC3F34230FF1ADAFB6FFCC2CABCBE +:15214E00AFFA228327B9F058535126EF07D6AB320F1BE92ABB9B +:15216300310E7EFE10B3F819D31A3A07F87D3BB24315B044DB21 +:152178003186FC07B368A9EAD330D6C7E19B414BD18E5BED0E8D +:15218D00BF12D6DDE411AD64E5844BAE8B0BE05983BE4B41D8DD +:1521A200555689FA16C09EA0840D594AEC94856704C4797E691E +:1521B700BB51BF15CBF98B396DF25C0091759305FD19915B88C8 +:1521CC0072746106D29560ED226798B9257D6E271D682B8B05AC +:1521E1005C7F30415522CF2AA8C72CA443FD6889C56D51868E26 +:1521F60014ED8A65E51BE11CBD4FC0194C09F8026E82F3A7EC3D +:15220B00A33EE68235223F8347C6753C138F3EB0F82661619B93 +:152220009C7900F03F8C65FD1FBBDF083F719FE89FC0339683D4 +:15223500C7DE73C0B69C8F49C1C71B36F75AFE7082D7259C38A8 +:15224A0033E7914354D0D24055CE975679875080BA653E202FCF +:15225F000F8FB28717A1EFFA0ACF4773D2E07B7909738E1DB4DE +:15227400B114F508C6FE992D27E80BE30D65CF935E9DDFD31477 +:15228900A69C2FFCAC05D42BD05FD660525C841797F61AECC022 +:15229E00ADC607FF96F690A911BEBEF7E118A96F1A8A768AF9BB +:1522B30023E24E017B0D535E3C7D1DD5D37624735E3EB39E9A77 +:1522C8003A66DD7EADEBA9F06B962D539847365C22D6BDB93243 +:1522DD002564086919967CE163128C7179E2EB5958C7A33D4393 +:1522F200794219E0BC32C51AFEA5AF44AE52A1F504CF1B0EC06E +:15230700DC6717E83C7FA01DF767BCDA92FAF7D19EC23AFC1118 +:15231C00EDD6E0659893CB93BE55DC36DE2FF37DEEC74B4F0E1C +:1523310070B9E3F960A2DCC2F2F7E4FA3622DB46F3DACA720B9E +:15234600CBEDF3B836FC5EF9CD60DE37B2DCC2F22E09BF5FB607 +:15235B008DE5B595E51696DBEBD4C512FE6AD916DBE1FB028718 +:15237000BE6975D4E13B9E6DC2334D6E90A362B0558A36622134 +:15238500BF1475BF81E31DD046F19EA9B9734343CD0AAC57CB16 +:15239A007A2E18A5DA116BBEF94993BFE55343891CB75E8E95C9 +:1523AF006C72C39A0BECF1BC9991192B95C805CB96D999A0DB1C +:1523C4009257709F2E3B077E0A3652E1E746D8B4F928E757464D +:1523D900AF200CF5E08831583CAA236D73375759F67CE632C014 +:1523EE00CFE58EF3BB8BF8592FA147ACFCF92CF2400127CC19EB +:15240300E73C796A76AF91F8ADD84754A54EFBA679F27480DF1E +:152418008D23E6C8C008CF89518BB3F98F8B31F7007C8D07F85F +:15242D00DE7E36AEB50EE4CD67CBCDFF36BEE9984FAD45FF072C +:152442003A3ACF9F086B23ACC4DBC7F9F912C06BFAD4E10B5CB6 +:15245700CCB3BB400BB611FB20A6C5F7472AC7DA4B0EC68D21C8 +:15246C009015B5294E93220662B9C57E29BF37096D33D66BB0B8 +:152481006E4FA17D97F0307EAB4716B1622FDE75D743272F66C3 +:1524960071AB05FC107704F0F23D0AD3C2F11A02BBAF4E8CD0AA +:1524AB00CB12278E6F0E4EA877E7E1CCED7F75FB4607FE900352 +:1524C000BF5600BFE2C0BFA000FEAA6BC48FFE456F6380DAB4A9 +:1524D500200D139F081A1600AE7CFCEAC4118E4B8B8CC0DA3C30 +:1524EA00D10E6B6F0B7D1F45E377CACC5B101961CF83DF833679 +:1524FF00ED92D3CFC1589F5A65F5B65103EF74BBF46455338FA4 +:152514002756DFB4B4AA6D6B50FB6143E366ED9EBF587FB7B6A6 +:15252900E127BBBA3B1FDDA5ADEFDCDED9B1AB33A8B56CB9679D +:15253E00C7CECE8D5D3B7EFCA3AEEE2DF5CB6E5B16D0AA1FD909 +:15255300D5B56DE7CE1D8F6DE978BC235457D75877DBD23F5BD6 +:15256800AE3DBC6D7BE72E2DD0585BD750DB7807BC04EB03C11A +:15257D00FADBB4AA4CFCCCC6575BBBB533BAA3BBF6A11D8F4646 +:152592006B3BB67644773D51FB68C7B6C76A77ED7CA8B6735700 +:1525A700B4F6E1276A3B3AB6F3B2ED3B764497EDBAA96E857601 +:1525BC00ABD6B9755BB7B6B5F3E18E1F6FEFD61EEAEA78EC478C +:1525D1009D5AF5EEEECEDDDD4B11CBB783BF75E7B6C73B77D624 +:1525E6003E0CDDDAD2D1FDE896AD3B1F5FF6D04D2B1AAE063F10 +:1525FB00039E9F6799E30FB7EFC77D42B58ACEF537B4576BF5C9 +:152610006C199EE5B1F3F423CACA85FA05E350E870B4880CD334 +:15262500F63FA63379FAEDDABDD67FFECEB552517F6054692D59 +:15263A00B40AE6DE39D0253E78BE85BA539ECBEEFA22ED797785 +:15264F009112DCA81D613550379F8C3787B401C6EBC3CAD30165 +:1526640028437DD3E428C3762AD8408069F56BA5AB6C9B500E21 +:15267900BA710611BE04FEBF02B0F7A9CF44D14F1CFE657A16F7 +:15268E00D2E5CC6B77E6B4C72E8B585C1F6F5F4DBBA03D513FA2 +:1526A300B77CF0CD04E68D39F0B328E1676797B9C85CA40FE9F8 +:1526B800F069C718F66106AC53317F8E4C2DC538ACCFDF72AB4E +:1526CD00817DC77B164BFEA1D1C02B54AA0096D8AF3A44C3DAC6 +:1526E2000BB4FE6DC00DFE940FBEB7F1E0391EBCB301CA2C2721 +:1526F700CE35E934C7C9EF6D04FFEA783A3DA732E2127B6AE153 +:15270C00017A1DD80584997C0BF3660350F60AA7AB04ECE521AB +:152721007E6FC47EDC972BB3C7CD3E6311FB038EDDE77CEC30F5 +:152736007EA36930EFD4BE845B5B6195B41C85F13EC061E33C5F +:15274B00C43958AABD6CD57CE56ACAFAAB620C6C7E3BC7C1F730 +:152760004EDAFD75F5574EA66739C703E951811E9F63BCA211D6 +:15277500378D257F65A920875A722431D7BF1BDA76515F7211DD +:15278A009B9D2CDEB43AB914E435DA8E776AE01D89782F0E0997 +:15279F00DF4DDF55709DA453F465947F79D0C07B36D662FC4621 +:1527B400C533BB61EE8B0E9ACBF5D74275ABD66845ABDE2F396E +:1527C9004FFDA15BF83E63EFEBE959975C765ED6009B9133FE04 +:1527DE006B29DE5D89EDDAA1DD19D92E906C01B8ADD66A11DF97 +:1527F30048F03B29E5B326B2860EF0BC9145D485F77F014FC4CC +:152808009D94B9CFBD2E71278EB8E76B047CE95AFD52B180EFB5 +:15281D00A523C603DAECE05C6D76DDEB8BCA82D6E21B83A7B1E3 +:152832000EE3BAE3E9598B355790D3A90E50DC8376C3BC3C0DA3 +:15284700F320137F9B7A45D8E7A957AC9F5754EB7CBF1874E630 +:15285C00A0840FDFF3BDD47E8065B7B5DB6D873607DBF0BEB4B9 +:1528710012DE07DCDFCDC7A57F21E6512B7CCFE358324E77F2F6 +:1528860028C233D982D251C3F7DF87190A4E6B12CF389FE7E720 +:15289B00A9ACD0ABFA10C09D5F5A632C07BEE2D9D81A729EF631 +:1528B00086DE88624C2D896B83B6A5860563751DC84EC99E710C +:1528C5008AB90441DCFF507F21C646CE65F4A915BE2ED380AECD +:1528DA00503BA75FFD85357129ED395A24FA79178C75538131D3 +:1528EF00857575597E9F7A2FA5790E09C2D92EBF9F0F73AE6456 +:15290400CA34F0BEBA2258A784928729FD4DDA637F8B730575F3 +:15291900E284E43BC66F911701E083DD6618EAF83B7B864652D2 +:15292E006911EF8436A54773798F325888569CC7E5C91EE6FB92 +:152943004CF0FC83BFCDFD6E02F98F72CE75C37E6AF37A1078EE +:15295800DD9A1CB1265E933E80B3DFB83724FB4D7F2FFA8D63CC +:15296D008FF0A200AF468E1997CD51219B788ED6D576B71186B2 +:15298200FA9B6DF9936321F89885D1F07B416B1464E2E3D78499 +:152997004CCC2FAD37FC23AEA02D1B78CC3B2AE2B952364EE849 +:1529AC00E8DF2D262756A15CF81A135C1E2C73B1EE1E386228C5 +:1529C100A073174B3910FB02B9E37E12F8EC575F0199EFA15EF8 +:1529D600900B5F4F9D91BA28F96DCF07C737181B2FC4EF6538A7 +:1529EB00DFA13DE7793E1E984F9837649F7FB9CE211BDD201B4B +:152A0000D13342365C781796940DCC8343DEF01C07CCEB782D44 +:152A15003B7E086F76B8CBD0FFFD2FEB41C759D5C936AB2AD9BA +:152A2A0062819EB3400FB202F909FC5E665CEF946A553CC61AE4 +:152A3F002BB00F06FA9BCEF00E1891728C1B8DB5A3DFE6F28C47 +:152A540018B89FA6CB73D6E8833FC0F79712FCAC18DFFF8275A5 +:152A69003B9E0FFB79C54958ABC6F95E981AEBB3300F7275EC6C +:152A7E0014F7FFCC581C65729EAAF559ABB553168367191B3372 +:152A93004E6BA29E2C8AD38FAFE21FBAC984E723A5B9F8B1A2B3 +:152AA800CF5D3F73FD4F7B4F1B1DC575DD9BD5AC342B0D627676 +:152ABD00D95D495848232C12C9519C5DB1C8922CC242A88FEC13 +:152AD20010654B9D744612F63AB603B19D84B634C7E784C42B00 +:152AE7005889058FF03015F65A266695480E6E209539909014D9 +:152AFC0092A5761C9152B2E1381C9AA4F638716C9AB8B6EC6293 +:152B110087A436DB7BEFCCAC56027F25ED39FDD13367CECCFB72 +:152B2600BEEFDEF7EEBBEFBDFBEEBB95BB86F37317D82FD98F5D +:152B3B00D9F7D9636C823DC40CB69D6D619BD917D84676275BBC +:152B5000CF6E6537B33EA6B04FB0B5ECE3EC63ECA3AC9B5DC784 +:152B650056B3556C255BC196C38CB29375B076D6C696B1085B45 +:152B7A00CA5A599885D887D8D5EC83AC059E0FB0AB58333C4D64 +:152B8F00ECFDF0BC8F2D81A7119E2BE1590C4F033C323CF5F4B3 +:152BA400D4C1B3889E5A7AAEA067A1FDD4D0536D3F558527687B +:152BB9003F81C2E32F7A16143DBE598F77CE235DF2CCBFE4A91D +:152BCE00BCEC33EF2D1FF16D9F8A777CCADFF5E379C747C0C3D7 +:152BE300535AF6BB963D6099CEB280EC52D7DE1F63F241F46BAC +:152BF800043FDDFE6F82FF9CFDDF02FF1207FFC863EA9A207EDC +:152C0D0054D359B7968349B2C4299A242F3E28C5E1CDC06B2E5B +:152C22003E487602C97E6C13D9BE9365DBCF63FB71E017B7FD26 +:152C3700CA6D3F17F8656CBF0ADBAF04FC303F2893CE264A2C4B +:152C4C0016B2F342BDE2909D07EA1187ECB4A8371C8234310E91 +:152C6100F768656DE3B751D0BA4A83D9F6A81BE41AF48BD1B952 +:152C7600FFB0EECB70ADC25433F081865161AA83EC1B26DE2674 +:152C8B006CF26DC2C81E0B84554218F81BE8CF9FE850A9EC5CF1 +:152CA000B3E1E0CEC139D62367C3983B4234D1659A8787749C89 +:152CB500F731AC27A509F5237E118792CB8A3F99B5C3813776CE +:152CCA00C98B0DDDC9E7B8E51F837831E49BD262831740067A12 +:152CDF008B6F8C9B89932BFA975C33FFBAED4FF8CFE6E7A36DBF +:152CF40009EB3CB7AC4D93FD5BD9D2E720DD4999743D4AED7F28 +:152D09003A37EB82B686F66043EDC03B5D2CE96A37CA609ECA75 +:152D1E00473BD4E9860E5A9F9BFEBE7B19E204DDB8469A857495 +:152D3300226B471D6CA30570018C5613E456A38C5D05B05F65E1 +:152D4800B883D1FEDC65FC24CEF263F2AB06F2DAA6B96B14217A +:152D5D0059273F6CDFF0BD49E65A79A099941868E571BE2C35E6 +:152D7200A03D4A18CFC35064BBDE42EB5061834908974CB0C425 +:152D87005CD55046B38EE5F353D5AA94688EE0574834B7E23778 +:152D9C008675CD8548A6C6B8D48ED15E6528A425A84FB46B511B +:152DB100D26D8AA27F3C3FBF1BE2C4C88E24CAD0D659D8B8163F +:152DC600A573001BAC33B1A18D961E14BBDBBE272065EB48E02C +:152DDB003AEF7C002A09F397A4AEB3A482FB3DE87E7505BF8CF3 +:152DF000E5B6E8A2CCB7B2D856FD3CD62B27EB96DD5C4B6FAAC7 +:152E0500C52C69A53C213F5A57C2FFD8889EAA49281CD9F31C8E +:152E1A00310A7A20B11FA4B17EB5F2FD3A2F9F30989E84791408 +:152E2F00BFEC9B377F13F27F328DFEE8D7027EA373FCAAC16F26 +:152E4400688EDFA6150097F47CFA7337BF1006815913E5A7F5FB +:152E5900BBD99456BBF205B5B7FE99F043EDE7ECB316093A3FF3 +:152E6E00BC287106EF0EA075B3452B4FA97C665C77C1B828CBA6 +:152E8300DF4A33FDBC21A44668AE836B6D4276775B10E7515087 +:152E98000ED3BF615CC1BDA0221ECAD933E1C99B5F6A031880EB +:152EAD00A64F035CA7744EDBA93EB4EE79ED8AA806ED68A70154 +:152EC200384B5C5CB13A2C6C87F2625B27D9BE52B42D3E2908A7 +:152ED70068EB74DBA8D0FD02F83F306AB9BF6EBBBF3D3A95CFC1 +:152EEC00073217E75CF311FB693AE99AD2116F77B3AC96F85E05 +:152F010069EB97BF5CDA8AFA10A3B9879485A71F504A4E3DA5BB +:152F16005EC7CE8417668FA964672DA4DB76067354D780F4F77E +:152F2B00EAF95B9E3616724F42F81943481C68C3392CE63D7D7E +:152F4000CB295DC894B61EBAA77419CA26C447A4B18349570694 +:152F5500E87C58C7BAFC61EF6024781CF2967EAD617D24843B52 +:152F6A00F6F8A4807B23D2B68312C1FFC383CF431F2C978753B1 +:152F7F0068DBBA4C1E4CEC4A680AD7A3411FFDA98E3657E38FD5 +:152F940031769F80FB095A6ABAE13503E2EE78496E591683F8DE +:152FA9009BE3AB5B518EA1BE251DD0F9CC578047BA5BE3D9FD8E +:152FBE00AD4C3FAC4F63DB8370EC3F6BC19FCF1C80F63348B612 +:152FD300299A6CDB31D4D7F461B20BDF44FD0C64DBCC30F4B3E3 +:152FE80084C6036D25A645F02B30AD15BFB85F266476431E596D +:152FFD00B2C55A9D49EA9C00380A65C9862AB643EC1FFBA6308D +:153012006CDC88A1CC9D491A572534F2CF803FBA512E9C6ED029 +:153027007431CEB77A4176C47E32DD306E2C0C66FA8F5E742F22 +:15303C00035C1A536FE40509E0E98232CE60BF0AA5B52CF0E088 +:153051002EC89765F6184F15CEF7A47411301002E09E1FD42243 +:153066004C3F9EA67929F0B3EDD153CAE9DB4B5BD36C504927FD +:15307B00762B171BF965E9E8B052951C51776DD5945D1D6749C3 +:15309000B694CCFBD39D4BEAAEA13DA3506212D762BD8B92B8B7 +:1530A50027A8D766A84ED69AB680F67513B466DDCEA32CFDBCA3 +:1530BA00CE75A38EE113C6AEACA6E07AA190D903E9B6219E69A5 +:1530CF006FAFDABCDFA8351F369A0037B550D75C298805108ECA +:1530E400FDB349DE46B63C280F49439B4E42B57C9F4E36F7D6B9 +:1530F900691AA4D39137F0F1437AC4FC1EC4DD66A00D4E616AB7 +:15310E008F8A79BA4E4E908E5AEC71C66A70BF3F74846C05F0F8 +:153123003D432AD469D4D5B3534D95B1D9FD23876BFB29ED8BE7 +:15313800FFC6FFF0618EE8427B1E7EF311D203A45B7670CD1FF4 +:15314D00FD5892F4B5B0CED6FE478AF63F8CEC88526D0EA543D0 +:15316200E6231969A5A60AD76B6AC91A4DE565CD1005DCD3DEE3 +:15317700A3354577B7E1B9B1C000B41F98B75627D07DD808DA47 +:15318C006E3CD36EF1FDDD86DF145BD18FEC8D16F643D2B4E610 +:1531A100EF42DCE446F446A28375C69963FB34D4CBB6CE365B69 +:1531B6007720FC02F2E2D6A0CE5E86E8C7A50EA8C14583C60317 +:1531CB0051EB5C2CAE9DBB7A2CDBCB3716D921E03EAA912D62AA +:1531E0000969AB7FED20D93284FAE33A346F022FCB9D277C7B31 +:1531F5004DBE57A4B9439AF6195CA46B6ADDB101F35C03ED4235 +:15320A0021BC9CF945ADC95C102EE6F1C8DB918EC4DF0BBC1DC8 +:15321F00F8FC86D25EBFF9BA4176DBFE11DBE190B1E5CD7CA012 +:15323400E54DECBB162D10D77E73A7EED246546FA7B5D7EF02FD +:153249001E81F7CB886C64A9086D65211B09231DB5A236AA591F +:15325E00F4D2D3A4F375AE9FDA18D00FDD3CB3F45F5336DD9182 +:15327300CE9806DD48D7B934251AD8F478271CBF5B5AFD4FD299 +:15328800A29C6891B6F7796668F28EB4281A6B1D3AE8DF477B45 +:15329D005995A1629AF8E2EF0F93DDEDD8C0E4857BDEDF26C538 +:1532B200CB605C1DD0D1B636F2AECD5F2C6D9DFA2F871F59FCB0 +:1532C700A31A68E65BA4191CF04DA421D6D5DAF3B1CAC0F230DC +:1532DC00EFC2B9A882BC64D1A5A688269B099E94657705C27175 +:1532F1005F5132771A9C9CA4F6846EA5C8BE40A4287DE4930561 +:153306007D5FD2134EB309D2DB6C42DA0F4C28A2EC26DE1C225F +:15331B003D404DAF895ABCA8D00FA1CEDC061C8FE17BFD29C2BE +:1533300001F45B7FEA0F567DCD39D76CA18DFBEA60AABF06645E +:153345000199650E8658F660949907AB7F9BF7C07712DC93E0AA +:15335A003FD96DA77FABF8CAB9D9F1ABEDF838AEEF7FBDA84C2E +:15336F00D4C780F947715AB2CF45771668FAC57BF8655DB87E3E +:153384002E1F4DDC37754C2985E9062F8FA4D04E49B9FC448ADD +:15339900EC86D37E5096CE544AF22198B72475D15CD27AE3FDB6 +:1533AE00790FE2417B30EF999B67316CA4770869BBE407F5F373 +:1533C300CF6A2023E96403C56A877F6750DBB56CAD4CEF0279DE +:1533D800B115E4A2F7D236A79F1DD193AE94CEF6F1BDD3CF6A0E +:1533ED0046D29536BAE45DC6EB17B17F24ECB9C980F11CCA42CA +:15340200407FDC5F95A18C629C5C787A363E717FD796672D5DEB +:15341700687D8F8EB23307FD0BEB086E63F5DF82BC188A914D54 +:15342C0074279FEC8F67F2697C2D2FD4E2D9A16035C8F103FAC1 +:153441004928F36E16D798194AE3BA986836E9A5C7C3EAB7121E +:15345600CDE1C1F6F659B26519C375E276EAF765DCADC067AE49 +:15346B00D765339666D22B862034A8B8D66CC9958BDBCA61EE8B +:15348000E2AA53A80CB4878769DC0361B5321A8E944399FBEB54 +:15349500AF6DAB3565181B9BF46A33A47362A73AF895B0E6CE17 +:1534AA00C23C31D76E387788A0EE07B374D041DE6C0CF3B8563E +:1534BF001DFBD424D36F191552B87FF857F43557B896CDACFF5A +:1534D40057DB7A174D363F0B013F6B5750AEF7C95C88E62A504F +:1534E9000FDEB11D937B64B226BB47ADB1EF6FF0C3388DE3317F +:1534FE00CB7DC7F072CFA9AD0D95D7B0BAA97EC6CE6912FB759A +:153513009B9F7B59DD29BB5B51560C01AFACE526D440F048BF54 +:1535280010FDF5D25AF8BA4EED26BBF4C827AB56A26EC011FBD2 +:15353D00BEA1843605E3BE2F7158F5D682DC52B0CFFCCE6F157A +:15355200C8E6F84DAF288BF8E2653067F98ECECC470E8E83CCE6 +:15356700556BDEAF23EFC276817BD85E18AF9FAA19591A05598C +:15357C0007C7A14FB875926FFEE9412DECC8346FBC997F4B99EA +:1535910026FDFBFC5BCA34ED6F25D3C45ED04CE77C39F21CC0B6 +:1535A60095D0707B5B39E93423DE8EB5F98FFF07E47F4C5B0B28 +:1535BB00B87BA05D776C76109E828943053C05CD2561E11CEEF2 +:1535D000296D99E44F1C437E1D5C68CE0B835BF79901FA969B53 +:1535E5008BE8AB035FBF5CFD619C8DB8BA5F564F5EC80B880779 +:1535FA00AC6B8B5D7766D7BDF63275C734E90BEFBDFE8B80EE1D +:15360F00D5C85763BBD2B1D7E7CC6FA08E747744113D5B8AE3A5 +:15362400C476EB37B0B47623C8F0CF3F35B254968F4F0297D654 +:153639007C1C8CB7D219C36FB74B1EF505A49F1B77B3B39A97FE +:15364E007B91EE4FB862E5CB6A28FBBDC8151D163EAF602F502E +:15366300DBC3FE7A05CE67426709A7D8E6703D17D784EB4C771E +:15367800AB13A7EAF8D305BC57415A491E48272A92BD18F72EE4 +:15368D005CB28D1D4AA32E4AC9D4310C1B759D3CA6EA799847E0 +:1536A2004178937C7B1B7E119EF32BCA966DBAF91990177FAEFD +:1536B7000BF263A32DF2BF1AD5E7ED3AC6862645D437CBACD512 +:1536CC00AC7F9C4B0D4D9E5B61A53F0278F3DB795D58B1BEED6D +:1536E1006AF6F5569A0B15C5C5B49847713AB4F7BEE5DE334AFE +:1536F60048FECBA5E88FE32588D21FC7FF0771CC8C0D65503E7B +:15370B00C5B4E5A8630FB8C4F361B5BBBE4A785D28838C60E796 +:153720005F39EBBF2AECB2FED3E5F2FC307C7557A525B763FE8C +:15373500AE8777A83437FA21F00A90BB8CE8238A144DAAD5302F +:15374A0096D079BD7761A31F5F1863525C6AAD8AFB984CDA4A08 +:15375F00E3901480F1C41E87684CC2B0F7301E3963913D2E5D94 +:15377400763CC2B108C7A408D9F4288C291A3B618D29563932C9 +:15378900AB965F3116A06C01E394206F37BA5FCD0BE5192D5589 +:15379E000E7047A2C956677E580DE31AC6697AD5A1F7A05EDB5A +:1537B3006ACD2B733FA0701DC343801F4CCF32CFE97417484EF5 +:1537C8008379654A2BCD24133E2847CA1C4A639F2B318F699847 +:1537DD0027B6356C734DF2B3A3D8A6CEBEE1C86B36CC00EBA1A5 +:1537F2005D5F813E3CA0D37959B439FA5D6B5CDDF3CA4CFFF2E4 +:1538070006ADF32F82BD5F3659C53C208B7AF62DB0DC719E794D +:15381C0036BB98670A5E4BCE6EB27993A523E2C6BB03FCCE58AA +:1538310098D136039EFCC73BD45520CFBA07C6D491DC98522753 +:15384600BB3B17CA1FFC30AE9D511AA9592D9C178D3540BBE016 +:15385B0086F87883EE96701D8E1B7A716F73849D1FD0CC1378F1 +:15387000B9D15C797276F9AB12CD4BFFA4722ED1BF09F53756D0 +:15388500B10A495AACA2BE2DEE75476A58855BFA06E9475E9528 +:15389A0079B30B75A7825F0AA3AC4B3A51645F00CFE5423CA71A +:1538AF003CF4EF02F78CCD6E9AEB94E3BEF81341B47DD3D4FF48 +:1538C4004610F36D253D9F5C35AB10E363C05797A8EF93B98E87 +:1538D90052482FC61B8C0BE0CF7F6940B7F412F921679DC02DFA +:1538EE006D517F0161685F6F04E340BD704F4F46DD29F0E3E3FC +:1539030063C651F487FF17618E7ED64E877B5BCF813F7EC78161 +:15391800C6783EF0A8CB3A53398234F74FA31D4656B60FEDE209 +:15392D00BDAC49A71F5450AFB51AE737D2214D100FA83D40DB6E +:153942000532DF5B66EE21BB48B5C00B8326C61FDEC26D1FA1AC +:15395700FBE170AE7355A66BA9245A672FD0F6C97CCA736254CD +:15396C0080388215C75F9DE19772FB2E4DCB6265A4EFAA03DE24 +:153981002201EB4C23EAB7A0DD41DCCF37C18F49C9C2FE1A2F08 +:153996009F37EE02BAF1801711FA66BCCABEA3720E7D437141CA +:1539AB008B9B3F3CC83F3DA0BEE177F2AD2DE49BB2F38DDBB65E +:1539C000677700AF385A86B695E47E964B18B4FE2E4534AEAEF2 +:1539D500BD9F379B0CC1443FA095D94EE5579BD306CA4392991B +:1539EA00813CE3FDB82EB9A3668342BCAA6E637FAD8967CCCFD0 +:1539FF00F6F3F2678DA341AB7D34429A263337DA02E923905F61 +:153A1400D702E609417A0BB63F4B236C68A77415CAA076FB725B +:153A2900D545FBA3E6EF8C1D3531254A792AFD317043FC83ABCF +:153A3E00E11B87BC4B614E70A3B9D7889A0FA4BB4D7D34065FA4 +:153A5300DCD38BC17F16C215282BE7B36DF1B20CE1009015D890 +:153A6800519351FACD8C711BE41B07D8FCD85E01572DF015E0BB +:153A7D008B362E6508AF85FFD590871FBE8D3077DB00FFE716D1 +:153A920060DB065C815F37F8F1C06F9E02BF50D0A2477C8E4D94 +:153AA7005FF7D30915DA5D854FE6979714D18B4378E47103D74A +:153ABC00A042F2B826E0FFE5F4E5E83C48448BB958C5D5995BCC +:153AD10022D86F4A3B642D4B3A81CD7A359E6991068C52DA2366 +:153AE600E6869C3C3250667D7A8CCE0570350975C67E4B14E2A1 +:153AFB00453406F90D215EFC4D05DEA69CC231AD5945BBE28BDE +:153B1000E5DEA56CD32B8353CF32E6E4C3360D68999FD8FB05AF +:153B25009BC63413FE51074328C0D3A12FC47105C39EB5F48CEF +:153B3A005B1CFE047ED99FA0AEDEB2E502C00A3207C1EDD09B26 +:153B4F00492097DBE9826CF972B6A983F277F46D310DE45551D0 +:153B6400C9BA280CF32A0B5E8A2FECDF7E6E461F5EC2BB96FCCD +:153B7900FB0A75ECFA31D6F1807A030C0DD29726F4F88F11604E +:153B8E00B44D64ADF7EBE0CEC03B096F16DE1CBC26BCD3787B99 +:153BA300758E0CAD3119DE50CE8ACB360D5A75B574E6C9CD7E81 +:153BB80039DB2DCF7147E7B8E373DC8939EECC1C77768EDB9CD5 +:153BCD00E366BF9A53FEAF8A74FA013FDDDC6CFB0393483BFFD1 +:153BE20064C16E531CEA161838AC56D2D9503B1F9873E3DCFA61 +:153BF70086F8BA48E0D8849ECE219D66F03605EEB3F09E83F799 +:153C0C0002BC02D0A71ADE2678DBE1ED86578177C34FACB8ECF6 +:153C2100D004E12DE3D01FDC8837BDC88D784B14B9116F1B8B77 +:153C3600DC88B778911BF1162B7223DEA2456EC45BA8C88D78AC +:153C4B00938BCBFFD58C5D442A1FDC818E8C816D1BF54BF97BFD +:153C6000D65DEB9C6B279C5DCE3E03E0576445F89D1BE74F0C29 +:153C750047DE7314E417908DF427E6310FEA1AC29CBA33CD31E8 +:153C8A008F00FFC0673A451823CBE545D73C05E3622DFC231DFB +:153C9F0079699B7A971778D67C5671076BEC8CCEB778DA4DF0DC +:153CB4001F996FF1B23AD6B8DCD11B91D1CE2F8CF93AE48138E6 +:153CC9009BAE84F11BD29FAB44D9E1D1193B0A20EF9DA91F80D0 +:153CDE0071793FCA08FAF40AF7F227208EECBDFCF8E48C73B8E8 +:153CF3009789E311A0D1531C4F8472B7DA67BC41DE597E16F2D1 +:153D0800F290FC3E9B8FD502BC9B251C0F51BED8AEEF88E3B99A +:153D1D009E47F52DD1FD547FCF87DCBD92DCAC23CF6F03B4794F +:153D320057EEC6B5306DE33C5CCF1FD399FEA81E80B97B271B90 +:153D4700A4F8839E0985AB6987B175CCC07B8078905BC9B66F83 +:153D5C006C587B6A3E8E637ABFE44D511E47459021218D203F57 +:153D7100AAF330167B2A715D6ECC401B0688E746C9923F10D617 +:153D86009C385BBEDB378F553C01F965E6E138D3A827696C6ACA +:153D9B00A2B109CF137235213A9F7EF662DE539E18E874C79ABA +:153DB00054596ED05F5CC12DBF0BD24CCDB76422070F3E5B5772 +:153DC5006B66FD43D6A7A7914F6D25BB6B98BF74FA030A9ED3D9 +:153DDA0040987DD1B1A53CC82A3CE4390D79F6824C85E7407863 +:153DEF00D265A57138407607A62D9BA17C7CC21065EBFED03C4A +:153E0400E9413FAA0580E7F3F26306C6AF043E4AF7A59780FC2C +:153E19008C770C16DDDF721EF2F8511CDA5E1C6D16587691BFD7 +:153E2E00CBC63A4570E33883B88C9633CFEBD0665F65039D0EF2 +:153E4300EC164EF6116FC23CE8CC045BD2E9C07D1EE046FD401A +:153E5800A04305DAF9C0B6C1A3DED985BCC7B1FB5D5CA7605144 +:153E6D009D9CF106EB45FBBCC0EF102E777618E039AA511DA462 +:153E8200319C7340BDB7CFD89D8D0F68231EE6B9016075D27CEB +:153E9700383AD8897BD4FF7CE0E7FB45B9C50890AEA70A7D760A +:153EAC00B5E1C0CECBFB691E86FF38C64B368ED6D8703A7A6FBD +:153EC100362E03B8BFD60261BE38BFDC5F32D337244FA36ADD4C +:153ED600E39AA6F28CE3E3CB5924827BD6796BEF219FFFF2F1E0 +:153EEB0008F82575BC5BC09BBB57F59EBE56918EAF54EB645735 +:153F000017E9B4E6B6A30E89C7533C6EDA70B6B225342E4F0ACC +:153F1500CCF334D4F167D0F6D8A6AF525E185F405E1F19A77B66 +:153F2A000BE8FC47570B9D7B00395CFF6662AC13CF44207E1FE7 +:153F3F00887374AF9C8D779FCF747756A1BC6E1ED3CFDFFC9DFD +:153F5400E53F0337D69937272EDFDE0047567BB3DA8F681ED6B2 +:153F6900779BEEDE60D7049587FDCCA2A74C3875F835DFB5043E +:153F7E00F729315CAFCB8E459CFAC6B8D9ED12F5122EC6B94E46 +:153F930084DBC1DB4BD971E201621C78825DCECF208F775BA70C +:153FA8003AD3BD3C543EBB2D76BF9EF7AC063A8AF1A2BAC88FA0 +:153FBD00E9A87F56A80BCC61ACFA3715EA8270F05D1FA4BA1001 +:153FD2009EE2636F8927B7D4A8DAEB1E79ACAF707C17E9FAE127 +:153FE700DC688FCBE6138003E0E99E82CDF1DC8076F2BF1C7DE8 +:153FFC00CB16AA13EACF3A696F837448EF34A429E63377BF6960 +:15401100B55751DEAFCBF171ED73D18930968D6D51DA7CD43A54 +:1540260057969B80F9C2A041F6E1A72D5EEEF415DE3C60489E81 +:15403B0009D50B3CF77E985B8926F215CDAEFF9199FA43BBA8E9 +:15405000EA3A46F5AF02BAD9F42D8C21E5C8EFA83F68AA6507E9 +:15406500DCEA0F17D1164AE4D0ACFEF09BEC21B28F82386BBD10 +:15407A00C53AEF8DE53CCC863BA12D5BFDA46BD06AC700EB5097 +:15408F0002CF30EBFDBBC9B6F9B139F4D62D7AD71F5D6E805B09 +:1540A4008C8F17D1F5908E6966E83A6ED72B45F5429EE3ED1A8C +:1540B900A63A2DCCF0CBB1ED3BB42CB45FF0E333686B3FA90FC2 +:1540CE0041FFB3ECEC5BF5F802B44FA72DFAD8D1CE4A281F618E +:1540E300B900B02C84B677A86C76DB3BF99FD0EEE422F8E200AC +:1540F8005FBC083ED981CFE24B84CFAE4182AF982F4C4F5B7B51 +:15410D00C8F8E5E3D69DB37A34B9B1B268CC49FCDE694B85B9DC +:15412200AB8F454608B768CB223D9DAF28B43D906D7E81BADD7A +:154137005FE5AF95E2D6FCDB17DDAF3E0969020D7CAFF7745A0A +:15414C007171CCBB00C3728774E97446E1610E7E10609570CC13 +:1541610081F683EB92828072A7A6058347FA65909112F78EF437 +:154176006E41FFD4EF90876F114E1EA37DF073F5C3CB58EEA8CC +:15418B006E84B85ECCA72E398C36C1FC5578BF10F827613ECE96 +:1541A000A4618387FC708F93DC502E4F7B2AC306A5C3B2F461E7 +:1541B500D4175D5097E13B07AC345B1230A7C77511618DA6D2CC +:1541CA00FDBCA87364CFE91156CC7F6BB7A694F49C5713F9BC33 +:1541DF006FE4239A8275E6214D5DF2C03A841FC74E840561C3C2 +:1541F4003D8476802170FA88521587BA9EF88AEA631AF0F08C51 +:15420900F22D1C17EC3CD1FE3CC8C03E4CE7D47D08F24FED3C5F +:15421E004CF7FE627BA1B8B1435B84EDBF534D840DEA8475C1C0 +:154233007B41912E8807A61FD3109F6DA83600E10E2ECE16F0E9 +:15424800609555C003AEBFE62C3C04BFCF77A67A70AF79421B7B +:15425D0000FF11EC2F8013F4C3B50D1C832D788F010E0E289865 +:154272007F49CF6BEA66C2C301C50BF5431C48782E05F74EF013 +:15428700CE0D280B6DDA86A0FCBAE0B97EC75EAD65DF04E6FFDB +:15429C00AF30B6A326A5BCCACE698B42ECD38D32FF61C79E62DB +:1542B100EE9364AF96ECCE74D31AC19251EB6C608AD245CD6D7D +:1542C6001AB46D0F7C711FCDC8BD36D3CEF13C18AE55611B6D33 +:1542DB00C1B934EA1E86DA35F61AE9B58DC2989B4D34B97B3965 +:1542F00021A2F289B0BA0760AD5726F19E385D977777D1FC14F6 +:15430500E248C03B44F9639D82FCD94E49FEC4723E26E3789DC3 +:15431A007D0EE461FCF6E35C2AF628D9BC0D74C886953FCA8CB7 +:15432F0063D91084B540FA2648DF08E9D1AF56FE44A79307B46F +:15434400A74E11C205087F6EC567293F91E666AF6C71E26CC493 +:154359007200267FC7B495B76EC18D388A60DF00385BE467BB1B +:15436E00F88E901183705C2FE882F934970AAB5202F7D2ACF8F1 +:15438300981FB481000FF9603CD2E77E0DCF015AF769601F6EDA +:1543980067F6FC1ADBBC346E97B3AF1F6D3254D3D97DCB0FE76F +:1543AD004CE8876D2260E9B05F325FE2388B9E057FC8BFD6990B +:1543C200FF901E1F944F7704650CF3B54BE75CD6D9C17D3A8668 +:1543D70021FF015E6B95057102B9AFA9FED35F53505EF5771D0F +:1543EC00B2EEE580303FCEFDD9611CDFB58FBF50C26AB387DBB4 +:1544010036C2B827DAF30C4B67D09273D066BC9038B0B40A64E3 +:154416004F3FE61BDA67C151E0932982CF1F4D46C83E04B8311D +:15442B00CFEAE8785B6D519E85B90BF05C4A6FF3CFDFD8ED19DF +:15444000EB81733B80CDF71CADE934CEA4293E8F48F76DDFA789 +:15445500FDF632E9F6CF4907ED5DBFDC7A52D4DCABFDFB65D2F4 +:15446A00DFF52ED2BF7C997491778477AF76EE32E9DE60EF5C67 +:15447F00DEF49B73F6D3707DA7B8FD01ADA65F9BBDBE31373CC9 +:15449400F1FADB874FBF53F8FF76FE73C2C5E2F6FF76EB03FFC6 +:1544A9001FFE47854B45F8F7CDE54BFF67E0B7DB47ECBDA5C765 +:1544BE00FEB580974916FB24D9B869EA1F94E2B7AD82AE287AF2 +:1544D3006F573508C7BB56C5EBB6AB74D607656EEF0675DEEA92 +:1544E800EDAA2CDFA9CDBB6E40F5F7688AC835A8FECA063509AF +:1544FD00728BDDA7D75D80B159F236A998DF1F9BD7DEEB35652F +:154512001275FF7A70EE12D7502389974B7A3F073C392036A83C +:15452700E53D2DEAC3D7372BF53DCD4A50BC4D1D2CF98082F66E +:15453C002017F17167AEE2C7F83C77A54A6B0FAB078877200F1F +:15455100A9AF4C2AA8DFE584FB28BC59757B1324DFD5DF9450C1 +:15456600697FC9BE2F7C2E0CAB6C182A0086BD0043A0A87C2C1D +:15457B00B70E60C078942FE45F5CF6053BDFE9A27CF3F967F20B +:15459000229E150FB3DEB578473AE49D28896B888F3CB3F2BAA4 +:1545A5009AB10555801B11CAF4AC69061C35288BC416B5F6430B +:1545BA007CAF9B0DF4D57F9EEFDD3B3F4934C0759110C0817BDE +:1545CF00705791DD9019D81126929358E21EAA1BC074D286E933 +:1545E40028D65DBC51ADDFB956E52A1DD8F2171DD83A01B66A62 +:1545F900B181FC1320203AF4F254B6A822C1B45D595499547755 +:15460E006DDD51680B88E73FE4F3360C8CEA893695ACFDE3E983 +:154623007BB0DC9C0D075793C2BBA784F99A05837767A3EA852E +:15463800F2B06EBDB62E3F2ABD115ECA66F0520F6DA7624D974C +:15464D001AE889103CDB4AB62BE580970A31A996B264DF0EBB47 +:154662006D2EA6BACF947B0ECAD221CC0BF802BAFB1C1890F65F +:15467700F5DD372A280BD5F7DCA8CCA53F74226F39ED1BCCF4C2 +:15468C00A7FAA93D148F3BD5A2066E8AAB3CBB539D07711FE630 +:1546A10058D06DFF1BF05FD10370427BA9A88CA8DAE31DCADEFE +:1546B600131D4AC5A9356A4003BF9DAB55ED233740DBBF41C1A6 +:1546CB003610009CD6AFB170C1C7B95E996DA0B60D729ADFCD92 +:1546E000DDA28AF112BCF7C4EFC1BD9ABAEEFE79DCADAAC8AF72 +:1546F50052C59550DE7577A8E2EA1BD4E192554A04D70156CE75 +:15470A00C42F0B5AE766287E326CC57FF233AAF844873ABC35B0 +:15471F00ACB861DCF53E7E9B52FFA1925EB48D2C24C27D9E6CDC +:1547340047DFFD684F4A0BABF5A76E51B9931DAA067139618691 +:15474900169BB08F07E99CCD3AB4A5220C40BAE31D7D34D76B64 +:15475E0067BDA5DE505F99B7BDAF3EB556D906BC4106FF21F8F1 +:154773007E1A79CE4FD6ABE250878A72B52CDF8AB29D20263FAF +:15478800A3726BEE5429ECC90E080FABC38033A43FB6719C93FD +:15479D0094FF03D75B7F0A70A80DA881539F512B4E6EA736B0B1 +:1547B2000BDAC03CA07D7954EB2BE64B4877A41DE928DB34C57B +:1547C70036791DC0D28BF0039EF16EBF1EF84F96DCA5CC837208 +:1547DC0010FEC1ADD6FFAA8BF900F225C78D71616C58B7278FDB +:1547F1006B3856DB36606A85F843BE0773AE054EBBBA1BE290E4 +:154806003E39C070D71CFD4AEFE3B54AFDC96AC06DB57AB97630 +:15481B00F4129B6947BF64563B421A94433B0A8A77115E1EB6C7 +:15483000DB12B6A380067E73DAD2F6C49FAF2F0F6E00FAC4FB9D +:15484500B7B35BD7CF0BC6FA39F10ED57157446F5D8F749A376F +:15485A00B0B68F9DE8ED73BEF52FBBE87E9DF2C4DABE8A6C6F1C +:15486F001FE7019A5FD9A0B9810E1781F688BFAB8916AEDE0ABE +:154884006D0BD0E10EA0C30EE2E9C5B428B16991B4EEF5F17365 +:15489900C29550766CDD14D105DB4D6CDDD13974019AF86EB218 +:1548AE00E9027CD7B7B6882EEF2BA2CBABA43339D3B7B742BF10 +:1548C3001E29A213D987863680FE9B6D5A9D063A39B4D9F01E37 +:1548D800E971A6881E3FB2E9817D3A60D3E2123A006D8A695101 +:1548ED0016FDD4FAD2E8DAF5EC6ED62B663FD5374FDAD057C62A +:15490200FE7A7D79E26FFAC4ECADE4AEFF3CF5579FC8C01DBD70 +:1549170093F0CE6F6ED05CC07B2F96C5B47207EFD04F2BC4AD95 +:15492C00C0FFFE42AD5873EF2CBC975F0EEFA9C548F322BCC7E7 +:1549410009EF4E7D8BF10F3CDF779D8D7F5C13C17EE2E0DF5732 +:15495600847F17AD6D58F81DB1F15B897C0AC2F0DEF0E23EE01F +:15496B00A47F89C6058B66988EECD3DB74B0701E9905CB97015C +:15498000CF6286EB7D12BE49E03DA59007DE9FBCF763B7A9F5A9 +:154995003D5D8A54B254292BB956C1362C02EF61273AFAF6FE68 +:1549AA000B849D5AA3F84A3EA2784A3E6A8571ABFAD8F537F4B0 +:1549BF006D8BBB7A11AEC5F69DF2D046BCA5B28BC648F4477B35 +:1549D40018CE1C05CB47BB9125CED86D8F1F180F75A511AEE79C +:1549E900F3793FC429F4FD27A1EFE3D87506A693B85E82F2017F +:1549FE008C75FE27ECF8DF82FFFA9779FCFA8E505E2975976B5E +:154A1300FC36D4D3629C7597298C2C795F74FC768369A4F38504 +:104A2800FEFE99F5D6F2FF06E2E5D1A4A89C0000A7 +:00000001FF diff --git a/trunk/drivers/atm/sba200e_ecd.data b/trunk/drivers/atm/sba200e_ecd.data new file mode 100644 index 000000000000..d097e743b846 --- /dev/null +++ b/trunk/drivers/atm/sba200e_ecd.data @@ -0,0 +1,928 @@ +:150000001F8B0808AC5A10380203736261323030655F65636426 +:150015002E62696E327D00DC3A0D6C14D7996FD7B3F5AE71CCD4 +:15002A0078592F3F8DD70F0AA949E8DD022E07F61A1644AA40C3 +:15003F00012D88A433EE52268844E8924B571792229D1B0F8EB1 +:15005400013B7DD0C7608813E1640D5E58529C6C909D101DE4AC +:1500690016357749A4E4BA8A7227541DC9AA17295C4A2F76455E +:15007E00259438EC7DDF9B19EF7831C4A1524F772B8DDF9BF742 +:15009300BEF7FDBFEFFBDE1B3FFCD3BF7F88B808896E2484FED3 +:1500A8008890844A880EFD1CB4BBA00DB710128396439B8076CC +:1500BD0018DA4E68B51FC3036D16DA1DB8364E88026DE92FBA6D +:1500D2001EFE486452BF7C63D90D63AE825E0863FB54E1A984C2 +:1500E700782F999F6AB59F9E3C49B19D522690D8ED9FFB737D9F +:1500FC00FCD38F45DB66F353D2B6AD1433AEF2F2F209D77F491D +:15011100BE34E18787275C3FF52678EDF13693B20B7EE47FE17D +:15012600E71A20BB45FB4AA95D5E29DC72DD983C8589E52B4C68 +:15013B00927E7959B9A987A7DA6E4DCF24842D778E97CC7F63BA +:15015000F90B6D6DE8BEAEEBF97C299D49C95956A43F7A5BF4D5 +:150165005F7C512AA1FBB7D87EF4AFBF99905E79919E97FCDF83 +:15017A00FFB93C759E5BCDF3F48DEFDA29E89C2A8EA109DC0E0B +:15018F005FF8FFFE2B387E24ACB3FC6765A432BB6F911CF4C674 +:1501A400C1977CFA72F2308031121A8EE3BC3E026FE14E96FF67 +:1501B900025AF9AA21793BD46B5B3B1A708EC8A429FF1CF1557A +:1501CE003E4F7C81FDC4977802FA5DC447C2618EEBEA932EC057 +:1501E3004BB79000C012130F873C52EDEA50657DA14AB86BAFA6 +:1501F80014D4B75C5C467C1D4F126F20B8231E269759EF9EFE32 +:15020D009D846F61249CE1FA03844C0B6A716FD52F20EB9C6518 +:1502220035C1447C7AEB6916F59268404FA9249C341086C4F6C2 +:15023700182477ACC79FE300570FFC87E3FBC3A4657AEB6A1692 +:15024C0085F4D4BE7FB34AE4F5AC7D7DB3FA3C213546D2DD045F +:150261007C32C81F7230EF6A9E22B7A8B81EE7116EDFCCCB8A9D +:1502760067E549751FF5B490DC6C5641483010844C26EF66BEA1 +:15028B006067FCC3B9C4E721F3D53DC3EE1669F72655BAB04CF6 +:1502A00095B6AC654B008EF03EFD6EBA6531EA08F113F958A63E +:1502B500F8F4EB015853B966BE7AB950A8FEB04D8DB4FF933BA0 +:1502CA00021254BC2478DA75DB3C456FC2D306E429775C5F2546 +:1502DF0078A202FFB7626115F9D9AB95B5608BFC601B04DD5402 +:1502F4000575C0F90BA1C39DD5640A91FBF4DC8A2D0DE780D715 +:150309001DC0AB3D1FAB26E3C3487898BD07DA0F053964FC6180 +:15031E00B09F6E2C85F4EFDDC054B2B33F93978886ED30B49447 +:15033300768879E085CA723BCEF75CC37918AB1763BB718C8F81 +:15034800E218973A503F887F41CB78FCF545FC0256ACB3E8DA10 +:15035D0034052D8BEE84341DF8D924F1874DFC62BDC065D1B458 +:1503720069396575E2BF52823F5CC47F03AE9BF17F2BFD283F5C +:15038700BE7DFE1BC41863C362AC4325B1FE8C3D3EF66ED31296 +:15039C00F6BE39FF0257281DAF69ED17F8883C2F83386A5A1923 +:1503B1001BB5E418C30B73E3E48AF573539E9BF37F2BFCD76E07 +:1503C600827FCCEEB1FE1E1B7F838D9FA45929AE521C387FCD8B +:1503DB00E143B62C02A73CD433A10CE3F647A7B91FAAFA55D204 +:1503F00030CFB4AD06B685FE0DBED990327DD38903EC5BB9A572 +:15040500685F6F5587E09B3474B0AC44A2105B784D2CAD1ECE76 +:15041A00B85B80BE512D77A9570A85A0D33FD6FD99EB3BC4FAF6 +:15042F00CE09D78FAD053C57715DCCE12B18A2352F4BE4DF3E26 +:15044400A3E73F3562F9670D7FEEAC3AFD034D21B14BAC4EB966 +:15045900475D4C7FC5F6DC3B9020F2BF81EF26793FC4F5605035 +:15046E0089631EE0D00FC49222DEE3788D3E00FDB481E324B744 +:15048300A8470EEE8A93DC7B10B366C4F7CDDCA178E9E3ACFDEA +:15049800FD956A27C4B7F6F7D7837DE688787987152FBF0532CD +:1504AD00C87598AB92BC1BCF26E134E7D056692EE07F3ED0CF67 +:1504C20033CC96D2CAB56AA12CCB24D72A55EADDC8BAC949C5A3 +:1504D700A50DB0EEB2E30AC28C421A3D4C5E56C05E0CAB886E6F +:1504EC00F23A8C67712DF4FF45113C02DE68FE6D03E4309096C9 +:15050100DB45AABB203749D1BBD5BB80A7629CBF17F86C6701DD +:15051600E06D6788F8BC40FB933677C4BBE135950CFEDCC09CF9 +:15052B0087FC728B5FC455F5515EED2E3BA9A05ED65592181934 +:150540001C30B244C0E918E7BB519E705AC4FC2A42FC2496D294 +:1505550047B7F635873457A377C309F0B30106F089DD3F9C0F86 +:15056A00364FF16B85424D9DF26B359AFF9457B94EA8B1FCDB9D +:15057F009C84327177E57915E18379C83D202BD2385A0672CBE6 +:1505940003461053742C63CEC97F32C0F601EF8697D559078ED5 +:1505A900C3BE4D097EC0EE19B0BBD8136BE99A8829F3A21ECFAA +:1505BE00CAE3AAB013E634CB4601878D1EADB5725A02721ADA1A +:1505D30000748276C8A27FA15F800E9016D959D40FEAE5975DB2 +:1505E800DF079D844D9D583CD83A09002E874EAA854E56AC5F7D +:1505FD002CF0900C0BB60AF9C00FF764AC07F676126B984CB013 +:1506120055E82BFA3CD80FD619159837071F671F423DF547CC48 +:150627009D9ABBB94EF94FD5EDFED9920D9ABB2948DDCDE3ED05 +:15063C007B3FE4F1ACE201DD96CA8CF2A1DC1EB2006AA3679877 +:150651000CB2CABD9BD88E3B896FAFB6B1C9BBE105F0796ED6EE +:1506660014E1A5ACB002FD803221E3D52B26CFBC5F7F80DEBF28 +:15067B00988492F15AB2470D8C32C12FE9EF63DDD98560AF85B3 +:1506900006ECCF8CF5F4E05E053D0AD9486CD0C0F501D8C35394 +:1506A5001C72BD05754ABA6D6364519B29DBDD753F5B485DC4FE +:1506BA006BCAFA6BF53A79F216B2E641D6939396B5F5DBC477B6 +:1506CF004CC8FA30C8BAC39435047BBBE1F7A67CB1E3FA532095 +:1506E4005F6DF63BEAD4489390AD2C36430DE9A1E66F635D12CB +:1506F9003B20628096FFDC38EB2553A0E5B81F85AE5007644910 +:15070E00D12FE4BE8CF5801EFA8A7AC8BD6A209D523DF4801E4A +:1507230074D043D0D24325E80169074B68831F4E194FF38472E3 +:15073800C0972AEED189F7E6346B6F46C6E6D1C78027EC8760F4 +:15074D00EF3AF72BEE55C253FAB5151EC10BC417D8AF2761BF9D +:150762007ECADD9543AA6BE659D5D53524F6EC11C79EED297B45 +:15077700C5DEB37E9C3F52DCB335E8FFE8D7CE7D3B0BE05046FB +:15078C00BF4346AD9C4C71EEE7B1FC943BCDFDC1CBF1EA46B191 +:1507A1005788F48AD452BDAC53F4AB5DEB45BC8E06486C8EF056 +:1507B6005F6EE65EC88572F20A93D6ACC59C974940CE2B4C4D3A +:1507CB00B05EFDB8C2662694C06E880F77A4541FFA4FCCB0FC60 +:1507E00087C7671D931ABD55AB61BFC6581BD118FA4ADA05352E +:1507F50041586188A322F20CD3A03568598B1F7CEB04ACF36627 +:15080A008FA9011DF3FFEF0D51CBE01EF84BB6DB3E6764B09B53 +:15081F00E9E04BC89773FE51F0AD1524C1B6E9879693F065A3B1 +:150834001E6581396FB61DCE4A585F7C435A0F9AB4B278CE7380 +:15084900CCAD4A8E3621FE34B9357E5D33D7E74BD637265BC568 +:15085E00FAA513ACA7DA492677758B1C6DCF47110FCCDD958C37 +:1508730034A1FEEDB501FD984A61CE8BF0B1B9803B950925C1C8 +:15088800A6164C8305238BF5A9CC647C22F0A6D48CF11F7DAC82 +:15089D00167D35D76F94D64FEB1E76D43FA2AE642C8AB58F2916 +:1508B200DF196CCD7ACFEA53689DF58F63FD1C0D7D1060A1FEDC +:1508C700411CD21AA61EC43D0BF2E27E1A572BE3F1F93E2FEEED +:1508DC0053C31FCCC6F17C5BA75C51FF86BE06E7DDA19D24F6BF +:1508F10004C39C9E7B40D4893C8BF50E9C875D33CD9A270A7153 +:1509060003EB2B92DB8E7006C2C9C119702E7E5A9C8BA747FA68 +:15091B00C59938181D54B1CEC0F544AE15676212AA8F4F8F3447 +:150930008873309E89CB8066FBFEFBADF3F0BDEAF32EFB3CBC70 +:15094500D43C7BDE10C78B67CF89F2349E3DDFAA29397B62AE9C +:15095A00B6CFC3B992F33087986B3F373B0F7F4D8C7C4CDB1875 +:15096F00F11C3CA3BA601DC6BA3D10C776BF9B56BC55C7314647 +:150984008A5A40C43898C739A0853569CD9CA4A7C98449A13EBA +:15099900A222060A9B891858EDADFA15F8C48098DB4EACF36D2F +:1509AE0091DF1EC423D60B9D9B7024F62763F7BB19657A24259F +:1509C3006C00670103C726F7FCB3217C16EC1BA8492A585360D5 +:1509D8002C47BF7906F9224BD94BA843FB5EE0366C531F98D827 +:1509ED003613DD0B94C796AA28EB3EBC178056DC0B403BFE5E71 +:150A020060693CEEBAF15EE0EB6CD6FE17B0D944FAE413D8D15A +:150A17005B750FD830CA2C7939CAEB6D9D6DE290470CBF43DE6A +:150A2C00042153049FAD7D967D070C8499DC73613C3F729F6190 +:150A4100E39D01786D5BDBF1E9CE478AF1C5E5EB107ADA94DD30 +:150A5600D3689F51E58D49A5A67590C5800FAC0FF04CAA79CD1A +:150A6B003C8DF05CE80DFC0A748363EE92B161475C9A41E7F61F +:150A800060CCB93802B97A659F1AD0D07F1A18C81E708580C77E +:150A950031BED23C564648A3E66944597640DFB5C63C7FE1F838 +:150AAA00E1DA2106B508F7C82F412CEF33EEA4A70D29B9C7210B +:150ABF0097CE104EFF119EB74C5C4B268B2B79AA880BE087AD61 +:150AD40073A08BE8784634F0DDA6F34DE4D11DF2F43878D02783 +:150AE900290FC2651E30E5D11DF27C2DAE1279AE96C873F536FA +:150AFE00E5C938E479C7C1436692F2205CFE7E539E8C439EAFE6 +:150B1300C55522CFB51279AEDDA63CC991A23C67478A3CE0F891 +:150B280064E44138D99207FB4B268BAB449ED11279461DF2440C +:150B3D00ADFB0C19F3B9E5E3750A53EFFB09D2357D04DF975A45 +:150B5200EF19EBBDDE7A47FAF83E43BC2799F065A0B1AB4CB4FF +:150B6700ECAAF59EB6DEAF59EF17ADF751EBFD1DC0B38B9EE038 +:150B7C00D8D760AE93BECCC5BD03F47BE86B5CD403D04FD337E7 +:150B91007994DEC5CC73C5592303EBE05C51334BF33407939EC7 +:150BA600667FDED3EC053B606D8F3236D05302CF7658BB9ABEDF +:150BBB002AF074437F337D83E3FAB74C3E38D2DC4E777313AFA4 +:150BD0006E0C025EBC6B5841DE6167B6BEBC5CDC59004C15F5B9 +:150BE50034E2D80B5B5F136359C7D8335BDF1463C8933DF6E484 +:150BFA00D6BDCB6DFC7751D37E886796E8A7F9768B3EF2B4B65E +:150C0F006E60998DD386455C36ACCD2BF216B26011EF5F514FEF +:150C2400B3B84BB1743AFC88A9D39CF8EE61CA3EC3CE1F304F8C +:150C3900C7CD9BF4EEB6700C9A638CFF9D09F3A1850369071099 +:150C4E0007CC651F2DCE452C3DC6617E1DE80F75C7A01FA7072F +:150C6300399E8FCE099E2E0B3E1FA5CFF15EA1DF1EE3F48870DB +:150C780040FF03D73D4D7B67526543E88D85CFE692CA0F962315 +:150C8D001F9D424715509B2E592E352D0AED5EC861EE6E319754 +:150CA20011FC56243D8DB3DE949A82A1830B0D98AB5A6EF28FE3 +:150CB700FAAA807D72FD2BA9E98BDAE7161E82B93F367B9A2BEB +:150CCC00B4F2C6CF2EFD2182387F57CB22B8FEB7BD831184FDD0 +:150CE100E0D269C8FB3B044DE03FA38B7686E019E4CCC444BBDF +:150CF6004BE026E1682629DA84E0036A8E0CEE89E9172EABAEBD +:150D0B00F735D87FAFB0CA60268EFA31D75D36368BD6D41109F9 +:150D20006B8602EDB495C755D7FA47A0F6D9CFEEC05C097A3363 +:150D3500E9268D0ED1EE303A45DB23F4590EE705D7FEC701FEB1 +:150D4A007BAC2A1806782A6219C20F8A36619C15ED52A1F32969 +:150D5F001700FEFD7F10B5D5D4600CE0A386C977D2E887F6692B +:150D740061875D467AA498DB4808EAADB0226CB30D6C93A007C3 +:150D8900B81CCCC1D845B6B4CCBA2B17ED45A301DA9DDF273E14 +:150D9E001E76B7C0318F1D182DF8D1971E85F14A7A02EA055D0D +:150DB300E8AF0CCE160BBE8370E6BEC25CB9CD82457D5BFB8D79 +:150DC80061FF29A029FBDE533B9625AD6F6D507FC1B896FF8DAF +:150DDD0011681D62E8C0DBF3AF1BF0CE75E02D104DA9B20FCFF3 +:150DF20039EF1B121D323E69B0F8A1B3D9F52F4D1A4761BD6C70 +:150E0700F1C32D7E8ECE29F283B9EE030B36EBE0277B0B7E623A +:150E1C000E7E36033FF0CEF904FC6C76F0F39845E33DDC47160B +:150E31003F598B9F4A073F98AB5659B0E86F363FD8BF193F51AC +:150E4600073FAB811F78E7C909F8796B71919F8FBE30699C1BBB +:150E5B00C19C66F28334909FD6D9457E30D79C3161052D37C413 +:150E7000D68EE694310A676A3BC63A3F0F6874906BF434C4E84F +:150E8500CD4C0EDE173FBC2CCDF0FF560EE74E2AD65D9091B78B +:150E9A0062CA7F8CE0652EF17B1D79334EFB7959D57995E60779 +:150EAF0058714DDAB868C5631B5601B86ED8DB7E888DCEF53124 +:150EC400DACD37037D05F850E85178AEF0049DCB77D105E03353 +:150ED9000DBC9346C056AB799DB24D35C8A1447D3EC5BAF55427 +:150EEE00A207E093F41C4F53C60FF79E663564409DB6A597D514 +:150F03005EBAC23AB67C97EDA99DCFF66E59C8F6F52E639D97C5 +:150F180056B223B56718DED37CFCDB32DCD30CFFB7E7D9DEF32D +:150F2D00ACF2C231F5E0A5FD500FEC5FE2E4EB9D30F155D1D593 +:150F4200CD6363B176D6B090F8FCCE3121403B3B7A93F1CDD75E +:150F57000A378C2B5A3BC77889FA09D44FB08EB7B33B9B26184E +:150F6C00875AE06A1DF179434911ABC046F2DCE4318EF6C5F74D +:150F81004F46AC1A413EC789CCB844C51D2BBF8AFF6810E6FCBA +:150F96009A687BF8A8DBAC7586451B66A4007551554AEDD6878E +:150FAB00946EBD5F9926A5D4236543CA91E88072186CF9ACFEB4 +:150FC00086E27DEF0FAA8005E0837A9722AF632AFA4185833FB6 +:150FD500BC8390D890187F52AB6CFCC4FE770F2B6EFCFB0A33BF +:150FEA003F6A63B934C991E73990C72A925F35CC4A3E8179C4C6 +:150FFF00CA8567451D63E6AFB366AC039D99F98F5B303D026617 +:1510140047314F8AFDF09845277B039D3BC6D131F3E559510FD6 +:15102900D97432169D0F2D3A264C0F33E3709A87AF12D21B76BE +:15103E00B5941F48A981E83CBCDFF3FBB5EF468290ABAE5E372C +:15105300E5FD40FBEBC6CBD0F782FEEB14380779061290B39AFC +:151068005DA1745CA678DF1B66C92CC489A4AB65333D652C022E +:15107D001C92FC3DC8435D3C14DD1F3948BA13788676877AE21E +:15109200D23D50A3C5468CB974C4705BBA8ED02E234A0F1A8197 +:1510A7007C8A734F6AE702DA67605C895D0039F2FD5C069C38D8 +:1510BC000E276206072EAF93E6A617FA9A9DEBEB9443AA61E19E +:1510D100C0B5D8475C147049A1FA78B464BD1FD647E97306D4F3 +:1510E60010D6FAEE09D7E7FE1173537D1C7909C3DC02A833C232 +:1510FB00B48BE1DD96413A120AFD2FC3E3C238779A19E470422A +:15111000D23A0C3FE46037D6BBB17EC3AB751B95DA39718F365C +:15112500DE8FCF5A7EAC8FF3E331FFCDA614D9E1BF55502B8C04 +:15113A00F928F801DA0F7DB4FCC0805A43E6A9A66CF5A66CD11A +:15114F00BE66A73F0768170F6A529384E766C29917ECB1733E0C +:15116400F1E1FBBE999DCAC54DC4F7E2CCA422D3F9C236ABD16A +:151179000EB096AFEE7E085BCF52F13F2D15B383264E79893719 +:15118E002E43FF568F0947444B8336DF14F65D1D91AB16A81DE5 +:1511A300EEF90F79AC71EED71FB2E7F1FF6AE4E8DC07251B479E +:1511B800B4FB41BFDD5F591C17FB04E498438E36617E801A931D +:1511CD004E8BF5604D631CA2520BD51883B37A0061360998CB74 +:1511E200D6779F4EBCA3A0247692076973837DCF82DF034657E0 +:1511F700342F36BFD19B7797884F4E7633C487637EB95B7D077F +:15120C00713AE82F17B829C33B5949FE0CE87719B80EE95BEBFC +:1512210032B80EE89D71F62F3AF158BF83B9E39073F0FBEF1552 +:15123600568DF74FFC285B8BFB92DE1B09D2798DCC8A0F3FA1C4 +:15124B000F35EA629F778AEFE5BBA75C413ADC2F3F67DE75C28B +:1512600018E4AB1A1BBFA4CD6558B309D81F7EDE4272FD7C9ADA +:1512750003B6C2829520374F16EE10F0BA0AE2DD0B5A5D13D6FA +:15128A0008E677FE432A9C9E184473435AF339F8E46CD63B4C08 +:15129F00104FA67AF42893454EE83FF3BB42A11AEF06B789B5BD +:1512B40069B17681B69FD5C84FAB776AE759448333656C9E811D +:1512C900F489DC6F081EB09F4B19923C5745DC52FEA88DDBE4E5 +:1512DE0011F6DA589FA78C2CD058A44D6FACD2A6477EA04D6DF9 +:1512F30044BE376975CDB67C923C5B2D956F3273820F7BACC455 +:151308007E7C18BF7D9F03DB65E24B08A9C63AC6E53BA7BEE98E +:15131D00C2FBC734D64D747A10725E6CC8C0DA424A0E31D7BBE7 +:15133200E7D5FF065E7B5CC48BF6C77BF9465AD358456B227E15 +:151347007A47E366D0D32A5ADBB8CEB237E2A8965F1577D4E057 +:15135C000C34289F51CB80C60298AF86BE1BFA088773F6B90BB5 +:15137100E15DD638AE0F26E78571BD8CB2027D19F8284CA5ECCB +:1513860008E953189C8702AE3EF17DE059F17F5203D67D685A64 +:15139B009CD1719F797D57D4368823337C4755D7CC4EF57052CB +:1513B0006AA9B9705E9D23EE5933868EDF5E760E88EF34384755 +:1513C5008E0DB1CBE2FB0C65B3C8A9E508432C18F17DA56F880C +:1513DA00CDD2BE6A126B89398EDF4DF4248EFFBC89C883064DB6 +:1513EF00A6F03B8821AF1950A330EED79AC5B817DEA980AB6D72 +:1514040092F05E22F6BA7118FC026582FD5F8D7715B3A2A71B27 +:15141900C59D456ED038AC4942EF788FF70CC43C5BC6A0252368 +:15142E00CA11B1F27D7D01CF75FF43CC13064755A4D993BC91CC +:151443001988C3038611280C0F1CD6E045326894648038C168C9 +:151458002556E40688EE7B5CD089266EB450729055768B5B5FCA +:15146D003081041F5CF34C206BE1DE84CD94932B2203071A3D8B +:15148200ACCBDE79BB68A5AE721677C7D5B9DEECD69E4779615E +:151497008D6CDC65AB38E7BEAFBBDFCC9BC9A0E0DED5FD987AC3 +:1514AC006FBEEEF77D5F7FFDF5F77DDDFD7547F5F31B315A88AC +:1514C1001BB88ED10BB618607BCEF31C0253B2E941318E59B05A +:1514D600E751CCF18671A03F4CDCB28FC53814642D3F01387A39 +:1514EB00433155770FB3BC0699D9A328ABEF954FB03595493179 +:151500002F4698A20CB3BD8A291B2C2060E47206562A6057702E +:151515006D46C454576DDF30DD1B292025CAB0698761DCE8CF5F +:15152A00819102899467C3E8203CE5C8192A83AFA9C032D15E21 +:15153F00DC8F21F4769E6B22BEBFF4E59C7F70B1EFE3D4E291CB +:151554003FC5FFF019EAE881BE606BC0316AD10929C3F44592AE +:1515690030FAF4188BBB3F01BB07D1C3168CBB93E9B888CB7601 +:15157E00C1548AC935947C3DCD6728F916EDE819566B6CBC2309 +:151593004EF46F7DA14186B319437E5C0345D9C8C3B42F1C65B4 +:1515A800F07A019F12B1117B029F3EDC2F92193EA6035EFC1FE0 +:1515BD008E1956FFA7447F768BFE64BA60C90D6224A00FF3A197 +:1515D200D7696F826C29B2D96359B4C7259E72CEF3BD2FD3E9DE +:1515E700C559F685CBFB75B6CF555344C27ADD1915C74C0DDB68 +:1515FC0013E730B2613AACC00E2BC6711C376BC1E339C47B8D20 +:15161100CCE1A1E409E0F7049D3FC9E4EED3053F0C0636CD57B4 +:15162600191773BF8421C3372C8708FA8C3DC3678CD9888F0E7C +:15163B009BF9EA933CF549BAFE5B5CD600837773773ADE8E53ED +:151650006931CC3E443BF19DB5C90BBC5B6D82F729479CE97FDA +:15166500C09B29DF579729B7607BF3C0A40DD3614E3B2C67FFB1 +:15167A0091E9BB1863D6F8B58FED8E9CB18D4FE7C7710DCBAE50 +:15168F00F58D9EE71BABEC255B19C674ED8BC82CCBA6A03CAC55 +:1516A400727C5F72A1536BC8299F85B4EF47DA71A3028C776FB2 +:1516B900C4B945C6BD0EC0157E28639F5037702C5865E5F6325F +:1516CE0090834BE0614F1B8EA21C1C56FBB9FE71989E0B037C5D +:1516E3007B2C983703D3F3C0667AB261D8A62E5B9B2D58671E54 +:1516F80058A1C70ED38D4431D8B685423E246AA0FDC0F1E915CD +:15170D00FA1E4FEB3BC0D017D8D63A4811616B1AA8BF5EA6BF42 +:1517220031C3D2F39907713D3C418FC2B8F785B86DCB8743BE31 +:15173700611C5086397BF230D6331B6CF350B4EF681FB7A15DC2 +:15174C00C1B526F8EEC0C2B8CAF0839EC14490E683CB36B861D9 +:15176100AFBF203F5C0678AB43D8DF626E732D99615C500F659D +:1517760079E5E5CDDFD6591F27B43E7DB8EDC0C284CA7310AFE4 +:15178B00436EFF8BB8B09D5FD507C68DF0F58D7165F76B42D8B7 +:1517A0007BCB77737B9C2DEB6C7B9C8717F886F302710A3E0187 +:1517B500F76CC4C7F6C3F3C8214F7D92AE9FCDDF6E9BDEE11865 +:1517CA007678A68F71E2993EC60B3CD3C733C903DBEF9E3EC6AB +:1517DF009D9EE9E359CA8161FD57ECDF66E6BC221EC371CE7D03 +:1517F40003CA7489CDF7C15397785C62129B2F9473CA245B99AC +:1518090037A7CC652B5B905356642B5B2C0B3F129834E23DC8D7 +:15181E00972EF2CBAD582446838A3390893D6294E5EA425F6464 +:15183300628FA8C6E38C9CD853CEE4C8C8BE924647DD2AE853AA +:1518480098670742867C3B2105072B357D32E5763A3AD5367878 +:15185D004A20935E85AFC3FE0874EA70F4F7E5646A805EE941AA +:15187200044EC44576EDFFFFFDD5D610F7D86729370D75A835F8 +:15188700F749EBACBD4DDC2F24EDFA293667688F9E1A67CFD1D9 +:15189C00532CC7AA3D796A929DC989D2C446BE16678B410D07AF +:1518B10019FE18E539713F71ABF7F3BC65EE67BBC1CF0E829F2F +:1518C600051FC9E456C2E466F9EA1AE083783AD5F2CF84EC22A0 +:1518DB000E263BB47D51C0E307F847F749AB91D6D98D7C8C8CD2 +:1518F000C013D71B1D0A8B154DFCBF212BF68CD107BF617F17F3 +:15190500B179E0A4896D045924842C12421609218B04CAA2F079 +:15191A005E57A33D7EB95EF9E158F228CB033395AEC0D1422EFD +:15192F002B0EBB13600702F12CD83D00EB0B9CB66045089B0F62 +:15194400B05B03A30863FB3A5CA6572E810C4196172F4D9765C3 +:15195900C37AE2BE700965E95F7DBDEDBADEF69CCBA30F054261 +:15196E001F3EAA26EEDAEA6C3E2B24E2AE075E9CC0EBDA3CBC7E +:15198300C6A17E29E3B574F58DF4C1F5F27B3C0FBF8582DF525A +:15199800A0DD1F9AAEBFFA35F4B77322E52E8076B44F4C6F471A +:1519AD0012F0344F603BBCAB6F54976EA43DF13CED91447B1A71 +:1519C200818773F7417BBE01FDD6FF8236297E2A2BA594D97E0D +:1519D700B0798EBB0889001CFF4BA4D6D88DEF01D550403A8B99 +:1519EC0015CD9495EA57D91E33D899FA08AE37478DF001EE1352 +:151A010095837CAE32FE32F86249077FD8CDD64B0DA837161922 +:151A1600328B9A4E9A139F72DC7EC09B9AAD1B53F0DFC1FFBBA4 +:151A2B002E7C9ACDCF0551F70A3C1B20DEF42A9C1E51393DA4D7 +:151A400083F4D02BDBE92D867A454D43663DD0DB2D709CFE9440 +:151A5500D3EB14F4E0BFCB2E4F59C8B3086489E5ED5524AB7C94 +:151A6A008E65FFAA7879434EF95C513E26CACB73CAE789F2E328 +:151A7F00A2DCCBCA278D1A9A39CF92823652D2A5E2DE9D0B7DD7 +:151A940074CEF9956E888768D4B905E28CAD55B8AEA977AD2A29 +:151AA90056A4A02AE29A9E8517D5AAD0BE60AD2D5F60CF48D3BE +:151ABE000728ABE7DB3FAC0AD8E01FFFF0E5AB085FB3F5832A70 +:151AD3007B7EC18537BFFF1AC29FF8DB9F559162DCDBEE373A7F +:151AE800FFE5856AAF4FDF4A1E236E974ADCD3F8B4E58F2987E0 +:151AFD00B2FD338F35264DB4210E0F9FC331989CDD362B3EC2C4 +:151B12007A3341D7A7D6F2DC19ACDB5337ACCE8C3C12D85FC732 +:151B2700EC391DB5EC39945967724637E69FEF1B9FA7DCF14B5D +:151B3C002977661E46B55EDDAFE2BE0AC48DEEEE8551753D59D3 +:151B51001EF490E5AB16298EE0799045CF42AA6ED0FDC17369BF +:151B6600B9C4D99AC4CD4C1E740FC6284E88F50673CADDB672FB +:151B7B0009CA3B3372ED2E9048B70BCA1D65D07FA2CE22E6D307 +:151B9000F8B73741FD0651FF0EB0FF3EE1DFB0CC07651584EB9F +:151BA50013FE5F7261402B81FF8B6C75965C8869DE1C7E1E8494 +:151BBA007E4A4462A60B7C6CF96F53EEE8D594BBF9CBD42CD1C5 +:151BCF00BE7511B0D3A03F5976C52BF45442F9839E86927F6EF3 +:151BE400E84E320BF50CE3600B37AE5FE21EA16CE30B73854FA4 +:151BF90047980F360222BFA108F02E00F97B9712B7EEE7BABFE7 +:151C0E00600DE016FB3054F8F31749BFD13B3AA8BEB90CF7E984 +:151C230002068F654B0C561EA830D07717B863DA0F963E5CEE8D +:151C3800AD8CD2D65732F1168577A90F2255788EC2EF1CFC9498 +:151C4D005EB0AFF01B17BFD65EBEFE85F82EFE12D7BF94C6F455 +:151C6200BC4CC0A3FFC1E161012F009F5683EF7480CE837E2B7B +:151C770000FF50CCD618264DE9DB84BC823E830E9896DCADF9D7 +:151C8C000796596D9394037406B3ADD4083C4A48D17FA6DC93CD +:151CA100249BAEEE22B370AD1BF1FF33CC476702DD31A81376E8 +:151CB600733F65E191051EF932E76DF493947B90E7F5883A101A +:151CCB0007D1210DC7EC646A361B23B837D6F7F7C7198C4CCED0 +:151CE00026DE9F0EF277F883F2CED48D9AB89FD6377A5C9D2F99 +:151CF500B1F50E93EFB3454DDC575B6BA3C3D71DFB8DC7C61FD8 +:151D0A001B5F363A98A53F37A3FE209FA043814ADCA386B8203C +:151D1F003C443146DBAFAC0BB01C45CC8D8BBC4B95C819C3C77B +:151D340072E8BF303D7CED9BF68A7557BE8E3BC2F70C020ADF8D +:151D49002F40BA387EC227CDE7593FDC40FC373E8438D2F3B0B3 +:151D5E00AFE741D0065A69FA79F475DB3AF0CB69FB17A5E3B899 +:151D7300D62B1BEC9C14192D20E037D8FA3EE0A0631B591E841D +:151D8800CF9A67CD2103EC0C12CA784CD834FCBEFB5EE296C690 +:151D9D005FD2E40F5F52ED362D6D77D99C6CC448FDD57B923824 +:151DB2003324A32D66F3191AA37790C120E6EA4FFDFB7095BD05 +:151DC7006F6E1263BBA482E45D1FE56B9BBAC03B22F026742EFA +:151DDC003FC0ABC738DE25C7B3F0CE1078C757E7E0457B08F1E8 +:151DF100D5BE85FD2A3BAF0F3610F126393E7D19EEC9CB83B482 +:151E06003039AC4BC933BAAB28C6D6F966029DB961AA3922869F +:151E1B007128296D91944EE316F91D6D2C95F279A25230334FC2 +:151E30000D1B1877EE72A0ADAA6DB4CEDD635E358B4B587EE23F +:151E4500A4A9E2B3B8A291C80FBCCAE64201E554E8D13CED0713 +:151E5A00FF15E847FFD5CFFCD7BE8523AA67B4EB5E466F5CEA4B +:151E6F00A49571CE7B38A67B301E13F082484C972B13AC7D8726 +:151E8400C801D584B1ECDA30C8F6D1BE85361EFAC411194EB76D +:151E99006F6E6830687DCBED46FA7D1A3FFDFD997CEC7DE0FFB5 +:151EAE003DBAE0875E831F80CB601F91173B4D07DF4FDF9375AB +:151EC3002604ED1501BE8B47F83C5FC44F203B2E1F9E4F922D53 +:151ED80047B9EBD5ACFD0B186FC88303FA1AD73F43C9237B8A4E +:151EED00F95C4DFF25C07BC351D5E5116B64C0D3C5421DCF3873 +:151F0200CFC2F2B64D3C470A7DCC3231BFAB653A12D7FF14CA3C +:151F17002CDE19DF507FD7261607B33C8E7A51EF7BB67AD5C94A +:151F2C00D7F7C04F47786213DBD3D0314F00DB82F349E4A3F77A +:151F4100A598EA1DE5FC20DCA2DB2AF09DCC4377C446779BA8EC +:151F5600F7B6ADDE7AA08BF5466DF5DA44BD9FE4E16F7DF2845B +:151F6B008EE3EA1CE3F16F74F403B5789E06F83BCC746798AD4C +:151F800015F7FE1DF04A0619AFB5365EDB05EEF7F3F03A6EE3A1 +:151F95006197A8F78F7978BD60ABB75BD4FBD7AFE035BA39C326 +:151FAA006BFDD7F05A6FE33529700F6C9ECE6B7C7386875F8943 +:151FBF007A439BAFD19F9B33FD59738DFEACB1D1BD68F5671EA7 +:151FD400BA2336BA13567F5E836E77038EAFB328031AB6D3C5F7 +:151FE900F68AFB3F106EE9FC7EA87F84C4D23ADFE0E43A7FD59C +:151FFE00C1755E6FC8D00E3B39ED8E86AFA00D741B045D8B5E7B +:1520130083AD9D0D02474F7E1C14C7ACB516ADE6DA3C3C4FF630 +:152028005AC6DEB1F18CE771E5E394F92FBCB7473E4D31CE73E4 +:15203D00157569FB206E94C197C9F5EF6A0B8C33DA41DCA3B7F4 +:15205200D9A01F40BBF2D91EEB3B9F23A61ED18755D417BEF704 +:15206700774085F9EA1E9C9FAE67B832BEE12EC055007E216DFF +:15207C005743C3AA6B438CD954664F2D7FA1A33D8D317B2AD7C5 +:1520910001FF60471DB6F7ACF61663BE4EBFEA5848B514E65951 +:1520A600E0BAEF659EFBC57D5382D3A7C29E86FB786C07BE8FF4 +:1520BB00B765909DE791C3BA46D12F4586C12FBDADB9A2670C99 +:1520D000F44D79FDC98F32F33B9ECFD0A9F970BB1AD712C4FFBC +:1520E500A9546A5EEE5C8FAF47B2FD70B3640AECAB1BC656B88C +:1520FA00D4A0A18E36B4C5AE426E93252BCEC6F32DBF4BA57368 +:15210F003F9529969F39DF9E372855F27B70545B3DBC8028B73B +:152124001EFA84C30A9EA11AA188E7093C4355E6C0DBD558FC4D +:15213900EB284E3462F92DA141ED96D0DBA8336615D6C19800DF +:15214E00F3A901EEDB1A3333FFDFD618ECCF6218A3101F4D680E +:15216300FCFBB7D1A77B0B3C1DDA7BBFCDF0E49F6271928DA775 +:152178008451454EAEF1298E80451BEF02BA83D18C52ACEFBB81 +:15218D00F50B33FDBEEE8B349DE492936B0BD2795F309F147980 +:1521A200F8C8D7FC5B3127A28F9AEC2C5729CB19BA17C5217371 +:1521B7005CBC6E9CA2FCC12D9AB2BC17FAFA347CD36B4ACA69E7 +:1521CC00B3D1164F5E7C84906714E79AB30E316FCD43E7218C26 +:1521E1005DF2E2F69B4EF94DC07DD620B4CF94A2EF9A986F8196 +:1521F600EB9F69DF8DF38A42317E11EFB7C57D14A20CFFE7B9AD +:15220B00EF83E596A21E4DCC40BE127482E78C5397E0CF65E79A +:1522200003FA1BF945BCBE6082E51BB1BC0FF9A4897CC83F5F73 +:152235008EBC73DD13EBF1150319FD463C138F703CFE298E9FB9 +:15224A00E34D30F9CCFF791775C01C0EEFAFE823C32A9EA3C3D2 +:15225F0098977F9330B14ED63800FCC707ECF7C9F07623FEC926 +:152274004778FB389D78161D6B4D00EB323926B91C6FD9DA6987 +:15228900E23D116C4E63A7993E5F1B32382F1586CCE4526BF06A +:15229E009C8480E112F9A00C1E1EA44F2DC5D8F518CB47B4F334 +:1522B300E07D6D39B5F71DD431257908F7E6A9A5272CC606DB7A +:1522C8007A9874AAECDEA8B0C1E4827C61B904EDA515BA819379 +:1522DD00E4C2A24E8D1EB8533B7F21E526E3036CFEEDC53E92E8 +:1522F2004F6992F22EF545F8F9796BEEB2A070FAFCA9A36E8876 +:15230700CDE7B2E650E327CD7B6F740E15FE4BD3D229CC23ECDB +:15231C0077F2F969B64E711D425E4A845C589F04A33C7F4D1EC1 +:1523310030713E8DFE0CF5097580C94AE773E9A35FA6E6D8F47E +:15234600384B9F59DE7800C63E9D30E6F9028DB87EE2519697DC +:15235B007F88FE14E6E9CF287706AFC098BC2BE965E7B07B1FA4 +:15237000E5F4E38FE2251B0798DE610E97809B083F27E6B551F3 +:152385005137915357C04D841F15E3DDC2FF9EF8E67CCE37023B +:15239A006E22BC55E03F27EA2673EA0AB889F0B502FF3281BF77 +:1523AF0053D4C57AF8BED8666FBA6D65F88E67DBF04C9B0BF426 +:1523C400A8107C95A40C98282F49DEAFA19F092883788676EE70 +:1523D900DC505F9504F3D3F91D135A9132642ED22FADF5557FB6 +:1523EE00A64991D3E66B51E71617CFFB9C373332638D14993002 +:152403002D9D9D09B62D7915D7D13263E0FBE02325766E884EE9 +:152418001B8F627CA5ED0AE2900F0E68BD85832AF23677ABDF7C +:15242D00B4C633D301B409101B3892EFB2FD46FEFD88993B9E8E +:1524420079FE24D08431631F272FDDDCA925FE89AFF3C9C2A6AC +:152457007DDD38D98BB9A2D618E91960392BB2F0A7385696619D +:15246C006E00C41A8FB1B5F7CCDED306C51910E7A9FEF0FD47F0 +:15248100DB78AA2DF83FB0D139F1445819A04E4F17936729E02E +:15249600ABFF2CE377E9E7397E1778C13A44EEC03326265B170D +:1524AB00298E373A0FC6B43ED015796D8CDFCF00B8703D05C6F8 +:1524C000E33C764700F8662CC77BC33087D8F2BFB8BFAA46965F +:1524D500D2420FDEBDD7618CFF3A435BCE1387B8224097AF4988 +:1524EA0098D85F7DE0F7E5B303C6154113FB378B2694BB7268E4 +:1524FF0066B7BFA4B1C1463F6CA3AFE4A12FD9E82FCE43DF7F80 +:1525140083F431BEE8AC0C18162FC8C3D825CEC362A0954B5FF5 +:152529003E3BC46829910103EF4082B9B789B18FA4F03B8F16DC +:15253E004706E861887BD0A74DD9E31C5C7393FD66679DA1E108 +:152553005D60532FFAABD87E5FC96D2BFC75CD41E54F2A2AB7BB +:152568002A0FFEF1A60794CDDFDBD9DEF2EC4E6553CBB696A616 +:15257D009D2D41A5FAF107B7EF686968DDFEDDEFB4B63F5EBE5C +:15259200F2EE9501A5E4999DAD4FEFD8B1FDB9C79B9E6F0AADAF +:1525A7005A55B9EAEE157F7497F2D4D3DB5A762A81CAB255156B +:1525BC006595ABE125581E0896DFADF8D3FB5B16BDB2B2E696EB +:1525D100B6EDED654F6E7FB6ADACA9B9A96DE70B65CF363DFDA7 +:1525E6005CD9CE1D4F96B5EC6C2B7BEA85B2A6A66D0CB66DFB24 +:1525FB00F6B6953B6F5B758F72A7D2D2FC74BBD2DCF254D3775B +:15261000B7B52B4FB6363DF79D16A564577BCBAEF61548E5FA76 +:15262500F037EF78FAF9961D654F41B31E6F6A7FF6F1E61DCF95 +:15263A00AF7CF2B67B2AAE853F8D9E9D679AE30B37EE67F71A4D +:15264F00F88DB9BE8AC612A59CAEC4B35CD6398D88B406EFD1B8 +:1526640038143AD25640FA8DC6DFA7D2E7341A958DE627BF703B +:15267900AC91E48735BF526DF861EC7D0CB6C40BCF37D176E26F +:15268E003E09DD6FB47E9172FF74A9146C50866829942D22C3C6 +:1526A3005521A587B2F2B0B4370030B4376B6D30AC27830F04B5 +:1526B8009C66B752B4CEF2090BC036CE203C96C0FF5701F73E78 +:1526CD00F9E5368C13CFFD756A16F2653FD7603FD310BDC2F71F +:1526E200CABA58FD12A31FEA13F9B2E9856FCE027D3B4FB48D99 +:1526F700B0B3D32B1D642EF2877C78959314DB3003E6A998E3FD +:15270C0046C657E03EA9D7577DA7866DEF02393A7F52A9E1B5D5 +:152721006A7EC0C5D7AB0E1961E58746CD08D08678CA0BDF5BC8 +:1527360074F01C97B77A850630D34EF3A1548AD1EC62FD72CC9E +:15274B003C9D4ACDC1FBC4F8BA738F7113F805C439F916AEE733 +:152760000700768CF1E5047F7908F90AEFC775B9F956BF5967CC +:152775006CA2BFC3BEBBCCFA0EF7571405C69DDC957029F7980F +:15278A00CEEAE3D0DF07186E1C8738068B94D7CCD22F1D6BED4A +:15279F00EBBF28734BDEF67EA87927E5FAAAF2D27752B3ECFD49 +:1527B40081FCC8C08FD7D65F6D1197114DFEEC556C93121D4848 +:1527C900CCC13BE7E8622314ED4890E2B6464F926CF14697828B +:1527DE003F3EC7EEC3F3F96AA1ED0F18787F29CE1DDF9470BE3A +:1527F300A41A18D348EF3FA3E11D51F5B8CF12C6B3DB611693D4 +:15280800F6EA41D50C55AEDBA414ACFBD079D1F0856E67EB8DA0 +:15281D00462235EB23B12F128AF6D09BB2F4A01EF3BFE763BD01 +:1528320066A8773ABDAF1231F07EEE40B49A12F915EA666D83D9 +:15284700793795F63ADCEB35DC4767F617BEDFE3C0F58C8BFC2C +:15285C00CEAAE601889DCB204E78925E29242ECFD880F69872A0 +:152871007370AE72F3AA3796CE0FBEBAECD6E018C091DED4894A +:15288600D4AC658A23C8F8917B0C5C7376C1383C0F7A9FDE0F44 +:15289B001B3FC6FDF1F831F32F1696A86C7D186CE4D142116F97 +:1528B000290EB6761A075C565DAB5E3BD4395837A0E29DA7C812 +:1528C5002FAEE7E6D2C2F18BDFB7C2F7EF39385FB8A679E10D71 +:1528DA001C3F7BE9E2A241CDFBDF47282A4A6D14CFB45F64E72D +:1528EF00E7CCD0EB6A1FE05D5454AADD8577C28E47D55272D174 +:15290400E80C9D68C33D2E05FBA96E8566429FA0AE38770F1B8D +:15291900B8B71FC4F58EF08F791F88B18B31B4C4E6610AF015FA +:15292E006A64FC877F6C8E4DA5DCA70B783BD7439FAECDD37719 +:15294300308F9E9FDBA6DEA914CBE9403CEDE2FB4530C69CE3B3 +:152958003A8C83FD4601CC4B42C923863196725BDFCE80B1811F +:15296D0036F0AC903BEEA7A22CC22007AB4E3F94B1F7F1970D63 +:15298200CCA762FB8F50A7F48D6CD95F0539E6E315C7ED82680B +:1529970007F57FCE653E359CFD1D933FEA33B305FB0D4BD6BDC7 +:1529AC0020EBDAE88079F5B8F0F9F676A34E8A761FFD0D6F378E +:1529C100F63DE2DB05F84A599F458C5D2C6E133AFA2BAEA378CF +:1529D6007EDA51F780867B86DFB2F450F40997670657E8379C5D +:1529EB00E736D00DE083E9C6A2A2B59AEF178EA0A523783CBFC9 +:152A00008DEFB30A1D39A3625CB78C9C5987FAE1AD4C30BD3021 +:152A1500F565AAEBFD214D025BBB4CE8035F0FC8EEFF1190B788 +:152A2A004F3EC6E29DD9A01F5EB0BF577E2DE46E8D0BDB37B8AA +:152A3F00679D4FEE2B717C437D94FD343A30AE7A218EAC17FDA3 +:152A54003EC3A623EDA023AD1F701D71809C25A123E597B99C53 +:152A690059EE01F6FFF14C3F223E4FB84D6BFDB7B672B0676627 +:152A7E0049B4CEF447FFA7BDEF8F8EE2B8F3AC1EF54833D22015 +:152A93005AC3CC20B0905A443892A33833625024598481B05E2D +:152AA8009910769673B2DD92B0C7B1BD109B64B93B6E1FEF85E7 +:152ABD00C42318890137B8E913589615337224AF7C0B398507C9 +:152AD200397C4F24E2C239B021DC2C211C9764F1388FD8BAACE3 +:152AE700CF283E62E3C466EEFBA9EE1E8D846CECDDBDF7EE8F21 +:152AFC009B7EF3BAEBF7B7BEDF6F557DABEA5BDF5A69AC4D3DC0 +:152B110064AC4ED519D4075AF65353DC2E34E6371EB9869F2B10 +:152B26000ACEB2EE45FDB55654BA5B0DDE817DA2914EC869824F +:152B3B007B50C5FAD98475AE1E32F7037C3D69949F0DE4EB5DA3 +:152B5000B09131CED8A10527686E3ACCD7BEA454B701BDC4D514 +:152B6500A9935CDE8BA786C193F324B9DB582D9F34747AFBF5F8 +:152B7A0011F5B46C86B3EA61EDEA07C8832E36E6FE07F17305BB +:152B8F005F77BC253C273C2C7C56F00937D8AFD97F633F64DFE9 +:152BA40063C3EC5966B0DD6C07DBCEFE9A6D618FB38DEC61F62A +:152BB90020EB600AFB125BCFFE8C7D917D81B5B17BD96AB68A61 +:152BCE00AD642BD8729A41B6B066D6C41AD93216664B59030BD8 +:152BE300B120FB0CBB9B7D9AD5D3F3297617ABA3A7967D929E0F +:152BF8003BD9127A6AE8F9043D8BE9A9A647A6A78A3F95F42CC7 +:152C0D00E24F057FEEE0CF42EB59C09F72EB999F7B02D6E3CFE1 +:152C22003DBEBC675EDEE39DF694CD78A45B9EB9B73CA5B33E15 +:152C3700733EF0F17CE85372DBA7F8233FEEDB3E2E6E3B338E52 +:152C4C00F3B1C15A4DE6674B4856A96CEA8C32F928FC6AC84FD6 +:152C6100B7BE6BE93B6D7DD7D3B724D037FA96CA5A8A1FD17442 +:152C7600D6A6A569522C098A26C98B8F4A31FAA7E89F597C1419 +:152C8B00E598B6496BB90D3659B6FCDC969F407E31CBAFD8F202 +:152CA00073905FCAF22BB1FC0AC80FF95199FC2CAAC4A2412BC1 +:152CB5002FE8F906AD3CA0D71BB4D2428F374869A202F66465D7 +:152CCA002D880E49BE4BA3D975BF93E469F845B99D8790EE4D6B +:152CDF00090DAE3375D4FEABFB5D679A558E9F0F091BFD90302C +:152CF4006E7F87C24A298CFC0DF88B679B555E76BACEB07167CF +:152D0900E31CF5485B30EA2F719AE8329F770775CCF318EAC994 +:152D1E00D3043B815FE0507298F1E3A7AC70EA135BE5C5866EE7 +:152D3300E593FA2FA67F94E245D15F4A8B0DD105BBA3B3BFA3AF +:152D4800C2549C74DEB7E498FAD62D7F8EFFF1EC5CE82698E770 +:152D5D00F7656DD2B4C76AEA6D705D4699EB74145ADFFC9CB4E6 +:152D720083788DD11C34D8447DA783251C4D4611ECA1469AD5B9 +:152D8700C9EA66BE1E37F943E732E0046EAC898E533A0F6B8218 +:152D9C004EB4514FB8A08E5673C90D4611BB8B60BFCB700622DC +:152DB1009DE959FC24C1F463F25B06FADADA996B124159E77EE0 +:152DC600E0EF029CCB151A44A29914EF6A10313F96AAF537A019 +:152DDB003B2F85A8C826BD9EAF3BC17E6C33D7C9803BEA28A727 +:152DF00032EA74942F9E2957A5785D186F57BCAE01EF28EA9AFF +:152E05000E72191A71391FC3DE6230A8C5799B68D2225CD728D1 +:152E1A0002FF58766E1BC58972FB879095CD33CF312DC2F5F20E +:152E2F0037F133A82CB8C53C03CDB659F714242D5D08ACEBCEA1 +:152E440025A012345F49E83A4B28D8DF81FBAD15E23296DEA113 +:152E59007B64B1814577C2AE9C8BA565DDB4FF6AEA31D5670A9B +:152E6E001A789E941F5F47C277B4574F2E882B42AA17DF464EDC +:152E8300CF23FA5FFB50BF0AF9A02ECA670DA62768DE242EFB76 +:152E9800EE83DFA5FC5FEE833FFCEAC9AF7F865F39F9F5CCF080 +:152EAD00DBBA82E0925EEBFBFA83AF874860D63CF2157D1B3BFC +:152EC200A355AC7C5D6DAF7A25F46CD3045FB75814BF44F57999 +:152ED7004A5BB4F2BCEABA4FE336CACB2DBBF3934F88CBC4D496 +:152EEC0090EEA0F15196BFDFC7F4EB862B69DAE3E476D4C70FBC +:152F01003406307FA2F298FEB7C61DC2EB2AF051CC5E098D3CFA +:152F1600F86623C142B4BD42F09DD7056D9FFAEC86D7B43B22A6 +:152F2B005486B4CF20DCC56FAE581D72ED46F93B47D94821CDB2 +:152F4000E3BE33EA725DA3F05DFDAEB6D7C9FFE97ED3FD3796FB +:152F5500FB3FF59FC966FD7DF679C0E8CFFB128E333AF0B68DCF +:152F6A008D6BF11F14367CEB5B850DD07FE84F3FAB2CBCF0B4B0 +:152F7F005270FEA2BA865D0A2D1C3FA9422748F8C900F4F5CCDC +:152F94003A120D70EED52FFD07F5FA43578C85C2CB14E792E1D4 +:152FA9008A1F69C4BC15F94F3E745E77A50A1B469F285CC6F5AF +:152FBE00645FE26BDE47138E14D1FAB88E7AFCE1507738708AB3 +:152FD300F2977EA3A12E12608EFE68D485FD1069D75189C3FEC9 +:152FE800E3A3AF513B2C96F726B3244F16C9DDF1FD714D11D6BF +:152FFD0069D44E7FAEC36E288D00EC2917F610B4E464F5EF0D02 +:153012008ABBE74DB97E5994E26F8FAD6EE0EBAF05E6594D31D5 +:15302700F56DEA279D0DB1F1C30D4C3FAE4F82FFB0BE47E1EB7B +:15303C00C95F4C1D211EEAE6F6486A2D7B41BCBDE97BB9DDF0EB +:153051005ADED648AE4DEDA5B616D744A2ABC4B430DE2EA635C4 +:15306600E08D3D3257EA00EC1D733BA2E5A9842EB85EC63C93F4 +:15307B00DB0B052FA28DB8CE216CC88842EE4E258CBBE21AF7B7 +:153090007FEF27541EB921134ED2D4D013131BCA486E445B997A +:1530A500AC1E321606529D63379DCB0897C6E9F7B22E89E06916 +:1530BA00A5322EA16D05FB349DFAE156CA97A5068C8BBC7E4946 +:1530CF009DDAA91424C0DEEED6C24C3F053BDAA3E82F7747CE85 +:1530E4002BBF7EB4B0A18F752B7DF1034AE91271595F64AF3217 +:1530F9003FD1ABEEDFA929FB9B2F73D952CA1CEC5BB3A4F2B3DC +:15310E007C8F28181FC5DA6BD9A204F600F58A14AF8FB986EDC6 +:1531230032EDF5E3BB4D24193AF39A2EB411EFEAA78DFDE39A1A +:1531380082F541576A80D2ED028EF95E5E79E6A0519179CEA8B5 +:15314D0025BC54503D338524165038DA67ADBC8BDB6EE1794811 +:153162009A7191E6A1E5F2533AB7B1B841D3289D8EBE418C1DA2 +:15317700D3C3991F50DC5DD4467A699C1B509167762EF4786000 +:15318C004B80BAFC7327D583F15EC5BBB257756843AA6B7CB87A +:1531A10011E7E87DA78E98F6BC4F33B6003A00D029A39FB8AE2A +:1531B60047A57AF73BD6ED53134579776CA4B1D69FD4BEF10F46 +:1531CB00E28F0F0A9C667C0FC4977981EB03F25B806033057EB2 +:1531E0002CC1F5B78013733F24C9F7438CF15EA53CD3D317CC90 +:1531F500BC9092566ABC0F2958ABA9A2AC191E17F6B807B4DAA8 +:15320A00C881469CF3F277116FD1BCB63C0EF7712360B985B33F +:15321F0003AA392E1C307C194F03FCB0B6EFCAED8FF4F13D009A +:15323400077097EED56B389DCCF3C9021BD1A0476D9E4B1EE5BE +:153249007DE9AF282F612DFAB214A7AF903CA20616751B4F47B0 +:15325E00CC73AC584B17BEA071BBBA12A7B3693B5AE23CFF9D4E +:15327300A35761D392EA8DF56831437D5BFA3AA7435946C4B92C +:15328800E57980A79CDB5F4A76DA773430FD4903F6C100A7902A +:15329D00F986569B9917CAEFFBD1E783BEBCDFCFF5F9D4FF6FB5 +:1532B2002A6CF765DEC638C06DAB48991EE3B1F7B37EDFFBE0EC +:1532C700779306C0B12FB34F7768BD6A598BB9E7EFA07E03F7AF +:1532DC00DE7858EF520FF1D042D61B02FDCE7D798A77CF59B649 +:1532F1007F2F73DDAF894ECE7B4437B845BEDF11E7FB58A037C4 +:15330600E8CB6D5EA19D133D67D292E3DEA2C3ED70FB9169045F +:15331B001AE4E3DEA6C7C7A04131A7419FB5CF33458BDBD220BD +:153330006FECB5F11F1B87BDB4D2603E2DBCB14F86605F8345EF +:15334500BB466F3CF1C946295644E36C972E901FFAB1CDDF28C2 +:15335A006C38F147FB3CA0D99F9413ADBC8B3443A03A8176A8A8 +:15336F00A3B9E7639681F290B77DBE7D4A7E32E9B1208F16DB67 +:15338400393C49D3EE0E85635F51CAEC3304EBBE1BB8953CFDD8 +:15339900E3AD79E9B77E39A7E7CBF583FBD830D7DBDC049A7748 +:1533AE000D2B1ED9C9FBE92D5C0F50D31744CCBE29D7EEA8CE2A +:1533C300C2268CCBF4BEEF3CC701B553DFB63F98F5CDCCB8F661 +:1533D8000BF6DCCB03C9CE052413C82C7534C8C68F4658E668BC +:1533ED00F93F66DDF41E25F728F98F3659E93F28BE32313DBE77 +:15340200CB8A8F717EE0EDBC32B1DF48F391FCB4A80F9F7B51F9 +:153417007D6E92FCD28AF573792CFED499934A2189F6A2DC9BBD +:15342C00849D9A62F97412679ECDFDA0717EE651928FD13C2606 +:15344100A17B324B1A4E1FC8BA81878167B3EE9979E6C3C6F7CB +:1534560031296DABFC8C7EFD558D64259C19485A7CF8EF0DCEEC +:15346B00BB416EB37E723FC98F0D241F7D1CDE9C7CB5574F3836 +:15348000481E1D11DB275FD58C84A3CF6895F71B6FDF44FB88C7 +:153495005B73952EE32A6422A23FF657652A231F2737AE4CC7E0 +:1534AA0027F6772DF9D6D47FD60774C8D202B52FD491DC46F8DA +:1534BF00DF91FC188C72BBDF763E727A2A1FDFEFB3AE0A9CED31 +:1534D4000994C32EB47E91CADC06BBF91968DC46344FA6562FE1 +:1534E9003C15527F10AF0B753735F13EAB88D1DC287D9F562434 +:1534FE003C4C7DCB9A19B2A6639928DFA7CB99681FEC1CBB5C2A +:15351300D514DE66C9998B1B8B694EE3A8547859B08B0879DDE3 +:15352800D915524B23A17031953D54754F634546A631B3562FB7 +:15353D00CF0475C1D3A2767F3BA439C769FE986E326C7BD4D0FD +:1535520001E132BFD445F2674D4874134CD1AF8C32FDA17E5706 +:1535670012FB88FF9ABF332B1CCB6ED5BF29B7F4306AAD7E2D55 +:15357C0048FD5A9302B9DF2B0B413E9709364DD94049BF30BA8B +:15359100607C405D60DD59E0A3711C63314BBF64940957D55FDC +:1535A60057977E96914CCED88426B1DF34FA846B6A69B5B301F8 +:1535BB0072648464F60A6158D593DD4A39E618D46FA29F14DD49 +:1535D000AF73FB344CDA31FA00FBEF212ECBC1760CB91792FC9F +:1535E5008DB7FD5F2817B5E7DC83669A8FF23F9CCD06642ABF7B +:1535FA00D1CA9FDBF69F257FFB1F4F4DE57DA7FCA73C0DEC3F98 +:15360F0049B566F92E8259B6E250BF1E58287F32945F1FF84BF5 +:15362400DC864D11CDA95ED259E685A33E6AE7C998735945E6DD +:15363900A08EFE14BC8A7DF5329219DA16F42E8D903C8631F194 +:15364E004B4E9DCB608DCF68215BEEDAF47EF603E52ECFBBD91D +:153663000F94BB9A6691BB1CE78EA890BD206FD9F2574EEE8AAB +:153678000C37E28CBB6F25CEBABFAE35DD9CDE1FF23E9368DB97 +:15368D0056FD686331D7C99ED03CEC64A3EFD4FF22584E6A8B1D +:1536A200334B7278704D38DB6D3CC006D104E1E9DECC1C93BEB6 +:1536B700382B6386EB62F2B87A37A1A1006E2B0C7E080B4085CD +:1536CC006486DF091AAF3E088F243B841D6DD7D41BEF645DC0D6 +:1536E1002770566FE1B0E63D138715B3E010694EBFF32F8B4708 +:1536F6003FE457C2E3A2C089CECBC063747F5FECF733AE95B49A +:15370B007065F3FFEDDCF2CCF4D103FA1AD6A7DD4FF39DEFFF58 +:15372000AC77A92C9F1AA5514CF30A24A74A970C9FD54E45E8FD +:153735005348BF34B6B1CB5A99F0867AC7CA6BEA216A87341F91 +:15374A006FC01AB85466A898FBB2F401CD357E90DE07B53B5395 +:15375F00628397E6805EF6BAEA3D754515F8BD15A3DCBE14B79D +:15377400AFF4438C1B716D60FC07E13B28DE1D142F30DE13B21D +:153789006D3F4994066D54A638B63F6C3FC11FEDAB32736F4889 +:15379E009A28E434E736A7CE5EE16D0AF76905327786A6EC5777 +:1537B3005DE1FD43F0D5D2507EF9F2AB81696EE9D5CA696EE8E9 +:1537C8005BCDA7B2E673B8BAF3E03A990757771E5C272DB8FEA1 +:1537DD0084E072E6C175320FAE25A19976B582164FE7E0CAF8FC +:1537F200A7C3955934CD0D9EA9A0B1B531833E90DF11C9F8DC00 +:153807004700EF8C111DC61AE711CFCC3F457C263F63283769B9 +:15381C009E9E7E5E0F73FB865D7DF192443BDCDBF85D55C7FA7E +:15383100A00F5570866091BBFA1DE7BECD797284AFDD3CAF0766 +:15384600E5471BCDB897B5EB2B8A96791E7885E629BFD45DF29A +:15385B00F7FAEBE5FF61C47F37939F7A463DD07F4CADD7CC6F34 +:15387000CCF37B46275698F98C52BE3E2BCF1B2B3636DECDFE86 +:15388500A681CFD3F3E2222DF2C84F778EE2EC78F2921294FFC4 +:15389A006229FC21BFD134EECFF0FD0C64B8684F0AF323A42D33 +:1538AF00C6990FE25D9C27ACD8FF3CE763F4AFA2957FE9B4EFA6 +:1538C400F92187F9DD572CCF0DD15B7770BD769DE7EF786E8FEB +:1538D900CA714CF3761FC9FF46E405458A24D472C23F3FDF2953 +:1538EE009936FF6FF72799272924D7ABD85767D24E2E1749FE99 +:15390300B862CB455C4642D8C7908F6CD9C8929366958F201BEC +:1539180041460A731B30391947D3CF99328E598ECCCAE5DF195D +:15392D00F320EB92DCE492771B23D7B2AEE294962C26B8C3914D +:153942004483BD76514E7216E224AF8166DD3AAB15DBB75F33B8 +:15395700E5AEF11FF3701DE141C20FD2B3D4555D583041E3BBD3 +:15396C00466D21A915A612712F9523A58EF5A19F04DF214FCC1D +:15398100DFC17FB5F2ABFDE6BC7E265FF7F2FE653EC9C5DE53D5 +:153996007B492619D3C08315046BEB1FF3E55FAB8E54B7792958 +:1539AB00677BE6CDACBF96E4DD6DBF356556BE1741F09D79D3A5 +:1539C0004C531630CF6FB9ACFDDFD1F9CC4D7329F7C83CD38DB4 +:1539D500F3A3DB1DCC7D86FEE6FCB0D6B28F62EA383953423B4C +:1539EA00F33569F6D962CF4F894F4E35ABAB683EE6EC1A547BD6 +:1539FF00D3834AA5EC6C59287FFA73580BE669A43A35771E3916 +:153A14005A4D7C24F488B16ADD29615D59E879E3505D985DEFCD +:153A2900D2B6FC149750CD9C0F4D2F7F55BC6EE93FAB9C5BF459 +:153A3E00C7829D35F35989242D56A12F0E5D0DD843724A7FCB73 +:153A5300F57BEF4ABDDF0ADDBFC03743E8C3B84E1FB761111D23 +:153A680036D6523CBB3CF8B7927BEACE013E472F96024D9DA766 +:153A7D0003B0AF54DBF95E00F936987A72E5ACC4131BA4B1734E +:153A9200897AA72C34632FD513AB366E90BFF8CD2EDDD4AB1599 +:153AA7007B2E5AF32BA7B443FD1585C13E682FE250BDB0372D1B +:153ABC0043F78FFCC4D8A031067FFA7EA390B92F5BE98AC87D98 +:153AD10095FCF11E221AC35ED698C33CB3DB0B9AFB26614796E4 +:153AE600158DC02EE7354DBAF08C02BDEC729C75938E692ECFE7 +:153AFB0011751DD1769E2CB6176506349CF3A8A07E349041FC40 +:153B1000BD3B30C60996EDC0BB52AD4B258F797608B675E6F2B3 +:153B25003C87FB711F93CB8CE32B4F894B85915BD3B26811D7DC +:153B3A00D7D6096F61BF797616FA59B09B0A3D948C1F77C324AA +:153B4F0072F73188F2756333D14D24BC78A82DC7E89BCDB21F0F +:153B64001B8CB9B458E6C747C52B5DEA7B3E3BDF8A5CBE492BCA +:153B7900DF98653B7B0FF52D63458C9F1966E9B8C1F793A4B0E2 +:153B8E00265436758A995AC395811FD12AD3C4CB2FCF4C92FB54 +:153BA3004CA79449519EB14EACB3EF59B049E17D5BE596CE8A23 +:153BB8000C6C185CEE14E5AF196301933F6A284D6D26DD5F4F2A +:153BCD00E9C3945FEB3CE60E527A13B63FE9036CB0B3BC0A7361 +:153BE20028669F5B8E744632EF187B16449508CF53E98C929B8F +:153BF700E21F5D4DEF18E55D4873DAFB33878C48E6E9BEB68CD8 +:153C0C00DE1FA537F6A8A3F43D4EE10A9595F65AB6C4598AE365 +:153C210000F64B61F3B13393321EA17C63049B0FFC4AB8AAA7B5 +:153C3600B78BDEB0D12B5378057DAFA63C7CF4AEA1F9DA26FA1D +:153C4B009E9807DE265C915F1BF989D4D75C24BF60C0A4476CD9 +:153C6000864D72E795B84A7C57E295C5E50579F412008F3C64E5 +:153C7500604D35280F515F3764CC464FF33C53588B3A58C9DDD8 +:153C8A00A987C2683785CDB216E53AAD757A39BF43A8CB30756C +:153C9F001D841E3B8F149559D537C8CFB5080BE2EA947DA00895 +:153CB400C50B6B8CF2EB015E7CB5B9BE6DE2EF3106D6A9B8178D +:153CC90061B1DCBE946DFD5DB7F21BC6EC7CD8D62E2DF8736B0E +:153CDE00FF6BEBA0B685BE7B6467BB2B074FB3BE10E310C27EAD +:153CF30063EAC9D7DBFD13F9457F0E5DD365CB5D046B8C997058 +:153D0800DBF4E6772A5AE9026CF972B6B599E76FEB8B230DE54F +:153D1D005552CA5A7918F22A0ADC8A2FB46F9F30759E439A7424 +:153D3200501D4772753C7701753CA2AE8149D46F0EEB9317007C +:153D4700306C5F99FB57F2CF281AFD23F48FD23F46FF2DF48FD5 +:153D5C00D35FA77F8AFEA3F41FFF9919976DED36EB6A9EF9E018 +:153D71006E7D867B74863B3DC33D39C32DBD36DD1D9CE18ECEF0 +:153D8600706F99E1D667B8475FCB3B9342F86913A6DBB78880A5 +:153D9B0076BED19C5DB049AA97BFEBB85ACACF365BF9548E74A6 +:153DB000626D684D6C43D87F7258AFBD083A4DE14D21F726FA49 +:153DC5006FA37F92FE7DF41FA1FF09FA9FA1FF65FA4FD0FFC613 +:153DDA0045332E3B36CCF196B2E94F6EE04DCF73036FF13C37CD +:153DEF00F0B625CF0DBCC5F2DCC05B34CF0DBC45F2DCC05B3084 +:153E0400CF0DBCC9F9E5BF36657F93974F6E7F73CA006F433FFD +:153E19005A7C62C33DB67D048EB3D9EC7F107E3D2C0FBF33E3C5 +:153E2E00FC33C3D1F78C91FC42B2947E7A0E734357B658165B92 +:153E4300FA04E676D137F5332D1E1A238BE5459FBD48E36205B5 +:153E58007D838EA2B44BDD5C467DD65C56F218AB6989CC35FBFF +:153E6D00B407E83B3CD7ECCB2A59CD725BFF49869D72DCFB4582 +:153E820079006793A5347E53FA8952C80E2F4ED9E92019F152A8 +:153E970055178DCB872123E8932B9CCB4F531CB96CF6F1C91EC9 +:153EAC00E7B0378FF1689299363AEC781E2A77A7659780E49DE9 +:153EC100E597292F3797F7A7F7631504EF7609E321E48BDDFA81 +:153ED6009E18CEA5BDA8EF881CE6F5777FC6D92EC9753AFA7C2A +:153EEB009C112A5B79006BB9DA9639D89F1AD499FEA2EE178621 +:153F0000D516D6CDE377BB87156141138DAD83460DD54D243929 +:153F150097DB268FEED52ECEC538A6774A65499EC7988764486F +:153F2A004AE3925FD4451A8BDDA558571EA4BEFC450378AE91FA +:153F3F004CF903B0A63DD3E5BB9139ACE434E5979A8371A6469B +:153F54004FF0B1A9968F4D380F2B2C08727B0A976F66DDC5F1B1 +:153F6900AE1667B45695E56AFD8D15C2F2CD94E6CC5C5326B23D +:153F7E00F1E0B5740FA7F477653D4EBC29A57772BB7EC85FBA96 +:153F9300F02905E78C00B33732B854245945A43C2729CF769297 +:153FA800A9708E49E4BAD87C1C862D490379A0BD8BB161C323AE +:153FBD009BF7BA66B91EFF8B9A9FFA7C51FE9E81F8B8FB976419 +:153FD200B00D1305243FE3CEC7BCFBA71294C7DFC588F762B02A +:153FE700B561DA75FFCF6CB0C5436E8C33C065A498B9DF269E84 +:153FFC007D8B75B5D8B09B3819E17D13F2E0677ED892161BEE59 +:15401100EB0437F45D890E25B02303DE100907176F64DDF6BD19 +:1540260005F9750AE4D5C91E6F502FAEB740FD1DE0728ED39C6C +:15403B00233AA6F13A4883FD34F7A07AEF9EB2731CEBD27ADD53 +:15405000CCBD8660B5D37C2ED2DD029D8B9F1CF9E5618F5C6F8D +:15406500F8B9AEB24A6D76B561C32ECA87F9BC0DDF18E3250BE4 +:15407A00476B2D386D3D4E0B977EEC15D7539837262EF7154C5C +:15408F00B50DC95DA39AF7EBF6F1F28C5343CB59380C1D8CAC5D +:1540A400B96796CD7EEB5498FC123AEE46294B3FA9965DB84765 +:1540B900914EAD542B65472BD7C94EEF864E94DB9D3F6E5A70DC +:1540CE0036B0257C5C1E7531F715AAE32F88F7D8D6E7795E88FB +:1540E300EF425F1F1EE2F7AEF0F34BADF5FCDC0EC9E1FA77E3C0 +:1540F800832D38D303FC3E8D7B0B49A6B5F0EEF5669C2DF321EE +:15410D00AF674EEAD71F7C69F92FC88D3A8B99E1D9F98D706485 +:15412200F29BC93F9ECC71FD40C6D91E681DE6E5A19D99F4946F +:15413700394EEDFE5A6C5D82B51884EB95E38361BBBE51613A5F +:15414C005F42CFE6664C6801DC36DEDE1C1FE27D8027467D8299 +:1541610055CE2F288F8F5AA7CA8C7379B0783A2FB6BD9D75AFA9 +:15417600263A7A62797591BFA7439F3257179AC398F5AFCDD556 +:15418B00057088AD9FE675E1788A0D7E209E9C528D6AAD9364C6 +:1541A000515FD7A9FD5C671573A30187D54F100EA84F77E7EEE2 +:1541B5004C487769E7FE68EB0FD7F33A411FDC4EFB08A503BD44 +:1541CA00FB284D7E3FB3ED7D935F3DF2615D8E0D695F8F0C8732 +:1541DF0050367851DA3E669E8B4C0FD37CA11BFB9D567D877409 +:1541F400BBAD88992386E41E56CBA8CF3D48732B4F06FD8A6685 +:15420900D5FFC454FD892FE6B79EE4F59F4F74B3E89B1B438A6B +:15421E00D1DFF1F6A0C1DE7FAE3DDC840D9FF0B169EDE1B7E3CD +:15423300C7B85D1FE0ACE121D35E01CA798EED6D215E36DB49B7 +:154248006BB7C9C7046B4F1C67F0F5CE03B8B3217A7206BD7508 +:15425D0093DE5563CB0D727B624379743DA623CD145D87AC7ADB +:154272002579BDD0E794B5EEE5755A98129783F76D5AE6F89743 +:15428700FCC414EE0A49E83DD4FECC7B42CC7AFC35F1A7CD8B26 +:15429C005E36D6524AE503961B04CB42E2BD6345D379EFDCFF00 +:1542B10026BE93F3E08B117CB13CF8641B3EB35FE2F86CEDE6C9 +:1542C600F0E5F70BF1EBA6CE03DE62CCBC07588F24B694E68D22 +:1542DB0039F1776D5ECACD5DBD2CDCCB710B5B2C7D93D9921C44 +:1542F000EF916CF32B9C55785EBC478A99F36F6FE4B0FA32A58C +:15430500F1578BED6517FA1487C0CAE6212C7D4C972EA414DCF3 +:15431A00F17094609530E610FF6C06AFBA20776A5A2070A253C4 +:15432F00261929FE646FFB0EF827DF411FBEC375EE24D7DB9887 +:15434400A8DABB8CA5C7742328B4239FCAC45ED89CF3CDC7FD16 +:1543590068E49FC07AB5B4D710293FECCD7337952BF23DC1BDA2 +:15436E00064F87B2F4BDD07F9E87BB95BBCC343BE234A7C7BA03 +:15438300886BAD063D0E3FD7A1B3E6F412BF4F604CDFD9A6299D +:1543980005EBAEABF16CD6DBFB794D419D454A539938B201F0C4 +:1543AD0063EC042C80CD4F75692218FC174E28F36354D7B3DF2C +:1543C20056BD4CA33E3CA57C1FE38295A77876402519D88B7446 +:1543D70076DD7B28FFE4BEE3FC1E66F00B8F1B3DB6C3B5FB1DAF +:1543EC003503D8A84EA80BBB3EA0812EC003D34F6AC06723D44E +:154401005C28DCC6C5E51C1ECCB27278C07A6DDAC443E08762E3 +:154416004B721D742486B52EF2EF457B219CC00F6B1B18834D1B +:15442B00784F120E8E28C8BF60DDEFD5ED1C0F479432AA1F70F9 +:1544400020E15C15D5DB853B83A82CD84C0E52F99581894EDBE9 +:154455001EB2699F27AEE9C4837B162495B7D884B628C8FEB2C2 +:15446A0046163F97B3D7F917DC1E32B79BD4C6D70896F49B67EE +:15447F005B933C5D24B30B7756B8E98D7D6023F6EE149FE33C0E +:1544940023D6AAC0A3F5984B439736D8A4E937B89E663F8DB948 +:1544A900E3F15A67BBE00AAB623CA40E10AC55CA28EEB9D475D6 +:1544BE00F9402B9F9F521C89FA0E8FFCC51697FCB51649FED26B +:1544D30072312A63BC1EBF4AF230DE9D984B455FE43695FDCD24 +:1544E800B261E60F9971703C4861F594BE96D2D7507AF855C8F3 +:1544FD005F6AB1F3207E6AF150B88BC2AFAEF81ACFCFC3E766D2 +:15451200BFDB61C7D9827208265FF3A499B76EC20D1C85D136AC +:1545270008CE7AF9D556B1396864281CEB05AD349F1692215583 +:15453C008A630FD88C8FFC8807FC22E58378FC7C020EA4C7CC33 +:15455100FB80D0869B9835BF06CF4B435639239DB02952CE6D45 +:154566004F987E9833C18FEB1B9A67316E992F098249CF9C3FD4 +:15457B00E55F61CF7FB85E2A95CFEF384B195BDEBD75CE659ECD +:154590007D1DD11186FE07772CF8ADFEC69FFE8EEABBF01D0521 +:1545A500F2AAAFF59879AF1085F930F767C731BE6BAFFCB680E3 +:1545BA00558C1F6FDC42E39EC79A67983AB0A69C833B095CF13E +:1545CF00234BE793ECE943BEC111138E5C3F99E4F0F9228930CA +:1545E400B76F426EE4591E196AACC8CB333777A13E97A7B7FA20 +:1545F900CFDF5AFC8C7A606E47B079AFF2359D9AA934F9E76932 +:15460E00F9FDE74F69FF384BBAC333D211BFEBB3AD27453287BE +:15462300B4FF394BFACD1F21FDB559D2856F0BEF216D6296747F +:15463800EFB1DB9737F9FE8CFD27ACEFE4F31FD6FCDF9DBEBE22 +:15464D0031335CFAC38787C76F17FE7F3BFF19E19E7CFEFFB008 +:15466200F581FF1FFE4F0A97F2F0EF9DD92FFD3F03BFC51FD198 +:154677008F971EED6B9E287359ECCBDC46536D67B7147B641541 +:15468C0035454FD9A3AA46E1B82BDA73EF6E15ED14E3A4A76CC6 +:1546A100933A67F56E55961FD7E6DCDBA5FAD6698A47A8567DC5 +:1546B600A5D56A82E416AB4D6FB84163B35456AB22BF7F6A5E9C +:1546CB0087EED314EC110BEB30778969D0A813E582F6AF539F69 +:1546E000ECF754ABC5EBEAD5E7EEAB53AAD6D52901CF236A774F +:1546F500C1A714DCC5B8488CD973151FE28BC22754BEF6B0BABF +:15470A008BF71DE843AA4A130AF413ED702F0FAF539D65712E7A +:15471F00DF553D1057F9FE1264E459605865C15042301C22180D +:15473400FC79E5A3DC4A8201F178BE947F7ED937AC7C27F3F2CE +:15474900CD665FC97A60EB20C4DAD7331640DEF18298067C644E +:15475E009999D7DD8CCD9B4FB8F15099EEB57584A36A6591A745 +:154773005EADF88CD8EE645D1D557F25B61F9A9BE034C0BA4825 +:1547880090E0C01EDC5DDC76DA14EC5EAE07833DB8F813BC6EA9 +:15479D0004D3390BA631D4DD73BF5AB56FBD2A94DAB0656FDA01 +:1547B200B0B5106CE59E6AEE1F2701D1A697BBB45EF5709876A1 +:1547C7002B8B4A13EAFE9D7B72BC003CFF219BB56060BC9EB026 +:1547DC000966EE374F3E8172D3161CB81FEC0C7DCFD54C18CA91 +:1547F100F6D5A865541EEAD66E9D4D81D226C74BD1145EAA8851 +:15480600774AD6B6AAFE75610ECFAE82DD4A31E1A5C493500B35 +:15481B0059A2638FC59B8B79DDA7CA9DA0B2740A2B237C11DDC4 +:15483000BD360CA07D55DBFD0A64A1AA75F72B33E94F8DA8AC8E +:1548450098EF1B4CB5A7AA33033C9E70BE5EF53F105345F6B844 +:15485A003A87E23E27B080D3FA36E8BB641DC149FC52521A56D0 +:15486F00B51F352B87CE362B25E7D7AA7E8DFCF6AD56B5CFAF8A +:1548840021DE5FA38007FC84D3AAB5262EC498D02EB34D9CB7E4 +:15489900494EF3398587544FAC0077EBF8DCD8ABA96CEB9C2374 +:1548AE003CAC7AC455AA67259577EF63AA67F51A756FC12A05F2 +:1548C300FA1EE2CAA9F84501F31C188F9F0899F15FFEAAEA3924 +:1548D800DDACEEDD19529C34EE96FDE811A5EA3305EDB0BDEDB4 +:1548ED008A873ADCE3CD1D07610F4D0BA955E71F528573CDAA2E +:15490200467105D7142DB6A28D07F8B9B10DB005E4EAA274A731 +:154917009A3BF85CAF89B51796053B8ACA9A3AAA92EB955DD473 +:15492C0037C8E4DF43EFBF449FF3F71B554F4FB30AB95A961F63 +:15494100866CE7F224BEAA0A6B1F5779D8CBCD141E52F712CEDB +:15495600407FF038E624C5FF5168AF3A4F38D4BA54FFF9AFAA3B +:15496B0025E776731ED84F3C3087685F1CD13AF2FB25D01DB469 +:15498000E33AF5164DC193F7122CED809FF08CBB49D7D177A2D7 +:1549950060B33287CA01FCDD3BCDEF5537B37EF44BB61B7169FF +:1549AA006CD83090C51A8EC9DB064DAD803FF47B34E79A67F3A6 +:1549BF00D5368AC3CF47100C9B67E80797FDA842A93A574EB8AA +:1549D4002D5767E3A337D9141FFD9A997C041A14131F053C9B2E +:1549E900395E9EB378097CE4D7C86F062FED8EFFF9C6E2C026AC +:1549FE00A24FAC73377B78E39C40B453F03CA6DAEE92C8C31BD2 +:154A130041A7395DEB3BD8D9F60EFB5D75CDC1EF702A8EAFEF25 +:154A280028196FEF10DC44F34F546B4EA2C34DA23DF07737A785 +:154A3D0085A3BD44DB4174788CE8B087F7E9F9B428B0689130FA +:154A5200EF8EF209AE4F50D9D10D67385DC037D10D6333E84242 +:154A670034F13E60D185FA5DEFFA3CBADC994797B7B8CEEF5418 +:154A7C00DBDE49EDBA378F4EDCFE38F100FCB75BB4BA803BFF2F +:154A91002CDA6CFA98F4B894478FBFB3E88136EDB768710B1D40 +:154AA6008836F9B4288A7C65636164FD46B68DB57BC6BFD23197 +:154ABB0047DAD451C4FECDC6E2F8BFEDF08C3FCCDD557FC5DBED +:154AD000ABD7C3C81D799CE35DDC5EAD39A8EFBD5914D58A6DA5 +:154AE500BC533B2DF1ECA4FEEF5FA9256B9F9C86F7E2D9F09E3E +:154AFA005C0C9AE7E13DC6F16ED7371FFFD4E77BEFB5F08F35C1 +:154B0F0011B4131BFFDE3CFC3BF8DA8689DF5E0BBFA5E8A7280A +:154B2400AC92E65AF96DC04EFF261F174C9A211DE8A658743081 +:154B3900711E9E06CBB708CF9E94D0FE32BD13D4F714521EB8D2 +:154B4E00FFFDD0171F51ABD6B52A52C152A5A8E01E053CECA121 +:154B6300BE879D6DEE38F4530A3BBF56F1167C5E71177CC10C75 +:154B7800135675B0FBD674EC8A39DA01D762E084CA261E292BCC +:154B8D00941D7C8C843FECB9D87314940FBBA705F6D86D8D1FA2 +:154BA20088075D7FC0F55A36EBA338B9B6FF32B57D8C5D9768CE +:154BB7003A89F512C80734D6F94E5BF1BF4FDF55D744BCBD27B6 +:154BCC00785E4975BF63E8117EC65230EF62A69125EB8D0C3DF1 +:154BE1006A308DEB88C1DF37B5DE5AFC7F00E871AED038A00037 +:014BF60000BE +:00000001FF diff --git a/trunk/drivers/atm/suni.c b/trunk/drivers/atm/suni.c index 6dd3f5919968..b1d063cc4fbe 100644 --- a/trunk/drivers/atm/suni.c +++ b/trunk/drivers/atm/suni.c @@ -1,14 +1,8 @@ -/* - * drivers/atm/suni.c - S/UNI PHY driver - * - * Supports the following: - * PMC PM5346 S/UNI LITE - * PMC PM5350 S/UNI 155 ULTRA - * PMC PM5355 S/UNI 622 - */ +/* drivers/atm/suni.c - PMC PM5346 SUNI (PHY) driver */ /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + #include #include #include @@ -35,6 +29,15 @@ #define DPRINTK(format,args...) #endif + +struct suni_priv { + struct k_sonet_stats sonet_stats; /* link diagnostics */ + int loop_mode; /* loopback mode */ + struct atm_dev *dev; /* device back-pointer */ + struct suni_priv *next; /* next SUNI */ +}; + + #define PRIV(dev) ((struct suni_priv *) dev->phy_data) #define PUT(val,reg) dev->ops->phy_put(dev,val,SUNI_##reg) @@ -152,105 +155,25 @@ static int get_diag(struct atm_dev *dev,void __user *arg) static int set_loopback(struct atm_dev *dev,int mode) { unsigned char control; - int reg, dle, lle; - - if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { - reg = SUNI_MCM; - dle = SUNI_MCM_DLE; - lle = SUNI_MCM_LLE; - } else { - reg = SUNI_MCT; - dle = SUNI_MCT_DLE; - lle = SUNI_MCT_LLE; - } - control = dev->ops->phy_get(dev, reg) & ~(dle | lle); + control = GET(MCT) & ~(SUNI_MCT_DLE | SUNI_MCT_LLE); switch (mode) { case ATM_LM_NONE: break; case ATM_LM_LOC_PHY: - control |= dle; + control |= SUNI_MCT_DLE; break; case ATM_LM_RMT_PHY: - control |= lle; + control |= SUNI_MCT_LLE; break; default: return -EINVAL; } - dev->ops->phy_put(dev, control, reg); + PUT(control,MCT); PRIV(dev)->loop_mode = mode; return 0; } -/* - * SONET vs. SDH Configuration - * - * Z0INS (register 0x06): 0 for SONET, 1 for SDH - * ENSS (register 0x3D): 0 for SONET, 1 for SDH - * LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD) - * LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD) - * S[1:0] (register 0x46): 00 for SONET, 10 for SDH - */ - -static int set_sonet(struct atm_dev *dev) -{ - if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { - PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC); - PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL); - PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL); - } - - REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT, - SUNI_TPOP_S_SONET, TPOP_APM); - - return 0; -} - -static int set_sdh(struct atm_dev *dev) -{ - if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) { - PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC); - PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL); - PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL); - } - - REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT, - SUNI_TPOP_S_SDH, TPOP_APM); - - return 0; -} - - -static int get_framing(struct atm_dev *dev, void __user *arg) -{ - int framing; - unsigned char s; - - - s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT; - if (s == SUNI_TPOP_S_SONET) - framing = SONET_FRAME_SONET; - else - framing = SONET_FRAME_SDH; - - return put_user(framing, (int __user *) arg) ? -EFAULT : 0; -} - -static int set_framing(struct atm_dev *dev, void __user *arg) -{ - int mode; - - if (get_user(mode, (int __user *) arg)) - return -EFAULT; - - if (mode == SONET_FRAME_SONET) - return set_sonet(dev); - else if (mode == SONET_FRAME_SDH) - return set_sdh(dev); - - return -EINVAL; -} - static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) { @@ -265,16 +188,14 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg) case SONET_GETDIAG: return get_diag(dev,arg); case SONET_SETFRAMING: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - return set_framing(dev, arg); + if ((int)(unsigned long)arg != SONET_FRAME_SONET) return -EINVAL; + return 0; case SONET_GETFRAMING: - return get_framing(dev, arg); + return put_user(SONET_FRAME_SONET,(int __user *)arg) ? + -EFAULT : 0; case SONET_GETFRSENSE: return -EINVAL; case ATM_SETLOOP: - if (!capable(CAP_NET_ADMIN)) - return -EPERM; return set_loopback(dev,(int)(unsigned long)arg); case ATM_GETLOOP: return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ? @@ -308,6 +229,10 @@ static int suni_start(struct atm_dev *dev) unsigned long flags; int first; + if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL))) + return -ENOMEM; + + PRIV(dev)->dev = dev; spin_lock_irqsave(&sunis_lock,flags); first = !sunis; PRIV(dev)->next = sunis; @@ -368,21 +293,16 @@ int suni_init(struct atm_dev *dev) { unsigned char mri; - if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL))) - return -ENOMEM; - PRIV(dev)->dev = dev; - mri = GET(MRI); /* reset SUNI */ - PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT; PUT(mri | SUNI_MRI_RESET,MRI); PUT(mri,MRI); PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */ - set_sonet(dev); + REG_CHANGE(SUNI_TPOP_APM_S,SUNI_TPOP_APM_S_SHIFT,SUNI_TPOP_S_SONET, + TPOP_APM); /* use SONET */ REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP, TACP_IUCHP); /* idle cells */ PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP); dev->phy = &suni_ops; - return 0; } diff --git a/trunk/drivers/atm/suni.h b/trunk/drivers/atm/suni.h index 7e3e656b3993..d14c835abc97 100644 --- a/trunk/drivers/atm/suni.h +++ b/trunk/drivers/atm/suni.h @@ -1,15 +1,14 @@ -/* - * drivers/atm/suni.h - S/UNI PHY driver - */ +/* drivers/atm/suni.h - PMC PM5346 SUNI (PHY) declarations */ /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ + #ifndef DRIVER_ATM_SUNI_H #define DRIVER_ATM_SUNI_H #include #include -#include + /* SUNI registers */ @@ -40,8 +39,7 @@ #define SUNI_RLOP_LFM 0x1F /* RLOP Line FEBE MSB */ #define SUNI_TLOP_CTRL 0x20 /* TLOP Control */ #define SUNI_TLOP_DIAG 0x21 /* TLOP Diagnostic */ - /* 0x22-0x27 reserved */ -#define SUNI_SSTB_CTRL 0x28 + /* 0x22-0x2F reserved */ #define SUNI_RPOP_SC 0x30 /* RPOP Status/Control */ #define SUNI_RPOP_IS 0x31 /* RPOP Interrupt Status */ /* 0x32 reserved */ @@ -54,7 +52,6 @@ #define SUNI_RPOP_PFM 0x3B /* RPOP Path FEBE MSB */ /* 0x3C reserved */ #define SUNI_RPOP_PBC 0x3D /* RPOP Path BIP-8 Configuration */ -#define SUNI_RPOP_RC 0x3D /* RPOP Ring Control (PM5355) */ /* 0x3E-0x3F reserved */ #define SUNI_TPOP_CD 0x40 /* TPOP Control/Diagnostic */ #define SUNI_TPOP_PC 0x41 /* TPOP Pointer Control */ @@ -85,8 +82,7 @@ #define SUNI_TACP_TCC 0x65 /* TACP Transmit Cell Counter */ #define SUNI_TACP_TCCM 0x66 /* TACP Transmit Cell Counter MSB */ #define SUNI_TACP_CFG 0x67 /* TACP Configuration */ -#define SUNI_SPTB_CTRL 0x68 /* SPTB Control */ - /* 0x69-0x7F reserved */ + /* 0x68-0x7F reserved */ #define SUNI_MT 0x80 /* Master Test */ /* 0x81-0xFF reserved */ @@ -98,18 +94,9 @@ #define SUNI_MRI_ID_SHIFT 0 #define SUNI_MRI_TYPE 0x70 /* R, SUNI type (lite is 011) */ #define SUNI_MRI_TYPE_SHIFT 4 -#define SUNI_MRI_TYPE_PM5346 0x3 /* S/UNI 155 LITE */ -#define SUNI_MRI_TYPE_PM5347 0x4 /* S/UNI 155 PLUS */ -#define SUNI_MRI_TYPE_PM5350 0x7 /* S/UNI 155 ULTRA */ -#define SUNI_MRI_TYPE_PM5355 0x1 /* S/UNI 622 */ #define SUNI_MRI_RESET 0x80 /* RW, reset & power down chip 0: normal operation 1: reset & low power */ - -/* MCM is reg 0x4 */ -#define SUNI_MCM_LLE 0x20 /* line loopback (PM5355) */ -#define SUNI_MCM_DLE 0x10 /* diagnostic loopback (PM5355) */ - /* MCT is reg 5 */ #define SUNI_MCT_LOOPT 0x01 /* RW, timing source, 0: from TRCLK+/- */ @@ -157,12 +144,6 @@ /* TLOP_DIAG is reg 0x21 */ #define SUNI_TLOP_DIAG_DBIP 0x01 /* insert line BIP err (continuously) */ -/* SSTB_CTRL is reg 0x28 */ -#define SUNI_SSTB_CTRL_LEN16 0x01 /* path trace message length bit */ - -/* RPOP_RC is reg 0x3D (PM5355) */ -#define SUNI_RPOP_RC_ENSS 0x40 /* enable size bit */ - /* TPOP_DIAG is reg 0x40 */ #define SUNI_TPOP_DIAG_PAIS 0x01 /* insert STS path alarm ind (cont) */ #define SUNI_TPOP_DIAG_DB3 0x02 /* insert path BIP err (continuously) */ @@ -210,9 +191,6 @@ pattern */ #define SUNI_TACP_IUCHP_GFC_SHIFT 4 -/* SPTB_CTRL is reg 0x68 */ -#define SUNI_SPTB_CTRL_LEN16 0x01 /* path trace message length */ - /* MT is reg 0x80 */ #define SUNI_MT_HIZIO 0x01 /* RW, all but data bus & MP interface tri-state */ @@ -227,14 +205,6 @@ #ifdef __KERNEL__ -struct suni_priv { - struct k_sonet_stats sonet_stats; /* link diagnostics */ - int loop_mode; /* loopback mode */ - int type; /* phy type */ - struct atm_dev *dev; /* device back-pointer */ - struct suni_priv *next; /* next SUNI */ -}; - int suni_init(struct atm_dev *dev); #endif diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index ee0a51a3a41d..422cfcad486d 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -762,7 +762,6 @@ static void device_remove_class_symlinks(struct device *dev) /** * dev_set_name - set a device name * @dev: device - * @fmt: format string for the device's name */ int dev_set_name(struct device *dev, const char *fmt, ...) { diff --git a/trunk/drivers/block/brd.c b/trunk/drivers/block/brd.c index 24b97b0bef99..680cdfc00b90 100644 --- a/trunk/drivers/block/brd.c +++ b/trunk/drivers/block/brd.c @@ -397,7 +397,6 @@ module_param(max_part, int, 0); MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk"); MODULE_LICENSE("GPL"); MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR); -MODULE_ALIAS("rd"); #ifndef MODULE /* Legacy boot options - nonmodular */ diff --git a/trunk/drivers/block/cciss.c b/trunk/drivers/block/cciss.c index 5f1e1cc6165a..e336b05fe4a7 100644 --- a/trunk/drivers/block/cciss.c +++ b/trunk/drivers/block/cciss.c @@ -53,16 +53,15 @@ #include #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) -#define DRIVER_NAME "HP CISS Driver (v 3.6.20)" -#define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20) +#define DRIVER_NAME "HP CISS Driver (v 3.6.14)" +#define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14) /* Embedded module documentation macros - see modules.h */ MODULE_AUTHOR("Hewlett-Packard Company"); -MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); +MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.14"); MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" - " SA6i P600 P800 P400 P400i E200 E200i E500 P700m" - " Smart Array G2 Series SAS/SATA Controllers"); -MODULE_VERSION("3.6.20"); + " SA6i P600 P800 P400 P400i E200 E200i E500"); +MODULE_VERSION("3.6.14"); MODULE_LICENSE("GPL"); #include "cciss_cmd.h" @@ -91,11 +90,6 @@ static const struct pci_device_id cciss_pci_device_id[] = { {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3243}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, - {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, {0,} @@ -129,11 +123,6 @@ static struct board_type products[] = { {0x3215103C, "Smart Array E200i", &SA5_access, 120}, {0x3237103C, "Smart Array E500", &SA5_access, 512}, {0x323D103C, "Smart Array P700m", &SA5_access, 512}, - {0x3241103C, "Smart Array P212", &SA5_access, 384}, - {0x3243103C, "Smart Array P410", &SA5_access, 384}, - {0x3245103C, "Smart Array P410i", &SA5_access, 384}, - {0x3247103C, "Smart Array P411", &SA5_access, 384}, - {0x3249103C, "Smart Array P812", &SA5_access, 384}, {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, }; diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 2d854bb9373e..595a925c62a9 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -118,8 +118,8 @@ config COMPUTONE order to become a dial-in server. If you have a card like that, say Y here and read . - To compile this driver as module, choose M here: the - module will be called ip2. + To compile this driver as modules, choose M here: the + modules will be called ip2 and ip2main. config ROCKETPORT tristate "Comtrol RocketPort support" @@ -749,7 +749,7 @@ config NVRAM if RTC_LIB=n config RTC - tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" + tristate "Enhanced Real Time Clock Support" depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ && !ARM && !SUPERH && !S390 && !AVR32 ---help--- @@ -1036,9 +1036,9 @@ config HPET non-periodic and/or periodic. config HPET_RTC_IRQ - bool - default HPET_EMULATE_RTC - depends on RTC && HPET + bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC + default n + depends on HPET help If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It is assumed the platform called hpet_alloc with the RTC IRQ values for diff --git a/trunk/drivers/char/agp/ati-agp.c b/trunk/drivers/char/agp/ati-agp.c index 07b4d8ff56e5..55c97f623242 100644 --- a/trunk/drivers/char/agp/ati-agp.c +++ b/trunk/drivers/char/agp/ati-agp.c @@ -457,10 +457,6 @@ static struct agp_device_ids ati_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_ATI_RS300_200, .chipset_name = "IGP9100/M", }, - { - .device_id = PCI_DEVICE_ID_ATI_RS350_133, - .chipset_name = "IGP9000/M", - }, { .device_id = PCI_DEVICE_ID_ATI_RS350_200, .chipset_name = "IGP9100/M", diff --git a/trunk/drivers/char/generic_nvram.c b/trunk/drivers/char/generic_nvram.c index a00869c650d5..2398e864c28d 100644 --- a/trunk/drivers/char/generic_nvram.c +++ b/trunk/drivers/char/generic_nvram.c @@ -133,7 +133,7 @@ static struct miscdevice nvram_dev = { int __init nvram_init(void) { - printk(KERN_INFO "Generic non-volatile memory driver v%s\n", + printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", NVRAM_VERSION); return misc_register(&nvram_dev); } diff --git a/trunk/drivers/char/hw_random/intel-rng.c b/trunk/drivers/char/hw_random/intel-rng.c index 27fdc0866496..5cc651ef75eb 100644 --- a/trunk/drivers/char/hw_random/intel-rng.c +++ b/trunk/drivers/char/hw_random/intel-rng.c @@ -273,7 +273,7 @@ static int __init intel_rng_hw_init(void *_intel_rng_hw) if (mfc != INTEL_FWH_MANUFACTURER_CODE || (dvc != INTEL_FWH_DEVICE_CODE_8M && dvc != INTEL_FWH_DEVICE_CODE_4M)) { - printk(KERN_NOTICE PFX "FWH not detected\n"); + printk(KERN_ERR PFX "FWH not detected\n"); return -ENODEV; } diff --git a/trunk/drivers/char/keyboard.c b/trunk/drivers/char/keyboard.c index d9a0a53c842d..7f7e798c1384 100644 --- a/trunk/drivers/char/keyboard.c +++ b/trunk/drivers/char/keyboard.c @@ -677,7 +677,12 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) static void k_self(struct vc_data *vc, unsigned char value, char up_flag) { - k_unicode(vc, conv_8bit_to_uni(value), up_flag); + unsigned int uni; + if (kbd->kbdmode == VC_UNICODE) + uni = value; + else + uni = conv_8bit_to_uni(value); + k_unicode(vc, uni, up_flag); } static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) diff --git a/trunk/drivers/char/pcmcia/ipwireless/hardware.c b/trunk/drivers/char/pcmcia/ipwireless/hardware.c index ba6340ae98af..fa9d3c945f31 100644 --- a/trunk/drivers/char/pcmcia/ipwireless/hardware.c +++ b/trunk/drivers/char/pcmcia/ipwireless/hardware.c @@ -251,11 +251,10 @@ struct ipw_hardware { int init_loops; struct timer_list setup_timer; - /* Flag if hw is ready to send next packet */ int tx_ready; - /* Count of pending packets to be sent */ - int tx_queued; struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; + /* True if any packets are queued for transmission */ + int tx_queued; int rx_bytes_queued; struct list_head rx_queue; @@ -405,8 +404,6 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data, spin_lock_irqsave(&hw->spinlock, flags); - hw->tx_ready = 0; - if (hw->hw_version == HW_VERSION_1) { outw((unsigned short) length, hw->base_port + IODWR); @@ -495,7 +492,6 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet) spin_lock_irqsave(&hw->spinlock, flags); list_add(&packet->queue, &hw->tx_queue[0]); - hw->tx_queued++; spin_unlock_irqrestore(&hw->spinlock, flags); } else { if (packet->packet_callback) @@ -953,10 +949,12 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) unsigned long flags; spin_lock_irqsave(&hw->spinlock, flags); - if (hw->tx_queued && hw->tx_ready) { + if (hw->tx_queued && hw->tx_ready != 0) { int priority; struct ipw_tx_packet *packet = NULL; + hw->tx_ready--; + /* Pick a packet */ for (priority = 0; priority < priority_limit; priority++) { if (!list_empty(&hw->tx_queue[priority])) { @@ -965,7 +963,6 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) struct ipw_tx_packet, queue); - hw->tx_queued--; list_del(&packet->queue); break; @@ -976,7 +973,6 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit) spin_unlock_irqrestore(&hw->spinlock, flags); return 0; } - spin_unlock_irqrestore(&hw->spinlock, flags); /* Send */ @@ -1067,7 +1063,7 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq, if (irqn & IR_TXINTR) { ack |= IR_TXINTR; spin_lock_irqsave(&hw->spinlock, flags); - hw->tx_ready = 1; + hw->tx_ready++; spin_unlock_irqrestore(&hw->spinlock, flags); } /* Received data */ @@ -1174,7 +1170,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq, if (memrxdone & MEMRX_RX_DONE) { writew(0, &hw->memory_info_regs->memreg_rx_done); spin_lock_irqsave(&hw->spinlock, flags); - hw->tx_ready = 1; + hw->tx_ready++; spin_unlock_irqrestore(&hw->spinlock, flags); tx = 1; } @@ -1238,7 +1234,7 @@ static void send_packet(struct ipw_hardware *hw, int priority, spin_lock_irqsave(&hw->spinlock, flags); list_add_tail(&packet->queue, &hw->tx_queue[priority]); - hw->tx_queued++; + hw->tx_queued = 1; spin_unlock_irqrestore(&hw->spinlock, flags); flush_packets_to_hw(hw); diff --git a/trunk/drivers/char/vt.c b/trunk/drivers/char/vt.c index 935f1c207a1f..fa1ffbf2c621 100644 --- a/trunk/drivers/char/vt.c +++ b/trunk/drivers/char/vt.c @@ -434,7 +434,7 @@ static void update_attr(struct vc_data *vc) vc->vc_blink, vc->vc_underline, vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; - vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, vc->vc_decscnm, false) << 8) | ' '; + vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, false, false) << 8) | ' '; } /* Note: inverting the screen twice should revert to the original state */ @@ -909,7 +909,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) if (vc->vc_tty) { struct winsize ws, *cws = &vc->vc_tty->winsize; - struct pid *pgrp = NULL; + unsigned long flags; memset(&ws, 0, sizeof(ws)); ws.ws_row = vc->vc_rows; @@ -917,14 +917,11 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) ws.ws_ypixel = vc->vc_scan_lines; mutex_lock(&vc->vc_tty->termios_mutex); - spin_lock_irq(&vc->vc_tty->ctrl_lock); - if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col)) - pgrp = get_pid(vc->vc_tty->pgrp); - spin_unlock_irq(&vc->vc_tty->ctrl_lock); - if (pgrp) { + spin_lock_irqsave(&vc->vc_tty->ctrl_lock, flags); + if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && + vc->vc_tty->pgrp) kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); - put_pid(pgrp); - } + spin_unlock_irqrestore(&vc->vc_tty->ctrl_lock, flags); *cws = ws; mutex_unlock(&vc->vc_tty->termios_mutex); } diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 1d41496ed2f8..86f0a2430624 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -412,7 +412,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy, int ret; mutex_unlock(&cpufreq_governor_mutex); - ret = request_module("%s", name); + ret = request_module(name); mutex_lock(&cpufreq_governor_mutex); if (ret == 0) @@ -625,7 +625,7 @@ static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, unsigned int freq = 0; unsigned int ret; - if (!policy->governor || !policy->governor->store_setspeed) + if (!policy->governor->store_setspeed) return -EINVAL; ret = sscanf(buf, "%u", &freq); @@ -639,7 +639,7 @@ static ssize_t store_scaling_setspeed(struct cpufreq_policy *policy, static ssize_t show_scaling_setspeed(struct cpufreq_policy *policy, char *buf) { - if (!policy->governor || !policy->governor->show_setspeed) + if (!policy->governor->show_setspeed) return sprintf(buf, "\n"); return policy->governor->show_setspeed(policy, buf); diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index 23554b676d6e..fc555a90bb21 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -38,8 +38,6 @@ static void cpuidle_kick_cpus(void) static void cpuidle_kick_cpus(void) {} #endif -static int __cpuidle_register_device(struct cpuidle_device *dev); - /** * cpuidle_idle_call - the main idle loop * @@ -140,12 +138,6 @@ int cpuidle_enable_device(struct cpuidle_device *dev) if (!dev->state_count) return -EINVAL; - if (dev->registered == 0) { - ret = __cpuidle_register_device(dev); - if (ret) - return ret; - } - if ((ret = cpuidle_add_state_sysfs(dev))) return ret; @@ -240,13 +232,10 @@ static void poll_idle_init(struct cpuidle_device *dev) {} #endif /* CONFIG_ARCH_HAS_CPU_RELAX */ /** - * __cpuidle_register_device - internal register function called before register - * and enable routines + * cpuidle_register_device - registers a CPU's idle PM feature * @dev: the cpu - * - * cpuidle_lock mutex must be held before this is called */ -static int __cpuidle_register_device(struct cpuidle_device *dev) +int cpuidle_register_device(struct cpuidle_device *dev) { int ret; struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); @@ -258,31 +247,15 @@ static int __cpuidle_register_device(struct cpuidle_device *dev) init_completion(&dev->kobj_unregister); + mutex_lock(&cpuidle_lock); + poll_idle_init(dev); per_cpu(cpuidle_devices, dev->cpu) = dev; list_add(&dev->device_list, &cpuidle_detected_devices); if ((ret = cpuidle_add_sysfs(sys_dev))) { - module_put(cpuidle_curr_driver->owner); - return ret; - } - - dev->registered = 1; - return 0; -} - -/** - * cpuidle_register_device - registers a CPU's idle PM feature - * @dev: the cpu - */ -int cpuidle_register_device(struct cpuidle_device *dev) -{ - int ret; - - mutex_lock(&cpuidle_lock); - - if ((ret = __cpuidle_register_device(dev))) { mutex_unlock(&cpuidle_lock); + module_put(cpuidle_curr_driver->owner); return ret; } @@ -305,9 +278,6 @@ void cpuidle_unregister_device(struct cpuidle_device *dev) { struct sys_device *sys_dev = get_cpu_sysdev((unsigned long)dev->cpu); - if (dev->registered == 0) - return; - cpuidle_pause_and_lock(); cpuidle_disable_device(dev); diff --git a/trunk/drivers/firmware/edd.c b/trunk/drivers/firmware/edd.c index 9e4f59dc7f1e..744011989044 100644 --- a/trunk/drivers/firmware/edd.c +++ b/trunk/drivers/firmware/edd.c @@ -753,7 +753,7 @@ edd_init(void) if (!edd_num_devices()) { printk(KERN_INFO "EDD information not available.\n"); - return -ENODEV; + return 1; } edd_kset = kset_create_and_add("edd", NULL, firmware_kobj); diff --git a/trunk/drivers/hwmon/hdaps.c b/trunk/drivers/hwmon/hdaps.c index 26df06f840eb..88e89653daaf 100644 --- a/trunk/drivers/hwmon/hdaps.c +++ b/trunk/drivers/hwmon/hdaps.c @@ -522,7 +522,6 @@ static struct dmi_system_id __initdata hdaps_whitelist[] = { HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), - HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), diff --git a/trunk/drivers/hwmon/ibmaem.c b/trunk/drivers/hwmon/ibmaem.c index c9416e657487..5c006c9a4311 100644 --- a/trunk/drivers/hwmon/ibmaem.c +++ b/trunk/drivers/hwmon/ibmaem.c @@ -189,8 +189,8 @@ static struct aem_iana_id system_x_id = { struct aem_find_firmware_req { struct aem_iana_id id; u8 rsvd; - __be16 index; - __be16 module_type_id; + u16 index; + u16 module_type_id; } __packed; struct aem_find_firmware_resp { @@ -202,7 +202,7 @@ struct aem_find_firmware_resp { struct aem_find_instance_req { struct aem_iana_id id; u8 instance_number; - __be16 module_type_id; + u16 module_type_id; } __packed; struct aem_find_instance_resp { @@ -444,17 +444,17 @@ static int aem_read_sensor(struct aem_data *data, u8 elt, u8 reg, } case 2: { u16 *x = buf; - *x = be16_to_cpup((__be16 *)rs_resp->bytes); + *x = be16_to_cpup((u16 *)rs_resp->bytes); break; } case 4: { u32 *x = buf; - *x = be32_to_cpup((__be32 *)rs_resp->bytes); + *x = be32_to_cpup((u32 *)rs_resp->bytes); break; } case 8: { u64 *x = buf; - *x = be64_to_cpup((__be64 *)rs_resp->bytes); + *x = be64_to_cpup((u64 *)rs_resp->bytes); break; } } diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index 1607536ff5fb..b4f3aefa12b6 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -1028,7 +1028,6 @@ endif config BLK_DEV_HD_ONLY bool "Old hard disk (MFM/RLL/IDE) driver" - depends on !ARM || ARCH_RPC || ARCH_SHARK || BROKEN help There are two drivers for MFM/RLL/IDE hard disks. Most people use the newer enhanced driver, but this old one is still around for two diff --git a/trunk/drivers/ide/arm/bast-ide.c b/trunk/drivers/ide/arm/bast-ide.c index 8e8c28104b45..713cef20622e 100644 --- a/trunk/drivers/ide/arm/bast-ide.c +++ b/trunk/drivers/ide/arm/bast-ide.c @@ -42,7 +42,6 @@ static int __init bastide_register(unsigned int base, unsigned int aux, int irq) hw.io_ports.ctl_addr = aux + (6 * 0x20); hw.irq = irq; - hw.chipset = ide_generic; hwif = ide_find_port(); if (hwif == NULL) diff --git a/trunk/drivers/ide/arm/ide_arm.c b/trunk/drivers/ide/arm/ide_arm.c index 2f311da4c963..4263ffd4ab20 100644 --- a/trunk/drivers/ide/arm/ide_arm.c +++ b/trunk/drivers/ide/arm/ide_arm.c @@ -49,7 +49,6 @@ static int __init ide_arm_init(void) memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = IDE_ARM_IRQ; - hw.chipset = ide_generic; hwif = ide_find_port(); if (hwif) { diff --git a/trunk/drivers/ide/arm/palm_bk3710.c b/trunk/drivers/ide/arm/palm_bk3710.c index d024ac8fad14..96378ebfb31f 100644 --- a/trunk/drivers/ide/arm/palm_bk3710.c +++ b/trunk/drivers/ide/arm/palm_bk3710.c @@ -409,6 +409,9 @@ static int __devinit palm_bk3710_probe(struct platform_device *pdev) ide_device_add(idx, &palm_bk3710_port_info); + if (!hwif->present) + goto out; + return 0; out: printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); diff --git a/trunk/drivers/ide/ide-generic.c b/trunk/drivers/ide/ide-generic.c index 9134488ac043..a6073e248f45 100644 --- a/trunk/drivers/ide/ide-generic.c +++ b/trunk/drivers/ide/ide-generic.c @@ -125,7 +125,6 @@ static int __init ide_generic_init(void) memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, io_addr, io_addr + 0x206); hw.irq = ide_default_irq(io_addr); - hw.chipset = ide_generic; ide_init_port_hw(hwif, &hw); idx[i] = i; diff --git a/trunk/drivers/ide/ide-pnp.c b/trunk/drivers/ide/ide-pnp.c index adbd01784162..6a8953f68e9f 100644 --- a/trunk/drivers/ide/ide-pnp.c +++ b/trunk/drivers/ide/ide-pnp.c @@ -55,7 +55,6 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = pnp_irq(dev, 0); - hw.chipset = ide_generic; hwif = ide_find_port(); if (hwif) { diff --git a/trunk/drivers/ide/ide-probe.c b/trunk/drivers/ide/ide-probe.c index 380fa0c8cc84..655ec7ef568a 100644 --- a/trunk/drivers/ide/ide-probe.c +++ b/trunk/drivers/ide/ide-probe.c @@ -1333,7 +1333,8 @@ static void ide_port_init_devices(ide_hwif_t *hwif) static void ide_init_port(ide_hwif_t *hwif, unsigned int port, const struct ide_port_info *d) { - hwif->channel = port; + if (d->chipset != ide_etrax100) + hwif->channel = port; if (d->chipset) hwif->chipset = d->chipset; @@ -1518,7 +1519,7 @@ int ide_device_add_all(u8 *idx, const struct ide_port_info *d) continue; } - if ((i & 1) && mate) { + if (d->chipset != ide_etrax100 && (i & 1) && mate) { hwif->mate = mate; mate->mate = hwif; } @@ -1664,7 +1665,6 @@ static void ide_legacy_init_one(u8 *idx, hw_regs_t *hw, u8 port_no, ide_std_init_ports(hw, base, ctl); hw->irq = irq; - hw->chipset = d->chipset; hwif = ide_find_port_slot(d); if (hwif) { diff --git a/trunk/drivers/ide/ide-proc.c b/trunk/drivers/ide/ide-proc.c index 55ec7f798772..8d6ad812a014 100644 --- a/trunk/drivers/ide/ide-proc.c +++ b/trunk/drivers/ide/ide-proc.c @@ -63,6 +63,7 @@ static int proc_ide_read_imodel case ide_pmac: name = "mac-io"; break; case ide_au1xxx: name = "au1xxx"; break; case ide_palm3710: name = "palm3710"; break; + case ide_etrax100: name = "etrax100"; break; case ide_acorn: name = "acorn"; break; default: name = "(unknown)"; break; } diff --git a/trunk/drivers/ide/legacy/buddha.c b/trunk/drivers/ide/legacy/buddha.c index 9a1d27ef3f8a..5c730e4dd735 100644 --- a/trunk/drivers/ide/legacy/buddha.c +++ b/trunk/drivers/ide/legacy/buddha.c @@ -138,8 +138,6 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, hw->irq = IRQ_AMIGA_PORTS; hw->ack_intr = ack_intr; - - hw->chipset = ide_generic; } /* diff --git a/trunk/drivers/ide/legacy/falconide.c b/trunk/drivers/ide/legacy/falconide.c index af11028b4794..9e449a0c623f 100644 --- a/trunk/drivers/ide/legacy/falconide.c +++ b/trunk/drivers/ide/legacy/falconide.c @@ -81,8 +81,6 @@ static void __init falconide_setup_ports(hw_regs_t *hw) hw->irq = IRQ_MFP_IDE; hw->ack_intr = NULL; - - hw->chipset = ide_generic; } /* diff --git a/trunk/drivers/ide/legacy/gayle.c b/trunk/drivers/ide/legacy/gayle.c index fed7d812761c..a9c2593a898c 100644 --- a/trunk/drivers/ide/legacy/gayle.c +++ b/trunk/drivers/ide/legacy/gayle.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -63,10 +62,7 @@ GAYLE_NUM_HWIFS-1) #define GAYLE_HAS_CONTROL_REG (!ide_doubler) #define GAYLE_IDEREG_SIZE (ide_doubler ? 0x1000 : 0x2000) - int ide_doubler = 0; /* support IDE doublers? */ -EXPORT_SYMBOL_GPL(ide_doubler); - module_param_named(doubler, ide_doubler, bool, 0); MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ @@ -116,8 +112,6 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, hw->irq = IRQ_AMIGA_PORTS; hw->ack_intr = ack_intr; - - hw->chipset = ide_generic; } /* diff --git a/trunk/drivers/ide/legacy/macide.c b/trunk/drivers/ide/legacy/macide.c index 2e84290d0bcc..caa2632dd08e 100644 --- a/trunk/drivers/ide/legacy/macide.c +++ b/trunk/drivers/ide/legacy/macide.c @@ -78,8 +78,6 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, hw->irq = irq; hw->ack_intr = ack_intr; - - hw->chipset = ide_generic; } static const char *mac_ide_name[] = diff --git a/trunk/drivers/ide/legacy/q40ide.c b/trunk/drivers/ide/legacy/q40ide.c index 8ff6e2d20834..6f535d00e638 100644 --- a/trunk/drivers/ide/legacy/q40ide.c +++ b/trunk/drivers/ide/legacy/q40ide.c @@ -70,8 +70,6 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base, hw->irq = irq; hw->ack_intr = ack_intr; - - hw->chipset = ide_generic; } static void q40ide_input_data(ide_drive_t *drive, struct request *rq, diff --git a/trunk/drivers/ide/pci/cmd640.c b/trunk/drivers/ide/pci/cmd640.c index b38a1980dcd5..aaf38109eaec 100644 --- a/trunk/drivers/ide/pci/cmd640.c +++ b/trunk/drivers/ide/pci/cmd640.c @@ -747,11 +747,9 @@ static int __init cmd640x_init(void) ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); hw[0].irq = 14; - hw[0].chipset = ide_cmd640; ide_std_init_ports(&hw[1], 0x170, 0x376); hw[1].irq = 15; - hw[1].chipset = ide_cmd640; printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); diff --git a/trunk/drivers/ide/pci/delkin_cb.c b/trunk/drivers/ide/pci/delkin_cb.c index af0f30051d5a..b9e457996d0e 100644 --- a/trunk/drivers/ide/pci/delkin_cb.c +++ b/trunk/drivers/ide/pci/delkin_cb.c @@ -47,18 +47,13 @@ static const struct ide_port_ops delkin_cb_port_ops = { .quirkproc = ide_undecoded_slave, }; -static const struct ide_port_info delkin_cb_port_info = { - .port_ops = &delkin_cb_port_ops, - .host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS | - IDE_HFLAG_NO_DMA, -}; - static int __devinit delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { unsigned long base; hw_regs_t hw; ide_hwif_t *hwif = NULL; + ide_drive_t *drive; int i, rc; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; @@ -84,7 +79,6 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base + 0x10, base + 0x1e); hw.irq = dev->irq; - hw.dev = &dev->dev; hw.chipset = ide_pci; /* this enables IRQ sharing */ hwif = ide_find_port(); @@ -95,16 +89,26 @@ delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); + hwif->port_ops = &delkin_cb_port_ops; idx[0] = i; - ide_device_add(idx, &delkin_cb_port_info); + ide_device_add(idx, NULL); - pci_set_drvdata(dev, hwif); + if (!hwif->present) + goto out_disable; + pci_set_drvdata(dev, hwif); + hwif->dev = &dev->dev; + drive = &hwif->drives[0]; + if (drive->present) { + drive->io_32bit = 1; + drive->unmask = 1; + } return 0; out_disable: + printk(KERN_ERR "delkin_cb: no IDE devices found\n"); pci_release_regions(dev); pci_disable_device(dev); return -ENODEV; @@ -135,12 +139,14 @@ static struct pci_driver driver = { .remove = delkin_cb_remove, }; -static int __init delkin_cb_init(void) +static int +delkin_cb_init (void) { return pci_register_driver(&driver); } -static void __exit delkin_cb_exit(void) +static void +delkin_cb_exit (void) { pci_unregister_driver(&driver); } diff --git a/trunk/drivers/ide/pci/sis5513.c b/trunk/drivers/ide/pci/sis5513.c index e127eb25ab63..4b0b85d8faf5 100644 --- a/trunk/drivers/ide/pci/sis5513.c +++ b/trunk/drivers/ide/pci/sis5513.c @@ -569,11 +569,6 @@ static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_devi { struct ide_port_info d = sis5513_chipset; u8 udma_rates[] = { 0x00, 0x00, 0x07, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f }; - int rc; - - rc = pci_enable_device(dev); - if (rc) - return rc; if (sis_find_family(dev) == 0) return -ENOTSUPP; diff --git a/trunk/drivers/ide/ppc/mpc8xx.c b/trunk/drivers/ide/ppc/mpc8xx.c index 236f9c38e519..f0e638dcc3ab 100644 --- a/trunk/drivers/ide/ppc/mpc8xx.c +++ b/trunk/drivers/ide/ppc/mpc8xx.c @@ -303,8 +303,6 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) pcmp->pcmc_per = 0x100000 >> (16 * _slot_); #endif /* CONFIG_IDE_8xx_PCCARD */ - hw->chipset = ide_generic; - return 0; } #endif /* CONFIG_IDE_8xx_PCCARD || CONFIG_IDE_8xx_DIRECT */ @@ -379,8 +377,6 @@ static int __init m8xx_ide_init_ports(hw_regs_t *hw, unsigned long data_port) ((immap_t *) IMAP_ADDR)->im_siu_conf.sc_siel |= (0x80000000 >> ioport_dsc[data_port].irq); - hw->chipset = ide_generic; - return 0; } #endif /* CONFIG_IDE_8xx_DIRECT */ diff --git a/trunk/drivers/infiniband/core/umem.c b/trunk/drivers/infiniband/core/umem.c index a1768dbb0720..fe78f7d25099 100644 --- a/trunk/drivers/infiniband/core/umem.c +++ b/trunk/drivers/infiniband/core/umem.c @@ -150,7 +150,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr, ret = 0; while (npages) { ret = get_user_pages(current, current->mm, cur_base, - min_t(unsigned long, npages, + min_t(int, npages, PAGE_SIZE / sizeof (struct page *)), 1, !umem->writable, page_list, vma_list); diff --git a/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c b/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c index b1441aeb60c2..9a054c6941a4 100644 --- a/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/trunk/drivers/infiniband/hw/amso1100/c2_rnic.c @@ -455,7 +455,8 @@ int __devinit c2_rnic_init(struct c2_dev *c2dev) IB_DEVICE_CURR_QP_STATE_MOD | IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_ZERO_STAG | - IB_DEVICE_MEM_WINDOW); + IB_DEVICE_MEM_WINDOW | + IB_DEVICE_SEND_W_INV); /* Allocate the qptr_array */ c2dev->qptr_array = vmalloc(C2_MAX_CQS * sizeof(void *)); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c index f093b0033daf..bbe0436f4f75 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -421,10 +421,8 @@ int ehca_post_send(struct ib_qp *qp, int ret = 0; unsigned long flags; - /* Reject WR if QP is in RESET, INIT or RTR state */ - if (unlikely(my_qp->state < IB_QPS_RTS)) { - ehca_err(qp->device, "Invalid QP state qp_state=%d qpn=%x", - my_qp->state, qp->qp_num); + if (unlikely(my_qp->state != IB_QPS_RTS)) { + ehca_err(qp->device, "QP not in RTS state qpn=%x", qp->qp_num); return -EINVAL; } diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h index 0bd8bcb184a1..59a8b254b97f 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/trunk/drivers/infiniband/hw/ipath/ipath_kernel.h @@ -232,11 +232,6 @@ struct ipath_sdma_desc { #define IPATH_SDMA_TXREQ_S_ABORTED 2 #define IPATH_SDMA_TXREQ_S_SHUTDOWN 3 -#define IPATH_SDMA_STATUS_SCORE_BOARD_DRAIN_IN_PROG (1ull << 63) -#define IPATH_SDMA_STATUS_ABORT_IN_PROG (1ull << 62) -#define IPATH_SDMA_STATUS_INTERNAL_SDMA_ENABLE (1ull << 61) -#define IPATH_SDMA_STATUS_SCB_EMPTY (1ull << 30) - /* max dwords in small buffer packet */ #define IPATH_SMALLBUF_DWORDS (dd->ipath_piosize2k >> 2) diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_mad.c b/trunk/drivers/infiniband/hw/ipath/ipath_mad.c index 5f9315d77a43..1ff46ae7dd99 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_mad.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_mad.c @@ -1492,10 +1492,6 @@ static int process_subn(struct ib_device *ibdev, int mad_flags, goto bail; } - case IB_MGMT_METHOD_TRAP: - case IB_MGMT_METHOD_REPORT: - case IB_MGMT_METHOD_REPORT_RESP: - case IB_MGMT_METHOD_TRAP_REPRESS: case IB_MGMT_METHOD_GET_RESP: /* * The ib_mad module will call us to process responses diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c index eaba03273e4f..0a8c1b8091a2 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_sdma.c @@ -263,10 +263,14 @@ static void sdma_abort_task(unsigned long opaque) hwstatus = ipath_read_kreg64(dd, dd->ipath_kregs->kr_senddmastatus); - if ((hwstatus & (IPATH_SDMA_STATUS_SCORE_BOARD_DRAIN_IN_PROG | - IPATH_SDMA_STATUS_ABORT_IN_PROG | - IPATH_SDMA_STATUS_INTERNAL_SDMA_ENABLE)) || - !(hwstatus & IPATH_SDMA_STATUS_SCB_EMPTY)) { + if (/* ScoreBoardDrainInProg */ + test_bit(63, &hwstatus) || + /* AbortInProg */ + test_bit(62, &hwstatus) || + /* InternalSDmaEnable */ + test_bit(61, &hwstatus) || + /* ScbEmpty */ + !test_bit(30, &hwstatus)) { if (dd->ipath_sdma_reset_wait > 0) { /* not done shutting down sdma */ --dd->ipath_sdma_reset_wait; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c index 7779165b2c2c..e0ec540042bf 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_verbs.c @@ -1494,8 +1494,7 @@ static int ipath_query_device(struct ib_device *ibdev, props->device_cap_flags = IB_DEVICE_BAD_PKEY_CNTR | IB_DEVICE_BAD_QKEY_CNTR | IB_DEVICE_SHUTDOWN_PORT | - IB_DEVICE_SYS_IMAGE_GUID | IB_DEVICE_RC_RNR_NAK_GEN | - IB_DEVICE_PORT_ACTIVE_EVENT | IB_DEVICE_SRQ_RESIZE; + IB_DEVICE_SYS_IMAGE_GUID; props->page_size_cap = PAGE_SIZE; props->vendor_id = dev->dd->ipath_vendorid; props->vendor_part_id = dev->dd->ipath_deviceid; diff --git a/trunk/drivers/isdn/hardware/eicon/divasmain.c b/trunk/drivers/isdn/hardware/eicon/divasmain.c index 16a874bb1561..5fcbdccd7a53 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasmain.c +++ b/trunk/drivers/isdn/hardware/eicon/divasmain.c @@ -806,6 +806,7 @@ static int DIVA_INIT_FUNCTION divas_init(void) if (!create_divas_proc()) { #ifdef MODULE + remove_divas_proc(); divas_unregister_chrdev(); divasfunc_exit(); #endif diff --git a/trunk/drivers/isdn/hardware/eicon/divasproc.c b/trunk/drivers/isdn/hardware/eicon/divasproc.c index 040827288ec9..fae895828a17 100644 --- a/trunk/drivers/isdn/hardware/eicon/divasproc.c +++ b/trunk/drivers/isdn/hardware/eicon/divasproc.c @@ -125,8 +125,8 @@ static const struct file_operations divas_fops = { int create_divas_proc(void) { - divas_proc_entry = proc_create(divas_proc_name, S_IFREG | S_IRUGO, - proc_net_eicon, &divas_fops); + proc_create(divas_proc_name, S_IFREG | S_IRUGO, proc_net_eicon, + &divas_fops); if (!divas_proc_entry) return (0); diff --git a/trunk/drivers/isdn/hysdn/hysdn_procconf.c b/trunk/drivers/isdn/hysdn/hysdn_procconf.c index 484299b031f8..15906d005b05 100644 --- a/trunk/drivers/isdn/hysdn/hysdn_procconf.c +++ b/trunk/drivers/isdn/hysdn/hysdn_procconf.c @@ -207,17 +207,30 @@ hysdn_conf_write(struct file *file, const char __user *buf, size_t count, loff_t /* read conf file -> output card info data */ /*******************************************/ static ssize_t -hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t *off) +hysdn_conf_read(struct file *file, char __user *buf, size_t count, loff_t * off) { char *cp; + int i; - if (!(file->f_mode & FMODE_READ)) - return -EPERM; /* no permission to read */ - - if (!(cp = file->private_data)) - return -EFAULT; /* should never happen */ - - return simple_read_from_buffer(buf, count, off, cp, strlen(cp)); + if (file->f_mode & FMODE_READ) { + if (!(cp = file->private_data)) + return (-EFAULT); /* should never happen */ + i = strlen(cp); /* get total string length */ + if (*off < i) { + /* still bytes to transfer */ + cp += *off; /* point to desired data offset */ + i -= *off; /* remaining length */ + if (i > count) + i = count; /* limit length to transfer */ + if (copy_to_user(buf, cp, i)) + return (-EFAULT); /* copy error */ + *off += i; /* adjust offset */ + } else + return (0); + } else + return (-EPERM); /* no permission to read */ + + return (i); } /* hysdn_conf_read */ /******************/ diff --git a/trunk/drivers/isdn/sc/ioctl.c b/trunk/drivers/isdn/sc/ioctl.c index 1081091bbfaf..7817d2244921 100644 --- a/trunk/drivers/isdn/sc/ioctl.c +++ b/trunk/drivers/isdn/sc/ioctl.c @@ -226,7 +226,6 @@ int sc_ioctl(int card, scs_ioctl *data) */ if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { kfree(rcvmsg); - kfree(spid); return -EFAULT; } diff --git a/trunk/drivers/md/md.c b/trunk/drivers/md/md.c index 7cf512a34ccf..51c19f86ff99 100644 --- a/trunk/drivers/md/md.c +++ b/trunk/drivers/md/md.c @@ -276,7 +276,6 @@ static mddev_t * mddev_find(dev_t unit) atomic_set(&new->active, 1); spin_lock_init(&new->write_lock); init_waitqueue_head(&new->sb_wait); - init_waitqueue_head(&new->recovery_wait); new->reshape_position = MaxSector; new->resync_max = MaxSector; new->level = LEVEL_NONE; @@ -5666,6 +5665,7 @@ void md_do_sync(mddev_t *mddev) window/2,(unsigned long long) max_sectors/2); atomic_set(&mddev->recovery_active, 0); + init_waitqueue_head(&mddev->recovery_wait); last_check = 0; if (j>2) { diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index c37e256b1176..425958a76b84 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2002,7 +2002,6 @@ static int __handle_issuing_new_read_requests5(struct stripe_head *sh, * have quiesced. */ if ((s->uptodate == disks - 1) && - (s->failed && disk_idx == s->failed_num) && !test_bit(STRIPE_OP_CHECK, &sh->ops.pending)) { set_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending); set_bit(R5_Wantcompute, &dev->flags); @@ -2088,9 +2087,7 @@ static void handle_issuing_new_read_requests6(struct stripe_head *sh, /* we would like to get this block, possibly * by computing it, but we might not be able to */ - if ((s->uptodate == disks - 1) && - (s->failed && (i == r6s->failed_num[0] || - i == r6s->failed_num[1]))) { + if (s->uptodate == disks-1) { pr_debug("Computing stripe %llu block %d\n", (unsigned long long)sh->sector, i); compute_block_1(sh, i, 0); @@ -2648,7 +2645,6 @@ static void handle_stripe5(struct stripe_head *sh) struct r5dev *dev; unsigned long pending = 0; mdk_rdev_t *blocked_rdev = NULL; - int prexor; memset(&s, 0, sizeof(s)); pr_debug("handling stripe %llu, state=%#lx cnt=%d, pd_idx=%d " @@ -2778,11 +2774,9 @@ static void handle_stripe5(struct stripe_head *sh) /* leave prexor set until postxor is done, allows us to distinguish * a rmw from a rcw during biodrain */ - prexor = 0; if (test_bit(STRIPE_OP_PREXOR, &sh->ops.complete) && test_bit(STRIPE_OP_POSTXOR, &sh->ops.complete)) { - prexor = 1; clear_bit(STRIPE_OP_PREXOR, &sh->ops.complete); clear_bit(STRIPE_OP_PREXOR, &sh->ops.ack); clear_bit(STRIPE_OP_PREXOR, &sh->ops.pending); @@ -2816,8 +2810,6 @@ static void handle_stripe5(struct stripe_head *sh) if (!test_and_set_bit( STRIPE_OP_IO, &sh->ops.pending)) sh->ops.count++; - if (prexor) - continue; if (!test_bit(R5_Insync, &dev->flags) || (i == sh->pd_idx && s.failed == 0)) set_bit(STRIPE_INSYNC, &sh->state); diff --git a/trunk/drivers/media/Makefile b/trunk/drivers/media/Makefile index 09a829d8a7e7..cc11c4c0e7e7 100644 --- a/trunk/drivers/media/Makefile +++ b/trunk/drivers/media/Makefile @@ -2,7 +2,12 @@ # Makefile for the kernel multimedia device drivers. # -obj-y += common/ video/ +obj-y := common/ + +obj-$(CONFIG_VIDEO_MEDIA) += common/ + +# Since hybrid devices are here, should be compiled if DVB and/or V4L +obj-$(CONFIG_VIDEO_MEDIA) += video/ obj-$(CONFIG_VIDEO_DEV) += radio/ obj-$(CONFIG_DVB_CORE) += dvb/ diff --git a/trunk/drivers/media/common/tuners/Kconfig b/trunk/drivers/media/common/tuners/Kconfig index 85482960d012..d6206540476b 100644 --- a/trunk/drivers/media/common/tuners/Kconfig +++ b/trunk/drivers/media/common/tuners/Kconfig @@ -21,7 +21,6 @@ config MEDIA_TUNER tristate default VIDEO_MEDIA && I2C depends on VIDEO_MEDIA && I2C - select FW_LOADER if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE && HOTPLUG select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE diff --git a/trunk/drivers/media/common/tuners/mxl5005s.c b/trunk/drivers/media/common/tuners/mxl5005s.c index 0dc2bef9f6a3..5d05b5390f66 100644 --- a/trunk/drivers/media/common/tuners/mxl5005s.c +++ b/trunk/drivers/media/common/tuners/mxl5005s.c @@ -101,7 +101,7 @@ enum { MXL_QAM, MXL_ANALOG_CABLE, MXL_ANALOG_OTA -}; +} tuner_modu_type; /* MXL5005 Tuner Register Struct */ struct TunerReg { @@ -194,7 +194,7 @@ enum { RFSYN_DIVM, /* 88 */ DN_BYPASS_AGC_I2C /* 89 */ #endif -}; +} MXL5005_ControlName; /* * The following context is source code provided by MaxLinear. diff --git a/trunk/drivers/media/common/tuners/tda18271-common.c b/trunk/drivers/media/common/tuners/tda18271-common.c index f1894fec32b9..42b5f5d4bfe6 100644 --- a/trunk/drivers/media/common/tuners/tda18271-common.c +++ b/trunk/drivers/media/common/tuners/tda18271-common.c @@ -648,11 +648,11 @@ int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq) unsigned char *regs = priv->tda18271_regs; u8 val; - int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val); + tda18271_lookup_map(fe, RF_CAL, freq, &val); regs[R_EB14] = val; - return ret; + return 0; } /* diff --git a/trunk/drivers/media/common/tuners/tda827x.c b/trunk/drivers/media/common/tuners/tda827x.c index 8555d9cf9051..d30d2c9094d9 100644 --- a/trunk/drivers/media/common/tuners/tda827x.c +++ b/trunk/drivers/media/common/tuners/tda827x.c @@ -418,13 +418,13 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high, unsigned char buf[] = {0x22, 0x01}; int arg; int gp_func; - struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) }; + struct i2c_msg msg = { .addr = priv->cfg->switch_addr, .flags = 0, + .buf = buf, .len = sizeof(buf) }; if (NULL == priv->cfg) { dprintk("tda827x_config not defined, cannot set LNA gain!\n"); return; } - msg.addr = priv->cfg->switch_addr; if (priv->cfg->config) { if (high) dprintk("setting LNA to high gain\n"); diff --git a/trunk/drivers/media/common/tuners/tea5761.c b/trunk/drivers/media/common/tuners/tea5761.c index b23dadeecd05..b93cdef9ac73 100644 --- a/trunk/drivers/media/common/tuners/tea5761.c +++ b/trunk/drivers/media/common/tuners/tea5761.c @@ -295,7 +295,7 @@ struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe, { struct tea5761_priv *priv = NULL; - if (tea5761_autodetection(i2c_adap, i2c_addr) != 0) + if (tea5761_autodetection(i2c_adap, i2c_addr) == EINVAL) return NULL; priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL); diff --git a/trunk/drivers/media/common/tuners/tuner-i2c.h b/trunk/drivers/media/common/tuners/tuner-i2c.h index cb1c7141f0c6..3ad6c8e0b04c 100644 --- a/trunk/drivers/media/common/tuners/tuner-i2c.h +++ b/trunk/drivers/media/common/tuners/tuner-i2c.h @@ -170,12 +170,4 @@ __fail: \ __ret; \ }) -#define hybrid_tuner_report_instance_count(state) \ -({ \ - int __ret = 0; \ - if (state) \ - __ret = state->i2c_props.count; \ - __ret; \ -}) - #endif /* __TUNER_I2C_H__ */ diff --git a/trunk/drivers/media/common/tuners/tuner-simple.c b/trunk/drivers/media/common/tuners/tuner-simple.c index 266c255cf0d8..be8d903171b7 100644 --- a/trunk/drivers/media/common/tuners/tuner-simple.c +++ b/trunk/drivers/media/common/tuners/tuner-simple.c @@ -1018,10 +1018,8 @@ struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe, fe->ops.i2c_gate_ctrl(fe, 1); if (1 != i2c_transfer(i2c_adap, &msg, 1)) - printk(KERN_WARNING "tuner-simple %d-%04x: " - "unable to probe %s, proceeding anyway.", - i2c_adapter_id(i2c_adap), i2c_addr, - tuners[type].name); + tuner_warn("unable to probe %s, proceeding anyway.", + tuners[type].name); if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); diff --git a/trunk/drivers/media/common/tuners/tuner-xc2028.c b/trunk/drivers/media/common/tuners/tuner-xc2028.c index 0cbde17bfbb7..9e9003cffc7f 100644 --- a/trunk/drivers/media/common/tuners/tuner-xc2028.c +++ b/trunk/drivers/media/common/tuners/tuner-xc2028.c @@ -46,7 +46,7 @@ module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0); MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the " "default firmware name\n"); -static LIST_HEAD(hybrid_tuner_instance_list); +static LIST_HEAD(xc2028_list); static DEFINE_MUTEX(xc2028_list_mutex); /* struct for storing firmware table */ @@ -68,11 +68,12 @@ struct firmware_properties { }; struct xc2028_data { - struct list_head hybrid_tuner_instance_list; + struct list_head xc2028_list; struct tuner_i2c_props i2c_props; int (*tuner_callback) (void *dev, int command, int arg); void *video_dev; + int count; __u32 frequency; struct firmware_description *firm; @@ -1071,19 +1072,20 @@ static int xc2028_dvb_release(struct dvb_frontend *fe) mutex_lock(&xc2028_list_mutex); - /* only perform final cleanup if this is the last instance */ - if (hybrid_tuner_report_instance_count(priv) == 1) { + priv->count--; + + if (!priv->count) { + list_del(&priv->xc2028_list); + kfree(priv->ctrl.fname); + free_firmware(priv); + kfree(priv); + fe->tuner_priv = NULL; } - if (priv) - hybrid_tuner_release_state(priv); - mutex_unlock(&xc2028_list_mutex); - fe->tuner_priv = NULL; - return 0; } @@ -1148,7 +1150,7 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, struct xc2028_config *cfg) { struct xc2028_data *priv; - int instance; + void *video_dev; if (debug) printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n"); @@ -1161,41 +1163,49 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, return NULL; } + video_dev = cfg->i2c_adap->algo_data; + + if (debug) + printk(KERN_DEBUG "xc2028: video_dev =%p\n", video_dev); + mutex_lock(&xc2028_list_mutex); - instance = hybrid_tuner_request_state(struct xc2028_data, priv, - hybrid_tuner_instance_list, - cfg->i2c_adap, cfg->i2c_addr, - "xc2028"); - switch (instance) { - case 0: - /* memory allocation failure */ - goto fail; - break; - case 1: - /* new tuner instance */ + list_for_each_entry(priv, &xc2028_list, xc2028_list) { + if (&priv->i2c_props.adap->dev == &cfg->i2c_adap->dev) { + video_dev = NULL; + if (debug) + printk(KERN_DEBUG "xc2028: reusing device\n"); + + break; + } + } + + if (video_dev) { + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (priv == NULL) { + mutex_unlock(&xc2028_list_mutex); + return NULL; + } + + priv->i2c_props.addr = cfg->i2c_addr; + priv->i2c_props.adap = cfg->i2c_adap; + priv->i2c_props.name = "xc2028"; + + priv->video_dev = video_dev; priv->tuner_callback = cfg->callback; priv->ctrl.max_len = 13; mutex_init(&priv->lock); - /* analog side (tuner-core) uses i2c_adap->algo_data. - * digital side is not guaranteed to have algo_data defined. - * - * digital side will always have fe->dvb defined. - * analog side (tuner-core) doesn't (yet) define fe->dvb. - */ - priv->video_dev = ((fe->dvb) && (fe->dvb->priv)) ? - fe->dvb->priv : cfg->i2c_adap->algo_data; - - fe->tuner_priv = priv; - break; - case 2: - /* existing tuner instance */ - fe->tuner_priv = priv; - break; + list_add_tail(&priv->xc2028_list, &xc2028_list); } + fe->tuner_priv = priv; + priv->count++; + + if (debug) + printk(KERN_DEBUG "xc2028: usage count is %i\n", priv->count); + memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops, sizeof(xc2028_dvb_tuner_ops)); @@ -1207,11 +1217,6 @@ struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe, mutex_unlock(&xc2028_list_mutex); return fe; -fail: - mutex_unlock(&xc2028_list_mutex); - - xc2028_dvb_release(fe); - return NULL; } EXPORT_SYMBOL(xc2028_attach); diff --git a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c index ae0d76a5d51d..449fb5c3d0b1 100644 --- a/trunk/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/trunk/drivers/media/dvb/b2c2/flexcop-usb.c @@ -379,7 +379,7 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) { - u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); + u16 frame_size = fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize; int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; int buffer_offset = 0; diff --git a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c index a824f3719f81..f5010e8671b8 100644 --- a/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/trunk/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -82,22 +82,22 @@ enum cinergyt2_ep1_cmd { struct dvbt_set_parameters_msg { uint8_t cmd; - __le32 freq; + uint32_t freq; uint8_t bandwidth; - __le16 tps; + uint16_t tps; uint8_t flags; } __attribute__((packed)); struct dvbt_get_status_msg { - __le32 freq; + uint32_t freq; uint8_t bandwidth; - __le16 tps; + uint16_t tps; uint8_t flags; - __le16 gain; + uint16_t gain; uint8_t snr; - __le32 viterbi_error_rate; - __le32 rs_error_rate; - __le32 uncorrected_block_count; + uint32_t viterbi_error_rate; + uint32_t rs_error_rate; + uint32_t uncorrected_block_count; uint8_t lock_bits; uint8_t prev_lock_bits; } __attribute__((packed)); @@ -136,7 +136,6 @@ struct cinergyt2 { wait_queue_head_t poll_wq; int pending_fe_events; int disconnect_pending; - unsigned int uncorrected_block_count; atomic_t inuse; void *streambuf; @@ -148,7 +147,7 @@ struct cinergyt2 { char phys[64]; struct delayed_work rc_query_work; int rc_input_event; - __le32 rc_last_code; + u32 rc_last_code; unsigned long last_event_jiffies; #endif }; @@ -161,7 +160,7 @@ enum { struct cinergyt2_rc_event { char type; - __le32 value; + uint32_t value; } __attribute__((packed)); static const uint32_t rc_keys[] = { @@ -620,11 +619,8 @@ static int cinergyt2_ioctl (struct inode *inode, struct file *file, { uint32_t unc_count; - if (mutex_lock_interruptible(&cinergyt2->sem)) - return -ERESTARTSYS; - unc_count = cinergyt2->uncorrected_block_count; - cinergyt2->uncorrected_block_count = 0; - mutex_unlock(&cinergyt2->sem); + unc_count = stat->uncorrected_block_count; + stat->uncorrected_block_count = 0; /* UNC are already converted to host byte order... */ return put_user(unc_count,(__u32 __user *) arg); @@ -773,7 +769,7 @@ static void cinergyt2_query_rc (struct work_struct *work) input_sync(cinergyt2->rc_input_dev); cinergyt2->rc_input_event = KEY_MAX; } - cinergyt2->rc_last_code = cpu_to_le32(~0); + cinergyt2->rc_last_code = ~0; } goto out; } @@ -784,7 +780,7 @@ static void cinergyt2_query_rc (struct work_struct *work) n, le32_to_cpu(rc_events[n].value), rc_events[n].type); if (rc_events[n].type == CINERGYT2_RC_EVENT_TYPE_NEC && - rc_events[n].value == cpu_to_le32(~0)) { + rc_events[n].value == ~0) { /* keyrepeat bit -> just repeat last rc_input_event */ } else { cinergyt2->rc_input_event = KEY_MAX; @@ -799,7 +795,7 @@ static void cinergyt2_query_rc (struct work_struct *work) if (cinergyt2->rc_input_event != KEY_MAX) { if (rc_events[n].value == cinergyt2->rc_last_code && - cinergyt2->rc_last_code != cpu_to_le32(~0)) { + cinergyt2->rc_last_code != ~0) { /* emit a key-up so the double event is recognized */ dprintk(1, "rc_input_event=%d UP\n", cinergyt2->rc_input_event); input_report_key(cinergyt2->rc_input_dev, @@ -833,7 +829,7 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) usb_make_path(cinergyt2->udev, cinergyt2->phys, sizeof(cinergyt2->phys)); strlcat(cinergyt2->phys, "/input0", sizeof(cinergyt2->phys)); cinergyt2->rc_input_event = KEY_MAX; - cinergyt2->rc_last_code = cpu_to_le32(~0); + cinergyt2->rc_last_code = ~0; INIT_DELAYED_WORK(&cinergyt2->rc_query_work, cinergyt2_query_rc); input_dev->name = DRIVER_NAME " remote control"; @@ -844,8 +840,8 @@ static int cinergyt2_register_rc(struct cinergyt2 *cinergyt2) input_dev->keycodesize = 0; input_dev->keycodemax = 0; input_dev->id.bustype = BUS_USB; - input_dev->id.vendor = le16_to_cpu(cinergyt2->udev->descriptor.idVendor); - input_dev->id.product = le16_to_cpu(cinergyt2->udev->descriptor.idProduct); + input_dev->id.vendor = cinergyt2->udev->descriptor.idVendor; + input_dev->id.product = cinergyt2->udev->descriptor.idProduct; input_dev->id.version = 1; input_dev->dev.parent = &cinergyt2->udev->dev; @@ -893,16 +889,18 @@ static void cinergyt2_query (struct work_struct *work) char cmd [] = { CINERGYT2_EP1_GET_TUNER_STATUS }; struct dvbt_get_status_msg *s = &cinergyt2->status; uint8_t lock_bits; + uint32_t unc; if (cinergyt2->disconnect_pending || mutex_lock_interruptible(&cinergyt2->sem)) return; + unc = s->uncorrected_block_count; lock_bits = s->lock_bits; cinergyt2_command(cinergyt2, cmd, sizeof(cmd), (char *) s, sizeof(*s)); - cinergyt2->uncorrected_block_count += - le32_to_cpu(s->uncorrected_block_count); + unc += le32_to_cpu(s->uncorrected_block_count); + s->uncorrected_block_count = unc; if (lock_bits != s->lock_bits) { wake_up_interruptible(&cinergyt2->poll_wq); diff --git a/trunk/drivers/media/dvb/dvb-core/dvb_net.c b/trunk/drivers/media/dvb/dvb-core/dvb_net.c index c2334aef4143..56d871cfd7fc 100644 --- a/trunk/drivers/media/dvb/dvb-core/dvb_net.c +++ b/trunk/drivers/media/dvb/dvb-core/dvb_net.c @@ -168,7 +168,7 @@ struct dvb_net_priv { * stolen from eth.c out of the linux kernel, hacked for dvb-device * by Michael Holzt */ -static __be16 dvb_net_eth_type_trans(struct sk_buff *skb, +static unsigned short dvb_net_eth_type_trans(struct sk_buff *skb, struct net_device *dev) { struct ethhdr *eth; @@ -277,10 +277,10 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) if(ext_len >= 0) { p->ule_next_hdr += ext_len; if (!p->ule_bridged) { - p->ule_sndu_type = ntohs(*(__be16 *)p->ule_next_hdr); + p->ule_sndu_type = ntohs(*(unsigned short *)p->ule_next_hdr); p->ule_next_hdr += 2; } else { - p->ule_sndu_type = ntohs(*(__be16 *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); + p->ule_sndu_type = ntohs(*(unsigned short *)(p->ule_next_hdr + ((p->ule_dbit ? 2 : 3) * ETH_ALEN))); /* This assures the extension handling loop will terminate. */ } } @@ -294,7 +294,7 @@ static int handle_one_ule_extension( struct dvb_net_priv *p ) if (ule_optional_ext_handlers[htype]) (void)ule_optional_ext_handlers[htype]( p ); p->ule_next_hdr += ext_len; - p->ule_sndu_type = ntohs( *(__be16 *)(p->ule_next_hdr-2) ); + p->ule_sndu_type = ntohs( *(unsigned short *)(p->ule_next_hdr-2) ); /* * note: the length of the next header type is included in the * length of THIS optional extension header @@ -594,8 +594,8 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Check for complete payload. */ if (priv->ule_sndu_remain <= 0) { /* Check CRC32, we've got it in our skb already. */ - __be16 ulen = htons(priv->ule_sndu_len); - __be16 utype = htons(priv->ule_sndu_type); + unsigned short ulen = htons(priv->ule_sndu_len); + unsigned short utype = htons(priv->ule_sndu_type); const u8 *tail; struct kvec iov[3] = { { &ulen, sizeof ulen }, diff --git a/trunk/drivers/media/dvb/dvb-usb/Kconfig b/trunk/drivers/media/dvb/dvb-usb/Kconfig index f00a0eb40420..cf4584e48b6d 100644 --- a/trunk/drivers/media/dvb/dvb-usb/Kconfig +++ b/trunk/drivers/media/dvb/dvb-usb/Kconfig @@ -1,6 +1,6 @@ config DVB_USB tristate "Support for various USB DVB devices" - depends on DVB_CORE && USB && I2C && INPUT + depends on DVB_CORE && USB && I2C depends on HOTPLUG # due to FW_LOADER select FW_LOADER help diff --git a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c index c4d40fe01d57..346223856f59 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/trunk/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -111,8 +111,8 @@ static int bristol_tuner_attach(struct dvb_usb_adapter *adap) struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); s8 a; int if1=1220; - if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && - adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) { + if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && + adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_500_2) { if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a; } return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id], @@ -402,8 +402,8 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) { struct usb_device_descriptor *desc = &adap->dev->udev->descriptor; - if (desc->idVendor == cpu_to_le16(USB_VID_PINNACLE) && - desc->idProduct == cpu_to_le16(USB_PID_PINNACLE_EXPRESSCARD_320CX)) + if (desc->idVendor == USB_VID_PINNACLE && + desc->idProduct == USB_PID_PINNACLE_EXPRESSCARD_320CX) dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); else dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); @@ -845,8 +845,8 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) struct i2c_adapter *tun_i2c; s8 a; int if1=1220; - if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && - adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_STICK)) { + if (adap->dev->udev->descriptor.idVendor == USB_VID_HAUPPAUGE && + adap->dev->udev->descriptor.idProduct == USB_PID_HAUPPAUGE_NOVA_T_STICK) { if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; } if (st->is_dib7000pc) @@ -990,12 +990,11 @@ static struct dib7000p_config dib7070p_dib7000p_config = { /* STK7070P */ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) { - struct usb_device_descriptor *p = &adap->dev->udev->descriptor; - if (p->idVendor == cpu_to_le16(USB_VID_PINNACLE) && - p->idProduct == cpu_to_le16(USB_PID_PINNACLE_PCTV72E)) - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + if (adap->dev->udev->descriptor.idVendor == USB_VID_PINNACLE && + adap->dev->udev->descriptor.idProduct == USB_PID_PINNACLE_PCTV72E) + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); else - dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); msleep(10); dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1); dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1); diff --git a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 733a7ff7b207..e1112e39fb63 100644 --- a/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/trunk/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c @@ -127,7 +127,7 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, if ((*pos + hx->len + 4) >= fw->size) return -EINVAL; - hx->addr = b[1] | (b[2] << 8); + hx->addr = le16_to_cpu( *((u16 *) &b[1]) ); hx->type = b[3]; if (hx->type == 0x04) { diff --git a/trunk/drivers/media/dvb/dvb-usb/gp8psk.c b/trunk/drivers/media/dvb/dvb-usb/gp8psk.c index 2653120673b7..9a942afaf0af 100644 --- a/trunk/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/trunk/drivers/media/dvb/dvb-usb/gp8psk.c @@ -146,24 +146,24 @@ static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff) if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) if (! (status & bm8pskFW_Loaded)) /* BCM4500 firmware loaded */ if(gp8psk_load_bcm4500fw(d)) - return -EINVAL; + return EINVAL; if (! (status & bmIntersilOn)) /* LNB Power */ if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0, &buf, 1)) - return -EINVAL; + return EINVAL; /* Set DVB mode to 1 */ if (gp_product_id == USB_PID_GENPIX_8PSK_REV_1_WARM) if (gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0)) - return -EINVAL; + return EINVAL; /* Abort possible TS (if previous tune crashed) */ if (gp8psk_usb_out_op(d, ARM_TRANSFER, 0, 0, NULL, 0)) - return -EINVAL; + return EINVAL; } else { /* Turn off LNB power */ if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1)) - return -EINVAL; + return EINVAL; /* Turn off 8psk power */ if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1)) return -EINVAL; diff --git a/trunk/drivers/media/dvb/dvb-usb/m920x.c b/trunk/drivers/media/dvb/dvb-usb/m920x.c index 54626a0dbf68..a12e6f784fda 100644 --- a/trunk/drivers/media/dvb/dvb-usb/m920x.c +++ b/trunk/drivers/media/dvb/dvb-usb/m920x.c @@ -16,7 +16,6 @@ #include "qt1010.h" #include "tda1004x.h" #include "tda827x.h" -#include /* debug */ static int dvb_usb_m920x_debug; @@ -348,13 +347,13 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar for (pass = 0; pass < 2; pass++) { for (i = 0; i + (sizeof(u16) * 3) < fw->size;) { - value = get_unaligned_le16(fw->data + i); + value = le16_to_cpu(*(u16 *)(fw->data + i)); i += sizeof(u16); - index = get_unaligned_le16(fw->data + i); + index = le16_to_cpu(*(u16 *)(fw->data + i)); i += sizeof(u16); - size = get_unaligned_le16(fw->data + i); + size = le16_to_cpu(*(u16 *)(fw->data + i)); i += sizeof(u16); if (pass == 1) { diff --git a/trunk/drivers/media/dvb/frontends/dib0070.h b/trunk/drivers/media/dvb/frontends/dib0070.h index 3eedfdf505bc..786e37d33889 100644 --- a/trunk/drivers/media/dvb/frontends/dib0070.h +++ b/trunk/drivers/media/dvb/frontends/dib0070.h @@ -37,20 +37,7 @@ struct dib0070_config { u8 flip_chip; }; -#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg); -#else -static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, - struct i2c_adapter *i2c, - struct dib0070_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - +extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg); extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open); extern u16 dib0070_wbd_offset(struct dvb_frontend *); diff --git a/trunk/drivers/media/dvb/frontends/dib7000p.h b/trunk/drivers/media/dvb/frontends/dib7000p.h index 07c4d12ed5b7..081bd81f3da2 100644 --- a/trunk/drivers/media/dvb/frontends/dib7000p.h +++ b/trunk/drivers/media/dvb/frontends/dib7000p.h @@ -37,20 +37,7 @@ struct dib7000p_config { #define DEFAULT_DIB7000P_I2C_ADDRESS 18 -#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE)) -extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000p_config *cfg); -#else -static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, - u8 i2c_addr, - struct dib7000p_config *cfg) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif - +extern struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg); extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]); extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int); diff --git a/trunk/drivers/media/dvb/frontends/or51132.c b/trunk/drivers/media/dvb/frontends/or51132.c index 5ed32544de39..c7b5785f81f2 100644 --- a/trunk/drivers/media/dvb/frontends/or51132.c +++ b/trunk/drivers/media/dvb/frontends/or51132.c @@ -126,7 +126,7 @@ static int or51132_readreg(struct or51132_state *state, u8 reg) reg, err); return -EREMOTEIO; } - return buf[0] | (buf[1] << 8); + return le16_to_cpup((u16*)buf); } static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) @@ -140,9 +140,9 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware dprintk("Firmware is %Zd bytes\n",fw->size); /* Get size of firmware A and B */ - firmwareAsize = le32_to_cpu(*((__le32*)fw->data)); + firmwareAsize = le32_to_cpu(*((u32*)fw->data)); dprintk("FirmwareA is %i bytes\n",firmwareAsize); - firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4))); + firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4))); dprintk("FirmwareB is %i bytes\n",firmwareBsize); /* Upload firmware */ diff --git a/trunk/drivers/media/dvb/ttpci/av7110.c b/trunk/drivers/media/dvb/ttpci/av7110.c index f05d43d8b5cf..747e7f1a6267 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110.c +++ b/trunk/drivers/media/dvb/ttpci/av7110.c @@ -51,7 +51,6 @@ #include #include #include -#include #include @@ -1462,9 +1461,9 @@ static int check_firmware(struct av7110* av7110) ptr += 4; /* check dpram file */ - crc = get_unaligned_be32(ptr); + crc = ntohl(*(u32*) ptr); ptr += 4; - len = get_unaligned_be32(ptr); + len = ntohl(*(u32*) ptr); ptr += 4; if (len >= 512) { printk("dvb-ttpci: dpram file is way too big.\n"); @@ -1479,9 +1478,9 @@ static int check_firmware(struct av7110* av7110) ptr += len; /* check root file */ - crc = get_unaligned_be32(ptr); + crc = ntohl(*(u32*) ptr); ptr += 4; - len = get_unaligned_be32(ptr); + len = ntohl(*(u32*) ptr); ptr += 4; if (len <= 200000 || len >= 300000 || diff --git a/trunk/drivers/media/dvb/ttpci/av7110_av.c b/trunk/drivers/media/dvb/ttpci/av7110_av.c index ec55a968f204..3e6b650fbb81 100644 --- a/trunk/drivers/media/dvb/ttpci/av7110_av.c +++ b/trunk/drivers/media/dvb/ttpci/av7110_av.c @@ -965,9 +965,8 @@ static u8 iframe_header[] = { 0x00, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len, int nonblock) { - unsigned i, n; + int i, n; int progressive = 0; - int match = 0; dprintk(2, "av7110:%p, \n", av7110); @@ -976,31 +975,12 @@ static int play_iframe(struct av7110 *av7110, char __user *buf, unsigned int len return -EBUSY; } - /* search in buf for instances of 00 00 01 b5 1? */ - for (i = 0; i < len; i++) { - unsigned char c; - if (get_user(c, buf + i)) - return -EFAULT; - if (match == 5) { - progressive = c & 0x08; - match = 0; - } - if (c == 0x00) { - match = (match == 1 || match == 2) ? 2 : 1; - continue; - } - switch (match++) { - case 2: if (c == 0x01) - continue; - break; - case 3: if (c == 0xb5) - continue; - break; - case 4: if ((c & 0xf0) == 0x10) - continue; - break; - } - match = 0; + for (i = 0; i < len - 5; i++) { + /* get progressive flag from picture extension */ + if (buf[i] == 0x00 && buf[i+1] == 0x00 && + buf[i+2] == 0x01 && (unsigned char)buf[i+3] == 0xb5 && + (buf[i+4] & 0xf0) == 0x10) + progressive = buf[i+5] & 0x08; } /* setting n always > 1, fixes problems when playing stillframes diff --git a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 5d2d81ab2371..732ce4de512e 100644 --- a/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/trunk/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c @@ -552,7 +552,7 @@ static void ttusb_process_muxpack(struct ttusb *ttusb, const u8 * muxpack, u16 csum = 0, cc; int i; for (i = 0; i < len; i += 2) - csum ^= le16_to_cpup((__le16 *) (muxpack + i)); + csum ^= le16_to_cpup((u16 *) (muxpack + i)); if (csum) { printk("%s: muxpack with incorrect checksum, ignoring\n", __func__); diff --git a/trunk/drivers/media/dvb/ttusb-dec/Kconfig b/trunk/drivers/media/dvb/ttusb-dec/Kconfig index a23cc0aa17d3..0712899e39a4 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/Kconfig +++ b/trunk/drivers/media/dvb/ttusb-dec/Kconfig @@ -1,6 +1,6 @@ config DVB_TTUSB_DEC tristate "Technotrend/Hauppauge USB DEC devices" - depends on DVB_CORE && USB && INPUT + depends on DVB_CORE && USB depends on HOTPLUG # due to FW_LOADER select FW_LOADER select CRC32 diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c index fefdc05e84ac..42eee04daa5d 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusb_dec.c @@ -343,7 +343,7 @@ static int ttusb_dec_get_stb_state (struct ttusb_dec *dec, unsigned int *mode, u8 c[COMMAND_PACKET_SIZE]; int c_length; int result; - __be32 tmp; + unsigned int tmp; dprintk("%s\n", __func__); @@ -398,9 +398,9 @@ static void ttusb_dec_set_pids(struct ttusb_dec *dec) 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - __be16 pcr = htons(dec->pid[DMX_PES_PCR]); - __be16 audio = htons(dec->pid[DMX_PES_AUDIO]); - __be16 video = htons(dec->pid[DMX_PES_VIDEO]); + u16 pcr = htons(dec->pid[DMX_PES_PCR]); + u16 audio = htons(dec->pid[DMX_PES_AUDIO]); + u16 video = htons(dec->pid[DMX_PES_VIDEO]); dprintk("%s\n", __func__); @@ -435,7 +435,7 @@ static void ttusb_dec_process_pva(struct ttusb_dec *dec, u8 *pva, int length) case 0x01: { /* VideoStream */ int prebytes = pva[5] & 0x03; int postbytes = (pva[5] & 0x0c) >> 2; - __be16 v_pes_payload_length; + u16 v_pes_payload_length; if (output_pva) { dec->video_filter->feed->cb.ts(pva, length, NULL, 0, @@ -1006,7 +1006,7 @@ static int ttusb_dec_start_sec_feed(struct dvb_demux_feed *dvbdmxfeed) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - __be16 pid; + u16 pid; u8 c[COMMAND_PACKET_SIZE]; int c_length; int result; @@ -1278,10 +1278,9 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) u8 *firmware = NULL; size_t firmware_size = 0; u16 firmware_csum = 0; - __be16 firmware_csum_ns; - __be32 firmware_size_nl; - u32 crc32_csum, crc32_check; - __be32 tmp; + u16 firmware_csum_ns; + u32 firmware_size_nl; + u32 crc32_csum, crc32_check, tmp; const struct firmware *fw_entry = NULL; dprintk("%s\n", __func__); @@ -1307,7 +1306,7 @@ static int ttusb_dec_boot_dsp(struct ttusb_dec *dec) valid. */ crc32_csum = crc32(~0L, firmware, 56) ^ ~0L; memcpy(&tmp, &firmware[56], 4); - crc32_check = ntohl(tmp); + crc32_check = htonl(tmp); if (crc32_csum != crc32_check) { printk("%s: crc32 check of DSP code failed (calculated " "0x%08x != 0x%08x in file), file invalid.\n", @@ -1628,7 +1627,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, usb_set_intfdata(intf, (void *)dec); - switch (id->idProduct) { + switch (le16_to_cpu(id->idProduct)) { case 0x1006: ttusb_dec_set_model(dec, TTUSB_DEC3000S); break; @@ -1653,7 +1652,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, ttusb_dec_init_dvb(dec); dec->adapter.priv = dec; - switch (id->idProduct) { + switch (le16_to_cpu(id->idProduct)) { case 0x1006: dec->fe = ttusbdecfe_dvbs_attach(&fe_config); break; diff --git a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 443af24097f3..eb5eaeccd7c4 100644 --- a/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/trunk/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -86,7 +86,7 @@ static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_fron 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff }; - __be32 freq = htonl(p->frequency / 1000); + u32 freq = htonl(p->frequency / 1000); memcpy(&b[4], &freq, sizeof (u32)); state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); @@ -117,10 +117,10 @@ static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_fron 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - __be32 freq; - __be32 sym_rate; - __be32 band; - __be32 lnb_voltage; + u32 freq; + u32 sym_rate; + u32 band; + u32 lnb_voltage; freq = htonl(p->frequency + (state->hi_band ? LOF_HI : LOF_LO)); diff --git a/trunk/drivers/media/video/au0828/Kconfig b/trunk/drivers/media/video/au0828/Kconfig index 52b2491581a8..def10d086373 100644 --- a/trunk/drivers/media/video/au0828/Kconfig +++ b/trunk/drivers/media/video/au0828/Kconfig @@ -1,7 +1,7 @@ config VIDEO_AU0828 tristate "Auvitek AU0828 support" - depends on I2C && INPUT && DVB_CORE && USB + depends on VIDEO_DEV && I2C && INPUT && DVB_CORE && USB select I2C_ALGOBIT select VIDEO_TVEEPROM select DVB_AU8522 if !DVB_FE_CUSTOMIZE diff --git a/trunk/drivers/media/video/au0828/au0828-dvb.c b/trunk/drivers/media/video/au0828/au0828-dvb.c index c6d470590380..c86a5f17eca8 100644 --- a/trunk/drivers/media/video/au0828/au0828-dvb.c +++ b/trunk/drivers/media/video/au0828/au0828-dvb.c @@ -353,6 +353,12 @@ int au0828_dvb_register(struct au0828_dev *dev) return -1; } + /* Put the analog decoder in standby to keep it quiet */ + au0828_call_i2c_clients(dev, TUNER_SET_STANDBY, NULL); + + if (dvb->frontend->ops.analog_ops.standby) + dvb->frontend->ops.analog_ops.standby(dvb->frontend); + /* register everything */ ret = dvb_register(dev); if (ret < 0) { diff --git a/trunk/drivers/media/video/bt8xx/bttv-cards.c b/trunk/drivers/media/video/bt8xx/bttv-cards.c index 8ef0424c26c4..f20a01cfc73e 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-cards.c +++ b/trunk/drivers/media/video/bt8xx/bttv-cards.c @@ -34,7 +34,6 @@ #include #include -#include #include #include "bttvp.h" @@ -3859,7 +3858,7 @@ static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) ee += i; /* found a valid descriptor */ - type = get_unaligned_be16((__be16 *)(ee+4)); + type = be16_to_cpup((u16*)(ee+4)); switch(type) { /* 848 based */ @@ -3919,7 +3918,7 @@ static void __devinit osprey_eeprom(struct bttv *btv, const u8 ee[256]) btv->c.nr, type); break; } - serial = get_unaligned_be32((__be32 *)(ee+6)); + serial = be32_to_cpup((u32*)(ee+6)); } printk(KERN_INFO "bttv%d: osprey eeprom: card=%d '%s' serial=%u\n", diff --git a/trunk/drivers/media/video/bt8xx/bttv-risc.c b/trunk/drivers/media/video/bt8xx/bttv-risc.c index 0af586876e72..e5979f77504c 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-risc.c +++ b/trunk/drivers/media/video/bt8xx/bttv-risc.c @@ -48,7 +48,7 @@ bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, { u32 instructions,line,todo; struct scatterlist *sg; - __le32 *rp; + u32 *rp; int rc; /* estimate risc mem: worst case is one write per page border + @@ -128,8 +128,7 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, unsigned int cpadding) { unsigned int instructions,line,todo,ylen,chroma; - __le32 *rp; - u32 ri; + u32 *rp,ri; struct scatterlist *ysg; struct scatterlist *usg; struct scatterlist *vsg; @@ -245,8 +244,7 @@ bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, { int dwords,rc,line,maxy,start,end,skip,nskips; struct btcx_skiplist *skips; - __le32 *rp; - u32 ri,ra; + u32 *rp,ri,ra; u32 addr; /* skip list for window clipping */ diff --git a/trunk/drivers/media/video/btcx-risc.c b/trunk/drivers/media/video/btcx-risc.c index f42701f82e7f..ce0840ccd594 100644 --- a/trunk/drivers/media/video/btcx-risc.c +++ b/trunk/drivers/media/video/btcx-risc.c @@ -63,7 +63,7 @@ int btcx_riscmem_alloc(struct pci_dev *pci, struct btcx_riscmem *risc, unsigned int size) { - __le32 *cpu; + u32 *cpu; dma_addr_t dma; if (NULL != risc->cpu && risc->size < size) diff --git a/trunk/drivers/media/video/btcx-risc.h b/trunk/drivers/media/video/btcx-risc.h index 861bc8112824..503e6c6d7b69 100644 --- a/trunk/drivers/media/video/btcx-risc.h +++ b/trunk/drivers/media/video/btcx-risc.h @@ -2,8 +2,8 @@ */ struct btcx_riscmem { unsigned int size; - __le32 *cpu; - __le32 *jmp; + u32 *cpu; + u32 *jmp; dma_addr_t dma; }; diff --git a/trunk/drivers/media/video/cx18/cx18-av-core.c b/trunk/drivers/media/video/cx18/cx18-av-core.c index 9a26751615c6..66864904c99b 100644 --- a/trunk/drivers/media/video/cx18/cx18-av-core.c +++ b/trunk/drivers/media/video/cx18/cx18-av-core.c @@ -182,16 +182,14 @@ static void input_change(struct cx18 *cx) if (std == V4L2_STD_NTSC_M_JP) { /* Japan uses EIAJ audio standard */ cx18_av_write(cx, 0x808, 0xf7); - cx18_av_write(cx, 0x80b, 0x02); } else if (std == V4L2_STD_NTSC_M_KR) { /* South Korea uses A2 audio standard */ cx18_av_write(cx, 0x808, 0xf8); - cx18_av_write(cx, 0x80b, 0x03); } else { /* Others use the BTSC audio standard */ cx18_av_write(cx, 0x808, 0xf6); - cx18_av_write(cx, 0x80b, 0x01); } + cx18_av_write(cx, 0x80b, 0x00); } else if (std & V4L2_STD_PAL) { /* Follow tuner change procedure for PAL */ cx18_av_write(cx, 0x808, 0xff); @@ -743,8 +741,8 @@ static void log_audio_status(struct cx18 *cx) { struct cx18_av_state *state = &cx->av_state; u8 download_ctl = cx18_av_read(cx, 0x803); - u8 mod_det_stat0 = cx18_av_read(cx, 0x804); - u8 mod_det_stat1 = cx18_av_read(cx, 0x805); + u8 mod_det_stat0 = cx18_av_read(cx, 0x805); + u8 mod_det_stat1 = cx18_av_read(cx, 0x804); u8 audio_config = cx18_av_read(cx, 0x808); u8 pref_mode = cx18_av_read(cx, 0x809); u8 afc0 = cx18_av_read(cx, 0x80b); @@ -762,12 +760,12 @@ static void log_audio_status(struct cx18 *cx) case 0x12: p = "dual with SAP"; break; case 0x14: p = "tri with SAP"; break; case 0xfe: p = "forced mode"; break; - default: p = "not defined"; break; + default: p = "not defined"; } CX18_INFO("Detected audio mode: %s\n", p); switch (mod_det_stat1) { - case 0x00: p = "not defined"; break; + case 0x00: p = "BTSC"; break; case 0x01: p = "EIAJ"; break; case 0x02: p = "A2-M"; break; case 0x03: p = "A2-BG"; break; @@ -781,13 +779,8 @@ static void log_audio_status(struct cx18 *cx) case 0x0b: p = "NICAM-I"; break; case 0x0c: p = "NICAM-L"; break; case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; - case 0x0e: p = "IF FM Radio"; break; - case 0x0f: p = "BTSC"; break; - case 0x10: p = "detected chrominance"; break; - case 0xfd: p = "unknown audio standard"; break; - case 0xfe: p = "forced audio standard"; break; case 0xff: p = "no detected audio standard"; break; - default: p = "not defined"; break; + default: p = "not defined"; } CX18_INFO("Detected audio standard: %s\n", p); CX18_INFO("Audio muted: %s\n", @@ -796,23 +789,22 @@ static void log_audio_status(struct cx18 *cx) (download_ctl & 0x10) ? "running" : "stopped"); switch (audio_config >> 4) { - case 0x00: p = "undefined"; break; - case 0x01: p = "BTSC"; break; - case 0x02: p = "EIAJ"; break; - case 0x03: p = "A2-M"; break; - case 0x04: p = "A2-BG"; break; - case 0x05: p = "A2-DK1"; break; - case 0x06: p = "A2-DK2"; break; - case 0x07: p = "A2-DK3"; break; - case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; - case 0x09: p = "AM-L"; break; - case 0x0a: p = "NICAM-BG"; break; - case 0x0b: p = "NICAM-DK"; break; - case 0x0c: p = "NICAM-I"; break; - case 0x0d: p = "NICAM-L"; break; - case 0x0e: p = "FM radio"; break; + case 0x00: p = "BTSC"; break; + case 0x01: p = "EIAJ"; break; + case 0x02: p = "A2-M"; break; + case 0x03: p = "A2-BG"; break; + case 0x04: p = "A2-DK1"; break; + case 0x05: p = "A2-DK2"; break; + case 0x06: p = "A2-DK3"; break; + case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; + case 0x08: p = "AM-L"; break; + case 0x09: p = "NICAM-BG"; break; + case 0x0a: p = "NICAM-DK"; break; + case 0x0b: p = "NICAM-I"; break; + case 0x0c: p = "NICAM-L"; break; + case 0x0d: p = "FM radio"; break; case 0x0f: p = "automatic detection"; break; - default: p = "undefined"; break; + default: p = "undefined"; } CX18_INFO("Configured audio standard: %s\n", p); @@ -823,9 +815,12 @@ static void log_audio_status(struct cx18 *cx) case 0x02: p = "MONO3 (STEREO forced MONO)"; break; case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; case 0x04: p = "STEREO"; break; - case 0x05: p = "DUAL1 (AC)"; break; - case 0x06: p = "DUAL2 (BC)"; break; - case 0x07: p = "DUAL3 (AB)"; break; + case 0x05: p = "DUAL1 (AB)"; break; + case 0x06: p = "DUAL2 (AC) (FM)"; break; + case 0x07: p = "DUAL3 (BC) (FM)"; break; + case 0x08: p = "DUAL4 (AC) (AM)"; break; + case 0x09: p = "DUAL5 (BC) (AM)"; break; + case 0x0a: p = "SAP"; break; default: p = "undefined"; } CX18_INFO("Configured audio mode: %s\n", p); @@ -840,11 +835,9 @@ static void log_audio_status(struct cx18 *cx) case 0x06: p = "BTSC"; break; case 0x07: p = "EIAJ"; break; case 0x08: p = "A2-M"; break; - case 0x09: p = "FM Radio (4.5 MHz)"; break; - case 0x0a: p = "FM Radio (5.5 MHz)"; break; - case 0x0b: p = "S-Video"; break; + case 0x09: p = "FM Radio"; break; case 0x0f: p = "automatic standard and mode detection"; break; - default: p = "undefined"; break; + default: p = "undefined"; } CX18_INFO("Configured audio system: %s\n", p); } @@ -864,24 +857,22 @@ static void log_audio_status(struct cx18 *cx) case 5: p = "language AC"; break; case 6: p = "language BC"; break; case 7: p = "language AB"; break; - default: p = "undefined"; break; + default: p = "undefined"; } CX18_INFO("Preferred audio mode: %s\n", p); if ((audio_config & 0xf) == 0xf) { - switch ((afc0 >> 3) & 0x1) { + switch ((afc0 >> 2) & 0x1) { case 0: p = "system DK"; break; case 1: p = "system L"; break; } CX18_INFO("Selected 65 MHz format: %s\n", p); - switch (afc0 & 0x7) { - case 0: p = "Chroma"; break; - case 1: p = "BTSC"; break; - case 2: p = "EIAJ"; break; - case 3: p = "A2-M"; break; - case 4: p = "autodetect"; break; - default: p = "undefined"; break; + switch (afc0 & 0x3) { + case 0: p = "BTSC"; break; + case 1: p = "EIAJ"; break; + case 2: p = "A2-M"; break; + default: p = "undefined"; } CX18_INFO("Selected 45 MHz format: %s\n", p); } diff --git a/trunk/drivers/media/video/cx18/cx18-cards.c b/trunk/drivers/media/video/cx18/cx18-cards.c index baccd079243d..553adbf2cd44 100644 --- a/trunk/drivers/media/video/cx18/cx18-cards.c +++ b/trunk/drivers/media/video/cx18/cx18-cards.c @@ -126,7 +126,7 @@ static const struct cx18_card cx18_card_hvr1600_samsung = { /* ------------------------------------------------------------------------- */ -/* Compro VideoMate H900: note that this card is analog only! */ +/* Compro VideoMate H900: not working at the moment! */ static const struct cx18_card_pci_info cx18_pci_h900[] = { { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, @@ -136,7 +136,7 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = { static const struct cx18_card cx18_card_h900 = { .type = CX18_CARD_COMPRO_H900, .name = "Compro VideoMate H900", - .comment = "VBI is not yet supported\n", + .comment = "DVB & VBI are not yet supported\n", .v4l2_capabilities = CX18_CAP_ENCODER, .hw_audio_ctrl = CX18_HW_CX23418, .hw_all = CX18_HW_TUNER, diff --git a/trunk/drivers/media/video/cx18/cx18-controls.c b/trunk/drivers/media/video/cx18/cx18-controls.c index 87cf41021665..2bdac5ebbb0d 100644 --- a/trunk/drivers/media/video/cx18/cx18-controls.c +++ b/trunk/drivers/media/video/cx18/cx18-controls.c @@ -159,7 +159,7 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt { if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) return -EINVAL; - if (atomic_read(&cx->ana_capturing) > 0) + if (atomic_read(&cx->capturing) > 0) return -EBUSY; /* First try to allocate sliced VBI buffers if needed. */ @@ -235,7 +235,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg) CX18_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { struct cx2341x_mpeg_params p = cx->params; - int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), arg, cmd); + int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->capturing), arg, cmd); if (err) return err; @@ -295,7 +295,7 @@ int cx18_control_ioctls(struct cx18 *cx, unsigned int cmd, void *arg) CX18_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) return cx2341x_ext_ctrls(&cx->params, - atomic_read(&cx->ana_capturing), arg, cmd); + atomic_read(&cx->capturing), arg, cmd); return -EINVAL; } diff --git a/trunk/drivers/media/video/cx18/cx18-driver.c b/trunk/drivers/media/video/cx18/cx18-driver.c index 2b810bb2a4c7..0dd4e0529970 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.c +++ b/trunk/drivers/media/video/cx18/cx18-driver.c @@ -670,7 +670,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, cx18_init_power(cx, 1); cx18_init_memory(cx); - cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); + cx->scb = (struct cx18_scb *)(cx->enc_mem + SCB_OFFSET); cx18_init_scb(cx); cx18_gpio_init(cx); @@ -751,6 +751,17 @@ static int __devinit cx18_probe(struct pci_dev *dev, if (cx->options.radio > 0) cx->v4l2_cap |= V4L2_CAP_RADIO; + retval = cx18_streams_setup(cx); + if (retval) { + CX18_ERR("Error %d setting up streams\n", retval); + goto free_irq; + } + retval = cx18_streams_register(cx); + if (retval) { + CX18_ERR("Error %d registering devices\n", retval); + goto free_streams; + } + if (cx->options.tuner > -1) { struct tuner_setup setup; @@ -777,16 +788,7 @@ static int __devinit cx18_probe(struct pci_dev *dev, are not. */ cx->tuner_std = cx->std; - retval = cx18_streams_setup(cx); - if (retval) { - CX18_ERR("Error %d setting up streams\n", retval); - goto free_irq; - } - retval = cx18_streams_register(cx); - if (retval) { - CX18_ERR("Error %d registering devices\n", retval); - goto free_streams; - } + cx18_init_on_first_open(cx); CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); @@ -887,7 +889,7 @@ static void cx18_remove(struct pci_dev *pci_dev) /* Stop all captures */ CX18_DEBUG_INFO("Stopping all streams\n"); - if (atomic_read(&cx->tot_capturing) > 0) + if (atomic_read(&cx->capturing) > 0) cx18_stop_all_captures(cx); /* Interrupts */ diff --git a/trunk/drivers/media/video/cx18/cx18-driver.h b/trunk/drivers/media/video/cx18/cx18-driver.h index de14ab59a206..a2a6c58d12fe 100644 --- a/trunk/drivers/media/video/cx18/cx18-driver.h +++ b/trunk/drivers/media/video/cx18/cx18-driver.h @@ -358,7 +358,7 @@ struct cx18 { u32 v4l2_cap; /* V4L2 capabilities of card */ u32 hw_flags; /* Hardware description of the board */ unsigned mdl_offset; - struct cx18_scb __iomem *scb; /* pointer to SCB */ + struct cx18_scb *scb; /* pointer to SCB */ struct cx18_av_state av_state; @@ -380,8 +380,7 @@ struct cx18 { int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ unsigned long i_flags; /* global cx18 flags */ - atomic_t ana_capturing; /* count number of active analog capture streams */ - atomic_t tot_capturing; /* total count number of active capture streams */ + atomic_t capturing; /* count number of active capture streams */ spinlock_t lock; /* lock access to this struct */ int search_pack_header; @@ -424,10 +423,6 @@ struct cx18 { struct mutex i2c_bus_lock[2]; struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; - /* gpio */ - u32 gpio_dir; - u32 gpio_val; - /* v4l2 and User settings */ /* codec settings */ diff --git a/trunk/drivers/media/video/cx18/cx18-fileops.c b/trunk/drivers/media/video/cx18/cx18-fileops.c index 1e537fe04a23..0b3141db174b 100644 --- a/trunk/drivers/media/video/cx18/cx18-fileops.c +++ b/trunk/drivers/media/video/cx18/cx18-fileops.c @@ -318,7 +318,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, size_t tot_written = 0; int single_frame = 0; - if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) { + if (atomic_read(&cx->capturing) == 0 && s->id == -1) { /* shouldn't happen */ CX18_DEBUG_WARN("Stream %s not initialized before read\n", s->name); @@ -361,8 +361,7 @@ static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, cx18_enqueue(s, buf, &s->q_free); cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *)&cx->scb->cpu_mdl[buf->id] - - cx->enc_mem, + (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, buf->id, s->buf_size); } else cx18_enqueue(s, buf, &s->q_io); @@ -582,7 +581,7 @@ int cx18_v4l2_close(struct inode *inode, struct file *filp) cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); /* Select correct audio input (i.e. TV tuner or Line in) */ cx18_audio_set_io(cx); - if (atomic_read(&cx->ana_capturing) > 0) { + if (atomic_read(&cx->capturing) > 0) { /* Undo video mute */ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, cx->params.video_mute | @@ -628,7 +627,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) } if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { - if (atomic_read(&cx->ana_capturing) > 0) { + if (atomic_read(&cx->capturing) > 0) { /* switching to radio while capture is in progress is not polite */ cx18_release_stream(s); @@ -695,7 +694,7 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) void cx18_mute(struct cx18 *cx) { - if (atomic_read(&cx->ana_capturing)) + if (atomic_read(&cx->capturing)) cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, cx18_find_handle(cx), 1); CX18_DEBUG_INFO("Mute\n"); @@ -703,7 +702,7 @@ void cx18_mute(struct cx18 *cx) void cx18_unmute(struct cx18 *cx) { - if (atomic_read(&cx->ana_capturing)) { + if (atomic_read(&cx->capturing)) { cx18_msleep_timeout(100, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, cx18_find_handle(cx), 12); diff --git a/trunk/drivers/media/video/cx18/cx18-gpio.c b/trunk/drivers/media/video/cx18/cx18-gpio.c index ceb63653c926..bb8bc86086d0 100644 --- a/trunk/drivers/media/video/cx18/cx18-gpio.c +++ b/trunk/drivers/media/video/cx18/cx18-gpio.c @@ -35,6 +35,9 @@ #define CX18_REG_GPIO_OUT2 0xc78104 #define CX18_REG_GPIO_DIR2 0xc7810c +static u32 gpio_dir; +static u32 gpio_val; + /* * HVR-1600 GPIO pins, courtesy of Hauppauge: * @@ -46,30 +49,25 @@ static void gpio_write(struct cx18 *cx) { - u32 dir = cx->gpio_dir; - u32 val = cx->gpio_val; - - write_reg((dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); - write_reg(((dir & 0xffff) << 16) | (val & 0xffff), + write_reg((gpio_dir & 0xffff) << 16, CX18_REG_GPIO_DIR1); + write_reg(((gpio_dir & 0xffff) << 16) | (gpio_val & 0xffff), CX18_REG_GPIO_OUT1); - write_reg(dir & 0xffff0000, CX18_REG_GPIO_DIR2); - write_reg((dir & 0xffff0000) | ((val & 0xffff0000) >> 16), + write_reg(gpio_dir & 0xffff0000, CX18_REG_GPIO_DIR2); + write_reg((gpio_dir & 0xffff0000) | ((gpio_val & 0xffff0000) >> 16), CX18_REG_GPIO_OUT2); } void cx18_gpio_init(struct cx18 *cx) { - cx->gpio_dir = cx->card->gpio_init.direction; - cx->gpio_val = cx->card->gpio_init.initial_value; + gpio_dir = cx->card->gpio_init.direction; + gpio_val = cx->card->gpio_init.initial_value; - if (cx->card->tuners[0].tuner == TUNER_XC2028) { - cx->gpio_dir |= 1 << cx->card->xceive_pin; - cx->gpio_val |= 1 << cx->card->xceive_pin; - } - - if (cx->gpio_dir == 0) + if (gpio_dir == 0) return; + gpio_dir |= 1 << cx->card->xceive_pin; + gpio_val |= 1 << cx->card->xceive_pin; + CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", read_reg(CX18_REG_GPIO_DIR1), read_reg(CX18_REG_GPIO_DIR2), read_reg(CX18_REG_GPIO_OUT1), read_reg(CX18_REG_GPIO_OUT2)); @@ -88,12 +86,13 @@ int cx18_reset_tuner_gpio(void *dev, int cmd, int value) return 0; CX18_DEBUG_INFO("Resetting tuner\n"); - cx->gpio_val &= ~(1 << cx->card->xceive_pin); + gpio_dir |= 1 << cx->card->xceive_pin; + gpio_val &= ~(1 << cx->card->xceive_pin); gpio_write(cx); schedule_timeout_interruptible(msecs_to_jiffies(1)); - cx->gpio_val |= 1 << cx->card->xceive_pin; + gpio_val |= 1 << cx->card->xceive_pin; gpio_write(cx); schedule_timeout_interruptible(msecs_to_jiffies(1)); return 0; diff --git a/trunk/drivers/media/video/cx18/cx18-ioctl.c b/trunk/drivers/media/video/cx18/cx18-ioctl.c index 4151f1e5493f..dbdcb86ec5aa 100644 --- a/trunk/drivers/media/video/cx18/cx18-ioctl.c +++ b/trunk/drivers/media/video/cx18/cx18-ioctl.c @@ -247,7 +247,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, if (!set_fmt || (cx->params.width == w && cx->params.height == h)) return 0; - if (atomic_read(&cx->ana_capturing) > 0) + if (atomic_read(&cx->capturing) > 0) return -EBUSY; cx->params.width = w; @@ -264,7 +264,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { if (set_fmt && streamtype == CX18_ENC_STREAM_TYPE_VBI && cx->vbi.sliced_in->service_set && - atomic_read(&cx->ana_capturing) > 0) + atomic_read(&cx->capturing) > 0) return -EBUSY; if (set_fmt) { cx->vbi.sliced_in->service_set = 0; @@ -293,7 +293,7 @@ static int cx18_try_or_set_fmt(struct cx18 *cx, int streamtype, return 0; if (set == 0) return -EINVAL; - if (atomic_read(&cx->ana_capturing) > 0 && cx->vbi.sliced_in->service_set == 0) + if (atomic_read(&cx->capturing) > 0 && cx->vbi.sliced_in->service_set == 0) return -EBUSY; cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in)); @@ -581,7 +581,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg break; if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || - atomic_read(&cx->ana_capturing) > 0) { + atomic_read(&cx->capturing) > 0) { /* Switching standard would turn off the radio or mess with already running streams, prevent that by returning EBUSY. */ @@ -677,7 +677,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg enc->flags = 0; if (try) return 0; - if (!atomic_read(&cx->ana_capturing)) + if (!atomic_read(&cx->capturing)) return -EPERM; if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; @@ -689,7 +689,7 @@ int cx18_v4l2_ioctls(struct cx18 *cx, struct file *filp, unsigned cmd, void *arg enc->flags = 0; if (try) return 0; - if (!atomic_read(&cx->ana_capturing)) + if (!atomic_read(&cx->capturing)) return -EPERM; if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) return 0; diff --git a/trunk/drivers/media/video/cx18/cx18-irq.c b/trunk/drivers/media/video/cx18/cx18-irq.c index 25114a5cbd57..6e14f8bda559 100644 --- a/trunk/drivers/media/video/cx18/cx18-irq.c +++ b/trunk/drivers/media/video/cx18/cx18-irq.c @@ -75,7 +75,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) cx18_buf_sync_for_device(s, buf); cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, + (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, buf->id, s->buf_size); } else set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); @@ -161,15 +161,13 @@ irqreturn_t cx18_irq_handler(int irq, void *dev_id) */ if (sw2) { - if (sw2 & (readl(&cx->scb->cpu2hpu_irq_ack) | - readl(&cx->scb->cpu2epu_irq_ack))) + if (sw2 & (cx->scb->cpu2hpu_irq_ack | cx->scb->cpu2epu_irq_ack)) wake_up(&cx->mb_cpu_waitq); - if (sw2 & (readl(&cx->scb->apu2hpu_irq_ack) | - readl(&cx->scb->apu2epu_irq_ack))) + if (sw2 & (cx->scb->apu2hpu_irq_ack | cx->scb->apu2epu_irq_ack)) wake_up(&cx->mb_apu_waitq); - if (sw2 & readl(&cx->scb->epu2hpu_irq_ack)) + if (sw2 & cx->scb->epu2hpu_irq_ack) wake_up(&cx->mb_epu_waitq); - if (sw2 & readl(&cx->scb->hpu2epu_irq_ack)) + if (sw2 & cx->scb->hpu2epu_irq_ack) wake_up(&cx->mb_hpu_waitq); } diff --git a/trunk/drivers/media/video/cx18/cx18-mailbox.c b/trunk/drivers/media/video/cx18/cx18-mailbox.c index 2a5ccef9185b..0c5f328bca54 100644 --- a/trunk/drivers/media/video/cx18/cx18-mailbox.c +++ b/trunk/drivers/media/video/cx18/cx18-mailbox.c @@ -94,10 +94,10 @@ static const struct cx18_api_info *find_api_info(u32 cmd) return NULL; } -static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu, +static struct cx18_mailbox *cx18_mb_is_complete(struct cx18 *cx, int rpu, u32 *state, u32 *irq, u32 *req) { - struct cx18_mailbox __iomem *mb = NULL; + struct cx18_mailbox *mb = NULL; int wait_count = 0; u32 ack; @@ -142,7 +142,7 @@ static struct cx18_mailbox __iomem *cx18_mb_is_complete(struct cx18 *cx, int rpu long cx18_mb_ack(struct cx18 *cx, const struct cx18_mailbox *mb) { const struct cx18_api_info *info = find_api_info(mb->cmd); - struct cx18_mailbox __iomem *ack_mb; + struct cx18_mailbox *ack_mb; u32 ack_irq; u8 rpu = CPU; @@ -182,7 +182,7 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) { const struct cx18_api_info *info = find_api_info(cmd); u32 state = 0, irq = 0, req, oldreq, err; - struct cx18_mailbox __iomem *mb; + struct cx18_mailbox *mb; wait_queue_head_t *waitq; int timeout = 100; int cnt = 0; diff --git a/trunk/drivers/media/video/cx18/cx18-streams.c b/trunk/drivers/media/video/cx18/cx18-streams.c index 1b921a336092..4ca9d847f1b1 100644 --- a/trunk/drivers/media/video/cx18/cx18-streams.c +++ b/trunk/drivers/media/video/cx18/cx18-streams.c @@ -36,13 +36,12 @@ #define CX18_DSP0_INTERRUPT_MASK 0xd0004C static struct file_operations cx18_v4l2_enc_fops = { - .owner = THIS_MODULE, - .read = cx18_v4l2_read, - .open = cx18_v4l2_open, - .ioctl = cx18_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .release = cx18_v4l2_close, - .poll = cx18_v4l2_enc_poll, + .owner = THIS_MODULE, + .read = cx18_v4l2_read, + .open = cx18_v4l2_open, + .ioctl = cx18_v4l2_ioctl, + .release = cx18_v4l2_close, + .poll = cx18_v4l2_enc_poll, }; /* offset from 0 to register ts v4l2 minors on */ @@ -444,7 +443,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) s->handle = data[0]; cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); - if (atomic_read(&cx->ana_capturing) == 0 && !ts) { + if (atomic_read(&cx->capturing) == 0 && !ts) { /* Stuff from Windows, we don't know what it is */ cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); @@ -467,14 +466,14 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) cx2341x_update(cx, cx18_api_func, NULL, &cx->params); } - if (atomic_read(&cx->tot_capturing) == 0) { + if (atomic_read(&cx->capturing) == 0) { clear_bit(CX18_F_I_EOS, &cx->i_flags); write_reg(7, CX18_DSP0_INTERRUPT_MASK); } cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, - (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, - (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); + (void *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, + (void *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); list_for_each(p, &s->q_free.list) { struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); @@ -482,8 +481,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) writel(buf->dma_handle, &cx->scb->cpu_mdl[buf->id].paddr); writel(s->buf_size, &cx->scb->cpu_mdl[buf->id].length); cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, - 1, buf->id, s->buf_size); + (void *)&cx->scb->cpu_mdl[buf->id] - cx->enc_mem, 1, + buf->id, s->buf_size); } /* begin_capture */ if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { @@ -493,9 +492,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s) } /* you're live! sit back and await interrupts :) */ - if (!ts) - atomic_inc(&cx->ana_capturing); - atomic_inc(&cx->tot_capturing); + atomic_inc(&cx->capturing); return 0; } @@ -526,7 +523,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) CX18_DEBUG_INFO("Stop Capture\n"); - if (atomic_read(&cx->tot_capturing) == 0) + if (atomic_read(&cx->capturing) == 0) return 0; if (s->type == CX18_ENC_STREAM_TYPE_MPG) @@ -540,9 +537,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); } - if (s->type != CX18_ENC_STREAM_TYPE_TS) - atomic_dec(&cx->ana_capturing); - atomic_dec(&cx->tot_capturing); + atomic_dec(&cx->capturing); /* Clear capture and no-read bits */ clear_bit(CX18_F_S_STREAMING, &s->s_flags); @@ -550,7 +545,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); s->handle = 0xffffffff; - if (atomic_read(&cx->tot_capturing) > 0) + if (atomic_read(&cx->capturing) > 0) return 0; write_reg(5, CX18_DSP0_INTERRUPT_MASK); diff --git a/trunk/drivers/media/video/cx23885/cx23885-core.c b/trunk/drivers/media/video/cx23885/cx23885-core.c index c4cc2f3b8876..f24abcd06dea 100644 --- a/trunk/drivers/media/video/cx23885/cx23885-core.c +++ b/trunk/drivers/media/video/cx23885/cx23885-core.c @@ -823,7 +823,7 @@ static void cx23885_dev_unregister(struct cx23885_dev *dev) iounmap(dev->lmmio); } -static __le32* cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, +static u32* cx23885_risc_field(u32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, unsigned int lines) @@ -883,7 +883,7 @@ int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, unsigned int padding, unsigned int lines) { u32 instructions, fields; - __le32 *rp; + u32 *rp; int rc; fields = 0; @@ -924,7 +924,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, unsigned int lines) { u32 instructions; - __le32 *rp; + u32 *rp; int rc; /* estimate risc mem: worst case is one write per page border + @@ -951,7 +951,7 @@ static int cx23885_risc_databuffer(struct pci_dev *pci, int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value) { - __le32 *rp; + u32 *rp; int rc; if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) diff --git a/trunk/drivers/media/video/cx88/cx88-cards.c b/trunk/drivers/media/video/cx88/cx88-cards.c index fa6d398e97b9..aeba26dc0a37 100644 --- a/trunk/drivers/media/video/cx88/cx88-cards.c +++ b/trunk/drivers/media/video/cx88/cx88-cards.c @@ -1493,16 +1493,10 @@ static const struct cx88_board cx88_boards[] = { }, }, [CX88_BOARD_POWERCOLOR_REAL_ANGEL] = { - .name = "PowerColor RA330", /* Long names may confuse LIRC. */ + .name = "PowerColor Real Angel 330", .tuner_type = TUNER_XC2028, .tuner_addr = 0x61, .input = { { - .type = CX88_VMUX_DEBUG, - .vmux = 3, /* Due to the way the cx88 driver is written, */ - .gpio0 = 0x00ff, /* there is no way to deactivate audio pass- */ - .gpio1 = 0xf39d, /* through without this entry. Furthermore, if */ - .gpio3 = 0x0000, /* the TV mux entry is first, you get audio */ - }, { /* from the tuner on boot for a little while. */ .type = CX88_VMUX_TELEVISION, .vmux = 0, .gpio0 = 0x00ff, @@ -2430,9 +2424,8 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl) switch (core->boardnr) { case CX88_BOARD_POWERCOLOR_REAL_ANGEL: - /* Now works with firmware version 2.7 */ - if (core->i2c_algo.udelay < 16) - core->i2c_algo.udelay = 16; + /* Doesn't work with firmware version 2.7 */ + ctl->fname = "xc3028-v25.fw"; break; case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: ctl->scode_table = XC3028_FE_ZARLINK456; diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index 60eeda3057e9..c4d1aff1fdb4 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -70,7 +70,7 @@ static DEFINE_MUTEX(devlist); /* @lpi: lines per IRQ, or 0 to not generate irqs. Note: IRQ to be generated _after_ lpi lines are transferred. */ -static __le32* cx88_risc_field(__le32 *rp, struct scatterlist *sglist, +static u32* cx88_risc_field(u32 *rp, struct scatterlist *sglist, unsigned int offset, u32 sync_line, unsigned int bpl, unsigned int padding, unsigned int lines, unsigned int lpi) @@ -130,7 +130,7 @@ int cx88_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, unsigned int bpl, unsigned int padding, unsigned int lines) { u32 instructions,fields; - __le32 *rp; + u32 *rp; int rc; fields = 0; @@ -168,7 +168,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, unsigned int lines, unsigned int lpi) { u32 instructions; - __le32 *rp; + u32 *rp; int rc; /* estimate risc mem: worst case is one write per page border + @@ -193,7 +193,7 @@ int cx88_risc_databuffer(struct pci_dev *pci, struct btcx_riscmem *risc, int cx88_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, u32 reg, u32 mask, u32 value) { - __le32 *rp; + u32 *rp; int rc; if ((rc = btcx_riscmem_alloc(pci, risc, 4*16)) < 0) diff --git a/trunk/drivers/media/video/em28xx/em28xx-video.c b/trunk/drivers/media/video/em28xx/em28xx-video.c index fb163ecd9216..8996175cc950 100644 --- a/trunk/drivers/media/video/em28xx/em28xx-video.c +++ b/trunk/drivers/media/video/em28xx/em28xx-video.c @@ -1166,13 +1166,13 @@ static int vidioc_g_register(struct file *file, void *priv, reg->val = ret; } else { - __le64 val = 0; + u64 val = 0; ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, reg->reg, (char *)&val, 2); if (ret < 0) return ret; - reg->val = le64_to_cpu(val); + reg->val = cpu_to_le64((__u64)val); } return 0; @@ -1183,9 +1183,9 @@ static int vidioc_s_register(struct file *file, void *priv, { struct em28xx_fh *fh = priv; struct em28xx *dev = fh->dev; - __le64 buf; + u64 buf; - buf = cpu_to_le64(reg->val); + buf = le64_to_cpu((__u64)reg->val); return em28xx_write_regs(dev, reg->reg, (char *)&buf, em28xx_reg_len(reg->reg)); diff --git a/trunk/drivers/media/video/ivtv/ivtv-driver.h b/trunk/drivers/media/video/ivtv/ivtv-driver.h index 9d23b1efd36d..ba06e813c58c 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-driver.h +++ b/trunk/drivers/media/video/ivtv/ivtv-driver.h @@ -259,12 +259,6 @@ struct ivtv_mailbox_data { /* Scatter-Gather array element, used in DMA transfers */ struct ivtv_sg_element { - __le32 src; - __le32 dst; - __le32 size; -}; - -struct ivtv_sg_host_element { u32 src; u32 dst; u32 size; @@ -355,8 +349,8 @@ struct ivtv_stream { u16 dma_xfer_cnt; /* Base Dev SG Array for cx23415/6 */ - struct ivtv_sg_host_element *sg_pending; - struct ivtv_sg_host_element *sg_processing; + struct ivtv_sg_element *sg_pending; + struct ivtv_sg_element *sg_processing; struct ivtv_sg_element *sg_dma; dma_addr_t sg_handle; int sg_pending_size; diff --git a/trunk/drivers/media/video/ivtv/ivtv-fileops.c b/trunk/drivers/media/video/ivtv/ivtv-fileops.c index db813e071ce6..f2fa434b677b 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-fileops.c +++ b/trunk/drivers/media/video/ivtv/ivtv-fileops.c @@ -587,7 +587,7 @@ ssize_t ivtv_v4l2_write(struct file *filp, const char __user *user_buf, size_t c since we may get here before the stream has been fully set-up */ if (mode == OUT_YUV && s->q_full.length == 0 && itv->dma_data_req_size) { while (count >= itv->dma_data_req_size) { - if (!ivtv_yuv_udma_stream_frame (itv, (void __user *)user_buf)) { + if (!ivtv_yuv_udma_stream_frame (itv, (void *)user_buf)) { bytes_written += itv->dma_data_req_size; user_buf += itv->dma_data_req_size; count -= itv->dma_data_req_size; diff --git a/trunk/drivers/media/video/ivtv/ivtv-irq.c b/trunk/drivers/media/video/ivtv/ivtv-irq.c index fba150a6cd23..d8ba3a4a8761 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-irq.c +++ b/trunk/drivers/media/video/ivtv/ivtv-irq.c @@ -231,14 +231,14 @@ static void dma_post(struct ivtv_stream *s) struct ivtv_buffer *buf = NULL; struct list_head *p; u32 offset; - __le32 *u32buf; + u32 *u32buf; int x = 0; IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA", s->name, s->dma_offset); list_for_each(p, &s->q_dma.list) { buf = list_entry(p, struct ivtv_buffer, list); - u32buf = (__le32 *)buf->buf; + u32buf = (u32 *)buf->buf; /* Sync Buffer */ ivtv_buf_sync_for_cpu(s, buf); @@ -444,7 +444,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) } s->dma_xfer_cnt++; - memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); + memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); s->sg_processing_size = s->sg_pending_size; s->sg_pending_size = 0; s->sg_processed = 0; @@ -473,7 +473,7 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) if (s->q_predma.bytesused) ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); s->dma_xfer_cnt++; - memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size); + memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); s->sg_processing_size = s->sg_pending_size; s->sg_pending_size = 0; s->sg_processed = 0; diff --git a/trunk/drivers/media/video/ivtv/ivtv-queue.c b/trunk/drivers/media/video/ivtv/ivtv-queue.c index 71bd13e22e2e..fc8b1eaa333b 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-queue.c +++ b/trunk/drivers/media/video/ivtv/ivtv-queue.c @@ -193,7 +193,7 @@ void ivtv_flush_queues(struct ivtv_stream *s) int ivtv_stream_alloc(struct ivtv_stream *s) { struct ivtv *itv = s->itv; - int SGsize = sizeof(struct ivtv_sg_host_element) * s->buffers; + int SGsize = sizeof(struct ivtv_sg_element) * s->buffers; int i; if (s->buffers == 0) diff --git a/trunk/drivers/media/video/ivtv/ivtv-streams.c b/trunk/drivers/media/video/ivtv/ivtv-streams.c index c854285a4371..c47c2b945147 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-streams.c +++ b/trunk/drivers/media/video/ivtv/ivtv-streams.c @@ -44,25 +44,23 @@ #include "ivtv-streams.h" static const struct file_operations ivtv_v4l2_enc_fops = { - .owner = THIS_MODULE, - .read = ivtv_v4l2_read, - .write = ivtv_v4l2_write, - .open = ivtv_v4l2_open, - .ioctl = ivtv_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .release = ivtv_v4l2_close, - .poll = ivtv_v4l2_enc_poll, + .owner = THIS_MODULE, + .read = ivtv_v4l2_read, + .write = ivtv_v4l2_write, + .open = ivtv_v4l2_open, + .ioctl = ivtv_v4l2_ioctl, + .release = ivtv_v4l2_close, + .poll = ivtv_v4l2_enc_poll, }; static const struct file_operations ivtv_v4l2_dec_fops = { - .owner = THIS_MODULE, - .read = ivtv_v4l2_read, - .write = ivtv_v4l2_write, - .open = ivtv_v4l2_open, - .ioctl = ivtv_v4l2_ioctl, - .compat_ioctl = v4l_compat_ioctl32, - .release = ivtv_v4l2_close, - .poll = ivtv_v4l2_dec_poll, + .owner = THIS_MODULE, + .read = ivtv_v4l2_read, + .write = ivtv_v4l2_write, + .open = ivtv_v4l2_open, + .ioctl = ivtv_v4l2_ioctl, + .release = ivtv_v4l2_close, + .poll = ivtv_v4l2_dec_poll, }; #define IVTV_V4L2_DEC_MPG_OFFSET 16 /* offset from 0 to register decoder mpg v4l2 minors on */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-version.h b/trunk/drivers/media/video/ivtv/ivtv-version.h index 442f43f11b73..02c5ab071d1b 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-version.h +++ b/trunk/drivers/media/video/ivtv/ivtv-version.h @@ -22,8 +22,8 @@ #define IVTV_DRIVER_NAME "ivtv" #define IVTV_DRIVER_VERSION_MAJOR 1 -#define IVTV_DRIVER_VERSION_MINOR 3 -#define IVTV_DRIVER_VERSION_PATCHLEVEL 0 +#define IVTV_DRIVER_VERSION_MINOR 2 +#define IVTV_DRIVER_VERSION_PATCHLEVEL 1 #define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL) #define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL) diff --git a/trunk/drivers/media/video/ivtv/ivtv-yuv.c b/trunk/drivers/media/video/ivtv/ivtv-yuv.c index 3092ff1d00a0..a9417f6e4087 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-yuv.c +++ b/trunk/drivers/media/video/ivtv/ivtv-yuv.c @@ -1116,7 +1116,7 @@ void ivtv_yuv_setup_stream_frame(struct ivtv *itv) } /* Attempt to dma a frame from a user buffer */ -int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src) +int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src) { struct yuv_playback_info *yi = &itv->yuv_info; struct ivtv_dma_frame dma_args; diff --git a/trunk/drivers/media/video/ivtv/ivtv-yuv.h b/trunk/drivers/media/video/ivtv/ivtv-yuv.h index ca5173fbf006..2fe5f1250762 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-yuv.h +++ b/trunk/drivers/media/video/ivtv/ivtv-yuv.h @@ -35,7 +35,7 @@ extern const u32 yuv_offset[IVTV_YUV_BUFFERS]; int ivtv_yuv_filter_check(struct ivtv *itv); void ivtv_yuv_setup_stream_frame(struct ivtv *itv); -int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src); +int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src); void ivtv_yuv_frame_complete(struct ivtv *itv); int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args); void ivtv_yuv_close(struct ivtv *itv); diff --git a/trunk/drivers/media/video/saa7134/saa7134-empress.c b/trunk/drivers/media/video/saa7134/saa7134-empress.c index 81431ee41842..1314522a8130 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-empress.c +++ b/trunk/drivers/media/video/saa7134/saa7134-empress.c @@ -163,7 +163,8 @@ ts_mmap(struct file *file, struct vm_area_struct * vma) static int empress_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct saa7134_dev *dev = file->private_data; + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; strcpy(cap->driver, "saa7134"); strlcpy(cap->card, saa7134_boards[dev->board].name, diff --git a/trunk/drivers/media/video/tuner-core.c b/trunk/drivers/media/video/tuner-core.c index 0d12ace61665..a0f7bc1edaa2 100644 --- a/trunk/drivers/media/video/tuner-core.c +++ b/trunk/drivers/media/video/tuner-core.c @@ -536,7 +536,7 @@ static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) static inline int check_mode(struct tuner *t, char *cmd) { if ((1 << t->mode & t->mode_mask) == 0) { - return -EINVAL; + return EINVAL; } switch (t->mode) { @@ -730,11 +730,11 @@ static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, t->mode = mode; - if (check_mode(t, cmd) == -EINVAL) { + if (check_mode(t, cmd) == EINVAL) { t->mode = T_STANDBY; if (analog_ops->standby) analog_ops->standby(&t->fe); - return -EINVAL; + return EINVAL; } return 0; } @@ -776,13 +776,13 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) break; case AUDC_SET_RADIO: if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO") - == -EINVAL) + == EINVAL) return 0; if (t->radio_freq) set_freq(client, t->radio_freq); break; case TUNER_SET_STANDBY: - if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL) + if (check_mode(t, "TUNER_SET_STANDBY") == EINVAL) return 0; t->mode = T_STANDBY; if (analog_ops->standby) @@ -790,9 +790,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) break; #ifdef CONFIG_VIDEO_ALLOW_V4L1 case VIDIOCSAUDIO: - if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL) + if (check_mode(t, "VIDIOCSAUDIO") == EINVAL) return 0; - if (check_v4l2(t) == -EINVAL) + if (check_v4l2(t) == EINVAL) return 0; /* Should be implemented, since bttv calls it */ @@ -810,10 +810,10 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) }; struct video_channel *vc = arg; - if (check_v4l2(t) == -EINVAL) + if (check_v4l2(t) == EINVAL) return 0; - if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL) + if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==EINVAL) return 0; if (vc->norm < ARRAY_SIZE(map)) @@ -827,9 +827,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { unsigned long *v = arg; - if (check_mode(t, "VIDIOCSFREQ") == -EINVAL) + if (check_mode(t, "VIDIOCSFREQ") == EINVAL) return 0; - if (check_v4l2(t) == -EINVAL) + if (check_v4l2(t) == EINVAL) return 0; set_freq(client, *v); @@ -839,9 +839,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct video_tuner *vt = arg; - if (check_mode(t, "VIDIOCGTUNER") == -EINVAL) + if (check_mode(t, "VIDIOCGTUNER") == EINVAL) return 0; - if (check_v4l2(t) == -EINVAL) + if (check_v4l2(t) == EINVAL) return 0; if (V4L2_TUNER_RADIO == t->mode) { @@ -883,9 +883,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct video_audio *va = arg; - if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL) + if (check_mode(t, "VIDIOCGAUDIO") == EINVAL) return 0; - if (check_v4l2(t) == -EINVAL) + if (check_v4l2(t) == EINVAL) return 0; if (V4L2_TUNER_RADIO == t->mode) { @@ -925,7 +925,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) v4l2_std_id *id = arg; if (set_mode (client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD") - == -EINVAL) + == EINVAL) return 0; switch_v4l2(); @@ -941,7 +941,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) struct v4l2_frequency *f = arg; if (set_mode (client, t, f->type, "VIDIOC_S_FREQUENCY") - == -EINVAL) + == EINVAL) return 0; switch_v4l2(); set_freq(client,f->frequency); @@ -952,7 +952,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_frequency *f = arg; - if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL) + if (check_mode(t, "VIDIOC_G_FREQUENCY") == EINVAL) return 0; switch_v4l2(); f->type = t->mode; @@ -973,7 +973,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_tuner *tuner = arg; - if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL) + if (check_mode(t, "VIDIOC_G_TUNER") == EINVAL) return 0; switch_v4l2(); @@ -1020,7 +1020,7 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) { struct v4l2_tuner *tuner = arg; - if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL) + if (check_mode(t, "VIDIOC_S_TUNER") == EINVAL) return 0; switch_v4l2(); diff --git a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c index 3d26a30abe1e..32e536edf09d 100644 --- a/trunk/drivers/media/video/usbvideo/quickcam_messenger.c +++ b/trunk/drivers/media/video/usbvideo/quickcam_messenger.c @@ -210,7 +210,7 @@ static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val) return ret; } -static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val) +static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val) { int ret; diff --git a/trunk/drivers/media/video/zoran.h b/trunk/drivers/media/video/zoran.h index 46b7ad477ceb..81cc3b00a079 100644 --- a/trunk/drivers/media/video/zoran.h +++ b/trunk/drivers/media/video/zoran.h @@ -285,7 +285,7 @@ struct zoran_mapping { struct zoran_jpg_buffer { struct zoran_mapping *map; - __le32 *frag_tab; /* addresses of frag table */ + u32 *frag_tab; /* addresses of frag table */ u32 frag_tab_bus; /* same value cached to save time in ISR */ enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */ struct zoran_sync bs; /* DONE: info to return to application */ @@ -450,7 +450,7 @@ struct zoran { unsigned long jpg_queued_num; /* count of frames queued since grab/play started */ /* zr36057's code buffer table */ - __le32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ + u32 *stat_com; /* stat_com[i] is indexed by dma_head/tail & BUZ_MASK_STAT_COM */ /* (value & BUZ_MASK_FRAME) corresponds to index in pend[] queue */ int jpg_pend[BUZ_MAX_FRAME]; diff --git a/trunk/drivers/media/video/zoran_device.c b/trunk/drivers/media/video/zoran_device.c index 88d369708e4c..37629ffd34c3 100644 --- a/trunk/drivers/media/video/zoran_device.c +++ b/trunk/drivers/media/video/zoran_device.c @@ -1320,7 +1320,7 @@ error_handler (struct zoran *zr, if (i) { /* Rotate stat_comm entries to make current entry first */ int j; - __le32 bus_addr[BUZ_NUM_STAT_COM]; + u32 bus_addr[BUZ_NUM_STAT_COM]; /* Here we are copying the stat_com array, which * is already in little endian format, so diff --git a/trunk/drivers/media/video/zoran_driver.c b/trunk/drivers/media/video/zoran_driver.c index 5394d7a5cfee..345c77e46837 100644 --- a/trunk/drivers/media/video/zoran_driver.c +++ b/trunk/drivers/media/video/zoran_driver.c @@ -495,7 +495,7 @@ jpg_fbuffer_alloc (struct file *file) jpg_fbuffer_free(file); return -ENOBUFS; } - fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem; + fh->jpg_buffers.buffer[i].frag_tab = (u32 *) mem; fh->jpg_buffers.buffer[i].frag_tab_bus = virt_to_bus((void *) mem); @@ -1167,7 +1167,7 @@ zoran_close_end_session (struct file *file) /* v4l capture */ if (fh->v4l_buffers.active != ZORAN_FREE) { - unsigned long flags; + long flags; spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); @@ -3436,7 +3436,7 @@ zoran_do_ioctl (struct inode *inode, /* unload capture */ if (zr->v4l_memgrab_active) { - unsigned long flags; + long flags; spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); @@ -4375,7 +4375,7 @@ zoran_vm_close (struct vm_area_struct *vma) mutex_lock(&zr->resource_lock); if (fh->v4l_buffers.active != ZORAN_FREE) { - unsigned long flags; + long flags; spin_lock_irqsave(&zr->spinlock, flags); zr36057_set_memgrab(zr, 0); @@ -4506,7 +4506,7 @@ zoran_mmap (struct file *file, if (todo > fraglen) todo = fraglen; pos = - le32_to_cpu(fh->jpg_buffers. + le32_to_cpu((unsigned long) fh->jpg_buffers. buffer[i].frag_tab[2 * j]); /* should just be pos on i386 */ page = virt_to_phys(bus_to_virt(pos)) diff --git a/trunk/drivers/message/fusion/mptfc.c b/trunk/drivers/message/fusion/mptfc.c index 1e24ab4ac38c..3cdd4e962115 100644 --- a/trunk/drivers/message/fusion/mptfc.c +++ b/trunk/drivers/message/fusion/mptfc.c @@ -1238,6 +1238,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->max_id = ioc->pfacts->MaxDevices; sh->max_lun = max_lun; + sh->this_id = ioc->pfacts[0].PortSCSIID; + /* Required entry. */ sh->unique_id = ioc->id; diff --git a/trunk/drivers/message/fusion/mptsas.c b/trunk/drivers/message/fusion/mptsas.c index 4d492ba232b0..468480771f13 100644 --- a/trunk/drivers/message/fusion/mptsas.c +++ b/trunk/drivers/message/fusion/mptsas.c @@ -3193,6 +3193,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) sh->transportt = mptsas_transport_template; + sh->this_id = ioc->pfacts[0].PortSCSIID; + /* Required entry. */ sh->unique_id = ioc->id; diff --git a/trunk/drivers/message/fusion/mptscsih.c b/trunk/drivers/message/fusion/mptscsih.c index c68ef00c2f92..b109bd8a4d19 100644 --- a/trunk/drivers/message/fusion/mptscsih.c +++ b/trunk/drivers/message/fusion/mptscsih.c @@ -2451,6 +2451,12 @@ mptscsih_slave_configure(struct scsi_device *sdev) ioc->name, sdev->sdtr, sdev->wdtr, sdev->ppr, sdev->inquiry_len)); + if (sdev->id > sh->max_id) { + /* error case, should never happen */ + scsi_adjust_queue_depth(sdev, 0, 1); + goto slave_configure_exit; + } + vdevice->configured_lun = 1; mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH); @@ -2464,6 +2470,8 @@ mptscsih_slave_configure(struct scsi_device *sdev) ioc->name, vtarget->negoFlags, vtarget->maxOffset, vtarget->minSyncFactor)); +slave_configure_exit: + dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "tagged %d, simple %d, ordered %d\n", ioc->name,sdev->tagged_supported, sdev->simple_tags, diff --git a/trunk/drivers/misc/fujitsu-laptop.c b/trunk/drivers/misc/fujitsu-laptop.c index 6d14e8fe1537..e2e7c05a147b 100644 --- a/trunk/drivers/misc/fujitsu-laptop.c +++ b/trunk/drivers/misc/fujitsu-laptop.c @@ -352,9 +352,3 @@ MODULE_AUTHOR("Jonathan Woithe"); MODULE_DESCRIPTION("Fujitsu laptop extras support"); MODULE_VERSION(FUJITSU_DRIVER_VERSION); MODULE_LICENSE("GPL"); - -static struct pnp_device_id pnp_ids[] = { - { .id = "FUJ02bf" }, - { .id = "" } -}; -MODULE_DEVICE_TABLE(pnp, pnp_ids); diff --git a/trunk/drivers/misc/kgdbts.c b/trunk/drivers/misc/kgdbts.c index e4ff50b95a5e..fa394104339c 100644 --- a/trunk/drivers/misc/kgdbts.c +++ b/trunk/drivers/misc/kgdbts.c @@ -102,6 +102,7 @@ #include #include #include +#include #define v1printk(a...) do { \ if (verbose) \ @@ -118,6 +119,7 @@ } while (0) #define MAX_CONFIG_LEN 40 +static const char hexchars[] = "0123456789abcdef"; static struct kgdb_io kgdbts_io_ops; static char get_buf[BUFMAX]; static int get_buf_cnt; @@ -129,8 +131,6 @@ static int repeat_test; static int test_complete; static int send_ack; static int final_ack; -static int force_hwbrks; -static int hwbreaks_ok; static int hw_break_val; static int hw_break_val2; #if defined(CONFIG_ARM) || defined(CONFIG_MIPS) || defined(CONFIG_SPARC) @@ -234,12 +234,12 @@ static void break_helper(char *bp_type, char *arg, unsigned long vaddr) static void sw_break(char *arg) { - break_helper(force_hwbrks ? "Z1" : "Z0", arg, 0); + break_helper("Z0", arg, 0); } static void sw_rem_break(char *arg) { - break_helper(force_hwbrks ? "z1" : "z0", arg, 0); + break_helper("z0", arg, 0); } static void hw_break(char *arg) @@ -619,8 +619,8 @@ static void fill_get_buf(char *buf) count++; } strcat(get_buf, "#"); - get_buf[count + 2] = hex_asc_hi(checksum); - get_buf[count + 3] = hex_asc_lo(checksum); + get_buf[count + 2] = hexchars[checksum >> 4]; + get_buf[count + 3] = hexchars[checksum & 0xf]; get_buf[count + 4] = '\0'; v2printk("get%i: %s\n", ts.idx, get_buf); } @@ -781,8 +781,6 @@ static void run_breakpoint_test(int is_hw_breakpoint) return; eprintk("kgdbts: ERROR %s test failed\n", ts.name); - if (is_hw_breakpoint) - hwbreaks_ok = 0; } static void run_hw_break_test(int is_write_test) @@ -800,11 +798,9 @@ static void run_hw_break_test(int is_write_test) kgdb_breakpoint(); hw_break_val_access(); if (is_write_test) { - if (test_complete == 2) { + if (test_complete == 2) eprintk("kgdbts: ERROR %s broke on access\n", ts.name); - hwbreaks_ok = 0; - } hw_break_val_write(); } kgdb_breakpoint(); @@ -813,7 +809,6 @@ static void run_hw_break_test(int is_write_test) return; eprintk("kgdbts: ERROR %s test failed\n", ts.name); - hwbreaks_ok = 0; } static void run_nmi_sleep_test(int nmi_sleep) @@ -917,7 +912,6 @@ static void kgdbts_run_tests(void) /* All HW break point tests */ if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) { - hwbreaks_ok = 1; v1printk("kgdbts:RUN hw breakpoint test\n"); run_breakpoint_test(1); v1printk("kgdbts:RUN hw write breakpoint test\n"); @@ -931,19 +925,6 @@ static void kgdbts_run_tests(void) run_nmi_sleep_test(nmi_sleep); } -#ifdef CONFIG_DEBUG_RODATA - /* Until there is an api to write to read-only text segments, use - * HW breakpoints for the remainder of any tests, else print a - * failure message if hw breakpoints do not work. - */ - if (!(arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT && hwbreaks_ok)) { - eprintk("kgdbts: HW breakpoints do not work," - "skipping remaining tests\n"); - return; - } - force_hwbrks = 1; -#endif /* CONFIG_DEBUG_RODATA */ - /* If the do_fork test is run it will be the last test that is * executed because a kernel thread will be spawned at the very * end to unregister the debug hooks. diff --git a/trunk/drivers/misc/thinkpad_acpi.c b/trunk/drivers/misc/thinkpad_acpi.c index b5969298f3d3..a0ce0b2fa03e 100644 --- a/trunk/drivers/misc/thinkpad_acpi.c +++ b/trunk/drivers/misc/thinkpad_acpi.c @@ -1293,7 +1293,7 @@ static void tpacpi_input_send_radiosw(void) mutex_lock(&tpacpi_inputdev_send_mutex); input_report_switch(tpacpi_inputdev, - SW_RFKILL_ALL, !!wlsw); + SW_RADIO, !!wlsw); input_sync(tpacpi_inputdev); mutex_unlock(&tpacpi_inputdev_send_mutex); @@ -1921,29 +1921,6 @@ static struct attribute *hotkey_mask_attributes[] __initdata = { &dev_attr_hotkey_wakeup_hotunplug_complete.attr, }; -static void hotkey_exit(void) -{ -#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL - hotkey_poll_stop_sync(); -#endif - - if (hotkey_dev_attributes) - delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); - - kfree(hotkey_keycode_map); - - if (tp_features.hotkey) { - dbg_printk(TPACPI_DBG_EXIT, - "restoring original hot key mask\n"); - /* no short-circuit boolean operator below! */ - if ((hotkey_mask_set(hotkey_orig_mask) | - hotkey_status_set(hotkey_orig_status)) != 0) - printk(TPACPI_ERR - "failed to restore hot key mask " - "to BIOS defaults\n"); - } -} - static int __init hotkey_init(struct ibm_init_struct *iibm) { /* Requirements for changing the default keymaps: @@ -2083,220 +2060,226 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n", str_supported(tp_features.hotkey)); - if (!tp_features.hotkey) - return 1; + if (tp_features.hotkey) { + hotkey_dev_attributes = create_attr_set(13, NULL); + if (!hotkey_dev_attributes) + return -ENOMEM; + res = add_many_to_attr_set(hotkey_dev_attributes, + hotkey_attributes, + ARRAY_SIZE(hotkey_attributes)); + if (res) + return res; - hotkey_dev_attributes = create_attr_set(13, NULL); - if (!hotkey_dev_attributes) - return -ENOMEM; - res = add_many_to_attr_set(hotkey_dev_attributes, - hotkey_attributes, - ARRAY_SIZE(hotkey_attributes)); - if (res) - goto err_exit; - - /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, - A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking - for HKEY interface version 0x100 */ - if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { - if ((hkeyv >> 8) != 1) { - printk(TPACPI_ERR "unknown version of the " - "HKEY interface: 0x%x\n", hkeyv); - printk(TPACPI_ERR "please report this to %s\n", - TPACPI_MAIL); - } else { - /* - * MHKV 0x100 in A31, R40, R40e, - * T4x, X31, and later - */ - tp_features.hotkey_mask = 1; + /* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, + A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking + for HKEY interface version 0x100 */ + if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) { + if ((hkeyv >> 8) != 1) { + printk(TPACPI_ERR "unknown version of the " + "HKEY interface: 0x%x\n", hkeyv); + printk(TPACPI_ERR "please report this to %s\n", + TPACPI_MAIL); + } else { + /* + * MHKV 0x100 in A31, R40, R40e, + * T4x, X31, and later + */ + tp_features.hotkey_mask = 1; + } } - } - vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", - str_supported(tp_features.hotkey_mask)); + vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n", + str_supported(tp_features.hotkey_mask)); - if (tp_features.hotkey_mask) { - if (!acpi_evalf(hkey_handle, &hotkey_all_mask, - "MHKA", "qd")) { - printk(TPACPI_ERR - "missing MHKA handler, " - "please report this to %s\n", - TPACPI_MAIL); - /* FN+F12, FN+F4, FN+F3 */ - hotkey_all_mask = 0x080cU; + if (tp_features.hotkey_mask) { + if (!acpi_evalf(hkey_handle, &hotkey_all_mask, + "MHKA", "qd")) { + printk(TPACPI_ERR + "missing MHKA handler, " + "please report this to %s\n", + TPACPI_MAIL); + /* FN+F12, FN+F4, FN+F3 */ + hotkey_all_mask = 0x080cU; + } } - } - /* hotkey_source_mask *must* be zero for - * the first hotkey_mask_get */ - res = hotkey_status_get(&hotkey_orig_status); - if (res) - goto err_exit; - - if (tp_features.hotkey_mask) { - res = hotkey_mask_get(); - if (res) - goto err_exit; - - hotkey_orig_mask = hotkey_mask; - res = add_many_to_attr_set( - hotkey_dev_attributes, - hotkey_mask_attributes, - ARRAY_SIZE(hotkey_mask_attributes)); - if (res) - goto err_exit; - } + /* hotkey_source_mask *must* be zero for + * the first hotkey_mask_get */ + res = hotkey_status_get(&hotkey_orig_status); + if (!res && tp_features.hotkey_mask) { + res = hotkey_mask_get(); + hotkey_orig_mask = hotkey_mask; + if (!res) { + res = add_many_to_attr_set( + hotkey_dev_attributes, + hotkey_mask_attributes, + ARRAY_SIZE(hotkey_mask_attributes)); + } + } #ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL - if (tp_features.hotkey_mask) { - hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK - & ~hotkey_all_mask; - } else { - hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; - } + if (tp_features.hotkey_mask) { + hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK + & ~hotkey_all_mask; + } else { + hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK; + } - vdbg_printk(TPACPI_DBG_INIT, - "hotkey source mask 0x%08x, polling freq %d\n", - hotkey_source_mask, hotkey_poll_freq); + vdbg_printk(TPACPI_DBG_INIT, + "hotkey source mask 0x%08x, polling freq %d\n", + hotkey_source_mask, hotkey_poll_freq); #endif - /* Not all thinkpads have a hardware radio switch */ - if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { - tp_features.hotkey_wlsw = 1; - printk(TPACPI_INFO - "radio switch found; radios are %s\n", - enabled(status, 0)); - res = add_to_attr_set(hotkey_dev_attributes, - &dev_attr_hotkey_radio_sw.attr); - } + /* Not all thinkpads have a hardware radio switch */ + if (!res && acpi_evalf(hkey_handle, &status, "WLSW", "qd")) { + tp_features.hotkey_wlsw = 1; + printk(TPACPI_INFO + "radio switch found; radios are %s\n", + enabled(status, 0)); + res = add_to_attr_set(hotkey_dev_attributes, + &dev_attr_hotkey_radio_sw.attr); + } - /* For X41t, X60t, X61t Tablets... */ - if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { - tp_features.hotkey_tablet = 1; - printk(TPACPI_INFO - "possible tablet mode switch found; " - "ThinkPad in %s mode\n", - (status & TP_HOTKEY_TABLET_MASK)? - "tablet" : "laptop"); - res = add_to_attr_set(hotkey_dev_attributes, - &dev_attr_hotkey_tablet_mode.attr); - } + /* For X41t, X60t, X61t Tablets... */ + if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) { + tp_features.hotkey_tablet = 1; + printk(TPACPI_INFO + "possible tablet mode switch found; " + "ThinkPad in %s mode\n", + (status & TP_HOTKEY_TABLET_MASK)? + "tablet" : "laptop"); + res = add_to_attr_set(hotkey_dev_attributes, + &dev_attr_hotkey_tablet_mode.attr); + } - if (!res) - res = register_attr_set_with_sysfs( - hotkey_dev_attributes, - &tpacpi_pdev->dev.kobj); - if (res) - goto err_exit; + if (!res) + res = register_attr_set_with_sysfs( + hotkey_dev_attributes, + &tpacpi_pdev->dev.kobj); + if (res) + return res; - /* Set up key map */ + /* Set up key map */ - hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, - GFP_KERNEL); - if (!hotkey_keycode_map) { - printk(TPACPI_ERR - "failed to allocate memory for key map\n"); - res = -ENOMEM; - goto err_exit; - } + hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, + GFP_KERNEL); + if (!hotkey_keycode_map) { + printk(TPACPI_ERR + "failed to allocate memory for key map\n"); + return -ENOMEM; + } - if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { - dbg_printk(TPACPI_DBG_INIT, - "using Lenovo default hot key map\n"); - memcpy(hotkey_keycode_map, &lenovo_keycode_map, - TPACPI_HOTKEY_MAP_SIZE); - } else { - dbg_printk(TPACPI_DBG_INIT, - "using IBM default hot key map\n"); - memcpy(hotkey_keycode_map, &ibm_keycode_map, - TPACPI_HOTKEY_MAP_SIZE); - } - - set_bit(EV_KEY, tpacpi_inputdev->evbit); - set_bit(EV_MSC, tpacpi_inputdev->evbit); - set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); - tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; - tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; - tpacpi_inputdev->keycode = hotkey_keycode_map; - for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { - if (hotkey_keycode_map[i] != KEY_RESERVED) { - set_bit(hotkey_keycode_map[i], - tpacpi_inputdev->keybit); + if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) { + dbg_printk(TPACPI_DBG_INIT, + "using Lenovo default hot key map\n"); + memcpy(hotkey_keycode_map, &lenovo_keycode_map, + TPACPI_HOTKEY_MAP_SIZE); } else { - if (i < sizeof(hotkey_reserved_mask)*8) - hotkey_reserved_mask |= 1 << i; + dbg_printk(TPACPI_DBG_INIT, + "using IBM default hot key map\n"); + memcpy(hotkey_keycode_map, &ibm_keycode_map, + TPACPI_HOTKEY_MAP_SIZE); } - } - if (tp_features.hotkey_wlsw) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_RFKILL_ALL, tpacpi_inputdev->swbit); - } - if (tp_features.hotkey_tablet) { - set_bit(EV_SW, tpacpi_inputdev->evbit); - set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); - } + set_bit(EV_KEY, tpacpi_inputdev->evbit); + set_bit(EV_MSC, tpacpi_inputdev->evbit); + set_bit(MSC_SCAN, tpacpi_inputdev->mscbit); + tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; + tpacpi_inputdev->keycodemax = TPACPI_HOTKEY_MAP_LEN; + tpacpi_inputdev->keycode = hotkey_keycode_map; + for (i = 0; i < TPACPI_HOTKEY_MAP_LEN; i++) { + if (hotkey_keycode_map[i] != KEY_RESERVED) { + set_bit(hotkey_keycode_map[i], + tpacpi_inputdev->keybit); + } else { + if (i < sizeof(hotkey_reserved_mask)*8) + hotkey_reserved_mask |= 1 << i; + } + } - /* Do not issue duplicate brightness change events to - * userspace */ - if (!tp_features.bright_acpimode) - /* update bright_acpimode... */ - tpacpi_check_std_acpi_brightness_support(); + if (tp_features.hotkey_wlsw) { + set_bit(EV_SW, tpacpi_inputdev->evbit); + set_bit(SW_RADIO, tpacpi_inputdev->swbit); + } + if (tp_features.hotkey_tablet) { + set_bit(EV_SW, tpacpi_inputdev->evbit); + set_bit(SW_TABLET_MODE, tpacpi_inputdev->swbit); + } - if (tp_features.bright_acpimode) { - printk(TPACPI_INFO - "This ThinkPad has standard ACPI backlight " - "brightness control, supported by the ACPI " - "video driver\n"); - printk(TPACPI_NOTICE - "Disabling thinkpad-acpi brightness events " - "by default...\n"); - - /* The hotkey_reserved_mask change below is not - * necessary while the keys are at KEY_RESERVED in the - * default map, but better safe than sorry, leave it - * here as a marker of what we have to do, especially - * when we finally become able to set this at runtime - * on response to X.org requests */ - hotkey_reserved_mask |= - (1 << TP_ACPI_HOTKEYSCAN_FNHOME) - | (1 << TP_ACPI_HOTKEYSCAN_FNEND); - } - - dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n"); - res = hotkey_status_set(1); - if (res) { - hotkey_exit(); - return res; - } - res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) - & ~hotkey_reserved_mask) - | hotkey_orig_mask); - if (res < 0 && res != -ENXIO) { - hotkey_exit(); - return res; - } + /* Do not issue duplicate brightness change events to + * userspace */ + if (!tp_features.bright_acpimode) + /* update bright_acpimode... */ + tpacpi_check_std_acpi_brightness_support(); + + if (tp_features.bright_acpimode) { + printk(TPACPI_INFO + "This ThinkPad has standard ACPI backlight " + "brightness control, supported by the ACPI " + "video driver\n"); + printk(TPACPI_NOTICE + "Disabling thinkpad-acpi brightness events " + "by default...\n"); + + /* The hotkey_reserved_mask change below is not + * necessary while the keys are at KEY_RESERVED in the + * default map, but better safe than sorry, leave it + * here as a marker of what we have to do, especially + * when we finally become able to set this at runtime + * on response to X.org requests */ + hotkey_reserved_mask |= + (1 << TP_ACPI_HOTKEYSCAN_FNHOME) + | (1 << TP_ACPI_HOTKEYSCAN_FNEND); + } - dbg_printk(TPACPI_DBG_INIT, - "legacy hot key reporting over procfs %s\n", - (hotkey_report_mode < 2) ? - "enabled" : "disabled"); + dbg_printk(TPACPI_DBG_INIT, + "enabling hot key handling\n"); + res = hotkey_status_set(1); + if (res) + return res; + res = hotkey_mask_set(((hotkey_all_mask | hotkey_source_mask) + & ~hotkey_reserved_mask) + | hotkey_orig_mask); + if (res < 0 && res != -ENXIO) + return res; - tpacpi_inputdev->open = &hotkey_inputdev_open; - tpacpi_inputdev->close = &hotkey_inputdev_close; + dbg_printk(TPACPI_DBG_INIT, + "legacy hot key reporting over procfs %s\n", + (hotkey_report_mode < 2) ? + "enabled" : "disabled"); - hotkey_poll_setup_safe(1); - tpacpi_input_send_radiosw(); - tpacpi_input_send_tabletsw(); + tpacpi_inputdev->open = &hotkey_inputdev_open; + tpacpi_inputdev->close = &hotkey_inputdev_close; - return 0; + hotkey_poll_setup_safe(1); + tpacpi_input_send_radiosw(); + tpacpi_input_send_tabletsw(); + } + + return (tp_features.hotkey)? 0 : 1; +} + +static void hotkey_exit(void) +{ +#ifdef CONFIG_THINKPAD_ACPI_HOTKEY_POLL + hotkey_poll_stop_sync(); +#endif -err_exit: - delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); - hotkey_dev_attributes = NULL; + if (tp_features.hotkey) { + dbg_printk(TPACPI_DBG_EXIT, + "restoring original hot key mask\n"); + /* no short-circuit boolean operator below! */ + if ((hotkey_mask_set(hotkey_orig_mask) | + hotkey_status_set(hotkey_orig_status)) != 0) + printk(TPACPI_ERR + "failed to restore hot key mask " + "to BIOS defaults\n"); + } - return (res < 0)? res : 1; + if (hotkey_dev_attributes) { + delete_attr_set(hotkey_dev_attributes, &tpacpi_pdev->dev.kobj); + hotkey_dev_attributes = NULL; + } } static void hotkey_notify(struct ibm_struct *ibm, u32 event) @@ -3336,7 +3319,7 @@ static struct tpacpi_led_classdev tpacpi_led_thinklight = { static int __init light_init(struct ibm_init_struct *iibm) { - int rc; + int rc = 0; vdbg_printk(TPACPI_DBG_INIT, "initializing light subdriver\n"); @@ -3354,23 +3337,20 @@ static int __init light_init(struct ibm_init_struct *iibm) tp_features.light_status = acpi_evalf(ec_handle, NULL, "KBLT", "qv"); - vdbg_printk(TPACPI_DBG_INIT, "light is %s, light status is %s\n", - str_supported(tp_features.light), - str_supported(tp_features.light_status)); + vdbg_printk(TPACPI_DBG_INIT, "light is %s\n", + str_supported(tp_features.light)); - if (!tp_features.light) - return 1; - - rc = led_classdev_register(&tpacpi_pdev->dev, - &tpacpi_led_thinklight.led_classdev); + if (tp_features.light) { + rc = led_classdev_register(&tpacpi_pdev->dev, + &tpacpi_led_thinklight.led_classdev); + } if (rc < 0) { tp_features.light = 0; tp_features.light_status = 0; - } else { - rc = 0; + } else { + rc = (tp_features.light)? 0 : 1; } - return rc; } @@ -3853,7 +3833,7 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = { "tpacpi::standby", }; -static int led_get_status(const unsigned int led) +static int led_get_status(unsigned int led) { int status; enum led_status_t led_s; @@ -3877,42 +3857,41 @@ static int led_get_status(const unsigned int led) /* not reached */ } -static int led_set_status(const unsigned int led, - const enum led_status_t ledstatus) +static int led_set_status(unsigned int led, enum led_status_t ledstatus) { /* off, on, blink. Index is led_status_t */ - static const unsigned int led_sled_arg1[] = { 0, 1, 3 }; - static const unsigned int led_led_arg1[] = { 0, 0x80, 0xc0 }; + static const int led_sled_arg1[] = { 0, 1, 3 }; + static const int led_exp_hlbl[] = { 0, 0, 1 }; /* led# * */ + static const int led_exp_hlcl[] = { 0, 1, 1 }; /* led# * */ + static const int led_led_arg1[] = { 0, 0x80, 0xc0 }; int rc = 0; switch (led_supported) { case TPACPI_LED_570: - /* 570 */ - if (led > 7) - return -EINVAL; - if (!acpi_evalf(led_handle, NULL, NULL, "vdd", - (1 << led), led_sled_arg1[ledstatus])) - rc = -EIO; - break; + /* 570 */ + led = 1 << led; + if (!acpi_evalf(led_handle, NULL, NULL, "vdd", + led, led_sled_arg1[ledstatus])) + rc = -EIO; + break; case TPACPI_LED_OLD: - /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ - if (led > 7) - return -EINVAL; - rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led)); - if (rc >= 0) - rc = ec_write(TPACPI_LED_EC_HLBL, - (ledstatus == TPACPI_LED_BLINK) << led); - if (rc >= 0) - rc = ec_write(TPACPI_LED_EC_HLCL, - (ledstatus != TPACPI_LED_OFF) << led); - break; + /* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */ + led = 1 << led; + rc = ec_write(TPACPI_LED_EC_HLMS, led); + if (rc >= 0) + rc = ec_write(TPACPI_LED_EC_HLBL, + led * led_exp_hlbl[ledstatus]); + if (rc >= 0) + rc = ec_write(TPACPI_LED_EC_HLCL, + led * led_exp_hlcl[ledstatus]); + break; case TPACPI_LED_NEW: - /* all others */ - if (!acpi_evalf(led_handle, NULL, NULL, "vdd", - led, led_led_arg1[ledstatus])) - rc = -EIO; - break; + /* all others */ + if (!acpi_evalf(led_handle, NULL, NULL, "vdd", + led, led_led_arg1[ledstatus])) + rc = -EIO; + break; default: rc = -ENXIO; } @@ -3999,6 +3978,7 @@ static void led_exit(void) } kfree(tpacpi_leds); + tpacpi_leds = NULL; } static int __init led_init(struct ibm_init_struct *iibm) @@ -4822,6 +4802,7 @@ static void brightness_exit(void) vdbg_printk(TPACPI_DBG_EXIT, "calling backlight_device_unregister()\n"); backlight_device_unregister(ibm_backlight_device); + ibm_backlight_device = NULL; } } @@ -5783,16 +5764,11 @@ static int __init fan_init(struct ibm_init_struct *iibm) fan_control_access_mode != TPACPI_FAN_WR_NONE) { rc = sysfs_create_group(&tpacpi_sensors_pdev->dev.kobj, &fan_attr_group); - if (rc < 0) - return rc; - - rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, + if (!(rc < 0)) + rc = driver_create_file(&tpacpi_hwmon_pdriver.driver, &driver_attr_fan_watchdog); - if (rc < 0) { - sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, - &fan_attr_group); + if (rc < 0) return rc; - } return 0; } else return 1; diff --git a/trunk/drivers/mmc/card/block.c b/trunk/drivers/mmc/card/block.c index f9ad960d7c1a..91ded3e82401 100644 --- a/trunk/drivers/mmc/card/block.c +++ b/trunk/drivers/mmc/card/block.c @@ -46,7 +46,7 @@ #define MMC_SHIFT 3 #define MMC_NUM_MINORS (256 >> MMC_SHIFT) -static DECLARE_BITMAP(dev_use, MMC_NUM_MINORS); +static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))]; /* * There is one mmc_blk_data per slot. diff --git a/trunk/drivers/mmc/host/wbsd.c b/trunk/drivers/mmc/host/wbsd.c index c303e7f57ab4..be624a049c67 100644 --- a/trunk/drivers/mmc/host/wbsd.c +++ b/trunk/drivers/mmc/host/wbsd.c @@ -1457,7 +1457,17 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) int ret; /* - * Set up tasklets. Must be done before requesting interrupt. + * Allocate interrupt. + */ + + ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); + if (ret) + return ret; + + host->irq = irq; + + /* + * Set up tasklets. */ tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); @@ -1470,15 +1480,6 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); - /* - * Allocate interrupt. - */ - ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); - if (ret) - return ret; - - host->irq = irq; - return 0; } diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index b402269301f6..25efd331ef28 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -346,10 +346,8 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, mutex_lock(&flash->lock); /* Wait until finished previous write command. */ - if (wait_till_ready(flash)) { - mutex_unlock(&flash->lock); + if (wait_till_ready(flash)) return 1; - } write_enable(flash); diff --git a/trunk/drivers/mtd/maps/omap_nor.c b/trunk/drivers/mtd/maps/omap_nor.c index c12d8056bebd..240b0e2d095d 100644 --- a/trunk/drivers/mtd/maps/omap_nor.c +++ b/trunk/drivers/mtd/maps/omap_nor.c @@ -110,7 +110,7 @@ static int __init omapflash_probe(struct platform_device *pdev) err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0); if (err > 0) add_mtd_partitions(info->mtd, info->parts, err); - else if (err <= 0 && pdata->parts) + else if (err < 0 && pdata->parts) add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts); else #endif diff --git a/trunk/drivers/mtd/nand/pxa3xx_nand.c b/trunk/drivers/mtd/nand/pxa3xx_nand.c index fe2bc7e42119..fceb468ccdec 100644 --- a/trunk/drivers/mtd/nand/pxa3xx_nand.c +++ b/trunk/drivers/mtd/nand/pxa3xx_nand.c @@ -1216,7 +1216,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev) clk_enable(info->clk); - return pxa3xx_nand_config_flash(info, info->flash_info); + return pxa3xx_nand_config_flash(info); } #else #define pxa3xx_nand_suspend NULL diff --git a/trunk/drivers/mtd/onenand/generic.c b/trunk/drivers/mtd/onenand/generic.c index ad81ab8e95e2..3d44d040a47d 100644 --- a/trunk/drivers/mtd/onenand/generic.c +++ b/trunk/drivers/mtd/onenand/generic.c @@ -76,7 +76,7 @@ static int __devinit generic_onenand_probe(struct device *dev) err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0); if (err > 0) add_mtd_partitions(&info->mtd, info->parts, err); - else if (err <= 0 && pdata->parts) + else if (err < 0 && pdata->parts) add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts); else #endif diff --git a/trunk/drivers/mtd/redboot.c b/trunk/drivers/mtd/redboot.c index c5030f94f04e..47474903263c 100644 --- a/trunk/drivers/mtd/redboot.c +++ b/trunk/drivers/mtd/redboot.c @@ -295,5 +295,5 @@ module_init(redboot_parser_init); module_exit(redboot_parser_exit); MODULE_LICENSE("GPL"); -MODULE_AUTHOR("David Woodhouse "); +MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse "); MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); diff --git a/trunk/drivers/net/7990.c b/trunk/drivers/net/7990.c index ad6b8a5b6574..750a46f4bc58 100644 --- a/trunk/drivers/net/7990.c +++ b/trunk/drivers/net/7990.c @@ -506,7 +506,6 @@ int lance_open (struct net_device *dev) return res; } -EXPORT_SYMBOL_GPL(lance_open); int lance_close (struct net_device *dev) { @@ -522,7 +521,6 @@ int lance_close (struct net_device *dev) return 0; } -EXPORT_SYMBOL_GPL(lance_close); void lance_tx_timeout(struct net_device *dev) { @@ -531,7 +529,7 @@ void lance_tx_timeout(struct net_device *dev) dev->trans_start = jiffies; netif_wake_queue (dev); } -EXPORT_SYMBOL_GPL(lance_tx_timeout); + int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) { @@ -588,7 +586,6 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev) return 0; } -EXPORT_SYMBOL_GPL(lance_start_xmit); /* taken from the depca driver via a2065.c */ static void lance_load_multicast (struct net_device *dev) @@ -657,7 +654,6 @@ void lance_set_multicast (struct net_device *dev) if (!stopped) netif_start_queue (dev); } -EXPORT_SYMBOL_GPL(lance_set_multicast); #ifdef CONFIG_NET_POLL_CONTROLLER void lance_poll(struct net_device *dev) diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 20b5367f7e0b..c537f53ffcb9 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -524,18 +524,6 @@ config STNIC If unsure, say N. -config SH_ETH - tristate "Renesas SuperH Ethernet support" - depends on SUPERH && \ - (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712) - select CRC32 - select MII - select MDIO_BITBANG - select PHYLIB - help - Renesas SuperH Ethernet device driver. - This driver support SH7710 and SH7712. - config SUNLANCE tristate "Sun LANCE support" depends on SBUS @@ -967,7 +955,7 @@ config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 select MII - depends on ARCH_PXA || SUPERH + depends on ARCH_PXA || SH_MAGIC_PANEL_R2 help This is a driver for SMSC's LAN911x series of Ethernet chipsets including the new LAN9115, LAN9116, LAN9117, and LAN9118. @@ -2453,7 +2441,7 @@ config CHELSIO_T3 config EHEA tristate "eHEA Ethernet support" - depends on IBMEBUS && INET && SPARSEMEM + depends on IBMEBUS && INET && SPARSEMEM && MEMORY_HOTPLUG select INET_LRO ---help--- This driver supports the IBM pSeries eHEA ethernet adapter. diff --git a/trunk/drivers/net/Makefile b/trunk/drivers/net/Makefile index c96fe2036800..dcbfe8421154 100644 --- a/trunk/drivers/net/Makefile +++ b/trunk/drivers/net/Makefile @@ -80,7 +80,6 @@ obj-$(CONFIG_VIA_RHINE) += via-rhine.o obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o obj-$(CONFIG_RIONET) += rionet.o -obj-$(CONFIG_SH_ETH) += sh_eth.o # # end link order section @@ -237,7 +236,6 @@ obj-$(CONFIG_USB_CATC) += usb/ obj-$(CONFIG_USB_KAWETH) += usb/ obj-$(CONFIG_USB_PEGASUS) += usb/ obj-$(CONFIG_USB_RTL8150) += usb/ -obj-$(CONFIG_USB_HSO) += usb/ obj-$(CONFIG_USB_USBNET) += usb/ obj-$(CONFIG_USB_ZD1201) += usb/ diff --git a/trunk/drivers/net/a2065.c b/trunk/drivers/net/a2065.c index 9c0837435b68..6c5719ae8cca 100644 --- a/trunk/drivers/net/a2065.c +++ b/trunk/drivers/net/a2065.c @@ -475,12 +475,16 @@ static irqreturn_t lance_interrupt (int irq, void *dev_id) return IRQ_HANDLED; } +struct net_device *last_dev; + static int lance_open (struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); volatile struct lance_regs *ll = lp->ll; int ret; + last_dev = dev; + /* Stop the Lance */ ll->rap = LE_CSR0; ll->rdp = LE_C0_STOP; diff --git a/trunk/drivers/net/atarilance.c b/trunk/drivers/net/atarilance.c index 0860cc280b01..4cceaac8863a 100644 --- a/trunk/drivers/net/atarilance.c +++ b/trunk/drivers/net/atarilance.c @@ -243,7 +243,7 @@ struct lance_private { /* Possible memory/IO addresses for probing */ -static struct lance_addr { +struct lance_addr { unsigned long memaddr; unsigned long ioaddr; int slow_flag; diff --git a/trunk/drivers/net/atlx/atl1.c b/trunk/drivers/net/atlx/atl1.c index 919ffb9bfa4e..32dc391e63cc 100644 --- a/trunk/drivers/net/atlx/atl1.c +++ b/trunk/drivers/net/atlx/atl1.c @@ -636,6 +636,22 @@ static s32 atl1_phy_leave_power_saving(struct atl1_hw *hw) return atl1_write_phy_reg(hw, 30, 0); } +/* + * Force the PHY into power saving mode using vendor magic. + */ +#ifdef CONFIG_PM +static void atl1_phy_enter_power_saving(struct atl1_hw *hw) +{ + atl1_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0x124E); + atl1_write_phy_reg(hw, MII_DBG_ADDR, 2); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0x3000); + atl1_write_phy_reg(hw, MII_DBG_ADDR, 3); + atl1_write_phy_reg(hw, MII_DBG_DATA, 0); + +} +#endif + /* * Resets the PHY and make all config validate * hw - Struct containing variables accessed by shared code @@ -2845,6 +2861,7 @@ static int atl1_suspend(struct pci_dev *pdev, pm_message_t state) ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; iowrite32(ctrl, hw->hw_addr + REG_PCIE_PHYMISC); ioread32(hw->hw_addr + REG_PCIE_PHYMISC); + atl1_phy_enter_power_saving(hw); hw->phy_configured = false; pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); exit: diff --git a/trunk/drivers/net/bnx2.c b/trunk/drivers/net/bnx2.c index 2c52d2c7c495..b32d22762b9b 100644 --- a/trunk/drivers/net/bnx2.c +++ b/trunk/drivers/net/bnx2.c @@ -5664,12 +5664,14 @@ bnx2_reset_task(struct work_struct *work) if (!netif_running(bp->dev)) return; + bp->in_reset_task = 1; bnx2_netif_stop(bp); bnx2_init_nic(bp, 1); atomic_set(&bp->intr_sem, 1); bnx2_netif_start(bp); + bp->in_reset_task = 0; } static void @@ -5845,7 +5847,12 @@ bnx2_close(struct net_device *dev) struct bnx2 *bp = netdev_priv(dev); u32 reset_code; - cancel_work_sync(&bp->reset_task); + /* Calling flush_scheduled_work() may deadlock because + * linkwatch_event() may be on the workqueue and it will try to get + * the rtnl_lock which we are holding. + */ + while (bp->in_reset_task) + msleep(1); bnx2_disable_int_sync(bp); bnx2_napi_disable(bp); diff --git a/trunk/drivers/net/bnx2.h b/trunk/drivers/net/bnx2.h index be7ccb5b77da..16020a10bf42 100644 --- a/trunk/drivers/net/bnx2.h +++ b/trunk/drivers/net/bnx2.h @@ -6656,6 +6656,7 @@ struct bnx2 { int current_interval; struct timer_list timer; struct work_struct reset_task; + int in_reset_task; /* Used to synchronize phy accesses. */ spinlock_t phy_lock; diff --git a/trunk/drivers/net/bnx2x.c b/trunk/drivers/net/bnx2x.c index 70cba64732ca..7bdb5af35951 100644 --- a/trunk/drivers/net/bnx2x.c +++ b/trunk/drivers/net/bnx2x.c @@ -6,8 +6,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir + * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver * UDP CSUM errata workaround by Arik Gendelman * Slowpath rework by Vladislav Zolotarov @@ -75,7 +74,7 @@ static char version[] __devinitdata = "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; -MODULE_AUTHOR("Eliezer Tamir"); +MODULE_AUTHOR("Eliezer Tamir "); MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRV_MODULE_VERSION); diff --git a/trunk/drivers/net/bnx2x.h b/trunk/drivers/net/bnx2x.h index 8e68d06510a6..4f0c0d31e7c1 100644 --- a/trunk/drivers/net/bnx2x.h +++ b/trunk/drivers/net/bnx2x.h @@ -6,8 +6,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir + * Written by: Eliezer Tamir * Based on code from Michael Chan's bnx2 driver */ diff --git a/trunk/drivers/net/bnx2x_init.h b/trunk/drivers/net/bnx2x_init.h index 370686eef97c..dcaecc53bdb1 100644 --- a/trunk/drivers/net/bnx2x_init.h +++ b/trunk/drivers/net/bnx2x_init.h @@ -6,8 +6,7 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * - * Maintained by: Eilon Greenstein - * Written by: Eliezer Tamir + * Written by: Eliezer Tamir */ #ifndef BNX2X_INIT_H diff --git a/trunk/drivers/net/declance.c b/trunk/drivers/net/declance.c index 3e3506411ac0..6b1e77cc069e 100644 --- a/trunk/drivers/net/declance.c +++ b/trunk/drivers/net/declance.c @@ -773,6 +773,8 @@ static irqreturn_t lance_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } +struct net_device *last_dev = 0; + static int lance_open(struct net_device *dev) { volatile u16 *ib = (volatile u16 *)dev->mem_start; @@ -780,6 +782,8 @@ static int lance_open(struct net_device *dev) volatile struct lance_regs *ll = lp->ll; int status = 0; + last_dev = dev; + /* Stop the Lance */ writereg(&ll->rap, LE_CSR0); writereg(&ll->rdp, LE_C0_STOP); diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index ccb8ca2cbb2b..cab1835173cd 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -4343,11 +4343,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_TSO; netdev->features |= NETIF_F_TSO6; - netdev->vlan_features |= NETIF_F_TSO; - netdev->vlan_features |= NETIF_F_TSO6; - netdev->vlan_features |= NETIF_F_HW_CSUM; - netdev->vlan_features |= NETIF_F_SG; - if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/trunk/drivers/net/ehea/ehea_main.c b/trunk/drivers/net/ehea/ehea_main.c index 075fd547421e..287a61918739 100644 --- a/trunk/drivers/net/ehea/ehea_main.c +++ b/trunk/drivers/net/ehea/ehea_main.c @@ -1766,20 +1766,16 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa) mutex_lock(&ehea_bcmc_regs.lock); /* Deregister old MAC in pHYP */ - if (port->state == EHEA_PORT_UP) { - ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); - if (ret) - goto out_upregs; - } + ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC); + if (ret) + goto out_upregs; port->mac_addr = cb0->port_mac_addr << 16; /* Register new MAC in pHYP */ - if (port->state == EHEA_PORT_UP) { - ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); - if (ret) - goto out_upregs; - } + ret = ehea_broadcast_reg_helper(port, H_REG_BCMC); + if (ret) + goto out_upregs; ret = 0; @@ -2605,8 +2601,7 @@ static int ehea_stop(struct net_device *dev) if (netif_msg_ifdown(port)) ehea_info("disabling port %s", dev->name); - cancel_work_sync(&port->reset_task); - + flush_scheduled_work(); mutex_lock(&port->port_lock); netif_stop_queue(dev); port_napi_disable(port); diff --git a/trunk/drivers/net/fec_mpc52xx.c b/trunk/drivers/net/fec_mpc52xx.c index 329edd9c08fc..5f9c42e7a7f1 100644 --- a/trunk/drivers/net/fec_mpc52xx.c +++ b/trunk/drivers/net/fec_mpc52xx.c @@ -78,7 +78,7 @@ module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0); MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ - NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) + NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN ) static int debug = -1; /* the above default */ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "debugging messages level"); diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index c980ce9719af..e4d697894364 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -3277,20 +3277,6 @@ static void nv_link_irq(struct net_device *dev) dprintk(KERN_DEBUG "%s: link change notification done.\n", dev->name); } -static void nv_msi_workaround(struct fe_priv *np) -{ - - /* Need to toggle the msi irq mask within the ethernet device, - * otherwise, future interrupts will not be detected. - */ - if (np->msi_flags & NV_MSI_ENABLED) { - u8 __iomem *base = np->base; - - writel(0, base + NvRegMSIIrqMask); - writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask); - } -} - static irqreturn_t nv_nic_irq(int foo, void *data) { struct net_device *dev = (struct net_device *) data; @@ -3313,8 +3299,6 @@ static irqreturn_t nv_nic_irq(int foo, void *data) if (!(events & np->irqmask)) break; - nv_msi_workaround(np); - spin_lock(&np->lock); nv_tx_done(dev); spin_unlock(&np->lock); @@ -3430,8 +3414,6 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) if (!(events & np->irqmask)) break; - nv_msi_workaround(np); - spin_lock(&np->lock); nv_tx_done_optimized(dev, TX_WORK_PER_LOOP); spin_unlock(&np->lock); @@ -3772,8 +3754,6 @@ static irqreturn_t nv_nic_irq_test(int foo, void *data) if (!(events & NVREG_IRQ_TIMER)) return IRQ_RETVAL(0); - nv_msi_workaround(np); - spin_lock(&np->lock); np->intr_test = 1; spin_unlock(&np->lock); diff --git a/trunk/drivers/net/hamradio/baycom_epp.c b/trunk/drivers/net/hamradio/baycom_epp.c index 00bc7fbb6b37..dde9c7e6408a 100644 --- a/trunk/drivers/net/hamradio/baycom_epp.c +++ b/trunk/drivers/net/hamradio/baycom_epp.c @@ -959,7 +959,7 @@ static int epp_close(struct net_device *dev) unsigned char tmp[1]; bc->work_running = 0; - cancel_delayed_work_sync(&bc->run_work); + flush_scheduled_work(); bc->stat = EPP_DCDBIT; tmp[0] = 0; pp->ops->epp_write_addr(pp, tmp, 1, 0); diff --git a/trunk/drivers/net/hplance.c b/trunk/drivers/net/hplance.c index 2e802634d366..be6e5bc7c881 100644 --- a/trunk/drivers/net/hplance.c +++ b/trunk/drivers/net/hplance.c @@ -220,12 +220,12 @@ static int hplance_close(struct net_device *dev) return 0; } -static int __init hplance_init_module(void) +int __init hplance_init_module(void) { return dio_register_driver(&hplance_driver); } -static void __exit hplance_cleanup_module(void) +void __exit hplance_cleanup_module(void) { dio_unregister_driver(&hplance_driver); } diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 7b6b780dc8a6..ae398f04c7b4 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -967,13 +967,8 @@ static int __devinit igb_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - - netdev->vlan_features |= NETIF_F_TSO; - netdev->vlan_features |= NETIF_F_TSO6; - netdev->vlan_features |= NETIF_F_HW_CSUM; - netdev->vlan_features |= NETIF_F_SG; + netdev->features |= NETIF_F_TSO6; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/trunk/drivers/net/ipg.c b/trunk/drivers/net/ipg.c index 679a0826780e..9b358f61ed7f 100644 --- a/trunk/drivers/net/ipg.c +++ b/trunk/drivers/net/ipg.c @@ -577,12 +577,12 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) /* NIC to be configured in promiscuous mode. */ receivemode = IPG_RM_RECEIVEALLFRAMES; } else if ((dev->flags & IFF_ALLMULTI) || - ((dev->flags & IFF_MULTICAST) && + (dev->flags & IFF_MULTICAST & (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { /* NIC to be configured to receive all multicast * frames. */ receivemode |= IPG_RM_RECEIVEMULTICAST; - } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { + } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { /* NIC to be configured to receive selected * multicast addresses. */ receivemode |= IPG_RM_RECEIVEMULTICASTHASH; diff --git a/trunk/drivers/net/ixgbe/ixgbe_82598.c b/trunk/drivers/net/ixgbe/ixgbe_82598.c index 2f38e847e2cd..6321b059ce13 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82598.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82598.c @@ -58,8 +58,8 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) { - hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES; - hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES; + hw->mac.num_rx_queues = IXGBE_82598_MAX_TX_QUEUES; + hw->mac.num_tx_queues = IXGBE_82598_MAX_RX_QUEUES; hw->mac.num_rx_addrs = IXGBE_82598_RAR_ENTRIES; /* PHY ops are filled in by default properly for Fiber only */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index 0d37c9025be4..7b859220c255 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -3518,13 +3518,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_TSO; - netdev->features |= NETIF_F_TSO6; - - netdev->vlan_features |= NETIF_F_TSO; - netdev->vlan_features |= NETIF_F_TSO6; - netdev->vlan_features |= NETIF_F_HW_CSUM; - netdev->vlan_features |= NETIF_F_SG; + netdev->features |= NETIF_F_TSO6; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; diff --git a/trunk/drivers/net/lib8390.c b/trunk/drivers/net/lib8390.c index 00d59ab2f8ac..ed495275b577 100644 --- a/trunk/drivers/net/lib8390.c +++ b/trunk/drivers/net/lib8390.c @@ -553,8 +553,6 @@ static void __ei_poll(struct net_device *dev) static void ei_tx_err(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; - /* ei_local is used on some platforms via the EI_SHIFT macro */ - struct ei_device *ei_local __maybe_unused = netdev_priv(dev); unsigned char txsr = ei_inb_p(e8390_base+EN0_TSR); unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); @@ -817,8 +815,6 @@ static void ei_rx_overrun(struct net_device *dev) { unsigned long e8390_base = dev->base_addr; unsigned char was_txing, must_resend = 0; - /* ei_local is used on some platforms via the EI_SHIFT macro */ - struct ei_device *ei_local __maybe_unused = netdev_priv(dev); /* * Record whether a Tx was in progress and then issue the diff --git a/trunk/drivers/net/mac8390.c b/trunk/drivers/net/mac8390.c index 98e3eb2697c9..9e700749bb31 100644 --- a/trunk/drivers/net/mac8390.c +++ b/trunk/drivers/net/mac8390.c @@ -117,6 +117,8 @@ enum mac8390_access { ACCESS_16, }; +extern enum mac8390_type mac8390_ident(struct nubus_dev * dev); +extern int mac8390_memsize(unsigned long membase); extern int mac8390_memtest(struct net_device * dev); static int mac8390_initdev(struct net_device * dev, struct nubus_dev * ndev, enum mac8390_type type); @@ -161,7 +163,7 @@ static void slow_sane_block_output(struct net_device *dev, int count, static void word_memcpy_tocard(void *tp, const void *fp, int count); static void word_memcpy_fromcard(void *tp, const void *fp, int count); -static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev) +enum mac8390_type __init mac8390_ident(struct nubus_dev * dev) { switch (dev->dr_sw) { case NUBUS_DRSW_3COM: @@ -232,7 +234,7 @@ static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev) return MAC8390_NONE; } -static enum mac8390_access __init mac8390_testio(volatile unsigned long membase) +enum mac8390_access __init mac8390_testio(volatile unsigned long membase) { unsigned long outdata = 0xA5A0B5B0; unsigned long indata = 0x00000000; @@ -250,7 +252,7 @@ static enum mac8390_access __init mac8390_testio(volatile unsigned long membase) return ACCESS_UNKNOWN; } -static int __init mac8390_memsize(unsigned long membase) +int __init mac8390_memsize(unsigned long membase) { unsigned long flags; int i, j; diff --git a/trunk/drivers/net/macb.c b/trunk/drivers/net/macb.c index e34630252cef..92dccd43bdca 100644 --- a/trunk/drivers/net/macb.c +++ b/trunk/drivers/net/macb.c @@ -80,12 +80,8 @@ static void __init macb_get_hwaddr(struct macb *bp) addr[4] = top & 0xff; addr[5] = (top >> 8) & 0xff; - if (is_valid_ether_addr(addr)) { + if (is_valid_ether_addr(addr)) memcpy(bp->dev->dev_addr, addr, sizeof(addr)); - } else { - dev_info(&bp->pdev->dev, "invalid hw address, using random\n"); - random_ether_addr(bp->dev->dev_addr); - } } static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum) diff --git a/trunk/drivers/net/macsonic.c b/trunk/drivers/net/macsonic.c index e64c2086d33c..b267161418ea 100644 --- a/trunk/drivers/net/macsonic.c +++ b/trunk/drivers/net/macsonic.c @@ -83,6 +83,9 @@ static unsigned int sonic_debug = 1; static int sonic_version_printed; +extern int mac_onboard_sonic_probe(struct net_device* dev); +extern int mac_nubus_sonic_probe(struct net_device* dev); + /* For onboard SONIC */ #define ONBOARD_SONIC_REGISTERS 0x50F0A000 #define ONBOARD_SONIC_PROM_BASE 0x50f08000 @@ -167,7 +170,7 @@ static int macsonic_close(struct net_device* dev) return err; } -static int __init macsonic_init(struct net_device *dev) +int __init macsonic_init(struct net_device* dev) { struct sonic_local* lp = netdev_priv(dev); @@ -215,7 +218,7 @@ static int __init macsonic_init(struct net_device *dev) return 0; } -static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) +int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) { struct sonic_local *lp = netdev_priv(dev); const int prom_addr = ONBOARD_SONIC_PROM_BASE; @@ -281,7 +284,7 @@ static int __init mac_onboard_sonic_ethernet_addr(struct net_device *dev) } else return 0; } -static int __init mac_onboard_sonic_probe(struct net_device *dev) +int __init mac_onboard_sonic_probe(struct net_device* dev) { /* Bwahahaha */ static int once_is_more_than_enough; @@ -402,9 +405,9 @@ static int __init mac_onboard_sonic_probe(struct net_device *dev) return macsonic_init(dev); } -static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, - unsigned long prom_addr, - int id) +int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev, + unsigned long prom_addr, + int id) { int i; for(i = 0; i < 6; i++) @@ -417,7 +420,7 @@ static int __init mac_nubus_sonic_ethernet_addr(struct net_device *dev, return 0; } -static int __init macsonic_ident(struct nubus_dev *ndev) +int __init macsonic_ident(struct nubus_dev* ndev) { if (ndev->dr_hw == NUBUS_DRHW_ASANTE_LC && ndev->dr_sw == NUBUS_DRSW_SONIC_LC) @@ -442,7 +445,7 @@ static int __init macsonic_ident(struct nubus_dev *ndev) return -1; } -static int __init mac_nubus_sonic_probe(struct net_device *dev) +int __init mac_nubus_sonic_probe(struct net_device* dev) { static int slots; struct nubus_dev* ndev = NULL; diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index b7915cdcc6a5..835b85d30bc6 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -62,6 +62,9 @@ #include #include +static char mv643xx_driver_name[] = "mv643xx_eth"; +static char mv643xx_driver_version[] = "1.0"; + #define MV643XX_CHECKSUM_OFFLOAD_TX #define MV643XX_NAPI #define MV643XX_TX_FAST_REFILL @@ -478,7 +481,21 @@ struct pkt_info { struct sk_buff *return_info; /* User resource return information */ }; -/* Ethernet port specific information */ + +/* global *******************************************************************/ +struct mv643xx_shared_private { + void __iomem *eth_base; + + /* used to protect SMI_REG, which is shared across ports */ + spinlock_t phy_lock; + + u32 win_protect; + + unsigned int t_clk; +}; + + +/* per-port *****************************************************************/ struct mv643xx_mib_counters { u64 good_octets_received; u32 bad_octets_received; @@ -512,17 +529,6 @@ struct mv643xx_mib_counters { u32 late_collision; }; -struct mv643xx_shared_private { - void __iomem *eth_base; - - /* used to protect SMI_REG, which is shared across ports */ - spinlock_t phy_lock; - - u32 win_protect; - - unsigned int t_clk; -}; - struct mv643xx_private { struct mv643xx_shared_private *shared; int port_num; /* User Ethernet port number */ @@ -585,93 +591,135 @@ struct mv643xx_private { struct mii_if_info mii; }; -/* Static function declarations */ -static void eth_port_init(struct mv643xx_private *mp); -static void eth_port_reset(struct mv643xx_private *mp); -static void eth_port_start(struct net_device *dev); -static void ethernet_phy_reset(struct mv643xx_private *mp); +/* port register accessors **************************************************/ +static inline u32 rdl(struct mv643xx_private *mp, int offset) +{ + return readl(mp->shared->eth_base + offset); +} -static void eth_port_write_smi_reg(struct mv643xx_private *mp, - unsigned int phy_reg, unsigned int value); +static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) +{ + writel(data, mp->shared->eth_base + offset); +} -static void eth_port_read_smi_reg(struct mv643xx_private *mp, - unsigned int phy_reg, unsigned int *value); -static void eth_clear_mib_counters(struct mv643xx_private *mp); +/* rxq/txq helper functions *************************************************/ +static void mv643xx_eth_port_enable_rx(struct mv643xx_private *mp, + unsigned int queues) +{ + wrl(mp, RECEIVE_QUEUE_COMMAND_REG(mp->port_num), queues); +} -static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, - struct pkt_info *p_pkt_info); -static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, - struct pkt_info *p_pkt_info); +static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_private *mp) +{ + unsigned int port_num = mp->port_num; + u32 queues; -static void eth_port_uc_addr_get(struct mv643xx_private *mp, - unsigned char *p_addr); -static void eth_port_uc_addr_set(struct mv643xx_private *mp, - unsigned char *p_addr); -static void eth_port_set_multicast_list(struct net_device *); -static void mv643xx_eth_port_enable_tx(struct mv643xx_private *mp, - unsigned int queues); -static void mv643xx_eth_port_enable_rx(struct mv643xx_private *mp, - unsigned int queues); -static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_private *mp); -static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_private *mp); -static int mv643xx_eth_open(struct net_device *); -static int mv643xx_eth_stop(struct net_device *); -static void eth_port_init_mac_tables(struct mv643xx_private *mp); -#ifdef MV643XX_NAPI -static int mv643xx_poll(struct napi_struct *napi, int budget); -#endif -static int ethernet_phy_get(struct mv643xx_private *mp); -static void ethernet_phy_set(struct mv643xx_private *mp, int phy_addr); -static int ethernet_phy_detect(struct mv643xx_private *mp); -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location); -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val); -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -static const struct ethtool_ops mv643xx_ethtool_ops; + /* Stop Rx port activity. Check port Rx activity. */ + queues = rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF; + if (queues) { + /* Issue stop command for active queues only */ + wrl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num), (queues << 8)); -static char mv643xx_driver_name[] = "mv643xx_eth"; -static char mv643xx_driver_version[] = "1.0"; + /* Wait for all Rx activity to terminate. */ + /* Check port cause register that all Rx queues are stopped */ + while (rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF) + udelay(PHY_WAIT_MICRO_SECONDS); + } -static inline u32 rdl(struct mv643xx_private *mp, int offset) + return queues; +} + +static void mv643xx_eth_port_enable_tx(struct mv643xx_private *mp, + unsigned int queues) { - return readl(mp->shared->eth_base + offset); + wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(mp->port_num), queues); } -static inline void wrl(struct mv643xx_private *mp, int offset, u32 data) +static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_private *mp) { - writel(data, mp->shared->eth_base + offset); + unsigned int port_num = mp->port_num; + u32 queues; + + /* Stop Tx port activity. Check port Tx activity. */ + queues = rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF; + if (queues) { + /* Issue stop command for active queues only */ + wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num), (queues << 8)); + + /* Wait for all Tx activity to terminate. */ + /* Check port cause register that all Tx queues are stopped */ + while (rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF) + udelay(PHY_WAIT_MICRO_SECONDS); + + /* Wait for Tx FIFO to empty */ + while (rdl(mp, PORT_STATUS_REG(port_num)) & + ETH_PORT_TX_FIFO_EMPTY) + udelay(PHY_WAIT_MICRO_SECONDS); + } + + return queues; } + +/* rx ***********************************************************************/ +static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev); + /* - * Changes MTU (maximum transfer unit) of the gigabit ethenret port + * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring. * - * Input : pointer to ethernet interface network device structure - * new mtu size - * Output : 0 upon success, -EINVAL upon failure + * DESCRIPTION: + * This routine returns a Rx buffer back to the Rx ring. It retrieves the + * next 'used' descriptor and attached the returned buffer to it. + * In case the Rx ring was in "resource error" condition, where there are + * no available Rx resources, the function resets the resource error flag. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct pkt_info *p_pkt_info Information on returned buffer. + * + * OUTPUT: + * New available Rx resource in Rx descriptor ring. + * + * RETURN: + * ETH_ERROR in case the routine can not access Rx desc ring. + * ETH_OK otherwise. */ -static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) +static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info) { - if ((new_mtu > 9500) || (new_mtu < 64)) - return -EINVAL; + int used_rx_desc; /* Where to return Rx resource */ + volatile struct eth_rx_desc *p_used_rx_desc; + unsigned long flags; - dev->mtu = new_mtu; - if (!netif_running(dev)) - return 0; + spin_lock_irqsave(&mp->lock, flags); - /* - * Stop and then re-open the interface. This will allocate RX - * skbs of the new MTU. - * There is a possible danger that the open will not succeed, - * due to memory being full, which might fail the open function. - */ - mv643xx_eth_stop(dev); - if (mv643xx_eth_open(dev)) { - printk(KERN_ERR "%s: Fatal error on opening device\n", - dev->name); - } + /* Get 'used' Rx descriptor */ + used_rx_desc = mp->rx_used_desc_q; + p_used_rx_desc = &mp->p_rx_desc_area[used_rx_desc]; - return 0; + p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr; + p_used_rx_desc->buf_size = p_pkt_info->byte_cnt; + mp->rx_skb[used_rx_desc] = p_pkt_info->return_info; + + /* Flush the write pipe */ + + /* Return the descriptor to DMA ownership */ + wmb(); + p_used_rx_desc->cmd_sts = + ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT; + wmb(); + + /* Move the used descriptor pointer to the next descriptor */ + mp->rx_used_desc_q = (used_rx_desc + 1) % mp->rx_ring_size; + + /* Any Rx return cancels the Rx resource error status */ + mp->rx_resource_err = 0; + + spin_unlock_irqrestore(&mp->lock, flags); + + return ETH_OK; } /* @@ -736,184 +784,81 @@ static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data) } /* - * mv643xx_eth_update_mac_address + * eth_port_receive - Get received information from Rx ring. * - * Update the MAC address of the port in the address table + * DESCRIPTION: + * This routine returns the received data to the caller. There is no + * data copying during routine operation. All information is returned + * using pointer to packet information struct passed from the caller. + * If the routine exhausts Rx ring resources then the resource error flag + * is set. * - * Input : pointer to ethernet interface network device structure - * Output : N/A - */ -static void mv643xx_eth_update_mac_address(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - eth_port_init_mac_tables(mp); - eth_port_uc_addr_set(mp, dev->dev_addr); -} - -/* - * mv643xx_eth_set_rx_mode + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct pkt_info *p_pkt_info User packet buffer. * - * Change from promiscuos to regular rx mode + * OUTPUT: + * Rx ring current and used indexes are updated. * - * Input : pointer to ethernet interface network device structure - * Output : N/A + * RETURN: + * ETH_ERROR in case the routine can not access Rx desc ring. + * ETH_QUEUE_FULL if Rx ring resources are exhausted. + * ETH_END_OF_JOB if there is no received data. + * ETH_OK otherwise. */ -static void mv643xx_eth_set_rx_mode(struct net_device *dev) +static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, + struct pkt_info *p_pkt_info) { - struct mv643xx_private *mp = netdev_priv(dev); - u32 config_reg; + int rx_next_curr_desc, rx_curr_desc, rx_used_desc; + volatile struct eth_rx_desc *p_rx_desc; + unsigned int command_status; + unsigned long flags; - config_reg = rdl(mp, PORT_CONFIG_REG(mp->port_num)); - if (dev->flags & IFF_PROMISC) - config_reg |= (u32) UNICAST_PROMISCUOUS_MODE; - else - config_reg &= ~(u32) UNICAST_PROMISCUOUS_MODE; - wrl(mp, PORT_CONFIG_REG(mp->port_num), config_reg); + /* Do not process Rx ring in case of Rx ring resource error */ + if (mp->rx_resource_err) + return ETH_QUEUE_FULL; - eth_port_set_multicast_list(dev); -} + spin_lock_irqsave(&mp->lock, flags); -/* - * mv643xx_eth_set_mac_address - * - * Change the interface's mac address. - * No special hardware thing should be done because interface is always - * put in promiscuous mode. - * - * Input : pointer to ethernet interface network device structure and - * a pointer to the designated entry to be added to the cache. - * Output : zero upon success, negative upon failure - */ -static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr) -{ - int i; + /* Get the Rx Desc ring 'curr and 'used' indexes */ + rx_curr_desc = mp->rx_curr_desc_q; + rx_used_desc = mp->rx_used_desc_q; - for (i = 0; i < 6; i++) - /* +2 is for the offset of the HW addr type */ - dev->dev_addr[i] = ((unsigned char *)addr)[i + 2]; - mv643xx_eth_update_mac_address(dev); - return 0; -} + p_rx_desc = &mp->p_rx_desc_area[rx_curr_desc]; -/* - * mv643xx_eth_tx_timeout - * - * Called upon a timeout on transmitting a packet - * - * Input : pointer to ethernet interface network device structure. - * Output : N/A - */ -static void mv643xx_eth_tx_timeout(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); - - printk(KERN_INFO "%s: TX timeout ", dev->name); - - /* Do the reset outside of interrupt context */ - schedule_work(&mp->tx_timeout_task); -} - -/* - * mv643xx_eth_tx_timeout_task - * - * Actual routine to reset the adapter when a timeout on Tx has occurred - */ -static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly) -{ - struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private, - tx_timeout_task); - struct net_device *dev = mp->dev; - - if (!netif_running(dev)) - return; - - netif_stop_queue(dev); - - eth_port_reset(mp); - eth_port_start(dev); - - if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) - netif_wake_queue(dev); -} - -/** - * mv643xx_eth_free_tx_descs - Free the tx desc data for completed descriptors - * - * If force is non-zero, frees uncompleted descriptors as well - */ -static int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) -{ - struct mv643xx_private *mp = netdev_priv(dev); - struct eth_tx_desc *desc; - u32 cmd_sts; - struct sk_buff *skb; - unsigned long flags; - int tx_index; - dma_addr_t addr; - int count; - int released = 0; - - while (mp->tx_desc_count > 0) { - spin_lock_irqsave(&mp->lock, flags); - - /* tx_desc_count might have changed before acquiring the lock */ - if (mp->tx_desc_count <= 0) { - spin_unlock_irqrestore(&mp->lock, flags); - return released; - } - - tx_index = mp->tx_used_desc_q; - desc = &mp->p_tx_desc_area[tx_index]; - cmd_sts = desc->cmd_sts; - - if (!force && (cmd_sts & ETH_BUFFER_OWNED_BY_DMA)) { - spin_unlock_irqrestore(&mp->lock, flags); - return released; - } - - mp->tx_used_desc_q = (tx_index + 1) % mp->tx_ring_size; - mp->tx_desc_count--; - - addr = desc->buf_ptr; - count = desc->byte_cnt; - skb = mp->tx_skb[tx_index]; - if (skb) - mp->tx_skb[tx_index] = NULL; - - if (cmd_sts & ETH_ERROR_SUMMARY) { - printk("%s: Error in TX\n", dev->name); - dev->stats.tx_errors++; - } + /* The following parameters are used to save readings from memory */ + command_status = p_rx_desc->cmd_sts; + rmb(); + /* Nothing to receive... */ + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { spin_unlock_irqrestore(&mp->lock, flags); + return ETH_END_OF_JOB; + } - if (cmd_sts & ETH_TX_FIRST_DESC) - dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); - else - dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE); - - if (skb) - dev_kfree_skb_irq(skb); + p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET; + p_pkt_info->cmd_sts = command_status; + p_pkt_info->buf_ptr = (p_rx_desc->buf_ptr) + RX_BUF_OFFSET; + p_pkt_info->return_info = mp->rx_skb[rx_curr_desc]; + p_pkt_info->l4i_chk = p_rx_desc->buf_size; - released = 1; - } + /* + * Clean the return info field to indicate that the + * packet has been moved to the upper layers + */ + mp->rx_skb[rx_curr_desc] = NULL; - return released; -} + /* Update current index in data structure */ + rx_next_curr_desc = (rx_curr_desc + 1) % mp->rx_ring_size; + mp->rx_curr_desc_q = rx_next_curr_desc; -static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev) -{ - struct mv643xx_private *mp = netdev_priv(dev); + /* Rx descriptors exhausted. Set the Rx ring resource error flag */ + if (rx_next_curr_desc == rx_used_desc) + mp->rx_resource_err = 1; - if (mv643xx_eth_free_tx_descs(dev, 0) && - mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) - netif_wake_queue(dev); -} + spin_unlock_irqrestore(&mp->lock, flags); -static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) -{ - mv643xx_eth_free_tx_descs(dev, 1); + return ETH_OK; } /* @@ -996,296 +941,458 @@ static int mv643xx_eth_receive_queue(struct net_device *dev, int budget) return received_packets; } -/* Set the mv643xx port configuration register for the speed/duplex mode. */ -static void mv643xx_eth_update_pscr(struct net_device *dev, - struct ethtool_cmd *ecmd) +#ifdef MV643XX_NAPI +/* + * mv643xx_poll + * + * This function is used in case of NAPI + */ +static int mv643xx_poll(struct napi_struct *napi, int budget) { - struct mv643xx_private *mp = netdev_priv(dev); - int port_num = mp->port_num; - u32 o_pscr, n_pscr; - unsigned int queues; - - o_pscr = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num)); - n_pscr = o_pscr; - - /* clear speed, duplex and rx buffer size fields */ - n_pscr &= ~(SET_MII_SPEED_TO_100 | - SET_GMII_SPEED_TO_1000 | - SET_FULL_DUPLEX_MODE | - MAX_RX_PACKET_MASK); - - if (ecmd->duplex == DUPLEX_FULL) - n_pscr |= SET_FULL_DUPLEX_MODE; + struct mv643xx_private *mp = container_of(napi, struct mv643xx_private, napi); + struct net_device *dev = mp->dev; + unsigned int port_num = mp->port_num; + int work_done; - if (ecmd->speed == SPEED_1000) - n_pscr |= SET_GMII_SPEED_TO_1000 | - MAX_RX_PACKET_9700BYTE; - else { - if (ecmd->speed == SPEED_100) - n_pscr |= SET_MII_SPEED_TO_100; - n_pscr |= MAX_RX_PACKET_1522BYTE; +#ifdef MV643XX_TX_FAST_REFILL + if (++mp->tx_clean_threshold > 5) { + mv643xx_eth_free_completed_tx_descs(dev); + mp->tx_clean_threshold = 0; } +#endif - if (n_pscr != o_pscr) { - if ((o_pscr & SERIAL_PORT_ENABLE) == 0) - wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); - else { - queues = mv643xx_eth_port_disable_tx(mp); + work_done = 0; + if ((rdl(mp, RX_CURRENT_QUEUE_DESC_PTR_0(port_num))) + != (u32) mp->rx_used_desc_q) + work_done = mv643xx_eth_receive_queue(dev, budget); - o_pscr &= ~SERIAL_PORT_ENABLE; - wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), o_pscr); - wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); - wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); - if (queues) - mv643xx_eth_port_enable_tx(mp, queues); - } + if (work_done < budget) { + netif_rx_complete(dev, napi); + wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0); + wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); } + + return work_done; } +#endif -/* - * mv643xx_eth_int_handler - * - * Main interrupt handler for the gigbit ethernet ports + +/* tx ***********************************************************************/ +/** + * has_tiny_unaligned_frags - check if skb has any small, unaligned fragments * - * Input : irq - irq number (not used) - * dev_id - a pointer to the required interface's data structure - * regs - not used - * Output : N/A + * Hardware can't handle unaligned fragments smaller than 9 bytes. + * This helper function detects that case. */ -static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) +static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) { - struct net_device *dev = (struct net_device *)dev_id; - struct mv643xx_private *mp = netdev_priv(dev); - u32 eth_int_cause, eth_int_cause_ext = 0; - unsigned int port_num = mp->port_num; + unsigned int frag; + skb_frag_t *fragp; - /* Read interrupt cause registers */ - eth_int_cause = rdl(mp, INTERRUPT_CAUSE_REG(port_num)) & - ETH_INT_UNMASK_ALL; - if (eth_int_cause & ETH_INT_CAUSE_EXT) { - eth_int_cause_ext = rdl(mp, - INTERRUPT_CAUSE_EXTEND_REG(port_num)) & - ETH_INT_UNMASK_ALL_EXT; - wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), - ~eth_int_cause_ext); + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + fragp = &skb_shinfo(skb)->frags[frag]; + if (fragp->size <= 8 && fragp->page_offset & 0x7) + return 1; } + return 0; +} - /* PHY status changed */ - if (eth_int_cause_ext & (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) { - struct ethtool_cmd cmd; +/** + * eth_alloc_tx_desc_index - return the index of the next available tx desc + */ +static int eth_alloc_tx_desc_index(struct mv643xx_private *mp) +{ + int tx_desc_curr; - if (mii_link_ok(&mp->mii)) { - mii_ethtool_gset(&mp->mii, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED); - if (!netif_carrier_ok(dev)) { - netif_carrier_on(dev); - if (mp->tx_ring_size - mp->tx_desc_count >= - MAX_DESCS_PER_SKB) - netif_wake_queue(dev); - } - } else if (netif_carrier_ok(dev)) { - netif_stop_queue(dev); - netif_carrier_off(dev); - } - } + BUG_ON(mp->tx_desc_count >= mp->tx_ring_size); -#ifdef MV643XX_NAPI - if (eth_int_cause & ETH_INT_CAUSE_RX) { - /* schedule the NAPI poll routine to maintain port */ - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); + tx_desc_curr = mp->tx_curr_desc_q; + mp->tx_curr_desc_q = (tx_desc_curr + 1) % mp->tx_ring_size; - /* wait for previous write to complete */ - rdl(mp, INTERRUPT_MASK_REG(port_num)); + BUG_ON(mp->tx_curr_desc_q == mp->tx_used_desc_q); - netif_rx_schedule(dev, &mp->napi); - } -#else - if (eth_int_cause & ETH_INT_CAUSE_RX) - mv643xx_eth_receive_queue(dev, INT_MAX); -#endif - if (eth_int_cause_ext & ETH_INT_CAUSE_TX) - mv643xx_eth_free_completed_tx_descs(dev); + return tx_desc_curr; +} - /* - * If no real interrupt occured, exit. - * This can happen when using gigE interrupt coalescing mechanism. - */ - if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0)) - return IRQ_NONE; +/** + * eth_tx_fill_frag_descs - fill tx hw descriptors for an skb's fragments. + * + * Ensure the data for each fragment to be transmitted is mapped properly, + * then fill in descriptors in the tx hw queue. + */ +static void eth_tx_fill_frag_descs(struct mv643xx_private *mp, + struct sk_buff *skb) +{ + int frag; + int tx_index; + struct eth_tx_desc *desc; - return IRQ_HANDLED; + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + + tx_index = eth_alloc_tx_desc_index(mp); + desc = &mp->p_tx_desc_area[tx_index]; + + desc->cmd_sts = ETH_BUFFER_OWNED_BY_DMA; + /* Last Frag enables interrupt and frees the skb */ + if (frag == (skb_shinfo(skb)->nr_frags - 1)) { + desc->cmd_sts |= ETH_ZERO_PADDING | + ETH_TX_LAST_DESC | + ETH_TX_ENABLE_INTERRUPT; + mp->tx_skb[tx_index] = skb; + } else + mp->tx_skb[tx_index] = NULL; + + desc = &mp->p_tx_desc_area[tx_index]; + desc->l4i_chk = 0; + desc->byte_cnt = this_frag->size; + desc->buf_ptr = dma_map_page(NULL, this_frag->page, + this_frag->page_offset, + this_frag->size, + DMA_TO_DEVICE); + } } -#ifdef MV643XX_COAL +static inline __be16 sum16_as_be(__sum16 sum) +{ + return (__force __be16)sum; +} -/* - * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path - * - * DESCRIPTION: - * This routine sets the RX coalescing interrupt mechanism parameter. - * This parameter is a timeout counter, that counts in 64 t_clk - * chunks ; that when timeout event occurs a maskable interrupt - * occurs. - * The parameter is calculated using the tClk of the MV-643xx chip - * , and the required delay of the interrupt in usec. - * - * INPUT: - * struct mv643xx_private *mp Ethernet port - * unsigned int delay Delay in usec - * - * OUTPUT: - * Interrupt coalescing mechanism value is set in MV-643xx chip. - * - * RETURN: - * The interrupt coalescing value set in the gigE port. +/** + * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw * + * Ensure the data for an skb to be transmitted is mapped properly, + * then fill in descriptors in the tx hw queue and start the hardware. */ -static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, - unsigned int delay) +static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, + struct sk_buff *skb) { - unsigned int port_num = mp->port_num; - unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; + int tx_index; + struct eth_tx_desc *desc; + u32 cmd_sts; + int length; + int nr_frags = skb_shinfo(skb)->nr_frags; - /* Set RX Coalescing mechanism */ - wrl(mp, SDMA_CONFIG_REG(port_num), - ((coal & 0x3fff) << 8) | - (rdl(mp, SDMA_CONFIG_REG(port_num)) - & 0xffc000ff)); + cmd_sts = ETH_TX_FIRST_DESC | ETH_GEN_CRC | ETH_BUFFER_OWNED_BY_DMA; - return coal; + tx_index = eth_alloc_tx_desc_index(mp); + desc = &mp->p_tx_desc_area[tx_index]; + + if (nr_frags) { + eth_tx_fill_frag_descs(mp, skb); + + length = skb_headlen(skb); + mp->tx_skb[tx_index] = NULL; + } else { + cmd_sts |= ETH_ZERO_PADDING | + ETH_TX_LAST_DESC | + ETH_TX_ENABLE_INTERRUPT; + length = skb->len; + mp->tx_skb[tx_index] = skb; + } + + desc->byte_cnt = length; + desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + BUG_ON(skb->protocol != htons(ETH_P_IP)); + + cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | + ETH_GEN_IP_V_4_CHECKSUM | + ip_hdr(skb)->ihl << ETH_TX_IHL_SHIFT; + + switch (ip_hdr(skb)->protocol) { + case IPPROTO_UDP: + cmd_sts |= ETH_UDP_FRAME; + desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check)); + break; + case IPPROTO_TCP: + desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check)); + break; + default: + BUG(); + } + } else { + /* Errata BTS #50, IHL must be 5 if no HW checksum */ + cmd_sts |= 5 << ETH_TX_IHL_SHIFT; + desc->l4i_chk = 0; + } + + /* ensure all other descriptors are written before first cmd_sts */ + wmb(); + desc->cmd_sts = cmd_sts; + + /* ensure all descriptors are written before poking hardware */ + wmb(); + mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED); + + mp->tx_desc_count += nr_frags + 1; } -#endif -/* - * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path - * - * DESCRIPTION: - * This routine sets the TX coalescing interrupt mechanism parameter. - * This parameter is a timeout counter, that counts in 64 t_clk - * chunks ; that when timeout event occurs a maskable interrupt - * occurs. - * The parameter is calculated using the t_cLK frequency of the - * MV-643xx chip and the required delay in the interrupt in uSec - * - * INPUT: - * struct mv643xx_private *mp Ethernet port - * unsigned int delay Delay in uSeconds - * - * OUTPUT: - * Interrupt coalescing mechanism value is set in MV-643xx chip. - * - * RETURN: - * The interrupt coalescing value set in the gigE port. +/** + * mv643xx_eth_start_xmit - queue an skb to the hardware for transmission * */ -static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, - unsigned int delay) +static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) { - unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; + struct mv643xx_private *mp = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + unsigned long flags; - /* Set TX Coalescing mechanism */ - wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); + BUG_ON(netif_queue_stopped(dev)); - return coal; + if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) { + stats->tx_dropped++; + printk(KERN_DEBUG "%s: failed to linearize tiny " + "unaligned fragment\n", dev->name); + return NETDEV_TX_BUSY; + } + + spin_lock_irqsave(&mp->lock, flags); + + if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) { + printk(KERN_ERR "%s: transmit with queue full\n", dev->name); + netif_stop_queue(dev); + spin_unlock_irqrestore(&mp->lock, flags); + return NETDEV_TX_BUSY; + } + + eth_tx_submit_descs_for_skb(mp, skb); + stats->tx_bytes += skb->len; + stats->tx_packets++; + dev->trans_start = jiffies; + + if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) + netif_stop_queue(dev); + + spin_unlock_irqrestore(&mp->lock, flags); + + return NETDEV_TX_OK; } + +/* mii management interface *************************************************/ +static int ethernet_phy_get(struct mv643xx_private *mp); + /* - * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. + * eth_port_read_smi_reg - Read PHY registers * * DESCRIPTION: - * This function prepares a Rx chained list of descriptors and packet - * buffers in a form of a ring. The routine must be called after port - * initialization routine and before port start routine. - * The Ethernet SDMA engine uses CPU bus addresses to access the various - * devices in the system (i.e. DRAM). This function uses the ethernet - * struct 'virtual to physical' routine (set by the user) to set the ring - * with physical addresses. + * This routine utilize the SMI interface to interact with the PHY in + * order to perform PHY register read. * * INPUT: - * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct mv643xx_private *mp Ethernet Port. + * unsigned int phy_reg PHY register address offset. + * unsigned int *value Register value buffer. * * OUTPUT: - * The routine updates the Ethernet port control struct with information - * regarding the Rx descriptors and buffers. + * Write the value of a specified PHY register into given buffer. * * RETURN: - * None. + * false if the PHY is busy or read data is not in valid state. + * true otherwise. + * */ -static void ether_init_rx_desc_ring(struct mv643xx_private *mp) +static void eth_port_read_smi_reg(struct mv643xx_private *mp, + unsigned int phy_reg, unsigned int *value) { - volatile struct eth_rx_desc *p_rx_desc; - int rx_desc_num = mp->rx_ring_size; + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; + int phy_addr = ethernet_phy_get(mp); + unsigned long flags; int i; - /* initialize the next_desc_ptr links in the Rx descriptors ring */ - p_rx_desc = (struct eth_rx_desc *)mp->p_rx_desc_area; - for (i = 0; i < rx_desc_num; i++) { - p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma + - ((i + 1) % rx_desc_num) * sizeof(struct eth_rx_desc); + /* the SMI register is a shared resource */ + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); + + /* wait for the SMI register to become available */ + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { + if (i == PHY_WAIT_ITERATIONS) { + printk("%s: PHY busy timeout\n", mp->dev->name); + goto out; + } + udelay(PHY_WAIT_MICRO_SECONDS); } - /* Save Rx desc pointer to driver struct. */ - mp->rx_curr_desc_q = 0; - mp->rx_used_desc_q = 0; + writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, + smi_reg); - mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc); + /* now wait for the data to be valid */ + for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { + if (i == PHY_WAIT_ITERATIONS) { + printk("%s: PHY read timeout\n", mp->dev->name); + goto out; + } + udelay(PHY_WAIT_MICRO_SECONDS); + } + + *value = readl(smi_reg) & 0xffff; +out: + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); } /* - * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory. + * eth_port_write_smi_reg - Write to PHY registers * * DESCRIPTION: - * This function prepares a Tx chained list of descriptors and packet - * buffers in a form of a ring. The routine must be called after port - * initialization routine and before port start routine. - * The Ethernet SDMA engine uses CPU bus addresses to access the various - * devices in the system (i.e. DRAM). This function uses the ethernet - * struct 'virtual to physical' routine (set by the user) to set the ring - * with physical addresses. + * This routine utilize the SMI interface to interact with the PHY in + * order to perform writes to PHY registers. * * INPUT: - * struct mv643xx_private *mp Ethernet Port Control srtuct. + * struct mv643xx_private *mp Ethernet Port. + * unsigned int phy_reg PHY register address offset. + * unsigned int value Register value. * * OUTPUT: - * The routine updates the Ethernet port control struct with information - * regarding the Tx descriptors and buffers. + * Write the given value to the specified PHY register. * * RETURN: - * None. + * false if the PHY is busy. + * true otherwise. + * */ -static void ether_init_tx_desc_ring(struct mv643xx_private *mp) +static void eth_port_write_smi_reg(struct mv643xx_private *mp, + unsigned int phy_reg, unsigned int value) { - int tx_desc_num = mp->tx_ring_size; - struct eth_tx_desc *p_tx_desc; + void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; + int phy_addr = ethernet_phy_get(mp); + unsigned long flags; int i; - /* Initialize the next_desc_ptr links in the Tx descriptors ring */ - p_tx_desc = (struct eth_tx_desc *)mp->p_tx_desc_area; - for (i = 0; i < tx_desc_num; i++) { - p_tx_desc[i].next_desc_ptr = mp->tx_desc_dma + - ((i + 1) % tx_desc_num) * sizeof(struct eth_tx_desc); + /* the SMI register is a shared resource */ + spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); + + /* wait for the SMI register to become available */ + for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { + if (i == PHY_WAIT_ITERATIONS) { + printk("%s: PHY busy timeout\n", mp->dev->name); + goto out; + } + udelay(PHY_WAIT_MICRO_SECONDS); } - mp->tx_curr_desc_q = 0; - mp->tx_used_desc_q = 0; + writel((phy_addr << 16) | (phy_reg << 21) | + ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); +out: + spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); +} - mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc); + +/* mib counters *************************************************************/ +/* + * eth_clear_mib_counters - Clear all MIB counters + * + * DESCRIPTION: + * This function clears all MIB counters of a specific ethernet port. + * A read from the MIB counter will reset the counter. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port. + * + * OUTPUT: + * After reading all MIB counters, the counters resets. + * + * RETURN: + * MIB counter value. + * + */ +static void eth_clear_mib_counters(struct mv643xx_private *mp) +{ + unsigned int port_num = mp->port_num; + int i; + + /* Perform dummy reads from MIB counters */ + for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION; + i += 4) + rdl(mp, MIB_COUNTERS_BASE(port_num) + i); } -static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) +static inline u32 read_mib(struct mv643xx_private *mp, int offset) { - struct mv643xx_private *mp = netdev_priv(dev); - int err; + return rdl(mp, MIB_COUNTERS_BASE(mp->port_num) + offset); +} - spin_lock_irq(&mp->lock); - err = mii_ethtool_sset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); +static void eth_update_mib_counters(struct mv643xx_private *mp) +{ + struct mv643xx_mib_counters *p = &mp->mib_counters; + int offset; - return err; + p->good_octets_received += + read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW); + p->good_octets_received += + (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32; + + for (offset = ETH_MIB_BAD_OCTETS_RECEIVED; + offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS; + offset += 4) + *(u32 *)((char *)p + offset) += read_mib(mp, offset); + + p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW); + p->good_octets_sent += + (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_HIGH) << 32; + + for (offset = ETH_MIB_GOOD_FRAMES_SENT; + offset <= ETH_MIB_LATE_COLLISION; + offset += 4) + *(u32 *)((char *)p + offset) += read_mib(mp, offset); } + +/* ethtool ******************************************************************/ +struct mv643xx_stats { + char stat_string[ETH_GSTRING_LEN]; + int sizeof_stat; + int stat_offset; +}; + +#define MV643XX_STAT(m) FIELD_SIZEOF(struct mv643xx_private, m), \ + offsetof(struct mv643xx_private, m) + +static const struct mv643xx_stats mv643xx_gstrings_stats[] = { + { "rx_packets", MV643XX_STAT(stats.rx_packets) }, + { "tx_packets", MV643XX_STAT(stats.tx_packets) }, + { "rx_bytes", MV643XX_STAT(stats.rx_bytes) }, + { "tx_bytes", MV643XX_STAT(stats.tx_bytes) }, + { "rx_errors", MV643XX_STAT(stats.rx_errors) }, + { "tx_errors", MV643XX_STAT(stats.tx_errors) }, + { "rx_dropped", MV643XX_STAT(stats.rx_dropped) }, + { "tx_dropped", MV643XX_STAT(stats.tx_dropped) }, + { "good_octets_received", MV643XX_STAT(mib_counters.good_octets_received) }, + { "bad_octets_received", MV643XX_STAT(mib_counters.bad_octets_received) }, + { "internal_mac_transmit_err", MV643XX_STAT(mib_counters.internal_mac_transmit_err) }, + { "good_frames_received", MV643XX_STAT(mib_counters.good_frames_received) }, + { "bad_frames_received", MV643XX_STAT(mib_counters.bad_frames_received) }, + { "broadcast_frames_received", MV643XX_STAT(mib_counters.broadcast_frames_received) }, + { "multicast_frames_received", MV643XX_STAT(mib_counters.multicast_frames_received) }, + { "frames_64_octets", MV643XX_STAT(mib_counters.frames_64_octets) }, + { "frames_65_to_127_octets", MV643XX_STAT(mib_counters.frames_65_to_127_octets) }, + { "frames_128_to_255_octets", MV643XX_STAT(mib_counters.frames_128_to_255_octets) }, + { "frames_256_to_511_octets", MV643XX_STAT(mib_counters.frames_256_to_511_octets) }, + { "frames_512_to_1023_octets", MV643XX_STAT(mib_counters.frames_512_to_1023_octets) }, + { "frames_1024_to_max_octets", MV643XX_STAT(mib_counters.frames_1024_to_max_octets) }, + { "good_octets_sent", MV643XX_STAT(mib_counters.good_octets_sent) }, + { "good_frames_sent", MV643XX_STAT(mib_counters.good_frames_sent) }, + { "excessive_collision", MV643XX_STAT(mib_counters.excessive_collision) }, + { "multicast_frames_sent", MV643XX_STAT(mib_counters.multicast_frames_sent) }, + { "broadcast_frames_sent", MV643XX_STAT(mib_counters.broadcast_frames_sent) }, + { "unrec_mac_control_received", MV643XX_STAT(mib_counters.unrec_mac_control_received) }, + { "fc_sent", MV643XX_STAT(mib_counters.fc_sent) }, + { "good_fc_received", MV643XX_STAT(mib_counters.good_fc_received) }, + { "bad_fc_received", MV643XX_STAT(mib_counters.bad_fc_received) }, + { "undersize_received", MV643XX_STAT(mib_counters.undersize_received) }, + { "fragments_received", MV643XX_STAT(mib_counters.fragments_received) }, + { "oversize_received", MV643XX_STAT(mib_counters.oversize_received) }, + { "jabber_received", MV643XX_STAT(mib_counters.jabber_received) }, + { "mac_receive_error", MV643XX_STAT(mib_counters.mac_receive_error) }, + { "bad_crc_event", MV643XX_STAT(mib_counters.bad_crc_event) }, + { "collision", MV643XX_STAT(mib_counters.collision) }, + { "late_collision", MV643XX_STAT(mib_counters.late_collision) }, +}; + +#define MV643XX_STATS_LEN ARRAY_SIZE(mv643xx_gstrings_stats) + static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct mv643xx_private *mp = netdev_priv(dev); @@ -1302,1038 +1409,798 @@ static int mv643xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) return err; } -/* - * mv643xx_eth_open - * - * This function is called when openning the network device. The function - * should initialize all the hardware, initialize cyclic Rx/Tx - * descriptors chain and buffers and allocate an IRQ to the network - * device. - * - * Input : a pointer to the network device structure - * - * Output : zero of success , nonzero if fails. - */ - -static int mv643xx_eth_open(struct net_device *dev) +static int mv643xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct mv643xx_private *mp = netdev_priv(dev); - unsigned int port_num = mp->port_num; - unsigned int size; int err; - /* Clear any pending ethernet port interrupts */ - wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0); - wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); - /* wait for previous write to complete */ - rdl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num)); + spin_lock_irq(&mp->lock); + err = mii_ethtool_sset(&mp->mii, cmd); + spin_unlock_irq(&mp->lock); - err = request_irq(dev->irq, mv643xx_eth_int_handler, - IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); - if (err) { - printk(KERN_ERR "%s: Can not assign IRQ\n", dev->name); - return -EAGAIN; - } + return err; +} - eth_port_init(mp); +static void mv643xx_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *drvinfo) +{ + strncpy(drvinfo->driver, mv643xx_driver_name, 32); + strncpy(drvinfo->version, mv643xx_driver_version, 32); + strncpy(drvinfo->fw_version, "N/A", 32); + strncpy(drvinfo->bus_info, "mv643xx", 32); + drvinfo->n_stats = MV643XX_STATS_LEN; +} - memset(&mp->timeout, 0, sizeof(struct timer_list)); - mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper; - mp->timeout.data = (unsigned long)dev; +static int mv643xx_eth_nway_restart(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); - /* Allocate RX and TX skb rings */ - mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size, - GFP_KERNEL); - if (!mp->rx_skb) { - printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); - err = -ENOMEM; - goto out_free_irq; - } - mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, - GFP_KERNEL); - if (!mp->tx_skb) { - printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name); - err = -ENOMEM; - goto out_free_rx_skb; - } + return mii_nway_restart(&mp->mii); +} - /* Allocate TX ring */ - mp->tx_desc_count = 0; - size = mp->tx_ring_size * sizeof(struct eth_tx_desc); - mp->tx_desc_area_size = size; +static u32 mv643xx_eth_get_link(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); - if (mp->tx_sram_size) { - mp->p_tx_desc_area = ioremap(mp->tx_sram_addr, - mp->tx_sram_size); - mp->tx_desc_dma = mp->tx_sram_addr; - } else - mp->p_tx_desc_area = dma_alloc_coherent(NULL, size, - &mp->tx_desc_dma, - GFP_KERNEL); + return mii_link_ok(&mp->mii); +} - if (!mp->p_tx_desc_area) { - printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", - dev->name, size); - err = -ENOMEM; - goto out_free_tx_skb; - } - BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */ - memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size); +static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, + uint8_t *data) +{ + int i; - ether_init_tx_desc_ring(mp); + switch(stringset) { + case ETH_SS_STATS: + for (i=0; i < MV643XX_STATS_LEN; i++) { + memcpy(data + i * ETH_GSTRING_LEN, + mv643xx_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); + } + break; + } +} - /* Allocate RX ring */ - mp->rx_desc_count = 0; - size = mp->rx_ring_size * sizeof(struct eth_rx_desc); - mp->rx_desc_area_size = size; +static void mv643xx_get_ethtool_stats(struct net_device *netdev, + struct ethtool_stats *stats, uint64_t *data) +{ + struct mv643xx_private *mp = netdev->priv; + int i; - if (mp->rx_sram_size) { - mp->p_rx_desc_area = ioremap(mp->rx_sram_addr, - mp->rx_sram_size); - mp->rx_desc_dma = mp->rx_sram_addr; - } else - mp->p_rx_desc_area = dma_alloc_coherent(NULL, size, - &mp->rx_desc_dma, - GFP_KERNEL); + eth_update_mib_counters(mp); - if (!mp->p_rx_desc_area) { - printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n", - dev->name, size); - printk(KERN_ERR "%s: Freeing previously allocated TX queues...", - dev->name); - if (mp->rx_sram_size) - iounmap(mp->p_tx_desc_area); - else - dma_free_coherent(NULL, mp->tx_desc_area_size, - mp->p_tx_desc_area, mp->tx_desc_dma); - err = -ENOMEM; - goto out_free_tx_skb; + for (i = 0; i < MV643XX_STATS_LEN; i++) { + char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset; + data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == + sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; } - memset((void *)mp->p_rx_desc_area, 0, size); +} - ether_init_rx_desc_ring(mp); +static int mv643xx_get_sset_count(struct net_device *netdev, int sset) +{ + switch (sset) { + case ETH_SS_STATS: + return MV643XX_STATS_LEN; + default: + return -EOPNOTSUPP; + } +} - mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ +static const struct ethtool_ops mv643xx_ethtool_ops = { + .get_settings = mv643xx_get_settings, + .set_settings = mv643xx_set_settings, + .get_drvinfo = mv643xx_get_drvinfo, + .get_link = mv643xx_eth_get_link, + .set_sg = ethtool_op_set_sg, + .get_sset_count = mv643xx_get_sset_count, + .get_ethtool_stats = mv643xx_get_ethtool_stats, + .get_strings = mv643xx_get_strings, + .nway_reset = mv643xx_eth_nway_restart, +}; -#ifdef MV643XX_NAPI - napi_enable(&mp->napi); -#endif - eth_port_start(dev); +/* address handling *********************************************************/ +/* + * eth_port_uc_addr_get - Read the MAC address from the port's hw registers + */ +static void eth_port_uc_addr_get(struct mv643xx_private *mp, + unsigned char *p_addr) +{ + unsigned int port_num = mp->port_num; + unsigned int mac_h; + unsigned int mac_l; - /* Interrupt Coalescing */ + mac_h = rdl(mp, MAC_ADDR_HIGH(port_num)); + mac_l = rdl(mp, MAC_ADDR_LOW(port_num)); -#ifdef MV643XX_COAL - mp->rx_int_coal = - eth_port_set_rx_coal(mp, MV643XX_RX_COAL); -#endif + p_addr[0] = (mac_h >> 24) & 0xff; + p_addr[1] = (mac_h >> 16) & 0xff; + p_addr[2] = (mac_h >> 8) & 0xff; + p_addr[3] = mac_h & 0xff; + p_addr[4] = (mac_l >> 8) & 0xff; + p_addr[5] = mac_l & 0xff; +} - mp->tx_int_coal = - eth_port_set_tx_coal(mp, MV643XX_TX_COAL); +/* + * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables + * + * DESCRIPTION: + * Go through all the DA filter tables (Unicast, Special Multicast & + * Other Multicast) and set each entry to 0. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port. + * + * OUTPUT: + * Multicast and Unicast packets are rejected. + * + * RETURN: + * None. + */ +static void eth_port_init_mac_tables(struct mv643xx_private *mp) +{ + unsigned int port_num = mp->port_num; + int table_index; - /* Unmask phy and link status changes interrupts */ - wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); + /* Clear DA filter unicast table (Ex_dFUT) */ + for (table_index = 0; table_index <= 0xC; table_index += 4) + wrl(mp, DA_FILTER_UNICAST_TABLE_BASE(port_num) + + table_index, 0); - /* Unmask RX buffer and TX end interrupt */ - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); + for (table_index = 0; table_index <= 0xFC; table_index += 4) { + /* Clear DA filter special multicast table (Ex_dFSMT) */ + wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num) + + table_index, 0); + /* Clear DA filter other multicast table (Ex_dFOMT) */ + wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num) + + table_index, 0); + } +} - return 0; +/* + * The entries in each table are indexed by a hash of a packet's MAC + * address. One bit in each entry determines whether the packet is + * accepted. There are 4 entries (each 8 bits wide) in each register + * of the table. The bits in each entry are defined as follows: + * 0 Accept=1, Drop=0 + * 3-1 Queue (ETH_Q0=0) + * 7-4 Reserved = 0; + */ +static void eth_port_set_filter_table_entry(struct mv643xx_private *mp, + int table, unsigned char entry) +{ + unsigned int table_reg; + unsigned int tbl_offset; + unsigned int reg_offset; -out_free_tx_skb: - kfree(mp->tx_skb); -out_free_rx_skb: - kfree(mp->rx_skb); -out_free_irq: - free_irq(dev->irq, dev); + tbl_offset = (entry / 4) * 4; /* Register offset of DA table entry */ + reg_offset = entry % 4; /* Entry offset within the register */ - return err; + /* Set "accepts frame bit" at specified table entry */ + table_reg = rdl(mp, table + tbl_offset); + table_reg |= 0x01 << (8 * reg_offset); + wrl(mp, table + tbl_offset, table_reg); } -static void mv643xx_eth_free_tx_rings(struct net_device *dev) +/* + * eth_port_uc_addr_set - Write a MAC address into the port's hw registers + */ +static void eth_port_uc_addr_set(struct mv643xx_private *mp, + unsigned char *p_addr) { - struct mv643xx_private *mp = netdev_priv(dev); - - /* Stop Tx Queues */ - mv643xx_eth_port_disable_tx(mp); + unsigned int port_num = mp->port_num; + unsigned int mac_h; + unsigned int mac_l; + int table; - /* Free outstanding skb's on TX ring */ - mv643xx_eth_free_all_tx_descs(dev); + mac_l = (p_addr[4] << 8) | (p_addr[5]); + mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | + (p_addr[3] << 0); - BUG_ON(mp->tx_used_desc_q != mp->tx_curr_desc_q); + wrl(mp, MAC_ADDR_LOW(port_num), mac_l); + wrl(mp, MAC_ADDR_HIGH(port_num), mac_h); - /* Free TX ring */ - if (mp->tx_sram_size) - iounmap(mp->p_tx_desc_area); - else - dma_free_coherent(NULL, mp->tx_desc_area_size, - mp->p_tx_desc_area, mp->tx_desc_dma); + /* Accept frames with this address */ + table = DA_FILTER_UNICAST_TABLE_BASE(port_num); + eth_port_set_filter_table_entry(mp, table, p_addr[5] & 0x0f); } -static void mv643xx_eth_free_rx_rings(struct net_device *dev) +/* + * mv643xx_eth_update_mac_address + * + * Update the MAC address of the port in the address table + * + * Input : pointer to ethernet interface network device structure + * Output : N/A + */ +static void mv643xx_eth_update_mac_address(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - int curr; - - /* Stop RX Queues */ - mv643xx_eth_port_disable_rx(mp); - /* Free preallocated skb's on RX rings */ - for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { - if (mp->rx_skb[curr]) { - dev_kfree_skb(mp->rx_skb[curr]); - mp->rx_desc_count--; - } - } - - if (mp->rx_desc_count) - printk(KERN_ERR - "%s: Error in freeing Rx Ring. %d skb's still" - " stuck in RX Ring - ignoring them\n", dev->name, - mp->rx_desc_count); - /* Free RX ring */ - if (mp->rx_sram_size) - iounmap(mp->p_rx_desc_area); - else - dma_free_coherent(NULL, mp->rx_desc_area_size, - mp->p_rx_desc_area, mp->rx_desc_dma); -} + eth_port_init_mac_tables(mp); + eth_port_uc_addr_set(mp, dev->dev_addr); +} /* - * mv643xx_eth_stop + * mv643xx_eth_set_mac_address * - * This function is used when closing the network device. - * It updates the hardware, - * release all memory that holds buffers and descriptors and release the IRQ. - * Input : a pointer to the device structure - * Output : zero if success , nonzero if fails + * Change the interface's mac address. + * No special hardware thing should be done because interface is always + * put in promiscuous mode. + * + * Input : pointer to ethernet interface network device structure and + * a pointer to the designated entry to be added to the cache. + * Output : zero upon success, negative upon failure */ - -static int mv643xx_eth_stop(struct net_device *dev) +static int mv643xx_eth_set_mac_address(struct net_device *dev, void *addr) { - struct mv643xx_private *mp = netdev_priv(dev); - unsigned int port_num = mp->port_num; - - /* Mask all interrupts on ethernet port */ - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); - /* wait for previous write to complete */ - rdl(mp, INTERRUPT_MASK_REG(port_num)); - -#ifdef MV643XX_NAPI - napi_disable(&mp->napi); -#endif - netif_carrier_off(dev); - netif_stop_queue(dev); - - eth_port_reset(mp); - - mv643xx_eth_free_tx_rings(dev); - mv643xx_eth_free_rx_rings(dev); - - free_irq(dev->irq, dev); + int i; + for (i = 0; i < 6; i++) + /* +2 is for the offset of the HW addr type */ + dev->dev_addr[i] = ((unsigned char *)addr)[i + 2]; + mv643xx_eth_update_mac_address(dev); return 0; } -#ifdef MV643XX_NAPI /* - * mv643xx_poll + * eth_port_mc_addr - Multicast address settings. * - * This function is used in case of NAPI + * The MV device supports multicast using two tables: + * 1) Special Multicast Table for MAC addresses of the form + * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF). + * The MAC DA[7:0] bits are used as a pointer to the Special Multicast + * Table entries in the DA-Filter table. + * 2) Other Multicast Table for multicast of another type. A CRC-8bit + * is used as an index to the Other Multicast Table entries in the + * DA-Filter table. This function calculates the CRC-8bit value. + * In either case, eth_port_set_filter_table_entry() is then called + * to set to set the actual table entry. */ -static int mv643xx_poll(struct napi_struct *napi, int budget) +static void eth_port_mc_addr(struct mv643xx_private *mp, unsigned char *p_addr) { - struct mv643xx_private *mp = container_of(napi, struct mv643xx_private, napi); - struct net_device *dev = mp->dev; unsigned int port_num = mp->port_num; - int work_done; + unsigned int mac_h; + unsigned int mac_l; + unsigned char crc_result = 0; + int table; + int mac_array[48]; + int crc[8]; + int i; -#ifdef MV643XX_TX_FAST_REFILL - if (++mp->tx_clean_threshold > 5) { - mv643xx_eth_free_completed_tx_descs(dev); - mp->tx_clean_threshold = 0; + if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) && + (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) { + table = DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num); + eth_port_set_filter_table_entry(mp, table, p_addr[5]); + return; } -#endif - work_done = 0; - if ((rdl(mp, RX_CURRENT_QUEUE_DESC_PTR_0(port_num))) - != (u32) mp->rx_used_desc_q) - work_done = mv643xx_eth_receive_queue(dev, budget); + /* Calculate CRC-8 out of the given address */ + mac_h = (p_addr[0] << 8) | (p_addr[1]); + mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) | + (p_addr[4] << 8) | (p_addr[5] << 0); - if (work_done < budget) { - netif_rx_complete(dev, napi); - wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0); - wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); - } + for (i = 0; i < 32; i++) + mac_array[i] = (mac_l >> i) & 0x1; + for (i = 32; i < 48; i++) + mac_array[i] = (mac_h >> (i - 32)) & 0x1; - return work_done; -} -#endif + crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^ + mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^ + mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^ + mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^ + mac_array[8] ^ mac_array[7] ^ mac_array[6] ^ mac_array[0]; -/** - * has_tiny_unaligned_frags - check if skb has any small, unaligned fragments - * - * Hardware can't handle unaligned fragments smaller than 9 bytes. - * This helper function detects that case. - */ + crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ + mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^ + mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^ + mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^ + mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^ + mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^ + mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ mac_array[0]; -static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) -{ - unsigned int frag; - skb_frag_t *fragp; + crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^ + mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^ + mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^ + mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^ + mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ + mac_array[6] ^ mac_array[2] ^ mac_array[1] ^ mac_array[0]; - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - fragp = &skb_shinfo(skb)->frags[frag]; - if (fragp->size <= 8 && fragp->page_offset & 0x7) - return 1; - } - return 0; -} + crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ + mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^ + mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^ + mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ + mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[7] ^ + mac_array[3] ^ mac_array[2] ^ mac_array[1]; -/** - * eth_alloc_tx_desc_index - return the index of the next available tx desc - */ -static int eth_alloc_tx_desc_index(struct mv643xx_private *mp) -{ - int tx_desc_curr; + crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^ + mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^ + mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^ + mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^ + mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ mac_array[4] ^ + mac_array[3] ^ mac_array[2]; - BUG_ON(mp->tx_desc_count >= mp->tx_ring_size); + crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^ + mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^ + mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^ + mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^ + mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[5] ^ + mac_array[4] ^ mac_array[3]; - tx_desc_curr = mp->tx_curr_desc_q; - mp->tx_curr_desc_q = (tx_desc_curr + 1) % mp->tx_ring_size; + crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^ + mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^ + mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^ + mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^ + mac_array[12] ^ mac_array[10] ^ mac_array[6] ^ mac_array[5] ^ + mac_array[4]; - BUG_ON(mp->tx_curr_desc_q == mp->tx_used_desc_q); + crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^ + mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^ + mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^ + mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^ + mac_array[11] ^ mac_array[7] ^ mac_array[6] ^ mac_array[5]; - return tx_desc_curr; + for (i = 0; i < 8; i++) + crc_result = crc_result | (crc[i] << i); + + table = DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num); + eth_port_set_filter_table_entry(mp, table, crc_result); } -/** - * eth_tx_fill_frag_descs - fill tx hw descriptors for an skb's fragments. - * - * Ensure the data for each fragment to be transmitted is mapped properly, - * then fill in descriptors in the tx hw queue. +/* + * Set the entire multicast list based on dev->mc_list. */ -static void eth_tx_fill_frag_descs(struct mv643xx_private *mp, - struct sk_buff *skb) +static void eth_port_set_multicast_list(struct net_device *dev) { - int frag; - int tx_index; - struct eth_tx_desc *desc; - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag]; + struct dev_mc_list *mc_list; + int i; + int table_index; + struct mv643xx_private *mp = netdev_priv(dev); + unsigned int eth_port_num = mp->port_num; - tx_index = eth_alloc_tx_desc_index(mp); - desc = &mp->p_tx_desc_area[tx_index]; + /* If the device is in promiscuous mode or in all multicast mode, + * we will fully populate both multicast tables with accept. + * This is guaranteed to yield a match on all multicast addresses... + */ + if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) { + for (table_index = 0; table_index <= 0xFC; table_index += 4) { + /* Set all entries in DA filter special multicast + * table (Ex_dFSMT) + * Set for ETH_Q0 for now + * Bits + * 0 Accept=1, Drop=0 + * 3-1 Queue ETH_Q0=0 + * 7-4 Reserved = 0; + */ + wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - desc->cmd_sts = ETH_BUFFER_OWNED_BY_DMA; - /* Last Frag enables interrupt and frees the skb */ - if (frag == (skb_shinfo(skb)->nr_frags - 1)) { - desc->cmd_sts |= ETH_ZERO_PADDING | - ETH_TX_LAST_DESC | - ETH_TX_ENABLE_INTERRUPT; - mp->tx_skb[tx_index] = skb; - } else - mp->tx_skb[tx_index] = NULL; + /* Set all entries in DA filter other multicast + * table (Ex_dFOMT) + * Set for ETH_Q0 for now + * Bits + * 0 Accept=1, Drop=0 + * 3-1 Queue ETH_Q0=0 + * 7-4 Reserved = 0; + */ + wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); + } + return; + } - desc = &mp->p_tx_desc_area[tx_index]; - desc->l4i_chk = 0; - desc->byte_cnt = this_frag->size; - desc->buf_ptr = dma_map_page(NULL, this_frag->page, - this_frag->page_offset, - this_frag->size, - DMA_TO_DEVICE); + /* We will clear out multicast tables every time we get the list. + * Then add the entire new list... + */ + for (table_index = 0; table_index <= 0xFC; table_index += 4) { + /* Clear DA filter special multicast table (Ex_dFSMT) */ + wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE + (eth_port_num) + table_index, 0); + + /* Clear DA filter other multicast table (Ex_dFOMT) */ + wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE + (eth_port_num) + table_index, 0); } -} -static inline __be16 sum16_as_be(__sum16 sum) -{ - return (__force __be16)sum; + /* Get pointer to net_device multicast list and add each one... */ + for (i = 0, mc_list = dev->mc_list; + (i < 256) && (mc_list != NULL) && (i < dev->mc_count); + i++, mc_list = mc_list->next) + if (mc_list->dmi_addrlen == 6) + eth_port_mc_addr(mp, mc_list->dmi_addr); } -/** - * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw +/* + * mv643xx_eth_set_rx_mode * - * Ensure the data for an skb to be transmitted is mapped properly, - * then fill in descriptors in the tx hw queue and start the hardware. + * Change from promiscuos to regular rx mode + * + * Input : pointer to ethernet interface network device structure + * Output : N/A */ -static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp, - struct sk_buff *skb) +static void mv643xx_eth_set_rx_mode(struct net_device *dev) { - int tx_index; - struct eth_tx_desc *desc; - u32 cmd_sts; - int length; - int nr_frags = skb_shinfo(skb)->nr_frags; + struct mv643xx_private *mp = netdev_priv(dev); + u32 config_reg; - cmd_sts = ETH_TX_FIRST_DESC | ETH_GEN_CRC | ETH_BUFFER_OWNED_BY_DMA; + config_reg = rdl(mp, PORT_CONFIG_REG(mp->port_num)); + if (dev->flags & IFF_PROMISC) + config_reg |= (u32) UNICAST_PROMISCUOUS_MODE; + else + config_reg &= ~(u32) UNICAST_PROMISCUOUS_MODE; + wrl(mp, PORT_CONFIG_REG(mp->port_num), config_reg); - tx_index = eth_alloc_tx_desc_index(mp); - desc = &mp->p_tx_desc_area[tx_index]; + eth_port_set_multicast_list(dev); +} - if (nr_frags) { - eth_tx_fill_frag_descs(mp, skb); - length = skb_headlen(skb); - mp->tx_skb[tx_index] = NULL; - } else { - cmd_sts |= ETH_ZERO_PADDING | - ETH_TX_LAST_DESC | - ETH_TX_ENABLE_INTERRUPT; - length = skb->len; - mp->tx_skb[tx_index] = skb; +/* rx/tx queue initialisation ***********************************************/ +/* + * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. + * + * DESCRIPTION: + * This function prepares a Rx chained list of descriptors and packet + * buffers in a form of a ring. The routine must be called after port + * initialization routine and before port start routine. + * The Ethernet SDMA engine uses CPU bus addresses to access the various + * devices in the system (i.e. DRAM). This function uses the ethernet + * struct 'virtual to physical' routine (set by the user) to set the ring + * with physical addresses. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * + * OUTPUT: + * The routine updates the Ethernet port control struct with information + * regarding the Rx descriptors and buffers. + * + * RETURN: + * None. + */ +static void ether_init_rx_desc_ring(struct mv643xx_private *mp) +{ + volatile struct eth_rx_desc *p_rx_desc; + int rx_desc_num = mp->rx_ring_size; + int i; + + /* initialize the next_desc_ptr links in the Rx descriptors ring */ + p_rx_desc = (struct eth_rx_desc *)mp->p_rx_desc_area; + for (i = 0; i < rx_desc_num; i++) { + p_rx_desc[i].next_desc_ptr = mp->rx_desc_dma + + ((i + 1) % rx_desc_num) * sizeof(struct eth_rx_desc); } - desc->byte_cnt = length; - desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + /* Save Rx desc pointer to driver struct. */ + mp->rx_curr_desc_q = 0; + mp->rx_used_desc_q = 0; - if (skb->ip_summed == CHECKSUM_PARTIAL) { - BUG_ON(skb->protocol != htons(ETH_P_IP)); + mp->rx_desc_area_size = rx_desc_num * sizeof(struct eth_rx_desc); +} - cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | - ETH_GEN_IP_V_4_CHECKSUM | - ip_hdr(skb)->ihl << ETH_TX_IHL_SHIFT; +static void mv643xx_eth_free_rx_rings(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + int curr; - switch (ip_hdr(skb)->protocol) { - case IPPROTO_UDP: - cmd_sts |= ETH_UDP_FRAME; - desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check)); - break; - case IPPROTO_TCP: - desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check)); - break; - default: - BUG(); + /* Stop RX Queues */ + mv643xx_eth_port_disable_rx(mp); + + /* Free preallocated skb's on RX rings */ + for (curr = 0; mp->rx_desc_count && curr < mp->rx_ring_size; curr++) { + if (mp->rx_skb[curr]) { + dev_kfree_skb(mp->rx_skb[curr]); + mp->rx_desc_count--; } - } else { - /* Errata BTS #50, IHL must be 5 if no HW checksum */ - cmd_sts |= 5 << ETH_TX_IHL_SHIFT; - desc->l4i_chk = 0; } - /* ensure all other descriptors are written before first cmd_sts */ - wmb(); - desc->cmd_sts = cmd_sts; + if (mp->rx_desc_count) + printk(KERN_ERR + "%s: Error in freeing Rx Ring. %d skb's still" + " stuck in RX Ring - ignoring them\n", dev->name, + mp->rx_desc_count); + /* Free RX ring */ + if (mp->rx_sram_size) + iounmap(mp->p_rx_desc_area); + else + dma_free_coherent(NULL, mp->rx_desc_area_size, + mp->p_rx_desc_area, mp->rx_desc_dma); +} - /* ensure all descriptors are written before poking hardware */ - wmb(); - mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED); +/* + * ether_init_tx_desc_ring - Curve a Tx chain desc list and buffer in memory. + * + * DESCRIPTION: + * This function prepares a Tx chained list of descriptors and packet + * buffers in a form of a ring. The routine must be called after port + * initialization routine and before port start routine. + * The Ethernet SDMA engine uses CPU bus addresses to access the various + * devices in the system (i.e. DRAM). This function uses the ethernet + * struct 'virtual to physical' routine (set by the user) to set the ring + * with physical addresses. + * + * INPUT: + * struct mv643xx_private *mp Ethernet Port Control srtuct. + * + * OUTPUT: + * The routine updates the Ethernet port control struct with information + * regarding the Tx descriptors and buffers. + * + * RETURN: + * None. + */ +static void ether_init_tx_desc_ring(struct mv643xx_private *mp) +{ + int tx_desc_num = mp->tx_ring_size; + struct eth_tx_desc *p_tx_desc; + int i; - mp->tx_desc_count += nr_frags + 1; + /* Initialize the next_desc_ptr links in the Tx descriptors ring */ + p_tx_desc = (struct eth_tx_desc *)mp->p_tx_desc_area; + for (i = 0; i < tx_desc_num; i++) { + p_tx_desc[i].next_desc_ptr = mp->tx_desc_dma + + ((i + 1) % tx_desc_num) * sizeof(struct eth_tx_desc); + } + + mp->tx_curr_desc_q = 0; + mp->tx_used_desc_q = 0; + + mp->tx_desc_area_size = tx_desc_num * sizeof(struct eth_tx_desc); } /** - * mv643xx_eth_start_xmit - queue an skb to the hardware for transmission + * mv643xx_eth_free_tx_descs - Free the tx desc data for completed descriptors * + * If force is non-zero, frees uncompleted descriptors as well */ -static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) +static int mv643xx_eth_free_tx_descs(struct net_device *dev, int force) { struct mv643xx_private *mp = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; + struct eth_tx_desc *desc; + u32 cmd_sts; + struct sk_buff *skb; unsigned long flags; + int tx_index; + dma_addr_t addr; + int count; + int released = 0; - BUG_ON(netif_queue_stopped(dev)); + while (mp->tx_desc_count > 0) { + spin_lock_irqsave(&mp->lock, flags); - if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) { - stats->tx_dropped++; - printk(KERN_DEBUG "%s: failed to linearize tiny " - "unaligned fragment\n", dev->name); - return NETDEV_TX_BUSY; - } + /* tx_desc_count might have changed before acquiring the lock */ + if (mp->tx_desc_count <= 0) { + spin_unlock_irqrestore(&mp->lock, flags); + return released; + } - spin_lock_irqsave(&mp->lock, flags); + tx_index = mp->tx_used_desc_q; + desc = &mp->p_tx_desc_area[tx_index]; + cmd_sts = desc->cmd_sts; - if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) { - printk(KERN_ERR "%s: transmit with queue full\n", dev->name); - netif_stop_queue(dev); - spin_unlock_irqrestore(&mp->lock, flags); - return NETDEV_TX_BUSY; - } + if (!force && (cmd_sts & ETH_BUFFER_OWNED_BY_DMA)) { + spin_unlock_irqrestore(&mp->lock, flags); + return released; + } - eth_tx_submit_descs_for_skb(mp, skb); - stats->tx_bytes += skb->len; - stats->tx_packets++; - dev->trans_start = jiffies; + mp->tx_used_desc_q = (tx_index + 1) % mp->tx_ring_size; + mp->tx_desc_count--; - if (mp->tx_ring_size - mp->tx_desc_count < MAX_DESCS_PER_SKB) - netif_stop_queue(dev); + addr = desc->buf_ptr; + count = desc->byte_cnt; + skb = mp->tx_skb[tx_index]; + if (skb) + mp->tx_skb[tx_index] = NULL; - spin_unlock_irqrestore(&mp->lock, flags); + if (cmd_sts & ETH_ERROR_SUMMARY) { + printk("%s: Error in TX\n", dev->name); + dev->stats.tx_errors++; + } - return NETDEV_TX_OK; -} + spin_unlock_irqrestore(&mp->lock, flags); -#ifdef CONFIG_NET_POLL_CONTROLLER -static void mv643xx_netpoll(struct net_device *netdev) -{ - struct mv643xx_private *mp = netdev_priv(netdev); - int port_num = mp->port_num; + if (cmd_sts & ETH_TX_FIRST_DESC) + dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); + else + dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE); - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); - /* wait for previous write to complete */ - rdl(mp, INTERRUPT_MASK_REG(port_num)); + if (skb) + dev_kfree_skb_irq(skb); - mv643xx_eth_int_handler(netdev->irq, netdev); + released = 1; + } - wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); + return released; } -#endif -static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, - int speed, int duplex, - struct ethtool_cmd *cmd) +static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); - memset(cmd, 0, sizeof(*cmd)); - - cmd->port = PORT_MII; - cmd->transceiver = XCVR_INTERNAL; - cmd->phy_address = phy_address; - - if (speed == 0) { - cmd->autoneg = AUTONEG_ENABLE; - /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */ - cmd->speed = SPEED_100; - cmd->advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full; - if (mp->mii.supports_gmii) - cmd->advertising |= ADVERTISED_1000baseT_Full; - } else { - cmd->autoneg = AUTONEG_DISABLE; - cmd->speed = speed; - cmd->duplex = duplex; - } + if (mv643xx_eth_free_tx_descs(dev, 0) && + mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) + netif_wake_queue(dev); } -/*/ - * mv643xx_eth_probe - * - * First function called after registering the network device. - * It's purpose is to initialize the device as an ethernet device, - * fill the ethernet device structure with pointers * to functions, - * and set the MAC address of the interface - * - * Input : struct device * - * Output : -ENOMEM if failed , 0 if success - */ -static int mv643xx_eth_probe(struct platform_device *pdev) +static void mv643xx_eth_free_all_tx_descs(struct net_device *dev) { - struct mv643xx_eth_platform_data *pd; - int port_num; - struct mv643xx_private *mp; - struct net_device *dev; - u8 *p; - struct resource *res; - int err; - struct ethtool_cmd cmd; - int duplex = DUPLEX_HALF; - int speed = 0; /* default to auto-negotiation */ - DECLARE_MAC_BUF(mac); + mv643xx_eth_free_tx_descs(dev, 1); +} - pd = pdev->dev.platform_data; - if (pd == NULL) { - printk(KERN_ERR "No mv643xx_eth_platform_data\n"); - return -ENODEV; - } +static void mv643xx_eth_free_tx_rings(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); - if (pd->shared == NULL) { - printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); - return -ENODEV; - } + /* Stop Tx Queues */ + mv643xx_eth_port_disable_tx(mp); - dev = alloc_etherdev(sizeof(struct mv643xx_private)); - if (!dev) - return -ENOMEM; + /* Free outstanding skb's on TX ring */ + mv643xx_eth_free_all_tx_descs(dev); - platform_set_drvdata(pdev, dev); + BUG_ON(mp->tx_used_desc_q != mp->tx_curr_desc_q); - mp = netdev_priv(dev); - mp->dev = dev; -#ifdef MV643XX_NAPI - netif_napi_add(dev, &mp->napi, mv643xx_poll, 64); -#endif + /* Free TX ring */ + if (mp->tx_sram_size) + iounmap(mp->p_tx_desc_area); + else + dma_free_coherent(NULL, mp->tx_desc_area_size, + mp->p_tx_desc_area, mp->tx_desc_dma); +} - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - BUG_ON(!res); - dev->irq = res->start; - dev->open = mv643xx_eth_open; - dev->stop = mv643xx_eth_stop; - dev->hard_start_xmit = mv643xx_eth_start_xmit; - dev->set_mac_address = mv643xx_eth_set_mac_address; - dev->set_multicast_list = mv643xx_eth_set_rx_mode; +/* netdev ops and related ***************************************************/ +static void eth_port_reset(struct mv643xx_private *mp); - /* No need to Tx Timeout */ - dev->tx_timeout = mv643xx_eth_tx_timeout; +/* Set the mv643xx port configuration register for the speed/duplex mode. */ +static void mv643xx_eth_update_pscr(struct net_device *dev, + struct ethtool_cmd *ecmd) +{ + struct mv643xx_private *mp = netdev_priv(dev); + int port_num = mp->port_num; + u32 o_pscr, n_pscr; + unsigned int queues; -#ifdef CONFIG_NET_POLL_CONTROLLER - dev->poll_controller = mv643xx_netpoll; -#endif + o_pscr = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num)); + n_pscr = o_pscr; - dev->watchdog_timeo = 2 * HZ; - dev->base_addr = 0; - dev->change_mtu = mv643xx_eth_change_mtu; - dev->do_ioctl = mv643xx_eth_do_ioctl; - SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); + /* clear speed, duplex and rx buffer size fields */ + n_pscr &= ~(SET_MII_SPEED_TO_100 | + SET_GMII_SPEED_TO_1000 | + SET_FULL_DUPLEX_MODE | + MAX_RX_PACKET_MASK); -#ifdef MV643XX_CHECKSUM_OFFLOAD_TX -#ifdef MAX_SKB_FRAGS - /* - * Zero copy can only work if we use Discovery II memory. Else, we will - * have to map the buffers to ISA memory which is only 16 MB - */ - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; -#endif -#endif + if (ecmd->duplex == DUPLEX_FULL) + n_pscr |= SET_FULL_DUPLEX_MODE; - /* Configure the timeout task */ - INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task); + if (ecmd->speed == SPEED_1000) + n_pscr |= SET_GMII_SPEED_TO_1000 | + MAX_RX_PACKET_9700BYTE; + else { + if (ecmd->speed == SPEED_100) + n_pscr |= SET_MII_SPEED_TO_100; + n_pscr |= MAX_RX_PACKET_1522BYTE; + } - spin_lock_init(&mp->lock); + if (n_pscr != o_pscr) { + if ((o_pscr & SERIAL_PORT_ENABLE) == 0) + wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); + else { + queues = mv643xx_eth_port_disable_tx(mp); - mp->shared = platform_get_drvdata(pd->shared); - port_num = mp->port_num = pd->port_number; + o_pscr &= ~SERIAL_PORT_ENABLE; + wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), o_pscr); + wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); + wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), n_pscr); + if (queues) + mv643xx_eth_port_enable_tx(mp, queues); + } + } +} - if (mp->shared->win_protect) - wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); +/* + * mv643xx_eth_int_handler + * + * Main interrupt handler for the gigbit ethernet ports + * + * Input : irq - irq number (not used) + * dev_id - a pointer to the required interface's data structure + * regs - not used + * Output : N/A + */ - mp->shared_smi = mp->shared; - if (pd->shared_smi != NULL) - mp->shared_smi = platform_get_drvdata(pd->shared_smi); +static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) +{ + struct net_device *dev = (struct net_device *)dev_id; + struct mv643xx_private *mp = netdev_priv(dev); + u32 eth_int_cause, eth_int_cause_ext = 0; + unsigned int port_num = mp->port_num; - /* set default config values */ - eth_port_uc_addr_get(mp, dev->dev_addr); - mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; - mp->tx_ring_size = PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; + /* Read interrupt cause registers */ + eth_int_cause = rdl(mp, INTERRUPT_CAUSE_REG(port_num)) & + ETH_INT_UNMASK_ALL; + if (eth_int_cause & ETH_INT_CAUSE_EXT) { + eth_int_cause_ext = rdl(mp, + INTERRUPT_CAUSE_EXTEND_REG(port_num)) & + ETH_INT_UNMASK_ALL_EXT; + wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), + ~eth_int_cause_ext); + } - if (is_valid_ether_addr(pd->mac_addr)) - memcpy(dev->dev_addr, pd->mac_addr, 6); + /* PHY status changed */ + if (eth_int_cause_ext & (ETH_INT_CAUSE_PHY | ETH_INT_CAUSE_STATE)) { + struct ethtool_cmd cmd; - if (pd->phy_addr || pd->force_phy_addr) - ethernet_phy_set(mp, pd->phy_addr); + if (mii_link_ok(&mp->mii)) { + mii_ethtool_gset(&mp->mii, &cmd); + mv643xx_eth_update_pscr(dev, &cmd); + mv643xx_eth_port_enable_tx(mp, ETH_TX_QUEUES_ENABLED); + if (!netif_carrier_ok(dev)) { + netif_carrier_on(dev); + if (mp->tx_ring_size - mp->tx_desc_count >= + MAX_DESCS_PER_SKB) + netif_wake_queue(dev); + } + } else if (netif_carrier_ok(dev)) { + netif_stop_queue(dev); + netif_carrier_off(dev); + } + } - if (pd->rx_queue_size) - mp->rx_ring_size = pd->rx_queue_size; +#ifdef MV643XX_NAPI + if (eth_int_cause & ETH_INT_CAUSE_RX) { + /* schedule the NAPI poll routine to maintain port */ + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); - if (pd->tx_queue_size) - mp->tx_ring_size = pd->tx_queue_size; + /* wait for previous write to complete */ + rdl(mp, INTERRUPT_MASK_REG(port_num)); - if (pd->tx_sram_size) { - mp->tx_sram_size = pd->tx_sram_size; - mp->tx_sram_addr = pd->tx_sram_addr; + netif_rx_schedule(dev, &mp->napi); } - - if (pd->rx_sram_size) { - mp->rx_sram_size = pd->rx_sram_size; - mp->rx_sram_addr = pd->rx_sram_addr; - } - - duplex = pd->duplex; - speed = pd->speed; - - /* Hook up MII support for ethtool */ - mp->mii.dev = dev; - mp->mii.mdio_read = mv643xx_mdio_read; - mp->mii.mdio_write = mv643xx_mdio_write; - mp->mii.phy_id = ethernet_phy_get(mp); - mp->mii.phy_id_mask = 0x3f; - mp->mii.reg_num_mask = 0x1f; - - err = ethernet_phy_detect(mp); - if (err) { - pr_debug("%s: No PHY detected at addr %d\n", - dev->name, ethernet_phy_get(mp)); - goto out; - } - - ethernet_phy_reset(mp); - mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); - mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd); - mv643xx_eth_update_pscr(dev, &cmd); - mv643xx_set_settings(dev, &cmd); - - SET_NETDEV_DEV(dev, &pdev->dev); - err = register_netdev(dev); - if (err) - goto out; - - p = dev->dev_addr; - printk(KERN_NOTICE - "%s: port %d with MAC address %s\n", - dev->name, port_num, print_mac(mac, p)); - - if (dev->features & NETIF_F_SG) - printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name); - - if (dev->features & NETIF_F_IP_CSUM) - printk(KERN_NOTICE "%s: TX TCP/IP Checksumming Supported\n", - dev->name); - -#ifdef MV643XX_CHECKSUM_OFFLOAD_TX - printk(KERN_NOTICE "%s: RX TCP/UDP Checksum Offload ON \n", dev->name); -#endif - -#ifdef MV643XX_COAL - printk(KERN_NOTICE "%s: TX and RX Interrupt Coalescing ON \n", - dev->name); -#endif - -#ifdef MV643XX_NAPI - printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name); -#endif - - if (mp->tx_sram_size > 0) - printk(KERN_NOTICE "%s: Using SRAM\n", dev->name); - - return 0; - -out: - free_netdev(dev); - - return err; -} - -static int mv643xx_eth_remove(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - - unregister_netdev(dev); - flush_scheduled_work(); - - free_netdev(dev); - platform_set_drvdata(pdev, NULL); - return 0; -} - -static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, - struct mbus_dram_target_info *dram) -{ - void __iomem *base = msp->eth_base; - u32 win_enable; - u32 win_protect; - int i; - - for (i = 0; i < 6; i++) { - writel(0, base + WINDOW_BASE(i)); - writel(0, base + WINDOW_SIZE(i)); - if (i < 4) - writel(0, base + WINDOW_REMAP_HIGH(i)); - } - - win_enable = 0x3f; - win_protect = 0; - - for (i = 0; i < dram->num_cs; i++) { - struct mbus_dram_window *cs = dram->cs + i; - - writel((cs->base & 0xffff0000) | - (cs->mbus_attr << 8) | - dram->mbus_dram_target_id, base + WINDOW_BASE(i)); - writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); - - win_enable &= ~(1 << i); - win_protect |= 3 << (2 * i); - } - - writel(win_enable, base + WINDOW_BAR_ENABLE); - msp->win_protect = win_protect; -} - -static int mv643xx_eth_shared_probe(struct platform_device *pdev) -{ - static int mv643xx_version_printed = 0; - struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; - struct mv643xx_shared_private *msp; - struct resource *res; - int ret; - - if (!mv643xx_version_printed++) - printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); - - ret = -EINVAL; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res == NULL) - goto out; - - ret = -ENOMEM; - msp = kmalloc(sizeof(*msp), GFP_KERNEL); - if (msp == NULL) - goto out; - memset(msp, 0, sizeof(*msp)); - - msp->eth_base = ioremap(res->start, res->end - res->start + 1); - if (msp->eth_base == NULL) - goto out_free; - - spin_lock_init(&msp->phy_lock); - msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; - - platform_set_drvdata(pdev, msp); +#else + if (eth_int_cause & ETH_INT_CAUSE_RX) + mv643xx_eth_receive_queue(dev, INT_MAX); +#endif + if (eth_int_cause_ext & ETH_INT_CAUSE_TX) + mv643xx_eth_free_completed_tx_descs(dev); /* - * (Re-)program MBUS remapping windows if we are asked to. + * If no real interrupt occured, exit. + * This can happen when using gigE interrupt coalescing mechanism. */ - if (pd != NULL && pd->dram != NULL) - mv643xx_eth_conf_mbus_windows(msp, pd->dram); - - return 0; - -out_free: - kfree(msp); -out: - return ret; -} - -static int mv643xx_eth_shared_remove(struct platform_device *pdev) -{ - struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); - - iounmap(msp->eth_base); - kfree(msp); - - return 0; -} - -static void mv643xx_eth_shutdown(struct platform_device *pdev) -{ - struct net_device *dev = platform_get_drvdata(pdev); - struct mv643xx_private *mp = netdev_priv(dev); - unsigned int port_num = mp->port_num; - - /* Mask all interrupts on ethernet port */ - wrl(mp, INTERRUPT_MASK_REG(port_num), 0); - rdl(mp, INTERRUPT_MASK_REG(port_num)); - - eth_port_reset(mp); -} - -static struct platform_driver mv643xx_eth_driver = { - .probe = mv643xx_eth_probe, - .remove = mv643xx_eth_remove, - .shutdown = mv643xx_eth_shutdown, - .driver = { - .name = MV643XX_ETH_NAME, - .owner = THIS_MODULE, - }, -}; - -static struct platform_driver mv643xx_eth_shared_driver = { - .probe = mv643xx_eth_shared_probe, - .remove = mv643xx_eth_shared_remove, - .driver = { - .name = MV643XX_ETH_SHARED_NAME, - .owner = THIS_MODULE, - }, -}; - -/* - * mv643xx_init_module - * - * Registers the network drivers into the Linux kernel - * - * Input : N/A - * - * Output : N/A - */ -static int __init mv643xx_init_module(void) -{ - int rc; - - rc = platform_driver_register(&mv643xx_eth_shared_driver); - if (!rc) { - rc = platform_driver_register(&mv643xx_eth_driver); - if (rc) - platform_driver_unregister(&mv643xx_eth_shared_driver); - } - return rc; -} + if ((eth_int_cause == 0x0) && (eth_int_cause_ext == 0x0)) + return IRQ_NONE; -/* - * mv643xx_cleanup_module - * - * Registers the network drivers into the Linux kernel - * - * Input : N/A - * - * Output : N/A - */ -static void __exit mv643xx_cleanup_module(void) -{ - platform_driver_unregister(&mv643xx_eth_driver); - platform_driver_unregister(&mv643xx_eth_shared_driver); + return IRQ_HANDLED; } -module_init(mv643xx_init_module); -module_exit(mv643xx_cleanup_module); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani" - " and Dale Farnsworth"); -MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); -MODULE_ALIAS("platform:" MV643XX_ETH_NAME); -MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME); - -/* - * The second part is the low level driver of the gigE ethernet ports. - */ - -/* - * Marvell's Gigabit Ethernet controller low level driver - * - * DESCRIPTION: - * This file introduce low level API to Marvell's Gigabit Ethernet - * controller. This Gigabit Ethernet Controller driver API controls - * 1) Operations (i.e. port init, start, reset etc'). - * 2) Data flow (i.e. port send, receive etc'). - * Each Gigabit Ethernet port is controlled via - * struct mv643xx_private. - * This struct includes user configuration information as well as - * driver internal data needed for its operations. - * - * Supported Features: - * - This low level driver is OS independent. Allocating memory for - * the descriptor rings and buffers are not within the scope of - * this driver. - * - The user is free from Rx/Tx queue managing. - * - This low level driver introduce functionality API that enable - * the to operate Marvell's Gigabit Ethernet Controller in a - * convenient way. - * - Simple Gigabit Ethernet port operation API. - * - Simple Gigabit Ethernet port data flow API. - * - Data flow and operation API support per queue functionality. - * - Support cached descriptors for better performance. - * - Enable access to all four DRAM banks and internal SRAM memory - * spaces. - * - PHY access and control API. - * - Port control register configuration API. - * - Full control over Unicast and Multicast MAC configurations. - * - * Operation flow: - * - * Initialization phase - * This phase complete the initialization of the the - * mv643xx_private struct. - * User information regarding port configuration has to be set - * prior to calling the port initialization routine. - * - * In this phase any port Tx/Rx activity is halted, MIB counters - * are cleared, PHY address is set according to user parameter and - * access to DRAM and internal SRAM memory spaces. - * - * Driver ring initialization - * Allocating memory for the descriptor rings and buffers is not - * within the scope of this driver. Thus, the user is required to - * allocate memory for the descriptors ring and buffers. Those - * memory parameters are used by the Rx and Tx ring initialization - * routines in order to curve the descriptor linked list in a form - * of a ring. - * Note: Pay special attention to alignment issues when using - * cached descriptors/buffers. In this phase the driver store - * information in the mv643xx_private struct regarding each queue - * ring. - * - * Driver start - * This phase prepares the Ethernet port for Rx and Tx activity. - * It uses the information stored in the mv643xx_private struct to - * initialize the various port registers. - * - * Data flow: - * All packet references to/from the driver are done using - * struct pkt_info. - * This struct is a unified struct used with Rx and Tx operations. - * This way the user is not required to be familiar with neither - * Tx nor Rx descriptors structures. - * The driver's descriptors rings are management by indexes. - * Those indexes controls the ring resources and used to indicate - * a SW resource error: - * 'current' - * This index points to the current available resource for use. For - * example in Rx process this index will point to the descriptor - * that will be passed to the user upon calling the receive - * routine. In Tx process, this index will point to the descriptor - * that will be assigned with the user packet info and transmitted. - * 'used' - * This index points to the descriptor that need to restore its - * resources. For example in Rx process, using the Rx buffer return - * API will attach the buffer returned in packet info to the - * descriptor pointed by 'used'. In Tx process, using the Tx - * descriptor return will merely return the user packet info with - * the command status of the transmitted buffer pointed by the - * 'used' index. Nevertheless, it is essential to use this routine - * to update the 'used' index. - * 'first' - * This index supports Tx Scatter-Gather. It points to the first - * descriptor of a packet assembled of multiple buffers. For - * example when in middle of Such packet we have a Tx resource - * error the 'curr' index get the value of 'first' to indicate - * that the ring returned to its state before trying to transmit - * this packet. - * - * Receive operation: - * The eth_port_receive API set the packet information struct, - * passed by the caller, with received information from the - * 'current' SDMA descriptor. - * It is the user responsibility to return this resource back - * to the Rx descriptor ring to enable the reuse of this source. - * Return Rx resource is done using the eth_rx_return_buff API. - * - * Prior to calling the initialization routine eth_port_init() the user - * must set the following fields under mv643xx_private struct: - * port_num User Ethernet port number. - * port_config User port configuration value. - * port_config_extend User port config extend value. - * port_sdma_config User port SDMA config value. - * port_serial_control User port serial control value. - * - * This driver data flow is done using the struct pkt_info which - * is a unified struct for Rx and Tx operations: - * - * byte_cnt Tx/Rx descriptor buffer byte count. - * l4i_chk CPU provided TCP Checksum. For Tx operation - * only. - * cmd_sts Tx/Rx descriptor command status. - * buf_ptr Tx/Rx descriptor buffer pointer. - * return_info Tx/Rx user resource return information. - */ - -/* Ethernet Port routines */ -static void eth_port_set_filter_table_entry(struct mv643xx_private *mp, - int table, unsigned char entry); - /* - * eth_port_init - Initialize the Ethernet port driver + * ethernet_phy_reset - Reset Ethernet port PHY. * * DESCRIPTION: - * This function prepares the ethernet port to start its activity: - * 1) Completes the ethernet port driver struct initialization toward port - * start routine. - * 2) Resets the device to a quiescent state in case of warm reboot. - * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM. - * 4) Clean MAC tables. The reset status of those tables is unknown. - * 5) Set PHY address. - * Note: Call this routine prior to eth_port_start routine and after - * setting user values in the user fields of Ethernet port control - * struct. + * This routine utilizes the SMI interface to reset the ethernet port PHY. * * INPUT: - * struct mv643xx_private *mp Ethernet port control struct + * struct mv643xx_private *mp Ethernet Port. * * OUTPUT: - * See description. + * The PHY is reset. * * RETURN: * None. + * */ -static void eth_port_init(struct mv643xx_private *mp) +static void ethernet_phy_reset(struct mv643xx_private *mp) { - mp->rx_resource_err = 0; + unsigned int phy_reg_data; - eth_port_reset(mp); + /* Reset the PHY */ + eth_port_read_smi_reg(mp, 0, &phy_reg_data); + phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ + eth_port_write_smi_reg(mp, 0, phy_reg_data); - eth_port_init_mac_tables(mp); + /* wait for PHY to come out of reset */ + do { + udelay(1); + eth_port_read_smi_reg(mp, 0, &phy_reg_data); + } while (phy_reg_data & 0x8000); } /* @@ -2423,943 +2290,930 @@ static void eth_port_start(struct net_device *dev) mv643xx_set_settings(dev, ðtool_cmd); } +#ifdef MV643XX_COAL + /* - * eth_port_uc_addr_set - Write a MAC address into the port's hw registers + * eth_port_set_rx_coal - Sets coalescing interrupt mechanism on RX path + * + * DESCRIPTION: + * This routine sets the RX coalescing interrupt mechanism parameter. + * This parameter is a timeout counter, that counts in 64 t_clk + * chunks ; that when timeout event occurs a maskable interrupt + * occurs. + * The parameter is calculated using the tClk of the MV-643xx chip + * , and the required delay of the interrupt in usec. + * + * INPUT: + * struct mv643xx_private *mp Ethernet port + * unsigned int delay Delay in usec + * + * OUTPUT: + * Interrupt coalescing mechanism value is set in MV-643xx chip. + * + * RETURN: + * The interrupt coalescing value set in the gigE port. + * */ -static void eth_port_uc_addr_set(struct mv643xx_private *mp, - unsigned char *p_addr) +static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp, + unsigned int delay) { unsigned int port_num = mp->port_num; - unsigned int mac_h; - unsigned int mac_l; - int table; - - mac_l = (p_addr[4] << 8) | (p_addr[5]); - mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) | - (p_addr[3] << 0); + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; - wrl(mp, MAC_ADDR_LOW(port_num), mac_l); - wrl(mp, MAC_ADDR_HIGH(port_num), mac_h); + /* Set RX Coalescing mechanism */ + wrl(mp, SDMA_CONFIG_REG(port_num), + ((coal & 0x3fff) << 8) | + (rdl(mp, SDMA_CONFIG_REG(port_num)) + & 0xffc000ff)); - /* Accept frames with this address */ - table = DA_FILTER_UNICAST_TABLE_BASE(port_num); - eth_port_set_filter_table_entry(mp, table, p_addr[5] & 0x0f); + return coal; } +#endif /* - * eth_port_uc_addr_get - Read the MAC address from the port's hw registers + * eth_port_set_tx_coal - Sets coalescing interrupt mechanism on TX path + * + * DESCRIPTION: + * This routine sets the TX coalescing interrupt mechanism parameter. + * This parameter is a timeout counter, that counts in 64 t_clk + * chunks ; that when timeout event occurs a maskable interrupt + * occurs. + * The parameter is calculated using the t_cLK frequency of the + * MV-643xx chip and the required delay in the interrupt in uSec + * + * INPUT: + * struct mv643xx_private *mp Ethernet port + * unsigned int delay Delay in uSeconds + * + * OUTPUT: + * Interrupt coalescing mechanism value is set in MV-643xx chip. + * + * RETURN: + * The interrupt coalescing value set in the gigE port. + * */ -static void eth_port_uc_addr_get(struct mv643xx_private *mp, - unsigned char *p_addr) +static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp, + unsigned int delay) { - unsigned int port_num = mp->port_num; - unsigned int mac_h; - unsigned int mac_l; + unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64; - mac_h = rdl(mp, MAC_ADDR_HIGH(port_num)); - mac_l = rdl(mp, MAC_ADDR_LOW(port_num)); + /* Set TX Coalescing mechanism */ + wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4); - p_addr[0] = (mac_h >> 24) & 0xff; - p_addr[1] = (mac_h >> 16) & 0xff; - p_addr[2] = (mac_h >> 8) & 0xff; - p_addr[3] = mac_h & 0xff; - p_addr[4] = (mac_l >> 8) & 0xff; - p_addr[5] = mac_l & 0xff; + return coal; } /* - * The entries in each table are indexed by a hash of a packet's MAC - * address. One bit in each entry determines whether the packet is - * accepted. There are 4 entries (each 8 bits wide) in each register - * of the table. The bits in each entry are defined as follows: - * 0 Accept=1, Drop=0 - * 3-1 Queue (ETH_Q0=0) - * 7-4 Reserved = 0; + * eth_port_init - Initialize the Ethernet port driver + * + * DESCRIPTION: + * This function prepares the ethernet port to start its activity: + * 1) Completes the ethernet port driver struct initialization toward port + * start routine. + * 2) Resets the device to a quiescent state in case of warm reboot. + * 3) Enable SDMA access to all four DRAM banks as well as internal SRAM. + * 4) Clean MAC tables. The reset status of those tables is unknown. + * 5) Set PHY address. + * Note: Call this routine prior to eth_port_start routine and after + * setting user values in the user fields of Ethernet port control + * struct. + * + * INPUT: + * struct mv643xx_private *mp Ethernet port control struct + * + * OUTPUT: + * See description. + * + * RETURN: + * None. */ -static void eth_port_set_filter_table_entry(struct mv643xx_private *mp, - int table, unsigned char entry) +static void eth_port_init(struct mv643xx_private *mp) { - unsigned int table_reg; - unsigned int tbl_offset; - unsigned int reg_offset; + mp->rx_resource_err = 0; - tbl_offset = (entry / 4) * 4; /* Register offset of DA table entry */ - reg_offset = entry % 4; /* Entry offset within the register */ + eth_port_reset(mp); - /* Set "accepts frame bit" at specified table entry */ - table_reg = rdl(mp, table + tbl_offset); - table_reg |= 0x01 << (8 * reg_offset); - wrl(mp, table + tbl_offset, table_reg); + eth_port_init_mac_tables(mp); } /* - * eth_port_mc_addr - Multicast address settings. + * mv643xx_eth_open * - * The MV device supports multicast using two tables: - * 1) Special Multicast Table for MAC addresses of the form - * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF). - * The MAC DA[7:0] bits are used as a pointer to the Special Multicast - * Table entries in the DA-Filter table. - * 2) Other Multicast Table for multicast of another type. A CRC-8bit - * is used as an index to the Other Multicast Table entries in the - * DA-Filter table. This function calculates the CRC-8bit value. - * In either case, eth_port_set_filter_table_entry() is then called - * to set to set the actual table entry. + * This function is called when openning the network device. The function + * should initialize all the hardware, initialize cyclic Rx/Tx + * descriptors chain and buffers and allocate an IRQ to the network + * device. + * + * Input : a pointer to the network device structure + * + * Output : zero of success , nonzero if fails. */ -static void eth_port_mc_addr(struct mv643xx_private *mp, unsigned char *p_addr) + +static int mv643xx_eth_open(struct net_device *dev) { + struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; - unsigned int mac_h; - unsigned int mac_l; - unsigned char crc_result = 0; - int table; - int mac_array[48]; - int crc[8]; - int i; + unsigned int size; + int err; - if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) && - (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) { - table = DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num); - eth_port_set_filter_table_entry(mp, table, p_addr[5]); - return; + /* Clear any pending ethernet port interrupts */ + wrl(mp, INTERRUPT_CAUSE_REG(port_num), 0); + wrl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + /* wait for previous write to complete */ + rdl(mp, INTERRUPT_CAUSE_EXTEND_REG(port_num)); + + err = request_irq(dev->irq, mv643xx_eth_int_handler, + IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev); + if (err) { + printk(KERN_ERR "%s: Can not assign IRQ\n", dev->name); + return -EAGAIN; } - /* Calculate CRC-8 out of the given address */ - mac_h = (p_addr[0] << 8) | (p_addr[1]); - mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) | - (p_addr[4] << 8) | (p_addr[5] << 0); + eth_port_init(mp); - for (i = 0; i < 32; i++) - mac_array[i] = (mac_l >> i) & 0x1; - for (i = 32; i < 48; i++) - mac_array[i] = (mac_h >> (i - 32)) & 0x1; + memset(&mp->timeout, 0, sizeof(struct timer_list)); + mp->timeout.function = mv643xx_eth_rx_refill_descs_timer_wrapper; + mp->timeout.data = (unsigned long)dev; - crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^ - mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^ - mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^ - mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^ - mac_array[8] ^ mac_array[7] ^ mac_array[6] ^ mac_array[0]; + /* Allocate RX and TX skb rings */ + mp->rx_skb = kmalloc(sizeof(*mp->rx_skb) * mp->rx_ring_size, + GFP_KERNEL); + if (!mp->rx_skb) { + printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); + err = -ENOMEM; + goto out_free_irq; + } + mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, + GFP_KERNEL); + if (!mp->tx_skb) { + printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name); + err = -ENOMEM; + goto out_free_rx_skb; + } - crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^ - mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^ - mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^ - mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^ - mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^ - mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ mac_array[0]; + /* Allocate TX ring */ + mp->tx_desc_count = 0; + size = mp->tx_ring_size * sizeof(struct eth_tx_desc); + mp->tx_desc_area_size = size; - crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^ - mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^ - mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^ - mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ - mac_array[6] ^ mac_array[2] ^ mac_array[1] ^ mac_array[0]; + if (mp->tx_sram_size) { + mp->p_tx_desc_area = ioremap(mp->tx_sram_addr, + mp->tx_sram_size); + mp->tx_desc_dma = mp->tx_sram_addr; + } else + mp->p_tx_desc_area = dma_alloc_coherent(NULL, size, + &mp->tx_desc_dma, + GFP_KERNEL); - crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^ - mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^ - mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ - mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[7] ^ - mac_array[3] ^ mac_array[2] ^ mac_array[1]; + if (!mp->p_tx_desc_area) { + printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", + dev->name, size); + err = -ENOMEM; + goto out_free_tx_skb; + } + BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */ + memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size); - crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^ - mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^ - mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^ - mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^ - mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ mac_array[4] ^ - mac_array[3] ^ mac_array[2]; + ether_init_tx_desc_ring(mp); - crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^ - mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^ - mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^ - mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^ - mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[5] ^ - mac_array[4] ^ mac_array[3]; + /* Allocate RX ring */ + mp->rx_desc_count = 0; + size = mp->rx_ring_size * sizeof(struct eth_rx_desc); + mp->rx_desc_area_size = size; - crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^ - mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^ - mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^ - mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^ - mac_array[12] ^ mac_array[10] ^ mac_array[6] ^ mac_array[5] ^ - mac_array[4]; + if (mp->rx_sram_size) { + mp->p_rx_desc_area = ioremap(mp->rx_sram_addr, + mp->rx_sram_size); + mp->rx_desc_dma = mp->rx_sram_addr; + } else + mp->p_rx_desc_area = dma_alloc_coherent(NULL, size, + &mp->rx_desc_dma, + GFP_KERNEL); - crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^ - mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^ - mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^ - mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^ - mac_array[11] ^ mac_array[7] ^ mac_array[6] ^ mac_array[5]; + if (!mp->p_rx_desc_area) { + printk(KERN_ERR "%s: Cannot allocate Rx ring (size %d bytes)\n", + dev->name, size); + printk(KERN_ERR "%s: Freeing previously allocated TX queues...", + dev->name); + if (mp->rx_sram_size) + iounmap(mp->p_tx_desc_area); + else + dma_free_coherent(NULL, mp->tx_desc_area_size, + mp->p_tx_desc_area, mp->tx_desc_dma); + err = -ENOMEM; + goto out_free_tx_skb; + } + memset((void *)mp->p_rx_desc_area, 0, size); - for (i = 0; i < 8; i++) - crc_result = crc_result | (crc[i] << i); + ether_init_rx_desc_ring(mp); - table = DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num); - eth_port_set_filter_table_entry(mp, table, crc_result); -} + mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ -/* - * Set the entire multicast list based on dev->mc_list. - */ -static void eth_port_set_multicast_list(struct net_device *dev) -{ +#ifdef MV643XX_NAPI + napi_enable(&mp->napi); +#endif - struct dev_mc_list *mc_list; - int i; - int table_index; - struct mv643xx_private *mp = netdev_priv(dev); - unsigned int eth_port_num = mp->port_num; + eth_port_start(dev); - /* If the device is in promiscuous mode or in all multicast mode, - * we will fully populate both multicast tables with accept. - * This is guaranteed to yield a match on all multicast addresses... - */ - if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) { - for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Set all entries in DA filter special multicast - * table (Ex_dFSMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); + /* Interrupt Coalescing */ - /* Set all entries in DA filter other multicast - * table (Ex_dFOMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - } - return; - } +#ifdef MV643XX_COAL + mp->rx_int_coal = + eth_port_set_rx_coal(mp, MV643XX_RX_COAL); +#endif + + mp->tx_int_coal = + eth_port_set_tx_coal(mp, MV643XX_TX_COAL); - /* We will clear out multicast tables every time we get the list. - * Then add the entire new list... - */ - for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Clear DA filter special multicast table (Ex_dFSMT) */ - wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); + /* Unmask phy and link status changes interrupts */ + wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT); - /* Clear DA filter other multicast table (Ex_dFOMT) */ - wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); - } + /* Unmask RX buffer and TX end interrupt */ + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); - /* Get pointer to net_device multicast list and add each one... */ - for (i = 0, mc_list = dev->mc_list; - (i < 256) && (mc_list != NULL) && (i < dev->mc_count); - i++, mc_list = mc_list->next) - if (mc_list->dmi_addrlen == 6) - eth_port_mc_addr(mp, mc_list->dmi_addr); + return 0; + +out_free_tx_skb: + kfree(mp->tx_skb); +out_free_rx_skb: + kfree(mp->rx_skb); +out_free_irq: + free_irq(dev->irq, dev); + + return err; } /* - * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables + * eth_port_reset - Reset Ethernet port * * DESCRIPTION: - * Go through all the DA filter tables (Unicast, Special Multicast & - * Other Multicast) and set each entry to 0. + * This routine resets the chip by aborting any SDMA engine activity and + * clearing the MIB counters. The Receiver and the Transmit unit are in + * idle state after this command is performed and the port is disabled. * * INPUT: * struct mv643xx_private *mp Ethernet Port. * * OUTPUT: - * Multicast and Unicast packets are rejected. + * Channel activity is halted. * * RETURN: * None. + * */ -static void eth_port_init_mac_tables(struct mv643xx_private *mp) +static void eth_port_reset(struct mv643xx_private *mp) { unsigned int port_num = mp->port_num; - int table_index; + unsigned int reg_data; - /* Clear DA filter unicast table (Ex_dFUT) */ - for (table_index = 0; table_index <= 0xC; table_index += 4) - wrl(mp, DA_FILTER_UNICAST_TABLE_BASE(port_num) + - table_index, 0); + mv643xx_eth_port_disable_tx(mp); + mv643xx_eth_port_disable_rx(mp); - for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Clear DA filter special multicast table (Ex_dFSMT) */ - wrl(mp, DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port_num) + - table_index, 0); - /* Clear DA filter other multicast table (Ex_dFOMT) */ - wrl(mp, DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port_num) + - table_index, 0); - } + /* Clear all MIB counters */ + eth_clear_mib_counters(mp); + + /* Reset the Enable bit in the Configuration Register */ + reg_data = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num)); + reg_data &= ~(SERIAL_PORT_ENABLE | + DO_NOT_FORCE_LINK_FAIL | + FORCE_LINK_PASS); + wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), reg_data); } /* - * eth_clear_mib_counters - Clear all MIB counters - * - * DESCRIPTION: - * This function clears all MIB counters of a specific ethernet port. - * A read from the MIB counter will reset the counter. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port. - * - * OUTPUT: - * After reading all MIB counters, the counters resets. - * - * RETURN: - * MIB counter value. + * mv643xx_eth_stop * + * This function is used when closing the network device. + * It updates the hardware, + * release all memory that holds buffers and descriptors and release the IRQ. + * Input : a pointer to the device structure + * Output : zero if success , nonzero if fails */ -static void eth_clear_mib_counters(struct mv643xx_private *mp) + +static int mv643xx_eth_stop(struct net_device *dev) { + struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; - int i; - - /* Perform dummy reads from MIB counters */ - for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION; - i += 4) - rdl(mp, MIB_COUNTERS_BASE(port_num) + i); -} -static inline u32 read_mib(struct mv643xx_private *mp, int offset) -{ - return rdl(mp, MIB_COUNTERS_BASE(mp->port_num) + offset); -} + /* Mask all interrupts on ethernet port */ + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); + /* wait for previous write to complete */ + rdl(mp, INTERRUPT_MASK_REG(port_num)); -static void eth_update_mib_counters(struct mv643xx_private *mp) -{ - struct mv643xx_mib_counters *p = &mp->mib_counters; - int offset; +#ifdef MV643XX_NAPI + napi_disable(&mp->napi); +#endif + netif_carrier_off(dev); + netif_stop_queue(dev); - p->good_octets_received += - read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW); - p->good_octets_received += - (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH) << 32; + eth_port_reset(mp); - for (offset = ETH_MIB_BAD_OCTETS_RECEIVED; - offset <= ETH_MIB_FRAMES_1024_TO_MAX_OCTETS; - offset += 4) - *(u32 *)((char *)p + offset) += read_mib(mp, offset); + mv643xx_eth_free_tx_rings(dev); + mv643xx_eth_free_rx_rings(dev); - p->good_octets_sent += read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_LOW); - p->good_octets_sent += - (u64)read_mib(mp, ETH_MIB_GOOD_OCTETS_SENT_HIGH) << 32; + free_irq(dev->irq, dev); - for (offset = ETH_MIB_GOOD_FRAMES_SENT; - offset <= ETH_MIB_LATE_COLLISION; - offset += 4) - *(u32 *)((char *)p + offset) += read_mib(mp, offset); + return 0; } -/* - * ethernet_phy_detect - Detect whether a phy is present - * - * DESCRIPTION: - * This function tests whether there is a PHY present on - * the specified port. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port. - * - * OUTPUT: - * None - * - * RETURN: - * 0 on success - * -ENODEV on failure - * - */ -static int ethernet_phy_detect(struct mv643xx_private *mp) +static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { - unsigned int phy_reg_data0; - int auto_neg; - - eth_port_read_smi_reg(mp, 0, &phy_reg_data0); - auto_neg = phy_reg_data0 & 0x1000; - phy_reg_data0 ^= 0x1000; /* invert auto_neg */ - eth_port_write_smi_reg(mp, 0, phy_reg_data0); - - eth_port_read_smi_reg(mp, 0, &phy_reg_data0); - if ((phy_reg_data0 & 0x1000) == auto_neg) - return -ENODEV; /* change didn't take */ + struct mv643xx_private *mp = netdev_priv(dev); - phy_reg_data0 ^= 0x1000; - eth_port_write_smi_reg(mp, 0, phy_reg_data0); - return 0; + return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); } /* - * ethernet_phy_get - Get the ethernet port PHY address. - * - * DESCRIPTION: - * This routine returns the given ethernet port PHY address. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port. - * - * OUTPUT: - * None. - * - * RETURN: - * PHY address. + * Changes MTU (maximum transfer unit) of the gigabit ethenret port * + * Input : pointer to ethernet interface network device structure + * new mtu size + * Output : 0 upon success, -EINVAL upon failure */ -static int ethernet_phy_get(struct mv643xx_private *mp) +static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) { - unsigned int reg_data; + if ((new_mtu > 9500) || (new_mtu < 64)) + return -EINVAL; - reg_data = rdl(mp, PHY_ADDR_REG); + dev->mtu = new_mtu; + if (!netif_running(dev)) + return 0; - return ((reg_data >> (5 * mp->port_num)) & 0x1f); + /* + * Stop and then re-open the interface. This will allocate RX + * skbs of the new MTU. + * There is a possible danger that the open will not succeed, + * due to memory being full, which might fail the open function. + */ + mv643xx_eth_stop(dev); + if (mv643xx_eth_open(dev)) { + printk(KERN_ERR "%s: Fatal error on opening device\n", + dev->name); + } + + return 0; } /* - * ethernet_phy_set - Set the ethernet port PHY address. - * - * DESCRIPTION: - * This routine sets the given ethernet port PHY address. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port. - * int phy_addr PHY address. - * - * OUTPUT: - * None. - * - * RETURN: - * None. + * mv643xx_eth_tx_timeout_task * + * Actual routine to reset the adapter when a timeout on Tx has occurred */ -static void ethernet_phy_set(struct mv643xx_private *mp, int phy_addr) +static void mv643xx_eth_tx_timeout_task(struct work_struct *ugly) { - u32 reg_data; - int addr_shift = 5 * mp->port_num; + struct mv643xx_private *mp = container_of(ugly, struct mv643xx_private, + tx_timeout_task); + struct net_device *dev = mp->dev; - reg_data = rdl(mp, PHY_ADDR_REG); - reg_data &= ~(0x1f << addr_shift); - reg_data |= (phy_addr & 0x1f) << addr_shift; - wrl(mp, PHY_ADDR_REG, reg_data); -} + if (!netif_running(dev)) + return; -/* - * ethernet_phy_reset - Reset Ethernet port PHY. - * - * DESCRIPTION: - * This routine utilizes the SMI interface to reset the ethernet port PHY. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port. - * - * OUTPUT: - * The PHY is reset. + netif_stop_queue(dev); + + eth_port_reset(mp); + eth_port_start(dev); + + if (mp->tx_ring_size - mp->tx_desc_count >= MAX_DESCS_PER_SKB) + netif_wake_queue(dev); +} + +/* + * mv643xx_eth_tx_timeout * - * RETURN: - * None. + * Called upon a timeout on transmitting a packet * + * Input : pointer to ethernet interface network device structure. + * Output : N/A */ -static void ethernet_phy_reset(struct mv643xx_private *mp) +static void mv643xx_eth_tx_timeout(struct net_device *dev) { - unsigned int phy_reg_data; + struct mv643xx_private *mp = netdev_priv(dev); - /* Reset the PHY */ - eth_port_read_smi_reg(mp, 0, &phy_reg_data); - phy_reg_data |= 0x8000; /* Set bit 15 to reset the PHY */ - eth_port_write_smi_reg(mp, 0, phy_reg_data); + printk(KERN_INFO "%s: TX timeout ", dev->name); - /* wait for PHY to come out of reset */ - do { - udelay(1); - eth_port_read_smi_reg(mp, 0, &phy_reg_data); - } while (phy_reg_data & 0x8000); + /* Do the reset outside of interrupt context */ + schedule_work(&mp->tx_timeout_task); } -static void mv643xx_eth_port_enable_tx(struct mv643xx_private *mp, - unsigned int queues) +#ifdef CONFIG_NET_POLL_CONTROLLER +static void mv643xx_netpoll(struct net_device *netdev) { - wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(mp->port_num), queues); + struct mv643xx_private *mp = netdev_priv(netdev); + int port_num = mp->port_num; + + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL); + /* wait for previous write to complete */ + rdl(mp, INTERRUPT_MASK_REG(port_num)); + + mv643xx_eth_int_handler(netdev->irq, netdev); + + wrl(mp, INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL); } +#endif -static void mv643xx_eth_port_enable_rx(struct mv643xx_private *mp, - unsigned int queues) +/* + * Wrappers for MII support library. + */ +static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location) { - wrl(mp, RECEIVE_QUEUE_COMMAND_REG(mp->port_num), queues); + struct mv643xx_private *mp = netdev_priv(dev); + int val; + + eth_port_read_smi_reg(mp, location, &val); + return val; } -static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_private *mp) +static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val) { - unsigned int port_num = mp->port_num; - u32 queues; + struct mv643xx_private *mp = netdev_priv(dev); + eth_port_write_smi_reg(mp, location, val); +} - /* Stop Tx port activity. Check port Tx activity. */ - queues = rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF; - if (queues) { - /* Issue stop command for active queues only */ - wrl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num), (queues << 8)); - /* Wait for all Tx activity to terminate. */ - /* Check port cause register that all Tx queues are stopped */ - while (rdl(mp, TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); +/* platform glue ************************************************************/ +static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp, + struct mbus_dram_target_info *dram) +{ + void __iomem *base = msp->eth_base; + u32 win_enable; + u32 win_protect; + int i; - /* Wait for Tx FIFO to empty */ - while (rdl(mp, PORT_STATUS_REG(port_num)) & - ETH_PORT_TX_FIFO_EMPTY) - udelay(PHY_WAIT_MICRO_SECONDS); + for (i = 0; i < 6; i++) { + writel(0, base + WINDOW_BASE(i)); + writel(0, base + WINDOW_SIZE(i)); + if (i < 4) + writel(0, base + WINDOW_REMAP_HIGH(i)); } - return queues; + win_enable = 0x3f; + win_protect = 0; + + for (i = 0; i < dram->num_cs; i++) { + struct mbus_dram_window *cs = dram->cs + i; + + writel((cs->base & 0xffff0000) | + (cs->mbus_attr << 8) | + dram->mbus_dram_target_id, base + WINDOW_BASE(i)); + writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i)); + + win_enable &= ~(1 << i); + win_protect |= 3 << (2 * i); + } + + writel(win_enable, base + WINDOW_BAR_ENABLE); + msp->win_protect = win_protect; } -static unsigned int mv643xx_eth_port_disable_rx(struct mv643xx_private *mp) +static int mv643xx_eth_shared_probe(struct platform_device *pdev) { - unsigned int port_num = mp->port_num; - u32 queues; + static int mv643xx_version_printed = 0; + struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; + struct mv643xx_shared_private *msp; + struct resource *res; + int ret; - /* Stop Rx port activity. Check port Rx activity. */ - queues = rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF; - if (queues) { - /* Issue stop command for active queues only */ - wrl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num), (queues << 8)); + if (!mv643xx_version_printed++) + printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n"); - /* Wait for all Rx activity to terminate. */ - /* Check port cause register that all Rx queues are stopped */ - while (rdl(mp, RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF) - udelay(PHY_WAIT_MICRO_SECONDS); - } + ret = -EINVAL; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) + goto out; - return queues; + ret = -ENOMEM; + msp = kmalloc(sizeof(*msp), GFP_KERNEL); + if (msp == NULL) + goto out; + memset(msp, 0, sizeof(*msp)); + + msp->eth_base = ioremap(res->start, res->end - res->start + 1); + if (msp->eth_base == NULL) + goto out_free; + + spin_lock_init(&msp->phy_lock); + msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000; + + platform_set_drvdata(pdev, msp); + + /* + * (Re-)program MBUS remapping windows if we are asked to. + */ + if (pd != NULL && pd->dram != NULL) + mv643xx_eth_conf_mbus_windows(msp, pd->dram); + + return 0; + +out_free: + kfree(msp); +out: + return ret; +} + +static int mv643xx_eth_shared_remove(struct platform_device *pdev) +{ + struct mv643xx_shared_private *msp = platform_get_drvdata(pdev); + + iounmap(msp->eth_base); + kfree(msp); + + return 0; } +static struct platform_driver mv643xx_eth_shared_driver = { + .probe = mv643xx_eth_shared_probe, + .remove = mv643xx_eth_shared_remove, + .driver = { + .name = MV643XX_ETH_SHARED_NAME, + .owner = THIS_MODULE, + }, +}; + /* - * eth_port_reset - Reset Ethernet port + * ethernet_phy_set - Set the ethernet port PHY address. * * DESCRIPTION: - * This routine resets the chip by aborting any SDMA engine activity and - * clearing the MIB counters. The Receiver and the Transmit unit are in - * idle state after this command is performed and the port is disabled. + * This routine sets the given ethernet port PHY address. * * INPUT: * struct mv643xx_private *mp Ethernet Port. + * int phy_addr PHY address. * * OUTPUT: - * Channel activity is halted. + * None. * * RETURN: * None. * */ -static void eth_port_reset(struct mv643xx_private *mp) +static void ethernet_phy_set(struct mv643xx_private *mp, int phy_addr) { - unsigned int port_num = mp->port_num; - unsigned int reg_data; - - mv643xx_eth_port_disable_tx(mp); - mv643xx_eth_port_disable_rx(mp); - - /* Clear all MIB counters */ - eth_clear_mib_counters(mp); + u32 reg_data; + int addr_shift = 5 * mp->port_num; - /* Reset the Enable bit in the Configuration Register */ - reg_data = rdl(mp, PORT_SERIAL_CONTROL_REG(port_num)); - reg_data &= ~(SERIAL_PORT_ENABLE | - DO_NOT_FORCE_LINK_FAIL | - FORCE_LINK_PASS); - wrl(mp, PORT_SERIAL_CONTROL_REG(port_num), reg_data); + reg_data = rdl(mp, PHY_ADDR_REG); + reg_data &= ~(0x1f << addr_shift); + reg_data |= (phy_addr & 0x1f) << addr_shift; + wrl(mp, PHY_ADDR_REG, reg_data); } - /* - * eth_port_read_smi_reg - Read PHY registers + * ethernet_phy_get - Get the ethernet port PHY address. * * DESCRIPTION: - * This routine utilize the SMI interface to interact with the PHY in - * order to perform PHY register read. + * This routine returns the given ethernet port PHY address. * * INPUT: * struct mv643xx_private *mp Ethernet Port. - * unsigned int phy_reg PHY register address offset. - * unsigned int *value Register value buffer. * * OUTPUT: - * Write the value of a specified PHY register into given buffer. + * None. * * RETURN: - * false if the PHY is busy or read data is not in valid state. - * true otherwise. + * PHY address. * */ -static void eth_port_read_smi_reg(struct mv643xx_private *mp, - unsigned int phy_reg, unsigned int *value) +static int ethernet_phy_get(struct mv643xx_private *mp) { - void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; - int phy_addr = ethernet_phy_get(mp); - unsigned long flags; - int i; - - /* the SMI register is a shared resource */ - spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); - - /* wait for the SMI register to become available */ - for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { - if (i == PHY_WAIT_ITERATIONS) { - printk("%s: PHY busy timeout\n", mp->dev->name); - goto out; - } - udelay(PHY_WAIT_MICRO_SECONDS); - } - - writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ, - smi_reg); + unsigned int reg_data; - /* now wait for the data to be valid */ - for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) { - if (i == PHY_WAIT_ITERATIONS) { - printk("%s: PHY read timeout\n", mp->dev->name); - goto out; - } - udelay(PHY_WAIT_MICRO_SECONDS); - } + reg_data = rdl(mp, PHY_ADDR_REG); - *value = readl(smi_reg) & 0xffff; -out: - spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); + return ((reg_data >> (5 * mp->port_num)) & 0x1f); } /* - * eth_port_write_smi_reg - Write to PHY registers + * ethernet_phy_detect - Detect whether a phy is present * * DESCRIPTION: - * This routine utilize the SMI interface to interact with the PHY in - * order to perform writes to PHY registers. + * This function tests whether there is a PHY present on + * the specified port. * * INPUT: * struct mv643xx_private *mp Ethernet Port. - * unsigned int phy_reg PHY register address offset. - * unsigned int value Register value. * * OUTPUT: - * Write the given value to the specified PHY register. + * None * * RETURN: - * false if the PHY is busy. - * true otherwise. + * 0 on success + * -ENODEV on failure * */ -static void eth_port_write_smi_reg(struct mv643xx_private *mp, - unsigned int phy_reg, unsigned int value) +static int ethernet_phy_detect(struct mv643xx_private *mp) { - void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG; - int phy_addr = ethernet_phy_get(mp); - unsigned long flags; - int i; + unsigned int phy_reg_data0; + int auto_neg; - /* the SMI register is a shared resource */ - spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); + eth_port_read_smi_reg(mp, 0, &phy_reg_data0); + auto_neg = phy_reg_data0 & 0x1000; + phy_reg_data0 ^= 0x1000; /* invert auto_neg */ + eth_port_write_smi_reg(mp, 0, phy_reg_data0); - /* wait for the SMI register to become available */ - for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) { - if (i == PHY_WAIT_ITERATIONS) { - printk("%s: PHY busy timeout\n", mp->dev->name); - goto out; - } - udelay(PHY_WAIT_MICRO_SECONDS); - } + eth_port_read_smi_reg(mp, 0, &phy_reg_data0); + if ((phy_reg_data0 & 0x1000) == auto_neg) + return -ENODEV; /* change didn't take */ - writel((phy_addr << 16) | (phy_reg << 21) | - ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg); -out: - spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); + phy_reg_data0 ^= 0x1000; + eth_port_write_smi_reg(mp, 0, phy_reg_data0); + return 0; } -/* - * Wrappers for MII support library. - */ -static int mv643xx_mdio_read(struct net_device *dev, int phy_id, int location) +static void mv643xx_init_ethtool_cmd(struct net_device *dev, int phy_address, + int speed, int duplex, + struct ethtool_cmd *cmd) { struct mv643xx_private *mp = netdev_priv(dev); - int val; - eth_port_read_smi_reg(mp, location, &val); - return val; -} + memset(cmd, 0, sizeof(*cmd)); -static void mv643xx_mdio_write(struct net_device *dev, int phy_id, int location, int val) -{ - struct mv643xx_private *mp = netdev_priv(dev); - eth_port_write_smi_reg(mp, location, val); + cmd->port = PORT_MII; + cmd->transceiver = XCVR_INTERNAL; + cmd->phy_address = phy_address; + + if (speed == 0) { + cmd->autoneg = AUTONEG_ENABLE; + /* mii lib checks, but doesn't use speed on AUTONEG_ENABLE */ + cmd->speed = SPEED_100; + cmd->advertising = ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full; + if (mp->mii.supports_gmii) + cmd->advertising |= ADVERTISED_1000baseT_Full; + } else { + cmd->autoneg = AUTONEG_DISABLE; + cmd->speed = speed; + cmd->duplex = duplex; + } } -/* - * eth_port_receive - Get received information from Rx ring. - * - * DESCRIPTION: - * This routine returns the received data to the caller. There is no - * data copying during routine operation. All information is returned - * using pointer to packet information struct passed from the caller. - * If the routine exhausts Rx ring resources then the resource error flag - * is set. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port Control srtuct. - * struct pkt_info *p_pkt_info User packet buffer. +/*/ + * mv643xx_eth_probe * - * OUTPUT: - * Rx ring current and used indexes are updated. + * First function called after registering the network device. + * It's purpose is to initialize the device as an ethernet device, + * fill the ethernet device structure with pointers * to functions, + * and set the MAC address of the interface * - * RETURN: - * ETH_ERROR in case the routine can not access Rx desc ring. - * ETH_QUEUE_FULL if Rx ring resources are exhausted. - * ETH_END_OF_JOB if there is no received data. - * ETH_OK otherwise. + * Input : struct device * + * Output : -ENOMEM if failed , 0 if success */ -static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, - struct pkt_info *p_pkt_info) +static int mv643xx_eth_probe(struct platform_device *pdev) { - int rx_next_curr_desc, rx_curr_desc, rx_used_desc; - volatile struct eth_rx_desc *p_rx_desc; - unsigned int command_status; - unsigned long flags; + struct mv643xx_eth_platform_data *pd; + int port_num; + struct mv643xx_private *mp; + struct net_device *dev; + u8 *p; + struct resource *res; + int err; + struct ethtool_cmd cmd; + int duplex = DUPLEX_HALF; + int speed = 0; /* default to auto-negotiation */ + DECLARE_MAC_BUF(mac); - /* Do not process Rx ring in case of Rx ring resource error */ - if (mp->rx_resource_err) - return ETH_QUEUE_FULL; + pd = pdev->dev.platform_data; + if (pd == NULL) { + printk(KERN_ERR "No mv643xx_eth_platform_data\n"); + return -ENODEV; + } - spin_lock_irqsave(&mp->lock, flags); + if (pd->shared == NULL) { + printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n"); + return -ENODEV; + } - /* Get the Rx Desc ring 'curr and 'used' indexes */ - rx_curr_desc = mp->rx_curr_desc_q; - rx_used_desc = mp->rx_used_desc_q; + dev = alloc_etherdev(sizeof(struct mv643xx_private)); + if (!dev) + return -ENOMEM; - p_rx_desc = &mp->p_rx_desc_area[rx_curr_desc]; + platform_set_drvdata(pdev, dev); - /* The following parameters are used to save readings from memory */ - command_status = p_rx_desc->cmd_sts; - rmb(); + mp = netdev_priv(dev); + mp->dev = dev; +#ifdef MV643XX_NAPI + netif_napi_add(dev, &mp->napi, mv643xx_poll, 64); +#endif - /* Nothing to receive... */ - if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { - spin_unlock_irqrestore(&mp->lock, flags); - return ETH_END_OF_JOB; - } + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + BUG_ON(!res); + dev->irq = res->start; - p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET; - p_pkt_info->cmd_sts = command_status; - p_pkt_info->buf_ptr = (p_rx_desc->buf_ptr) + RX_BUF_OFFSET; - p_pkt_info->return_info = mp->rx_skb[rx_curr_desc]; - p_pkt_info->l4i_chk = p_rx_desc->buf_size; + dev->open = mv643xx_eth_open; + dev->stop = mv643xx_eth_stop; + dev->hard_start_xmit = mv643xx_eth_start_xmit; + dev->set_mac_address = mv643xx_eth_set_mac_address; + dev->set_multicast_list = mv643xx_eth_set_rx_mode; + + /* No need to Tx Timeout */ + dev->tx_timeout = mv643xx_eth_tx_timeout; + +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = mv643xx_netpoll; +#endif + + dev->watchdog_timeo = 2 * HZ; + dev->base_addr = 0; + dev->change_mtu = mv643xx_eth_change_mtu; + dev->do_ioctl = mv643xx_eth_do_ioctl; + SET_ETHTOOL_OPS(dev, &mv643xx_ethtool_ops); +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX +#ifdef MAX_SKB_FRAGS /* - * Clean the return info field to indicate that the - * packet has been moved to the upper layers + * Zero copy can only work if we use Discovery II memory. Else, we will + * have to map the buffers to ISA memory which is only 16 MB */ - mp->rx_skb[rx_curr_desc] = NULL; + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; +#endif +#endif - /* Update current index in data structure */ - rx_next_curr_desc = (rx_curr_desc + 1) % mp->rx_ring_size; - mp->rx_curr_desc_q = rx_next_curr_desc; + /* Configure the timeout task */ + INIT_WORK(&mp->tx_timeout_task, mv643xx_eth_tx_timeout_task); - /* Rx descriptors exhausted. Set the Rx ring resource error flag */ - if (rx_next_curr_desc == rx_used_desc) - mp->rx_resource_err = 1; + spin_lock_init(&mp->lock); - spin_unlock_irqrestore(&mp->lock, flags); + mp->shared = platform_get_drvdata(pd->shared); + port_num = mp->port_num = pd->port_number; - return ETH_OK; -} + if (mp->shared->win_protect) + wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect); -/* - * eth_rx_return_buff - Returns a Rx buffer back to the Rx ring. - * - * DESCRIPTION: - * This routine returns a Rx buffer back to the Rx ring. It retrieves the - * next 'used' descriptor and attached the returned buffer to it. - * In case the Rx ring was in "resource error" condition, where there are - * no available Rx resources, the function resets the resource error flag. - * - * INPUT: - * struct mv643xx_private *mp Ethernet Port Control srtuct. - * struct pkt_info *p_pkt_info Information on returned buffer. - * - * OUTPUT: - * New available Rx resource in Rx descriptor ring. - * - * RETURN: - * ETH_ERROR in case the routine can not access Rx desc ring. - * ETH_OK otherwise. - */ -static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, - struct pkt_info *p_pkt_info) -{ - int used_rx_desc; /* Where to return Rx resource */ - volatile struct eth_rx_desc *p_used_rx_desc; - unsigned long flags; + mp->shared_smi = mp->shared; + if (pd->shared_smi != NULL) + mp->shared_smi = platform_get_drvdata(pd->shared_smi); + + /* set default config values */ + eth_port_uc_addr_get(mp, dev->dev_addr); + mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE; + mp->tx_ring_size = PORT_DEFAULT_TRANSMIT_QUEUE_SIZE; + + if (is_valid_ether_addr(pd->mac_addr)) + memcpy(dev->dev_addr, pd->mac_addr, 6); + + if (pd->phy_addr || pd->force_phy_addr) + ethernet_phy_set(mp, pd->phy_addr); - spin_lock_irqsave(&mp->lock, flags); + if (pd->rx_queue_size) + mp->rx_ring_size = pd->rx_queue_size; - /* Get 'used' Rx descriptor */ - used_rx_desc = mp->rx_used_desc_q; - p_used_rx_desc = &mp->p_rx_desc_area[used_rx_desc]; + if (pd->tx_queue_size) + mp->tx_ring_size = pd->tx_queue_size; - p_used_rx_desc->buf_ptr = p_pkt_info->buf_ptr; - p_used_rx_desc->buf_size = p_pkt_info->byte_cnt; - mp->rx_skb[used_rx_desc] = p_pkt_info->return_info; + if (pd->tx_sram_size) { + mp->tx_sram_size = pd->tx_sram_size; + mp->tx_sram_addr = pd->tx_sram_addr; + } - /* Flush the write pipe */ + if (pd->rx_sram_size) { + mp->rx_sram_size = pd->rx_sram_size; + mp->rx_sram_addr = pd->rx_sram_addr; + } - /* Return the descriptor to DMA ownership */ - wmb(); - p_used_rx_desc->cmd_sts = - ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT; - wmb(); + duplex = pd->duplex; + speed = pd->speed; - /* Move the used descriptor pointer to the next descriptor */ - mp->rx_used_desc_q = (used_rx_desc + 1) % mp->rx_ring_size; + /* Hook up MII support for ethtool */ + mp->mii.dev = dev; + mp->mii.mdio_read = mv643xx_mdio_read; + mp->mii.mdio_write = mv643xx_mdio_write; + mp->mii.phy_id = ethernet_phy_get(mp); + mp->mii.phy_id_mask = 0x3f; + mp->mii.reg_num_mask = 0x1f; - /* Any Rx return cancels the Rx resource error status */ - mp->rx_resource_err = 0; + err = ethernet_phy_detect(mp); + if (err) { + pr_debug("%s: No PHY detected at addr %d\n", + dev->name, ethernet_phy_get(mp)); + goto out; + } - spin_unlock_irqrestore(&mp->lock, flags); + ethernet_phy_reset(mp); + mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); + mv643xx_init_ethtool_cmd(dev, mp->mii.phy_id, speed, duplex, &cmd); + mv643xx_eth_update_pscr(dev, &cmd); + mv643xx_set_settings(dev, &cmd); - return ETH_OK; -} + SET_NETDEV_DEV(dev, &pdev->dev); + err = register_netdev(dev); + if (err) + goto out; -/************* Begin ethtool support *************************/ + p = dev->dev_addr; + printk(KERN_NOTICE + "%s: port %d with MAC address %s\n", + dev->name, port_num, print_mac(mac, p)); -struct mv643xx_stats { - char stat_string[ETH_GSTRING_LEN]; - int sizeof_stat; - int stat_offset; -}; + if (dev->features & NETIF_F_SG) + printk(KERN_NOTICE "%s: Scatter Gather Enabled\n", dev->name); -#define MV643XX_STAT(m) FIELD_SIZEOF(struct mv643xx_private, m), \ - offsetof(struct mv643xx_private, m) + if (dev->features & NETIF_F_IP_CSUM) + printk(KERN_NOTICE "%s: TX TCP/IP Checksumming Supported\n", + dev->name); -static const struct mv643xx_stats mv643xx_gstrings_stats[] = { - { "rx_packets", MV643XX_STAT(stats.rx_packets) }, - { "tx_packets", MV643XX_STAT(stats.tx_packets) }, - { "rx_bytes", MV643XX_STAT(stats.rx_bytes) }, - { "tx_bytes", MV643XX_STAT(stats.tx_bytes) }, - { "rx_errors", MV643XX_STAT(stats.rx_errors) }, - { "tx_errors", MV643XX_STAT(stats.tx_errors) }, - { "rx_dropped", MV643XX_STAT(stats.rx_dropped) }, - { "tx_dropped", MV643XX_STAT(stats.tx_dropped) }, - { "good_octets_received", MV643XX_STAT(mib_counters.good_octets_received) }, - { "bad_octets_received", MV643XX_STAT(mib_counters.bad_octets_received) }, - { "internal_mac_transmit_err", MV643XX_STAT(mib_counters.internal_mac_transmit_err) }, - { "good_frames_received", MV643XX_STAT(mib_counters.good_frames_received) }, - { "bad_frames_received", MV643XX_STAT(mib_counters.bad_frames_received) }, - { "broadcast_frames_received", MV643XX_STAT(mib_counters.broadcast_frames_received) }, - { "multicast_frames_received", MV643XX_STAT(mib_counters.multicast_frames_received) }, - { "frames_64_octets", MV643XX_STAT(mib_counters.frames_64_octets) }, - { "frames_65_to_127_octets", MV643XX_STAT(mib_counters.frames_65_to_127_octets) }, - { "frames_128_to_255_octets", MV643XX_STAT(mib_counters.frames_128_to_255_octets) }, - { "frames_256_to_511_octets", MV643XX_STAT(mib_counters.frames_256_to_511_octets) }, - { "frames_512_to_1023_octets", MV643XX_STAT(mib_counters.frames_512_to_1023_octets) }, - { "frames_1024_to_max_octets", MV643XX_STAT(mib_counters.frames_1024_to_max_octets) }, - { "good_octets_sent", MV643XX_STAT(mib_counters.good_octets_sent) }, - { "good_frames_sent", MV643XX_STAT(mib_counters.good_frames_sent) }, - { "excessive_collision", MV643XX_STAT(mib_counters.excessive_collision) }, - { "multicast_frames_sent", MV643XX_STAT(mib_counters.multicast_frames_sent) }, - { "broadcast_frames_sent", MV643XX_STAT(mib_counters.broadcast_frames_sent) }, - { "unrec_mac_control_received", MV643XX_STAT(mib_counters.unrec_mac_control_received) }, - { "fc_sent", MV643XX_STAT(mib_counters.fc_sent) }, - { "good_fc_received", MV643XX_STAT(mib_counters.good_fc_received) }, - { "bad_fc_received", MV643XX_STAT(mib_counters.bad_fc_received) }, - { "undersize_received", MV643XX_STAT(mib_counters.undersize_received) }, - { "fragments_received", MV643XX_STAT(mib_counters.fragments_received) }, - { "oversize_received", MV643XX_STAT(mib_counters.oversize_received) }, - { "jabber_received", MV643XX_STAT(mib_counters.jabber_received) }, - { "mac_receive_error", MV643XX_STAT(mib_counters.mac_receive_error) }, - { "bad_crc_event", MV643XX_STAT(mib_counters.bad_crc_event) }, - { "collision", MV643XX_STAT(mib_counters.collision) }, - { "late_collision", MV643XX_STAT(mib_counters.late_collision) }, -}; +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX + printk(KERN_NOTICE "%s: RX TCP/UDP Checksum Offload ON \n", dev->name); +#endif -#define MV643XX_STATS_LEN ARRAY_SIZE(mv643xx_gstrings_stats) +#ifdef MV643XX_COAL + printk(KERN_NOTICE "%s: TX and RX Interrupt Coalescing ON \n", + dev->name); +#endif -static void mv643xx_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) -{ - strncpy(drvinfo->driver, mv643xx_driver_name, 32); - strncpy(drvinfo->version, mv643xx_driver_version, 32); - strncpy(drvinfo->fw_version, "N/A", 32); - strncpy(drvinfo->bus_info, "mv643xx", 32); - drvinfo->n_stats = MV643XX_STATS_LEN; -} +#ifdef MV643XX_NAPI + printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name); +#endif -static int mv643xx_get_sset_count(struct net_device *netdev, int sset) -{ - switch (sset) { - case ETH_SS_STATS: - return MV643XX_STATS_LEN; - default: - return -EOPNOTSUPP; - } -} + if (mp->tx_sram_size > 0) + printk(KERN_NOTICE "%s: Using SRAM\n", dev->name); -static void mv643xx_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, uint64_t *data) -{ - struct mv643xx_private *mp = netdev->priv; - int i; + return 0; - eth_update_mib_counters(mp); +out: + free_netdev(dev); - for (i = 0; i < MV643XX_STATS_LEN; i++) { - char *p = (char *)mp+mv643xx_gstrings_stats[i].stat_offset; - data[i] = (mv643xx_gstrings_stats[i].sizeof_stat == - sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; - } + return err; } -static void mv643xx_get_strings(struct net_device *netdev, uint32_t stringset, - uint8_t *data) +static int mv643xx_eth_remove(struct platform_device *pdev) { - int i; + struct net_device *dev = platform_get_drvdata(pdev); - switch(stringset) { - case ETH_SS_STATS: - for (i=0; i < MV643XX_STATS_LEN; i++) { - memcpy(data + i * ETH_GSTRING_LEN, - mv643xx_gstrings_stats[i].stat_string, - ETH_GSTRING_LEN); - } - break; - } + unregister_netdev(dev); + flush_scheduled_work(); + + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + return 0; } -static u32 mv643xx_eth_get_link(struct net_device *dev) +static void mv643xx_eth_shutdown(struct platform_device *pdev) { + struct net_device *dev = platform_get_drvdata(pdev); struct mv643xx_private *mp = netdev_priv(dev); + unsigned int port_num = mp->port_num; - return mii_link_ok(&mp->mii); + /* Mask all interrupts on ethernet port */ + wrl(mp, INTERRUPT_MASK_REG(port_num), 0); + rdl(mp, INTERRUPT_MASK_REG(port_num)); + + eth_port_reset(mp); } -static int mv643xx_eth_nway_restart(struct net_device *dev) +static struct platform_driver mv643xx_eth_driver = { + .probe = mv643xx_eth_probe, + .remove = mv643xx_eth_remove, + .shutdown = mv643xx_eth_shutdown, + .driver = { + .name = MV643XX_ETH_NAME, + .owner = THIS_MODULE, + }, +}; + +/* + * mv643xx_init_module + * + * Registers the network drivers into the Linux kernel + * + * Input : N/A + * + * Output : N/A + */ +static int __init mv643xx_init_module(void) { - struct mv643xx_private *mp = netdev_priv(dev); + int rc; - return mii_nway_restart(&mp->mii); + rc = platform_driver_register(&mv643xx_eth_shared_driver); + if (!rc) { + rc = platform_driver_register(&mv643xx_eth_driver); + if (rc) + platform_driver_unregister(&mv643xx_eth_shared_driver); + } + return rc; } -static int mv643xx_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) +/* + * mv643xx_cleanup_module + * + * Registers the network drivers into the Linux kernel + * + * Input : N/A + * + * Output : N/A + */ +static void __exit mv643xx_cleanup_module(void) { - struct mv643xx_private *mp = netdev_priv(dev); - - return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); + platform_driver_unregister(&mv643xx_eth_driver); + platform_driver_unregister(&mv643xx_eth_shared_driver); } -static const struct ethtool_ops mv643xx_ethtool_ops = { - .get_settings = mv643xx_get_settings, - .set_settings = mv643xx_set_settings, - .get_drvinfo = mv643xx_get_drvinfo, - .get_link = mv643xx_eth_get_link, - .set_sg = ethtool_op_set_sg, - .get_sset_count = mv643xx_get_sset_count, - .get_ethtool_stats = mv643xx_get_ethtool_stats, - .get_strings = mv643xx_get_strings, - .nway_reset = mv643xx_eth_nway_restart, -}; +module_init(mv643xx_init_module); +module_exit(mv643xx_cleanup_module); -/************* End ethtool support *************************/ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR( "Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani" + " and Dale Farnsworth"); +MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX"); +MODULE_ALIAS("platform:" MV643XX_ETH_NAME); +MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME); diff --git a/trunk/drivers/net/pppoe.c b/trunk/drivers/net/pppoe.c index bafb69b6f7cb..58a26a47af29 100644 --- a/trunk/drivers/net/pppoe.c +++ b/trunk/drivers/net/pppoe.c @@ -341,6 +341,12 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) struct pppox_sock *relay_po; if (sk->sk_state & PPPOX_BOUND) { + struct pppoe_hdr *ph = pppoe_hdr(skb); + int len = ntohs(ph->length); + skb_pull_rcsum(skb, sizeof(struct pppoe_hdr)); + if (pskb_trim_rcsum(skb, len)) + goto abort_kfree; + ppp_input(&po->chan, skb); } else if (sk->sk_state & PPPOX_RELAY) { relay_po = get_item_by_addr(&po->pppoe_relay); @@ -351,6 +357,7 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) if ((sk_pppox(relay_po)->sk_state & PPPOX_CONNECTED) == 0) goto abort_put; + skb_pull(skb, sizeof(struct pppoe_hdr)); if (!__pppoe_xmit(sk_pppox(relay_po), skb)) goto abort_put; } else { @@ -381,7 +388,6 @@ static int pppoe_rcv(struct sk_buff *skb, { struct pppoe_hdr *ph; struct pppox_sock *po; - int len; if (!(skb = skb_share_check(skb, GFP_ATOMIC))) goto out; @@ -393,21 +399,10 @@ static int pppoe_rcv(struct sk_buff *skb, goto drop; ph = pppoe_hdr(skb); - len = ntohs(ph->length); - - skb_pull_rcsum(skb, sizeof(*ph)); - if (skb->len < len) - goto drop; po = get_item(ph->sid, eth_hdr(skb)->h_source, dev->ifindex); - if (!po) - goto drop; - - if (pskb_trim_rcsum(skb, len)) - goto drop; - - return sk_receive_skb(sk_pppox(po), skb, 0); - + if (po != NULL) + return sk_receive_skb(sk_pppox(po), skb, 0); drop: kfree_skb(skb); out: @@ -432,12 +427,12 @@ static int pppoe_disc_rcv(struct sk_buff *skb, if (dev_net(dev) != &init_net) goto abort; - if (!(skb = skb_share_check(skb, GFP_ATOMIC))) - goto out; - if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) goto abort; + if (!(skb = skb_share_check(skb, GFP_ATOMIC))) + goto out; + ph = pppoe_hdr(skb); if (ph->code != PADT_CODE) goto abort; @@ -942,10 +937,12 @@ static int pppoe_recvmsg(struct kiocb *iocb, struct socket *sock, m->msg_namelen = 0; if (skb) { - total_len = min(total_len, skb->len); - error = skb_copy_datagram_iovec(skb, 0, m->msg_iov, total_len); + struct pppoe_hdr *ph = pppoe_hdr(skb); + const int len = ntohs(ph->length); + + error = memcpy_toiovec(m->msg_iov, (unsigned char *) &ph->tag[0], len); if (error == 0) - error = total_len; + error = len; } kfree_skb(skb); diff --git a/trunk/drivers/net/pppol2tp.c b/trunk/drivers/net/pppol2tp.c index f9298827a76c..70cfdb46aa27 100644 --- a/trunk/drivers/net/pppol2tp.c +++ b/trunk/drivers/net/pppol2tp.c @@ -783,18 +783,14 @@ static int pppol2tp_recvmsg(struct kiocb *iocb, struct socket *sock, err = 0; skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err); - if (!skb) - goto end; - - if (len > skb->len) - len = skb->len; - else if (len < skb->len) - msg->msg_flags |= MSG_TRUNC; - - err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len); - if (likely(err == 0)) - err = len; - + if (skb) { + err = memcpy_toiovec(msg->msg_iov, (unsigned char *) skb->data, + skb->len); + if (err < 0) + goto do_skb_free; + err = skb->len; + } +do_skb_free: kfree_skb(skb); end: return err; diff --git a/trunk/drivers/net/r6040.c b/trunk/drivers/net/r6040.c index 858b191517b3..169edc154928 100644 --- a/trunk/drivers/net/r6040.c +++ b/trunk/drivers/net/r6040.c @@ -733,7 +733,7 @@ static void r6040_timer(unsigned long data) } /* Timer active again */ - mod_timer(&lp->timer, round_jiffies(jiffies + HZ)); + mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); } /* Read/set MAC address routines */ diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index 5694e894fc7a..dcc953e57ab1 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -2861,8 +2861,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) struct config_param *config; struct mac_info *mac_control; int pkts_processed = 0; - u8 __iomem *addr = NULL; - u8 val8 = 0; + u8 *addr = NULL, val8 = 0; struct s2io_nic *nic = dev->priv; struct XENA_dev_config __iomem *bar0 = nic->bar0; int budget_org = budget; @@ -2879,7 +2878,7 @@ static int s2io_poll_msix(struct napi_struct *napi, int budget) if (pkts_processed < budget_org) { netif_rx_complete(dev, napi); /*Re Enable MSI-Rx Vector*/ - addr = (u8 __iomem *)&bar0->xmsi_mask_reg; + addr = (u8 *)&bar0->xmsi_mask_reg; addr += 7 - ring->ring_no; val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; writeb(val8, addr); @@ -4365,10 +4364,9 @@ static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) return IRQ_HANDLED; if (sp->config.napi) { - u8 __iomem *addr = NULL; - u8 val8 = 0; + u8 *addr = NULL, val8 = 0; - addr = (u8 __iomem *)&bar0->xmsi_mask_reg; + addr = (u8 *)&bar0->xmsi_mask_reg; addr += (7 - ring->ring_no); val8 = (ring->ring_no == 0) ? 0x7f : 0xff; writeb(val8, addr); diff --git a/trunk/drivers/net/sfc/falcon.c b/trunk/drivers/net/sfc/falcon.c index 630406e142e5..8cb57987905e 100644 --- a/trunk/drivers/net/sfc/falcon.c +++ b/trunk/drivers/net/sfc/falcon.c @@ -755,10 +755,8 @@ void falcon_fini_rx(struct efx_rx_queue *rx_queue) continue; break; } - if (rc) { + if (rc) EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); - efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); - } /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); diff --git a/trunk/drivers/net/sh_eth.c b/trunk/drivers/net/sh_eth.c deleted file mode 100644 index f64d987140a9..000000000000 --- a/trunk/drivers/net/sh_eth.c +++ /dev/null @@ -1,1174 +0,0 @@ -/* - * SuperH Ethernet device driver - * - * Copyright (C) 2006,2007 Nobuhiro Iwamatsu - * Copyright (C) 2008 Renesas Solutions Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sh_eth.h" - -/* - * Program the hardware MAC address from dev->dev_addr. - */ -static void update_mac_address(struct net_device *ndev) -{ - u32 ioaddr = ndev->base_addr; - - ctrl_outl((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) | - (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), - ioaddr + MAHR); - ctrl_outl((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), - ioaddr + MALR); -} - -/* - * Get MAC address from SuperH MAC address register - * - * SuperH's Ethernet device doesn't have 'ROM' to MAC address. - * This driver get MAC address that use by bootloader(U-boot or sh-ipl+g). - * When you want use this device, you must set MAC address in bootloader. - * - */ -static void read_mac_address(struct net_device *ndev) -{ - u32 ioaddr = ndev->base_addr; - - ndev->dev_addr[0] = (ctrl_inl(ioaddr + MAHR) >> 24); - ndev->dev_addr[1] = (ctrl_inl(ioaddr + MAHR) >> 16) & 0xFF; - ndev->dev_addr[2] = (ctrl_inl(ioaddr + MAHR) >> 8) & 0xFF; - ndev->dev_addr[3] = (ctrl_inl(ioaddr + MAHR) & 0xFF); - ndev->dev_addr[4] = (ctrl_inl(ioaddr + MALR) >> 8) & 0xFF; - ndev->dev_addr[5] = (ctrl_inl(ioaddr + MALR) & 0xFF); -} - -struct bb_info { - struct mdiobb_ctrl ctrl; - u32 addr; - u32 mmd_msk;/* MMD */ - u32 mdo_msk; - u32 mdi_msk; - u32 mdc_msk; -}; - -/* PHY bit set */ -static void bb_set(u32 addr, u32 msk) -{ - ctrl_outl(ctrl_inl(addr) | msk, addr); -} - -/* PHY bit clear */ -static void bb_clr(u32 addr, u32 msk) -{ - ctrl_outl((ctrl_inl(addr) & ~msk), addr); -} - -/* PHY bit read */ -static int bb_read(u32 addr, u32 msk) -{ - return (ctrl_inl(addr) & msk) != 0; -} - -/* Data I/O pin control */ -static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit) -{ - struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); - if (bit) - bb_set(bitbang->addr, bitbang->mmd_msk); - else - bb_clr(bitbang->addr, bitbang->mmd_msk); -} - -/* Set bit data*/ -static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit) -{ - struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); - - if (bit) - bb_set(bitbang->addr, bitbang->mdo_msk); - else - bb_clr(bitbang->addr, bitbang->mdo_msk); -} - -/* Get bit data*/ -static int sh_get_mdio(struct mdiobb_ctrl *ctrl) -{ - struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); - return bb_read(bitbang->addr, bitbang->mdi_msk); -} - -/* MDC pin control */ -static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit) -{ - struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl); - - if (bit) - bb_set(bitbang->addr, bitbang->mdc_msk); - else - bb_clr(bitbang->addr, bitbang->mdc_msk); -} - -/* mdio bus control struct */ -static struct mdiobb_ops bb_ops = { - .owner = THIS_MODULE, - .set_mdc = sh_mdc_ctrl, - .set_mdio_dir = sh_mmd_ctrl, - .set_mdio_data = sh_set_mdio, - .get_mdio_data = sh_get_mdio, -}; - -static void sh_eth_reset(struct net_device *ndev) -{ - u32 ioaddr = ndev->base_addr; - - ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR); - mdelay(3); - ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR); -} - -/* free skb and descriptor buffer */ -static void sh_eth_ring_free(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - int i; - - /* Free Rx skb ringbuffer */ - if (mdp->rx_skbuff) { - for (i = 0; i < RX_RING_SIZE; i++) { - if (mdp->rx_skbuff[i]) - dev_kfree_skb(mdp->rx_skbuff[i]); - } - } - kfree(mdp->rx_skbuff); - - /* Free Tx skb ringbuffer */ - if (mdp->tx_skbuff) { - for (i = 0; i < TX_RING_SIZE; i++) { - if (mdp->tx_skbuff[i]) - dev_kfree_skb(mdp->tx_skbuff[i]); - } - } - kfree(mdp->tx_skbuff); -} - -/* format skb and descriptor buffer */ -static void sh_eth_ring_format(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - int i; - struct sk_buff *skb; - struct sh_eth_rxdesc *rxdesc = NULL; - struct sh_eth_txdesc *txdesc = NULL; - int rx_ringsize = sizeof(*rxdesc) * RX_RING_SIZE; - int tx_ringsize = sizeof(*txdesc) * TX_RING_SIZE; - - mdp->cur_rx = mdp->cur_tx = 0; - mdp->dirty_rx = mdp->dirty_tx = 0; - - memset(mdp->rx_ring, 0, rx_ringsize); - - /* build Rx ring buffer */ - for (i = 0; i < RX_RING_SIZE; i++) { - /* skb */ - mdp->rx_skbuff[i] = NULL; - skb = dev_alloc_skb(mdp->rx_buf_sz); - mdp->rx_skbuff[i] = skb; - if (skb == NULL) - break; - skb->dev = ndev; /* Mark as being used by this device. */ - skb_reserve(skb, RX_OFFSET); - - /* RX descriptor */ - rxdesc = &mdp->rx_ring[i]; - rxdesc->addr = (u32)skb->data & ~0x3UL; - rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP); - - /* The size of the buffer is 16 byte boundary. */ - rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; - } - - mdp->dirty_rx = (u32) (i - RX_RING_SIZE); - - /* Mark the last entry as wrapping the ring. */ - rxdesc->status |= cpu_to_le32(RC_RDEL); - - memset(mdp->tx_ring, 0, tx_ringsize); - - /* build Tx ring buffer */ - for (i = 0; i < TX_RING_SIZE; i++) { - mdp->tx_skbuff[i] = NULL; - txdesc = &mdp->tx_ring[i]; - txdesc->status = cpu_to_le32(TD_TFP); - txdesc->buffer_length = 0; - } - - txdesc->status |= cpu_to_le32(TD_TDLE); -} - -/* Get skb and descriptor buffer */ -static int sh_eth_ring_init(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - int rx_ringsize, tx_ringsize, ret = 0; - - /* - * +26 gets the maximum ethernet encapsulation, +7 & ~7 because the - * card needs room to do 8 byte alignment, +2 so we can reserve - * the first 2 bytes, and +16 gets room for the status word from the - * card. - */ - mdp->rx_buf_sz = (ndev->mtu <= 1492 ? PKT_BUF_SZ : - (((ndev->mtu + 26 + 7) & ~7) + 2 + 16)); - - /* Allocate RX and TX skb rings */ - mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE, - GFP_KERNEL); - if (!mdp->rx_skbuff) { - printk(KERN_ERR "%s: Cannot allocate Rx skb\n", ndev->name); - ret = -ENOMEM; - return ret; - } - - mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE, - GFP_KERNEL); - if (!mdp->tx_skbuff) { - printk(KERN_ERR "%s: Cannot allocate Tx skb\n", ndev->name); - ret = -ENOMEM; - goto skb_ring_free; - } - - /* Allocate all Rx descriptors. */ - rx_ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; - mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, - GFP_KERNEL); - - if (!mdp->rx_ring) { - printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n", - ndev->name, rx_ringsize); - ret = -ENOMEM; - goto desc_ring_free; - } - - mdp->dirty_rx = 0; - - /* Allocate all Tx descriptors. */ - tx_ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; - mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma, - GFP_KERNEL); - if (!mdp->tx_ring) { - printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", - ndev->name, tx_ringsize); - ret = -ENOMEM; - goto desc_ring_free; - } - return ret; - -desc_ring_free: - /* free DMA buffer */ - dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma); - -skb_ring_free: - /* Free Rx and Tx skb ring buffer */ - sh_eth_ring_free(ndev); - - return ret; -} - -static int sh_eth_dev_init(struct net_device *ndev) -{ - int ret = 0; - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; - u_int32_t rx_int_var, tx_int_var; - u32 val; - - /* Soft Reset */ - sh_eth_reset(ndev); - - ctrl_outl(RPADIR_PADS1, ioaddr + RPADIR); /* SH7712-DMA-RX-PAD2 */ - - /* all sh_eth int mask */ - ctrl_outl(0, ioaddr + EESIPR); - - /* FIFO size set */ - ctrl_outl(0, ioaddr + EDMR); /* Endian change */ - - ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR); - ctrl_outl(0, ioaddr + TFTR); - - ctrl_outl(RMCR_RST, ioaddr + RMCR); - - rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5; - tx_int_var = mdp->tx_int_var = DESC_I_TINT2; - ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER); - - ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR); - ctrl_outl(0, ioaddr + TRIMD); - - /* Descriptor format */ - sh_eth_ring_format(ndev); - - ctrl_outl((u32)mdp->rx_ring, ioaddr + RDLAR); - ctrl_outl((u32)mdp->tx_ring, ioaddr + TDLAR); - - ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR); - ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR); - - /* PAUSE Prohibition */ - val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) | - ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE; - - ctrl_outl(val, ioaddr + ECMR); - ctrl_outl(ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD | - ECSIPR_MPDIP, ioaddr + ECSR); - ctrl_outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | - ECSIPR_ICDIP | ECSIPR_MPDIP, ioaddr + ECSIPR); - - /* Set MAC address */ - update_mac_address(ndev); - - /* mask reset */ -#if defined(CONFIG_CPU_SUBTYPE_SH7710) - ctrl_outl(APR_AP, ioaddr + APR); - ctrl_outl(MPR_MP, ioaddr + MPR); - ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER); - ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR); -#endif - /* Setting the Rx mode will start the Rx process. */ - ctrl_outl(EDRRR_R, ioaddr + EDRRR); - - netif_start_queue(ndev); - - return ret; -} - -/* free Tx skb function */ -static int sh_eth_txfree(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - struct sh_eth_txdesc *txdesc; - int freeNum = 0; - int entry = 0; - - for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) { - entry = mdp->dirty_tx % TX_RING_SIZE; - txdesc = &mdp->tx_ring[entry]; - if (txdesc->status & cpu_to_le32(TD_TACT)) - break; - /* Free the original skb. */ - if (mdp->tx_skbuff[entry]) { - dev_kfree_skb_irq(mdp->tx_skbuff[entry]); - mdp->tx_skbuff[entry] = NULL; - freeNum++; - } - txdesc->status = cpu_to_le32(TD_TFP); - if (entry >= TX_RING_SIZE - 1) - txdesc->status |= cpu_to_le32(TD_TDLE); - - mdp->stats.tx_packets++; - mdp->stats.tx_bytes += txdesc->buffer_length; - } - return freeNum; -} - -/* Packet receive function */ -static int sh_eth_rx(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - struct sh_eth_rxdesc *rxdesc; - - int entry = mdp->cur_rx % RX_RING_SIZE; - int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx; - struct sk_buff *skb; - u16 pkt_len = 0; - u32 desc_status; - - rxdesc = &mdp->rx_ring[entry]; - while (!(rxdesc->status & cpu_to_le32(RD_RACT))) { - desc_status = le32_to_cpu(rxdesc->status); - pkt_len = rxdesc->frame_length; - - if (--boguscnt < 0) - break; - - if (!(desc_status & RDFEND)) - mdp->stats.rx_length_errors++; - - if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 | - RD_RFS5 | RD_RFS6 | RD_RFS10)) { - mdp->stats.rx_errors++; - if (desc_status & RD_RFS1) - mdp->stats.rx_crc_errors++; - if (desc_status & RD_RFS2) - mdp->stats.rx_frame_errors++; - if (desc_status & RD_RFS3) - mdp->stats.rx_length_errors++; - if (desc_status & RD_RFS4) - mdp->stats.rx_length_errors++; - if (desc_status & RD_RFS6) - mdp->stats.rx_missed_errors++; - if (desc_status & RD_RFS10) - mdp->stats.rx_over_errors++; - } else { - swaps((char *)(rxdesc->addr & ~0x3), pkt_len + 2); - skb = mdp->rx_skbuff[entry]; - mdp->rx_skbuff[entry] = NULL; - skb_put(skb, pkt_len); - skb->protocol = eth_type_trans(skb, ndev); - netif_rx(skb); - ndev->last_rx = jiffies; - mdp->stats.rx_packets++; - mdp->stats.rx_bytes += pkt_len; - } - rxdesc->status |= cpu_to_le32(RD_RACT); - entry = (++mdp->cur_rx) % RX_RING_SIZE; - } - - /* Refill the Rx ring buffers. */ - for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) { - entry = mdp->dirty_rx % RX_RING_SIZE; - rxdesc = &mdp->rx_ring[entry]; - if (mdp->rx_skbuff[entry] == NULL) { - skb = dev_alloc_skb(mdp->rx_buf_sz); - mdp->rx_skbuff[entry] = skb; - if (skb == NULL) - break; /* Better luck next round. */ - skb->dev = ndev; - skb_reserve(skb, RX_OFFSET); - rxdesc->addr = (u32)skb->data & ~0x3UL; - } - /* The size of the buffer is 16 byte boundary. */ - rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F; - if (entry >= RX_RING_SIZE - 1) - rxdesc->status |= - cpu_to_le32(RD_RACT | RD_RFP | RC_RDEL); - else - rxdesc->status |= - cpu_to_le32(RD_RACT | RD_RFP); - } - - /* Restart Rx engine if stopped. */ - /* If we don't need to check status, don't. -KDU */ - ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR); - - return 0; -} - -/* error control function */ -static void sh_eth_error(struct net_device *ndev, int intr_status) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; - u32 felic_stat; - - if (intr_status & EESR_ECI) { - felic_stat = ctrl_inl(ioaddr + ECSR); - ctrl_outl(felic_stat, ioaddr + ECSR); /* clear int */ - if (felic_stat & ECSR_ICD) - mdp->stats.tx_carrier_errors++; - if (felic_stat & ECSR_LCHNG) { - /* Link Changed */ - u32 link_stat = (ctrl_inl(ioaddr + PSR)); - if (!(link_stat & PHY_ST_LINK)) { - /* Link Down : disable tx and rx */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) & - ~(ECMR_RE | ECMR_TE), ioaddr + ECMR); - } else { - /* Link Up */ - ctrl_outl(ctrl_inl(ioaddr + EESIPR) & - ~DMAC_M_ECI, ioaddr + EESIPR); - /*clear int */ - ctrl_outl(ctrl_inl(ioaddr + ECSR), - ioaddr + ECSR); - ctrl_outl(ctrl_inl(ioaddr + EESIPR) | - DMAC_M_ECI, ioaddr + EESIPR); - /* enable tx and rx */ - ctrl_outl(ctrl_inl(ioaddr + ECMR) | - (ECMR_RE | ECMR_TE), ioaddr + ECMR); - } - } - } - - if (intr_status & EESR_TWB) { - /* Write buck end. unused write back interrupt */ - if (intr_status & EESR_TABT) /* Transmit Abort int */ - mdp->stats.tx_aborted_errors++; - } - - if (intr_status & EESR_RABT) { - /* Receive Abort int */ - if (intr_status & EESR_RFRMER) { - /* Receive Frame Overflow int */ - mdp->stats.rx_frame_errors++; - printk(KERN_ERR "Receive Frame Overflow\n"); - } - } - - if (intr_status & EESR_ADE) { - if (intr_status & EESR_TDE) { - if (intr_status & EESR_TFE) - mdp->stats.tx_fifo_errors++; - } - } - - if (intr_status & EESR_RDE) { - /* Receive Descriptor Empty int */ - mdp->stats.rx_over_errors++; - - if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R) - ctrl_outl(EDRRR_R, ioaddr + EDRRR); - printk(KERN_ERR "Receive Descriptor Empty\n"); - } - if (intr_status & EESR_RFE) { - /* Receive FIFO Overflow int */ - mdp->stats.rx_fifo_errors++; - printk(KERN_ERR "Receive FIFO Overflow\n"); - } - if (intr_status & - (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)) { - /* Tx error */ - u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR); - /* dmesg */ - printk(KERN_ERR "%s:TX error. status=%8.8x cur_tx=%8.8x ", - ndev->name, intr_status, mdp->cur_tx); - printk(KERN_ERR "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n", - mdp->dirty_tx, (u32) ndev->state, edtrr); - /* dirty buffer free */ - sh_eth_txfree(ndev); - - /* SH7712 BUG */ - if (edtrr ^ EDTRR_TRNS) { - /* tx dma start */ - ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); - } - /* wakeup */ - netif_wake_queue(ndev); - } -} - -static irqreturn_t sh_eth_interrupt(int irq, void *netdev) -{ - struct net_device *ndev = netdev; - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr, boguscnt = RX_RING_SIZE; - u32 intr_status = 0; - - ioaddr = ndev->base_addr; - spin_lock(&mdp->lock); - - intr_status = ctrl_inl(ioaddr + EESR); - /* Clear interrupt */ - ctrl_outl(intr_status, ioaddr + EESR); - - if (intr_status & (EESR_FRC | EESR_RINT8 | - EESR_RINT5 | EESR_RINT4 | EESR_RINT3 | EESR_RINT2 | - EESR_RINT1)) - sh_eth_rx(ndev); - if (intr_status & (EESR_FTC | - EESR_TINT4 | EESR_TINT3 | EESR_TINT2 | EESR_TINT1)) { - - sh_eth_txfree(ndev); - netif_wake_queue(ndev); - } - - if (intr_status & EESR_ERR_CHECK) - sh_eth_error(ndev, intr_status); - - if (--boguscnt < 0) { - printk(KERN_WARNING - "%s: Too much work at interrupt, status=0x%4.4x.\n", - ndev->name, intr_status); - } - - spin_unlock(&mdp->lock); - - return IRQ_HANDLED; -} - -static void sh_eth_timer(unsigned long data) -{ - struct net_device *ndev = (struct net_device *)data; - struct sh_eth_private *mdp = netdev_priv(ndev); - - mod_timer(&mdp->timer, jiffies + (10 * HZ)); -} - -/* PHY state control function */ -static void sh_eth_adjust_link(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - struct phy_device *phydev = mdp->phydev; - u32 ioaddr = ndev->base_addr; - int new_state = 0; - - if (phydev->link != PHY_DOWN) { - if (phydev->duplex != mdp->duplex) { - new_state = 1; - mdp->duplex = phydev->duplex; - } - - if (phydev->speed != mdp->speed) { - new_state = 1; - mdp->speed = phydev->speed; - } - if (mdp->link == PHY_DOWN) { - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF) - | ECMR_DM, ioaddr + ECMR); - new_state = 1; - mdp->link = phydev->link; - netif_schedule(ndev); - netif_carrier_on(ndev); - netif_start_queue(ndev); - } - } else if (mdp->link) { - new_state = 1; - mdp->link = PHY_DOWN; - mdp->speed = 0; - mdp->duplex = -1; - netif_stop_queue(ndev); - netif_carrier_off(ndev); - } - - if (new_state) - phy_print_status(phydev); -} - -/* PHY init function */ -static int sh_eth_phy_init(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - char phy_id[BUS_ID_SIZE]; - struct phy_device *phydev = NULL; - - snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, - mdp->mii_bus->id , mdp->phy_id); - - mdp->link = PHY_DOWN; - mdp->speed = 0; - mdp->duplex = -1; - - /* Try connect to PHY */ - phydev = phy_connect(ndev, phy_id, &sh_eth_adjust_link, - 0, PHY_INTERFACE_MODE_MII); - if (IS_ERR(phydev)) { - dev_err(&ndev->dev, "phy_connect failed\n"); - return PTR_ERR(phydev); - } - dev_info(&ndev->dev, "attached phy %i to driver %s\n", - phydev->addr, phydev->drv->name); - - mdp->phydev = phydev; - - return 0; -} - -/* PHY control start function */ -static int sh_eth_phy_start(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - int ret; - - ret = sh_eth_phy_init(ndev); - if (ret) - return ret; - - /* reset phy - this also wakes it from PDOWN */ - phy_write(mdp->phydev, MII_BMCR, BMCR_RESET); - phy_start(mdp->phydev); - - return 0; -} - -/* network device open function */ -static int sh_eth_open(struct net_device *ndev) -{ - int ret = 0; - struct sh_eth_private *mdp = netdev_priv(ndev); - - ret = request_irq(ndev->irq, &sh_eth_interrupt, 0, ndev->name, ndev); - if (ret) { - printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME); - return ret; - } - - /* Descriptor set */ - ret = sh_eth_ring_init(ndev); - if (ret) - goto out_free_irq; - - /* device init */ - ret = sh_eth_dev_init(ndev); - if (ret) - goto out_free_irq; - - /* PHY control start*/ - ret = sh_eth_phy_start(ndev); - if (ret) - goto out_free_irq; - - /* Set the timer to check for link beat. */ - init_timer(&mdp->timer); - mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ - setup_timer(&mdp->timer, sh_eth_timer, ndev); - - return ret; - -out_free_irq: - free_irq(ndev->irq, ndev); - return ret; -} - -/* Timeout function */ -static void sh_eth_tx_timeout(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; - struct sh_eth_rxdesc *rxdesc; - int i; - - netif_stop_queue(ndev); - - /* worning message out. */ - printk(KERN_WARNING "%s: transmit timed out, status %8.8x," - " resetting...\n", ndev->name, (int)ctrl_inl(ioaddr + EESR)); - - /* tx_errors count up */ - mdp->stats.tx_errors++; - - /* timer off */ - del_timer_sync(&mdp->timer); - - /* Free all the skbuffs in the Rx queue. */ - for (i = 0; i < RX_RING_SIZE; i++) { - rxdesc = &mdp->rx_ring[i]; - rxdesc->status = 0; - rxdesc->addr = 0xBADF00D0; - if (mdp->rx_skbuff[i]) - dev_kfree_skb(mdp->rx_skbuff[i]); - mdp->rx_skbuff[i] = NULL; - } - for (i = 0; i < TX_RING_SIZE; i++) { - if (mdp->tx_skbuff[i]) - dev_kfree_skb(mdp->tx_skbuff[i]); - mdp->tx_skbuff[i] = NULL; - } - - /* device init */ - sh_eth_dev_init(ndev); - - /* timer on */ - mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */ - add_timer(&mdp->timer); -} - -/* Packet transmit function */ -static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - struct sh_eth_txdesc *txdesc; - u32 entry; - int flags; - - spin_lock_irqsave(&mdp->lock, flags); - if ((mdp->cur_tx - mdp->dirty_tx) >= (TX_RING_SIZE - 4)) { - if (!sh_eth_txfree(ndev)) { - netif_stop_queue(ndev); - spin_unlock_irqrestore(&mdp->lock, flags); - return 1; - } - } - spin_unlock_irqrestore(&mdp->lock, flags); - - entry = mdp->cur_tx % TX_RING_SIZE; - mdp->tx_skbuff[entry] = skb; - txdesc = &mdp->tx_ring[entry]; - txdesc->addr = (u32)(skb->data); - /* soft swap. */ - swaps((char *)(txdesc->addr & ~0x3), skb->len + 2); - /* write back */ - __flush_purge_region(skb->data, skb->len); - if (skb->len < ETHERSMALL) - txdesc->buffer_length = ETHERSMALL; - else - txdesc->buffer_length = skb->len; - - if (entry >= TX_RING_SIZE - 1) - txdesc->status |= cpu_to_le32(TD_TACT | TD_TDLE); - else - txdesc->status |= cpu_to_le32(TD_TACT); - - mdp->cur_tx++; - - ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR); - ndev->trans_start = jiffies; - - return 0; -} - -/* device close function */ -static int sh_eth_close(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; - int ringsize; - - netif_stop_queue(ndev); - - /* Disable interrupts by clearing the interrupt mask. */ - ctrl_outl(0x0000, ioaddr + EESIPR); - - /* Stop the chip's Tx and Rx processes. */ - ctrl_outl(0, ioaddr + EDTRR); - ctrl_outl(0, ioaddr + EDRRR); - - /* PHY Disconnect */ - if (mdp->phydev) { - phy_stop(mdp->phydev); - phy_disconnect(mdp->phydev); - } - - free_irq(ndev->irq, ndev); - - del_timer_sync(&mdp->timer); - - /* Free all the skbuffs in the Rx queue. */ - sh_eth_ring_free(ndev); - - /* free DMA buffer */ - ringsize = sizeof(struct sh_eth_rxdesc) * RX_RING_SIZE; - dma_free_coherent(NULL, ringsize, mdp->rx_ring, mdp->rx_desc_dma); - - /* free DMA buffer */ - ringsize = sizeof(struct sh_eth_txdesc) * TX_RING_SIZE; - dma_free_coherent(NULL, ringsize, mdp->tx_ring, mdp->tx_desc_dma); - - return 0; -} - -static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - u32 ioaddr = ndev->base_addr; - - mdp->stats.tx_dropped += ctrl_inl(ioaddr + TROCR); - ctrl_outl(0, ioaddr + TROCR); /* (write clear) */ - mdp->stats.collisions += ctrl_inl(ioaddr + CDCR); - ctrl_outl(0, ioaddr + CDCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR); - ctrl_outl(0, ioaddr + LCCR); /* (write clear) */ - mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR); - ctrl_outl(0, ioaddr + CNDCR); /* (write clear) */ - - return &mdp->stats; -} - -/* ioctl to device funciotn*/ -static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq, - int cmd) -{ - struct sh_eth_private *mdp = netdev_priv(ndev); - struct phy_device *phydev = mdp->phydev; - - if (!netif_running(ndev)) - return -EINVAL; - - if (!phydev) - return -ENODEV; - - return phy_mii_ioctl(phydev, if_mii(rq), cmd); -} - - -/* Multicast reception directions set */ -static void sh_eth_set_multicast_list(struct net_device *ndev) -{ - u32 ioaddr = ndev->base_addr; - - if (ndev->flags & IFF_PROMISC) { - /* Set promiscuous. */ - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM, - ioaddr + ECMR); - } else { - /* Normal, unicast/broadcast-only mode. */ - ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT, - ioaddr + ECMR); - } -} - -/* SuperH's TSU register init function */ -static void sh_eth_tsu_init(u32 ioaddr) -{ - ctrl_outl(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */ - ctrl_outl(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */ - ctrl_outl(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */ - ctrl_outl(0xc, ioaddr + TSU_BSYSL0); - ctrl_outl(0xc, ioaddr + TSU_BSYSL1); - ctrl_outl(0, ioaddr + TSU_PRISL0); - ctrl_outl(0, ioaddr + TSU_PRISL1); - ctrl_outl(0, ioaddr + TSU_FWSL0); - ctrl_outl(0, ioaddr + TSU_FWSL1); - ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC); - ctrl_outl(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */ - ctrl_outl(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */ - ctrl_outl(0, ioaddr + TSU_FWSR); /* all interrupt status clear */ - ctrl_outl(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */ - ctrl_outl(0, ioaddr + TSU_TEN); /* Disable all CAM entry */ - ctrl_outl(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */ - ctrl_outl(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */ - ctrl_outl(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */ - ctrl_outl(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */ -} - -/* MDIO bus release function */ -static int sh_mdio_release(struct net_device *ndev) -{ - struct mii_bus *bus = dev_get_drvdata(&ndev->dev); - - /* unregister mdio bus */ - mdiobus_unregister(bus); - - /* remove mdio bus info from net_device */ - dev_set_drvdata(&ndev->dev, NULL); - - /* free bitbang info */ - free_mdio_bitbang(bus); - - return 0; -} - -/* MDIO bus init function */ -static int sh_mdio_init(struct net_device *ndev, int id) -{ - int ret, i; - struct bb_info *bitbang; - struct sh_eth_private *mdp = netdev_priv(ndev); - - /* create bit control struct for PHY */ - bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL); - if (!bitbang) { - ret = -ENOMEM; - goto out; - } - - /* bitbang init */ - bitbang->addr = ndev->base_addr + PIR; - bitbang->mdi_msk = 0x08; - bitbang->mdo_msk = 0x04; - bitbang->mmd_msk = 0x02;/* MMD */ - bitbang->mdc_msk = 0x01; - bitbang->ctrl.ops = &bb_ops; - - /* MII contorller setting */ - mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl); - if (!mdp->mii_bus) { - ret = -ENOMEM; - goto out_free_bitbang; - } - - /* Hook up MII support for ethtool */ - mdp->mii_bus->name = "sh_mii"; - mdp->mii_bus->dev = &ndev->dev; - mdp->mii_bus->id = id; - - /* PHY IRQ */ - mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); - if (!mdp->mii_bus->irq) { - ret = -ENOMEM; - goto out_free_bus; - } - - for (i = 0; i < PHY_MAX_ADDR; i++) - mdp->mii_bus->irq[i] = PHY_POLL; - - /* regist mdio bus */ - ret = mdiobus_register(mdp->mii_bus); - if (ret) - goto out_free_irq; - - dev_set_drvdata(&ndev->dev, mdp->mii_bus); - - return 0; - -out_free_irq: - kfree(mdp->mii_bus->irq); - -out_free_bus: - kfree(mdp->mii_bus); - -out_free_bitbang: - kfree(bitbang); - -out: - return ret; -} - -static int sh_eth_drv_probe(struct platform_device *pdev) -{ - int ret, i, devno = 0; - struct resource *res; - struct net_device *ndev = NULL; - struct sh_eth_private *mdp; - - /* get base addr */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(res == NULL)) { - dev_err(&pdev->dev, "invalid resource\n"); - ret = -EINVAL; - goto out; - } - - ndev = alloc_etherdev(sizeof(struct sh_eth_private)); - if (!ndev) { - printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME); - ret = -ENOMEM; - goto out; - } - - /* The sh Ether-specific entries in the device structure. */ - ndev->base_addr = res->start; - devno = pdev->id; - if (devno < 0) - devno = 0; - - ndev->dma = -1; - ndev->irq = platform_get_irq(pdev, 0); - if (ndev->irq < 0) { - ret = -ENODEV; - goto out_release; - } - - SET_NETDEV_DEV(ndev, &pdev->dev); - - /* Fill in the fields of the device structure with ethernet values. */ - ether_setup(ndev); - - mdp = netdev_priv(ndev); - spin_lock_init(&mdp->lock); - - /* get PHY ID */ - mdp->phy_id = (int)pdev->dev.platform_data; - - /* set function */ - ndev->open = sh_eth_open; - ndev->hard_start_xmit = sh_eth_start_xmit; - ndev->stop = sh_eth_close; - ndev->get_stats = sh_eth_get_stats; - ndev->set_multicast_list = sh_eth_set_multicast_list; - ndev->do_ioctl = sh_eth_do_ioctl; - ndev->tx_timeout = sh_eth_tx_timeout; - ndev->watchdog_timeo = TX_TIMEOUT; - - mdp->post_rx = POST_RX >> (devno << 1); - mdp->post_fw = POST_FW >> (devno << 1); - - /* read and set MAC address */ - read_mac_address(ndev); - - /* First device only init */ - if (!devno) { - /* reset device */ - ctrl_outl(ARSTR_ARSTR, ndev->base_addr + ARSTR); - mdelay(1); - - /* TSU init (Init only)*/ - sh_eth_tsu_init(SH_TSU_ADDR); - } - - /* network device register */ - ret = register_netdev(ndev); - if (ret) - goto out_release; - - /* mdio bus init */ - ret = sh_mdio_init(ndev, pdev->id); - if (ret) - goto out_unregister; - - /* pritnt device infomation */ - printk(KERN_INFO "%s: %s at 0x%x, ", - ndev->name, CARDNAME, (u32) ndev->base_addr); - - for (i = 0; i < 5; i++) - printk(KERN_INFO "%2.2x:", ndev->dev_addr[i]); - printk(KERN_INFO "%2.2x, IRQ %d.\n", ndev->dev_addr[i], ndev->irq); - - platform_set_drvdata(pdev, ndev); - - return ret; - -out_unregister: - unregister_netdev(ndev); - -out_release: - /* net_dev free */ - if (ndev) - free_netdev(ndev); - -out: - return ret; -} - -static int sh_eth_drv_remove(struct platform_device *pdev) -{ - struct net_device *ndev = platform_get_drvdata(pdev); - - sh_mdio_release(ndev); - unregister_netdev(ndev); - flush_scheduled_work(); - - free_netdev(ndev); - platform_set_drvdata(pdev, NULL); - - return 0; -} - -static struct platform_driver sh_eth_driver = { - .probe = sh_eth_drv_probe, - .remove = sh_eth_drv_remove, - .driver = { - .name = CARDNAME, - }, -}; - -static int __init sh_eth_init(void) -{ - return platform_driver_register(&sh_eth_driver); -} - -static void __exit sh_eth_cleanup(void) -{ - platform_driver_unregister(&sh_eth_driver); -} - -module_init(sh_eth_init); -module_exit(sh_eth_cleanup); - -MODULE_AUTHOR("Nobuhiro Iwamatsu, Yoshihiro Shimoda"); -MODULE_DESCRIPTION("Renesas SuperH Ethernet driver"); -MODULE_LICENSE("GPL v2"); diff --git a/trunk/drivers/net/sh_eth.h b/trunk/drivers/net/sh_eth.h deleted file mode 100644 index ca2db6bb3c61..000000000000 --- a/trunk/drivers/net/sh_eth.h +++ /dev/null @@ -1,464 +0,0 @@ -/* - * SuperH Ethernet device driver - * - * Copyright (C) 2006-2008 Nobuhiro Iwamatsu - * Copyright (C) 2008 Renesas Solutions Corp. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - * - * The full GNU General Public License is included in this distribution in - * the file called "COPYING". - */ - -#ifndef __SH_ETH_H__ -#define __SH_ETH_H__ - -#include -#include -#include -#include -#include -#include - -#define CARDNAME "sh-eth" -#define TX_TIMEOUT (5*HZ) - -#define TX_RING_SIZE 128 /* Tx ring size */ -#define RX_RING_SIZE 128 /* Rx ring size */ -#define RX_OFFSET 2 /* skb offset */ -#define ETHERSMALL 60 -#define PKT_BUF_SZ 1538 - -/* Chip Base Address */ -#define SH_ETH0_BASE 0xA7000000 -#define SH_ETH1_BASE 0xA7000400 -#define SH_TSU_ADDR 0xA7000804 - -/* Chip Registers */ -/* E-DMAC */ -#define EDMR 0x0000 -#define EDTRR 0x0004 -#define EDRRR 0x0008 -#define TDLAR 0x000C -#define RDLAR 0x0010 -#define EESR 0x0014 -#define EESIPR 0x0018 -#define TRSCER 0x001C -#define RMFCR 0x0020 -#define TFTR 0x0024 -#define FDR 0x0028 -#define RMCR 0x002C -#define EDOCR 0x0030 -#define FCFTR 0x0034 -#define RPADIR 0x0038 -#define TRIMD 0x003C -#define RBWAR 0x0040 -#define RDFAR 0x0044 -#define TBRAR 0x004C -#define TDFAR 0x0050 -/* Ether Register */ -#define ECMR 0x0160 -#define ECSR 0x0164 -#define ECSIPR 0x0168 -#define PIR 0x016C -#define MAHR 0x0170 -#define MALR 0x0174 -#define RFLR 0x0178 -#define PSR 0x017C -#define TROCR 0x0180 -#define CDCR 0x0184 -#define LCCR 0x0188 -#define CNDCR 0x018C -#define CEFCR 0x0194 -#define FRECR 0x0198 -#define TSFRCR 0x019C -#define TLFRCR 0x01A0 -#define RFCR 0x01A4 -#define MAFCR 0x01A8 -#define IPGR 0x01B4 -#if defined(CONFIG_CPU_SUBTYPE_SH7710) -#define APR 0x01B8 -#define MPR 0x01BC -#define TPAUSER 0x1C4 -#define BCFR 0x1CC -#endif /* CONFIG_CPU_SH7710 */ - -#define ARSTR 0x0800 - -/* TSU */ -#define TSU_CTRST 0x004 -#define TSU_FWEN0 0x010 -#define TSU_FWEN1 0x014 -#define TSU_FCM 0x018 -#define TSU_BSYSL0 0x020 -#define TSU_BSYSL1 0x024 -#define TSU_PRISL0 0x028 -#define TSU_PRISL1 0x02C -#define TSU_FWSL0 0x030 -#define TSU_FWSL1 0x034 -#define TSU_FWSLC 0x038 -#define TSU_QTAGM0 0x040 -#define TSU_QTAGM1 0x044 -#define TSU_ADQT0 0x048 -#define TSU_ADQT1 0x04C -#define TSU_FWSR 0x050 -#define TSU_FWINMK 0x054 -#define TSU_ADSBSY 0x060 -#define TSU_TEN 0x064 -#define TSU_POST1 0x070 -#define TSU_POST2 0x074 -#define TSU_POST3 0x078 -#define TSU_POST4 0x07C -#define TXNLCR0 0x080 -#define TXALCR0 0x084 -#define RXNLCR0 0x088 -#define RXALCR0 0x08C -#define FWNLCR0 0x090 -#define FWALCR0 0x094 -#define TXNLCR1 0x0A0 -#define TXALCR1 0x0A4 -#define RXNLCR1 0x0A8 -#define RXALCR1 0x0AC -#define FWNLCR1 0x0B0 -#define FWALCR1 0x0B4 - -#define TSU_ADRH0 0x0100 -#define TSU_ADRL0 0x0104 -#define TSU_ADRL31 0x01FC - -/* Register's bits */ - -/* EDMR */ -enum DMAC_M_BIT { - EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, EDMR_SRST = 0x01, -}; - -/* EDTRR */ -enum DMAC_T_BIT { - EDTRR_TRNS = 0x01, -}; - -/* EDRRR*/ -enum EDRRR_R_BIT { - EDRRR_R = 0x01, -}; - -/* TPAUSER */ -enum TPAUSER_BIT { - TPAUSER_TPAUSE = 0x0000ffff, - TPAUSER_UNLIMITED = 0, -}; - -/* BCFR */ -enum BCFR_BIT { - BCFR_RPAUSE = 0x0000ffff, - BCFR_UNLIMITED = 0, -}; - -/* PIR */ -enum PIR_BIT { - PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01, -}; - -/* PSR */ -enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, }; - -/* EESR */ -enum EESR_BIT { - EESR_TWB = 0x40000000, EESR_TABT = 0x04000000, - EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000, - EESR_ADE = 0x00800000, EESR_ECI = 0x00400000, - EESR_FTC = 0x00200000, EESR_TDE = 0x00100000, - EESR_TFE = 0x00080000, EESR_FRC = 0x00040000, - EESR_RDE = 0x00020000, EESR_RFE = 0x00010000, - EESR_TINT4 = 0x00000800, EESR_TINT3 = 0x00000400, - EESR_TINT2 = 0x00000200, EESR_TINT1 = 0x00000100, - EESR_RINT8 = 0x00000080, EESR_RINT5 = 0x00000010, - EESR_RINT4 = 0x00000008, EESR_RINT3 = 0x00000004, - EESR_RINT2 = 0x00000002, EESR_RINT1 = 0x00000001, -}; - -#define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ - | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI) - -/* EESIPR */ -enum DMAC_IM_BIT { - DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000, - DMAC_M_RABT = 0x02000000, - DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000, - DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000, - DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000, - DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000, - DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800, - DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200, - DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080, - DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008, - DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002, - DMAC_M_RINT1 = 0x00000001, -}; - -/* Receive descriptor bit */ -enum RD_STS_BIT { - RD_RACT = 0x80000000, RC_RDEL = 0x40000000, - RC_RFP1 = 0x20000000, RC_RFP0 = 0x10000000, - RD_RFE = 0x08000000, RD_RFS10 = 0x00000200, - RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080, - RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020, - RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008, - RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002, - RD_RFS1 = 0x00000001, -}; -#define RDF1ST RC_RFP1 -#define RDFEND RC_RFP0 -#define RD_RFP (RC_RFP1|RC_RFP0) - -/* FCFTR */ -enum FCFTR_BIT { - FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000, - FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004, - FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001, -}; -#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0) -#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0) - -/* Transfer descriptor bit */ -enum TD_STS_BIT { - TD_TACT = 0x80000000, TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000, - TD_TFP0 = 0x10000000, -}; -#define TDF1ST TD_TFP1 -#define TDFEND TD_TFP0 -#define TD_TFP (TD_TFP1|TD_TFP0) - -/* RMCR */ -enum RECV_RST_BIT { RMCR_RST = 0x01, }; -/* ECMR */ -enum FELIC_MODE_BIT { - ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000, - ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000, - ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020, - ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002, - ECMR_PRM = 0x00000001, -}; - -/* ECSR */ -enum ECSR_STATUS_BIT { - ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, ECSR_LCHNG = 0x04, - ECSR_MPD = 0x02, ECSR_ICD = 0x01, -}; - -/* ECSIPR */ -enum ECSIPR_STATUS_MASK_BIT { - ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, ECSIPR_LCHNGIP = 0x04, - ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01, -}; - -/* APR */ -enum APR_BIT { - APR_AP = 0x00000001, -}; - -/* MPR */ -enum MPR_BIT { - MPR_MP = 0x00000001, -}; - -/* TRSCER */ -enum DESC_I_BIT { - DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200, - DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010, - DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002, - DESC_I_RINT1 = 0x0001, -}; - -/* RPADIR */ -enum RPADIR_BIT { - RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, - RPADIR_PADR = 0x0003f, -}; - -/* FDR */ -enum FIFO_SIZE_BIT { - FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007, -}; -enum phy_offsets { - PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3, - PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6, - PHY_16 = 16, -}; - -/* PHY_CTRL */ -enum PHY_CTRL_BIT { - PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000, - PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400, - PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080, -}; -#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */ - -/* PHY_STAT */ -enum PHY_STAT_BIT { - PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000, - PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020, - PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004, - PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001, -}; - -/* PHY_ANA */ -enum PHY_ANA_BIT { - PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000, - PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100, - PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020, - PHY_A_SEL = 0x001f, -}; -/* PHY_ANL */ -enum PHY_ANL_BIT { - PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000, - PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100, - PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020, - PHY_L_SEL = 0x001f, -}; - -/* PHY_ANE */ -enum PHY_ANE_BIT { - PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004, - PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001, -}; - -/* DM9161 */ -enum PHY_16_BIT { - PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000, - PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800, - PHY_16_TXselect = 0x0400, - PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100, - PHY_16_Force100LNK = 0x0080, - PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020, - PHY_16_RPDCTR_EN = 0x0010, - PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004, - PHY_16_Sleepmode = 0x0002, - PHY_16_RemoteLoopOut = 0x0001, -}; - -#define POST_RX 0x08 -#define POST_FW 0x04 -#define POST0_RX (POST_RX) -#define POST0_FW (POST_FW) -#define POST1_RX (POST_RX >> 2) -#define POST1_FW (POST_FW >> 2) -#define POST_ALL (POST0_RX | POST0_FW | POST1_RX | POST1_FW) - -/* ARSTR */ -enum ARSTR_BIT { ARSTR_ARSTR = 0x00000001, }; - -/* TSU_FWEN0 */ -enum TSU_FWEN0_BIT { - TSU_FWEN0_0 = 0x00000001, -}; - -/* TSU_ADSBSY */ -enum TSU_ADSBSY_BIT { - TSU_ADSBSY_0 = 0x00000001, -}; - -/* TSU_TEN */ -enum TSU_TEN_BIT { - TSU_TEN_0 = 0x80000000, -}; - -/* TSU_FWSL0 */ -enum TSU_FWSL0_BIT { - TSU_FWSL0_FW50 = 0x1000, TSU_FWSL0_FW40 = 0x0800, - TSU_FWSL0_FW30 = 0x0400, TSU_FWSL0_FW20 = 0x0200, - TSU_FWSL0_FW10 = 0x0100, TSU_FWSL0_RMSA0 = 0x0010, -}; - -/* TSU_FWSLC */ -enum TSU_FWSLC_BIT { - TSU_FWSLC_POSTENU = 0x2000, TSU_FWSLC_POSTENL = 0x1000, - TSU_FWSLC_CAMSEL03 = 0x0080, TSU_FWSLC_CAMSEL02 = 0x0040, - TSU_FWSLC_CAMSEL01 = 0x0020, TSU_FWSLC_CAMSEL00 = 0x0010, - TSU_FWSLC_CAMSEL13 = 0x0008, TSU_FWSLC_CAMSEL12 = 0x0004, - TSU_FWSLC_CAMSEL11 = 0x0002, TSU_FWSLC_CAMSEL10 = 0x0001, -}; - -/* - * The sh ether Tx buffer descriptors. - * This structure should be 20 bytes. - */ -struct sh_eth_txdesc { - u32 status; /* TD0 */ -#if defined(CONFIG_CPU_LITTLE_ENDIAN) - u16 pad0; /* TD1 */ - u16 buffer_length; /* TD1 */ -#else - u16 buffer_length; /* TD1 */ - u16 pad0; /* TD1 */ -#endif - u32 addr; /* TD2 */ - u32 pad1; /* padding data */ -}; - -/* - * The sh ether Rx buffer descriptors. - * This structure should be 20 bytes. - */ -struct sh_eth_rxdesc { - u32 status; /* RD0 */ -#if defined(CONFIG_CPU_LITTLE_ENDIAN) - u16 frame_length; /* RD1 */ - u16 buffer_length; /* RD1 */ -#else - u16 buffer_length; /* RD1 */ - u16 frame_length; /* RD1 */ -#endif - u32 addr; /* RD2 */ - u32 pad0; /* padding data */ -}; - -struct sh_eth_private { - dma_addr_t rx_desc_dma; - dma_addr_t tx_desc_dma; - struct sh_eth_rxdesc *rx_ring; - struct sh_eth_txdesc *tx_ring; - struct sk_buff **rx_skbuff; - struct sk_buff **tx_skbuff; - struct net_device_stats stats; - struct timer_list timer; - spinlock_t lock; - u32 cur_rx, dirty_rx; /* Producer/consumer ring indices */ - u32 cur_tx, dirty_tx; - u32 rx_buf_sz; /* Based on MTU+slack. */ - /* MII transceiver section. */ - u32 phy_id; /* PHY ID */ - struct mii_bus *mii_bus; /* MDIO bus control */ - struct phy_device *phydev; /* PHY device control */ - enum phy_state link; - int msg_enable; - int speed; - int duplex; - u32 rx_int_var, tx_int_var; /* interrupt control variables */ - char post_rx; /* POST receive */ - char post_fw; /* POST forward */ - struct net_device_stats tsu_stats; /* TSU forward status */ -}; - -static void swaps(char *src, int len) -{ -#ifdef __LITTLE_ENDIAN__ - u32 *p = (u32 *)src; - u32 *maxp; - maxp = p + ((len + sizeof(u32) - 1) / sizeof(u32)); - - for (; p < maxp; p++) - *p = swab32(*p); -#endif -} diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index 7f1cfc48e1b2..c83406f4f2a7 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -4536,9 +4536,7 @@ static int sky2_resume(struct pci_dev *pdev) if (err) { printk(KERN_ERR PFX "%s: could not up: %d\n", dev->name, err); - rtnl_lock(); dev_close(dev); - rtnl_unlock(); goto out; } } diff --git a/trunk/drivers/net/smc911x.c b/trunk/drivers/net/smc911x.c index c5871624f972..4e2800205189 100644 --- a/trunk/drivers/net/smc911x.c +++ b/trunk/drivers/net/smc911x.c @@ -106,6 +106,56 @@ MODULE_ALIAS("platform:smc911x"); */ #define POWER_DOWN 1 + +/* store this information for the driver.. */ +struct smc911x_local { + /* + * If I have to wait until the DMA is finished and ready to reload a + * packet, I will store the skbuff here. Then, the DMA will send it + * out and free it. + */ + struct sk_buff *pending_tx_skb; + + /* version/revision of the SMC911x chip */ + u16 version; + u16 revision; + + /* FIFO sizes */ + int tx_fifo_kb; + int tx_fifo_size; + int rx_fifo_size; + int afc_cfg; + + /* Contains the current active receive/phy mode */ + int ctl_rfduplx; + int ctl_rspeed; + + u32 msg_enable; + u32 phy_type; + struct mii_if_info mii; + + /* work queue */ + struct work_struct phy_configure; + int work_pending; + + int tx_throttle; + spinlock_t lock; + + struct net_device *netdev; + +#ifdef SMC_USE_DMA + /* DMA needs the physical address of the chip */ + u_long physaddr; + int rxdma; + int txdma; + int rxdma_active; + int txdma_active; + struct sk_buff *current_rx_skb; + struct sk_buff *current_tx_skb; + struct device *dev; +#endif +}; + #if SMC_DEBUG > 0 #define DBG(n, args...) \ do { \ @@ -153,24 +203,24 @@ static void PRINT_PKT(u_char *buf, int length) /* this enables an interrupt in the interrupt mask register */ -#define SMC_ENABLE_INT(lp, x) do { \ +#define SMC_ENABLE_INT(x) do { \ unsigned int __mask; \ unsigned long __flags; \ spin_lock_irqsave(&lp->lock, __flags); \ - __mask = SMC_GET_INT_EN((lp)); \ + __mask = SMC_GET_INT_EN(); \ __mask |= (x); \ - SMC_SET_INT_EN((lp), __mask); \ + SMC_SET_INT_EN(__mask); \ spin_unlock_irqrestore(&lp->lock, __flags); \ } while (0) /* this disables an interrupt from the interrupt mask register */ -#define SMC_DISABLE_INT(lp, x) do { \ +#define SMC_DISABLE_INT(x) do { \ unsigned int __mask; \ unsigned long __flags; \ spin_lock_irqsave(&lp->lock, __flags); \ - __mask = SMC_GET_INT_EN((lp)); \ + __mask = SMC_GET_INT_EN(); \ __mask &= ~(x); \ - SMC_SET_INT_EN((lp), __mask); \ + SMC_SET_INT_EN(__mask); \ spin_unlock_irqrestore(&lp->lock, __flags); \ } while (0) @@ -179,6 +229,7 @@ static void PRINT_PKT(u_char *buf, int length) */ static void smc911x_reset(struct net_device *dev) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned int reg, timeout=0, resets=1; unsigned long flags; @@ -186,13 +237,13 @@ static void smc911x_reset(struct net_device *dev) DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); /* Take out of PM setting first */ - if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) { + if ((SMC_GET_PMT_CTRL() & PMT_CTRL_READY_) == 0) { /* Write to the bytetest will take out of powerdown */ - SMC_SET_BYTE_TEST(lp, 0); + SMC_SET_BYTE_TEST(0); timeout=10; do { udelay(10); - reg = SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_; + reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_; } while (--timeout && !reg); if (timeout == 0) { PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name); @@ -202,15 +253,15 @@ static void smc911x_reset(struct net_device *dev) /* Disable all interrupts */ spin_lock_irqsave(&lp->lock, flags); - SMC_SET_INT_EN(lp, 0); + SMC_SET_INT_EN(0); spin_unlock_irqrestore(&lp->lock, flags); while (resets--) { - SMC_SET_HW_CFG(lp, HW_CFG_SRST_); + SMC_SET_HW_CFG(HW_CFG_SRST_); timeout=10; do { udelay(10); - reg = SMC_GET_HW_CFG(lp); + reg = SMC_GET_HW_CFG(); /* If chip indicates reset timeout then try again */ if (reg & HW_CFG_SRST_TO_) { PRINTK("%s: chip reset timeout, retrying...\n", dev->name); @@ -226,7 +277,7 @@ static void smc911x_reset(struct net_device *dev) /* make sure EEPROM has finished loading before setting GPIO_CFG */ timeout=1000; - while ( timeout-- && (SMC_GET_E2P_CMD(lp) & E2P_CMD_EPC_BUSY_)) { + while ( timeout-- && (SMC_GET_E2P_CMD() & E2P_CMD_EPC_BUSY_)) { udelay(10); } if (timeout == 0){ @@ -235,24 +286,24 @@ static void smc911x_reset(struct net_device *dev) } /* Initialize interrupts */ - SMC_SET_INT_EN(lp, 0); - SMC_ACK_INT(lp, -1); + SMC_SET_INT_EN(0); + SMC_ACK_INT(-1); /* Reset the FIFO level and flow control settings */ - SMC_SET_HW_CFG(lp, (lp->tx_fifo_kb & 0xF) << 16); + SMC_SET_HW_CFG((lp->tx_fifo_kb & 0xF) << 16); //TODO: Figure out what appropriate pause time is - SMC_SET_FLOW(lp, FLOW_FCPT_ | FLOW_FCEN_); - SMC_SET_AFC_CFG(lp, lp->afc_cfg); + SMC_SET_FLOW(FLOW_FCPT_ | FLOW_FCEN_); + SMC_SET_AFC_CFG(lp->afc_cfg); /* Set to LED outputs */ - SMC_SET_GPIO_CFG(lp, 0x70070000); + SMC_SET_GPIO_CFG(0x70070000); /* * Deassert IRQ for 1*10us for edge type interrupts * and drive IRQ pin push-pull */ - SMC_SET_IRQ_CFG(lp, (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_); + SMC_SET_IRQ_CFG( (1 << 24) | INT_CFG_IRQ_EN_ | INT_CFG_IRQ_TYPE_ ); /* clear anything saved */ if (lp->pending_tx_skb != NULL) { @@ -268,45 +319,46 @@ static void smc911x_reset(struct net_device *dev) */ static void smc911x_enable(struct net_device *dev) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned mask, cfg, cr; unsigned long flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); - SMC_SET_MAC_ADDR(lp, dev->dev_addr); + SMC_SET_MAC_ADDR(dev->dev_addr); /* Enable TX */ - cfg = SMC_GET_HW_CFG(lp); + cfg = SMC_GET_HW_CFG(); cfg &= HW_CFG_TX_FIF_SZ_ | 0xFFF; cfg |= HW_CFG_SF_; - SMC_SET_HW_CFG(lp, cfg); - SMC_SET_FIFO_TDA(lp, 0xFF); + SMC_SET_HW_CFG(cfg); + SMC_SET_FIFO_TDA(0xFF); /* Update TX stats on every 64 packets received or every 1 sec */ - SMC_SET_FIFO_TSL(lp, 64); - SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000); + SMC_SET_FIFO_TSL(64); + SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(lp, cr); + SMC_GET_MAC_CR(cr); cr |= MAC_CR_TXEN_ | MAC_CR_HBDIS_; - SMC_SET_MAC_CR(lp, cr); - SMC_SET_TX_CFG(lp, TX_CFG_TX_ON_); + SMC_SET_MAC_CR(cr); + SMC_SET_TX_CFG(TX_CFG_TX_ON_); spin_unlock_irqrestore(&lp->lock, flags); /* Add 2 byte padding to start of packets */ - SMC_SET_RX_CFG(lp, (2<<8) & RX_CFG_RXDOFF_); + SMC_SET_RX_CFG((2<<8) & RX_CFG_RXDOFF_); /* Turn on receiver and enable RX */ if (cr & MAC_CR_RXEN_) DBG(SMC_DEBUG_RX, "%s: Receiver already enabled\n", dev->name); spin_lock_irqsave(&lp->lock, flags); - SMC_SET_MAC_CR(lp, cr | MAC_CR_RXEN_); + SMC_SET_MAC_CR( cr | MAC_CR_RXEN_ ); spin_unlock_irqrestore(&lp->lock, flags); /* Interrupt on every received packet */ - SMC_SET_FIFO_RSA(lp, 0x01); - SMC_SET_FIFO_RSL(lp, 0x00); + SMC_SET_FIFO_RSA(0x01); + SMC_SET_FIFO_RSL(0x00); /* now, enable interrupts */ mask = INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_ | INT_EN_RSFL_EN_ | @@ -317,7 +369,7 @@ static void smc911x_enable(struct net_device *dev) else { mask|=INT_EN_RDFO_EN_; } - SMC_ENABLE_INT(lp, mask); + SMC_ENABLE_INT(mask); } /* @@ -325,6 +377,7 @@ static void smc911x_enable(struct net_device *dev) */ static void smc911x_shutdown(struct net_device *dev) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned cr; unsigned long flags; @@ -332,35 +385,35 @@ static void smc911x_shutdown(struct net_device *dev) DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__); /* Disable IRQ's */ - SMC_SET_INT_EN(lp, 0); + SMC_SET_INT_EN(0); /* Turn of Rx and TX */ spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(lp, cr); + SMC_GET_MAC_CR(cr); cr &= ~(MAC_CR_TXEN_ | MAC_CR_RXEN_ | MAC_CR_HBDIS_); - SMC_SET_MAC_CR(lp, cr); - SMC_SET_TX_CFG(lp, TX_CFG_STOP_TX_); + SMC_SET_MAC_CR(cr); + SMC_SET_TX_CFG(TX_CFG_STOP_TX_); spin_unlock_irqrestore(&lp->lock, flags); } static inline void smc911x_drop_pkt(struct net_device *dev) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int fifo_count, timeout, reg; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__); - fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF; + fifo_count = SMC_GET_RX_FIFO_INF() & 0xFFFF; if (fifo_count <= 4) { /* Manually dump the packet data */ while (fifo_count--) - SMC_GET_RX_FIFO(lp); + SMC_GET_RX_FIFO(); } else { /* Fast forward through the bad packet */ - SMC_SET_RX_DP_CTRL(lp, RX_DP_CTRL_FFWD_BUSY_); + SMC_SET_RX_DP_CTRL(RX_DP_CTRL_FFWD_BUSY_); timeout=50; do { udelay(10); - reg = SMC_GET_RX_DP_CTRL(lp) & RX_DP_CTRL_FFWD_BUSY_; + reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_; } while (--timeout && reg); if (timeout == 0) { PRINTK("%s: timeout waiting for RX fast forward\n", dev->name); @@ -376,14 +429,14 @@ static inline void smc911x_drop_pkt(struct net_device *dev) */ static inline void smc911x_rcv(struct net_device *dev) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int pkt_len, status; struct sk_buff *skb; unsigned char *data; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", dev->name, __FUNCTION__); - status = SMC_GET_RX_STS_FIFO(lp); + status = SMC_GET_RX_STS_FIFO(); DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n", dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff); pkt_len = (status & RX_STS_PKT_LEN_) >> 16; @@ -420,23 +473,24 @@ static inline void smc911x_rcv(struct net_device *dev) skb_put(skb,pkt_len-4); #ifdef SMC_USE_DMA { + struct smc911x_local *lp = netdev_priv(dev); unsigned int fifo; /* Lower the FIFO threshold if possible */ - fifo = SMC_GET_FIFO_INT(lp); + fifo = SMC_GET_FIFO_INT(); if (fifo & 0xFF) fifo--; DBG(SMC_DEBUG_RX, "%s: Setting RX stat FIFO threshold to %d\n", dev->name, fifo & 0xff); - SMC_SET_FIFO_INT(lp, fifo); + SMC_SET_FIFO_INT(fifo); /* Setup RX DMA */ - SMC_SET_RX_CFG(lp, RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_)); + SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN16_ | ((2<<8) & RX_CFG_RXDOFF_)); lp->rxdma_active = 1; lp->current_rx_skb = skb; - SMC_PULL_DATA(lp, data, (pkt_len+2+15) & ~15); + SMC_PULL_DATA(data, (pkt_len+2+15) & ~15); /* Packet processing deferred to DMA RX interrupt */ } #else - SMC_SET_RX_CFG(lp, RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); - SMC_PULL_DATA(lp, data, pkt_len+2+3); + SMC_SET_RX_CFG(RX_CFG_RX_END_ALGN4_ | ((2<<8) & RX_CFG_RXDOFF_)); + SMC_PULL_DATA(data, pkt_len+2+3); DBG(SMC_DEBUG_PKTS, "%s: Received packet\n", dev->name); PRINT_PKT(data, ((pkt_len - 4) <= 64) ? pkt_len - 4 : 64); @@ -455,6 +509,7 @@ static inline void smc911x_rcv(struct net_device *dev) static void smc911x_hardware_send_pkt(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; struct sk_buff *skb; unsigned int cmdA, cmdB, len; unsigned char *buf; @@ -487,8 +542,8 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) DBG(SMC_DEBUG_TX, "%s: TX PKT LENGTH 0x%04x (%d) BUF 0x%p CMDA 0x%08x CMDB 0x%08x\n", dev->name, len, len, buf, cmdA, cmdB); - SMC_SET_TX_FIFO(lp, cmdA); - SMC_SET_TX_FIFO(lp, cmdB); + SMC_SET_TX_FIFO(cmdA); + SMC_SET_TX_FIFO(cmdB); DBG(SMC_DEBUG_PKTS, "%s: Transmitted packet\n", dev->name); PRINT_PKT(buf, len <= 64 ? len : 64); @@ -496,10 +551,10 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) /* Send pkt via PIO or DMA */ #ifdef SMC_USE_DMA lp->current_tx_skb = skb; - SMC_PUSH_DATA(lp, buf, len); + SMC_PUSH_DATA(buf, len); /* DMA complete IRQ will free buffer and set jiffies */ #else - SMC_PUSH_DATA(lp, buf, len); + SMC_PUSH_DATA(buf, len); dev->trans_start = jiffies; dev_kfree_skb(skb); #endif @@ -508,7 +563,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) netif_wake_queue(dev); } spin_unlock_irqrestore(&lp->lock, flags); - SMC_ENABLE_INT(lp, INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_); + SMC_ENABLE_INT(INT_EN_TDFA_EN_ | INT_EN_TSFL_EN_); } /* @@ -520,6 +575,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int free; unsigned long flags; @@ -528,7 +584,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) BUG_ON(lp->pending_tx_skb != NULL); - free = SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TDFREE_; + free = SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TDFREE_; DBG(SMC_DEBUG_TX, "%s: TX free space %d\n", dev->name, free); /* Turn off the flow when running out of space in FIFO */ @@ -537,7 +593,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) dev->name, free); spin_lock_irqsave(&lp->lock, flags); /* Reenable when at least 1 packet of size MTU present */ - SMC_SET_FIFO_TDA(lp, (SMC911X_TX_FIFO_LOW_THRESHOLD)/64); + SMC_SET_FIFO_TDA((SMC911X_TX_FIFO_LOW_THRESHOLD)/64); lp->tx_throttle = 1; netif_stop_queue(dev); spin_unlock_irqrestore(&lp->lock, flags); @@ -592,6 +648,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) */ static void smc911x_tx(struct net_device *dev) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned int tx_status; @@ -599,11 +656,11 @@ static void smc911x_tx(struct net_device *dev) dev->name, __FUNCTION__); /* Collect the TX status */ - while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) { + while (((SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16) != 0) { DBG(SMC_DEBUG_TX, "%s: Tx stat FIFO used 0x%04x\n", dev->name, - (SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16); - tx_status = SMC_GET_TX_STS_FIFO(lp); + (SMC_GET_TX_FIFO_INF() & TX_FIFO_INF_TSUSED_) >> 16); + tx_status = SMC_GET_TX_STS_FIFO(); dev->stats.tx_packets++; dev->stats.tx_bytes+=tx_status>>16; DBG(SMC_DEBUG_TX, "%s: Tx FIFO tag 0x%04x status 0x%04x\n", @@ -641,10 +698,10 @@ static void smc911x_tx(struct net_device *dev) static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int phydata; - SMC_GET_MII(lp, phyreg, phyaddr, phydata); + SMC_GET_MII(phyreg, phyaddr, phydata); DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n", __FUNCTION__, phyaddr, phyreg, phydata); @@ -658,12 +715,12 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg) static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg, int phydata) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", __FUNCTION__, phyaddr, phyreg, phydata); - SMC_SET_MII(lp, phyreg, phyaddr, phydata); + SMC_SET_MII(phyreg, phyaddr, phydata); } /* @@ -672,6 +729,7 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg, */ static void smc911x_phy_detect(struct net_device *dev) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); int phyaddr; unsigned int cfg, id1, id2; @@ -687,30 +745,30 @@ static void smc911x_phy_detect(struct net_device *dev) switch(lp->version) { case 0x115: case 0x117: - cfg = SMC_GET_HW_CFG(lp); + cfg = SMC_GET_HW_CFG(); if (cfg & HW_CFG_EXT_PHY_DET_) { cfg &= ~HW_CFG_PHY_CLK_SEL_; cfg |= HW_CFG_PHY_CLK_SEL_CLK_DIS_; - SMC_SET_HW_CFG(lp, cfg); + SMC_SET_HW_CFG(cfg); udelay(10); /* Wait for clocks to stop */ cfg |= HW_CFG_EXT_PHY_EN_; - SMC_SET_HW_CFG(lp, cfg); + SMC_SET_HW_CFG(cfg); udelay(10); /* Wait for clocks to stop */ cfg &= ~HW_CFG_PHY_CLK_SEL_; cfg |= HW_CFG_PHY_CLK_SEL_EXT_PHY_; - SMC_SET_HW_CFG(lp, cfg); + SMC_SET_HW_CFG(cfg); udelay(10); /* Wait for clocks to stop */ cfg |= HW_CFG_SMI_SEL_; - SMC_SET_HW_CFG(lp, cfg); + SMC_SET_HW_CFG(cfg); for (phyaddr = 1; phyaddr < 32; ++phyaddr) { /* Read the PHY identifiers */ - SMC_GET_PHY_ID1(lp, phyaddr & 31, id1); - SMC_GET_PHY_ID2(lp, phyaddr & 31, id2); + SMC_GET_PHY_ID1(phyaddr & 31, id1); + SMC_GET_PHY_ID2(phyaddr & 31, id2); /* Make sure it is a valid identifier */ if (id1 != 0x0000 && id1 != 0xffff && @@ -725,8 +783,8 @@ static void smc911x_phy_detect(struct net_device *dev) } default: /* Internal media only */ - SMC_GET_PHY_ID1(lp, 1, id1); - SMC_GET_PHY_ID2(lp, 1, id2); + SMC_GET_PHY_ID1(1, id1); + SMC_GET_PHY_ID2(1, id2); /* Save the PHY's address */ lp->mii.phy_id = 1; lp->phy_type = id1 << 16 | id2; @@ -743,15 +801,16 @@ static void smc911x_phy_detect(struct net_device *dev) static int smc911x_phy_fixed(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int phyaddr = lp->mii.phy_id; int bmcr; DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); /* Enter Link Disable state */ - SMC_GET_PHY_BMCR(lp, phyaddr, bmcr); + SMC_GET_PHY_BMCR(phyaddr, bmcr); bmcr |= BMCR_PDOWN; - SMC_SET_PHY_BMCR(lp, phyaddr, bmcr); + SMC_SET_PHY_BMCR(phyaddr, bmcr); /* * Set our fixed capabilities @@ -765,11 +824,11 @@ static int smc911x_phy_fixed(struct net_device *dev) bmcr |= BMCR_SPEED100; /* Write our capabilities to the phy control register */ - SMC_SET_PHY_BMCR(lp, phyaddr, bmcr); + SMC_SET_PHY_BMCR(phyaddr, bmcr); /* Re-Configure the Receive/Phy Control register */ bmcr &= ~BMCR_PDOWN; - SMC_SET_PHY_BMCR(lp, phyaddr, bmcr); + SMC_SET_PHY_BMCR(phyaddr, bmcr); return 1; } @@ -789,6 +848,7 @@ static int smc911x_phy_fixed(struct net_device *dev) static int smc911x_phy_reset(struct net_device *dev, int phy) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int timeout; unsigned long flags; unsigned int reg; @@ -796,15 +856,15 @@ static int smc911x_phy_reset(struct net_device *dev, int phy) DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); spin_lock_irqsave(&lp->lock, flags); - reg = SMC_GET_PMT_CTRL(lp); + reg = SMC_GET_PMT_CTRL(); reg &= ~0xfffff030; reg |= PMT_CTRL_PHY_RST_; - SMC_SET_PMT_CTRL(lp, reg); + SMC_SET_PMT_CTRL(reg); spin_unlock_irqrestore(&lp->lock, flags); for (timeout = 2; timeout; timeout--) { msleep(50); spin_lock_irqsave(&lp->lock, flags); - reg = SMC_GET_PMT_CTRL(lp); + reg = SMC_GET_PMT_CTRL(); spin_unlock_irqrestore(&lp->lock, flags); if (!(reg & PMT_CTRL_PHY_RST_)) { /* extra delay required because the phy may @@ -829,13 +889,13 @@ static int smc911x_phy_reset(struct net_device *dev, int phy) */ static void smc911x_phy_powerdown(struct net_device *dev, int phy) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int bmcr; /* Enter Link Disable state */ - SMC_GET_PHY_BMCR(lp, phy, bmcr); + SMC_GET_PHY_BMCR(phy, bmcr); bmcr |= BMCR_PDOWN; - SMC_SET_PHY_BMCR(lp, phy, bmcr); + SMC_SET_PHY_BMCR(phy, bmcr); } /* @@ -849,6 +909,7 @@ static void smc911x_phy_powerdown(struct net_device *dev, int phy) static void smc911x_phy_check_media(struct net_device *dev, int init) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int phyaddr = lp->mii.phy_id; unsigned int bmcr, cr; @@ -856,8 +917,8 @@ static void smc911x_phy_check_media(struct net_device *dev, int init) if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { /* duplex state has changed */ - SMC_GET_PHY_BMCR(lp, phyaddr, bmcr); - SMC_GET_MAC_CR(lp, cr); + SMC_GET_PHY_BMCR(phyaddr, bmcr); + SMC_GET_MAC_CR(cr); if (lp->mii.full_duplex) { DBG(SMC_DEBUG_MISC, "%s: Configuring for full-duplex mode\n", dev->name); bmcr |= BMCR_FULLDPLX; @@ -867,8 +928,8 @@ static void smc911x_phy_check_media(struct net_device *dev, int init) bmcr &= ~BMCR_FULLDPLX; cr &= ~MAC_CR_RCVOWN_; } - SMC_SET_PHY_BMCR(lp, phyaddr, bmcr); - SMC_SET_MAC_CR(lp, cr); + SMC_SET_PHY_BMCR(phyaddr, bmcr); + SMC_SET_MAC_CR(cr); } } @@ -886,6 +947,7 @@ static void smc911x_phy_configure(struct work_struct *work) struct smc911x_local *lp = container_of(work, struct smc911x_local, phy_configure); struct net_device *dev = lp->netdev; + unsigned long ioaddr = dev->base_addr; int phyaddr = lp->mii.phy_id; int my_phy_caps; /* My PHY capabilities */ int my_ad_caps; /* My Advertised capabilities */ @@ -898,11 +960,11 @@ static void smc911x_phy_configure(struct work_struct *work) * We should not be called if phy_type is zero. */ if (lp->phy_type == 0) - return; + goto smc911x_phy_configure_exit_nolock; if (smc911x_phy_reset(dev, phyaddr)) { printk("%s: PHY reset timed out\n", dev->name); - return; + goto smc911x_phy_configure_exit_nolock; } spin_lock_irqsave(&lp->lock, flags); @@ -910,7 +972,7 @@ static void smc911x_phy_configure(struct work_struct *work) * Enable PHY Interrupts (for register 18) * Interrupts listed here are enabled */ - SMC_SET_PHY_INT_MASK(lp, phyaddr, PHY_INT_MASK_ENERGY_ON_ | + SMC_SET_PHY_INT_MASK(phyaddr, PHY_INT_MASK_ENERGY_ON_ | PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_REMOTE_FAULT_ | PHY_INT_MASK_LINK_DOWN_); @@ -921,7 +983,7 @@ static void smc911x_phy_configure(struct work_struct *work) } /* Copy our capabilities from MII_BMSR to MII_ADVERTISE */ - SMC_GET_PHY_BMSR(lp, phyaddr, my_phy_caps); + SMC_GET_PHY_BMSR(phyaddr, my_phy_caps); if (!(my_phy_caps & BMSR_ANEGCAPABLE)) { printk(KERN_INFO "Auto negotiation NOT supported\n"); smc911x_phy_fixed(dev); @@ -950,7 +1012,7 @@ static void smc911x_phy_configure(struct work_struct *work) my_ad_caps &= ~(ADVERTISE_100FULL|ADVERTISE_10FULL); /* Update our Auto-Neg Advertisement Register */ - SMC_SET_PHY_MII_ADV(lp, phyaddr, my_ad_caps); + SMC_SET_PHY_MII_ADV(phyaddr, my_ad_caps); lp->mii.advertising = my_ad_caps; /* @@ -959,18 +1021,20 @@ static void smc911x_phy_configure(struct work_struct *work) * the link does not come up. */ udelay(10); - SMC_GET_PHY_MII_ADV(lp, phyaddr, status); + SMC_GET_PHY_MII_ADV(phyaddr, status); DBG(SMC_DEBUG_MISC, "%s: phy caps=0x%04x\n", dev->name, my_phy_caps); DBG(SMC_DEBUG_MISC, "%s: phy advertised caps=0x%04x\n", dev->name, my_ad_caps); /* Restart auto-negotiation process in order to advertise my caps */ - SMC_SET_PHY_BMCR(lp, phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); + SMC_SET_PHY_BMCR(phyaddr, BMCR_ANENABLE | BMCR_ANRESTART); smc911x_phy_check_media(dev, 1); smc911x_phy_configure_exit: spin_unlock_irqrestore(&lp->lock, flags); +smc911x_phy_configure_exit_nolock: + lp->work_pending = 0; } /* @@ -982,6 +1046,7 @@ static void smc911x_phy_configure(struct work_struct *work) static void smc911x_phy_interrupt(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int phyaddr = lp->mii.phy_id; int status; @@ -992,11 +1057,11 @@ static void smc911x_phy_interrupt(struct net_device *dev) smc911x_phy_check_media(dev, 0); /* read to clear status bits */ - SMC_GET_PHY_INT_SRC(lp, phyaddr,status); + SMC_GET_PHY_INT_SRC(phyaddr,status); DBG(SMC_DEBUG_MISC, "%s: PHY interrupt status 0x%04x\n", dev->name, status & 0xffff); DBG(SMC_DEBUG_MISC, "%s: AFC_CFG 0x%08x\n", - dev->name, SMC_GET_AFC_CFG(lp)); + dev->name, SMC_GET_AFC_CFG()); } /*--- END PHY CONTROL AND CONFIGURATION-------------------------------------*/ @@ -1008,6 +1073,7 @@ static void smc911x_phy_interrupt(struct net_device *dev) static irqreturn_t smc911x_interrupt(int irq, void *dev_id) { struct net_device *dev = dev_id; + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned int status, mask, timeout; unsigned int rx_overrun=0, cr, pkts; @@ -1018,21 +1084,21 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) spin_lock_irqsave(&lp->lock, flags); /* Spurious interrupt check */ - if ((SMC_GET_IRQ_CFG(lp) & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) != + if ((SMC_GET_IRQ_CFG() & (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) != (INT_CFG_IRQ_INT_ | INT_CFG_IRQ_EN_)) { spin_unlock_irqrestore(&lp->lock, flags); return IRQ_NONE; } - mask = SMC_GET_INT_EN(lp); - SMC_SET_INT_EN(lp, 0); + mask = SMC_GET_INT_EN(); + SMC_SET_INT_EN(0); /* set a timeout value, so I don't stay here forever */ timeout = 8; do { - status = SMC_GET_INT(lp); + status = SMC_GET_INT(); DBG(SMC_DEBUG_MISC, "%s: INT 0x%08x MASK 0x%08x OUTSIDE MASK 0x%08x\n", dev->name, status, mask, status & ~mask); @@ -1043,53 +1109,53 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) /* Handle SW interrupt condition */ if (status & INT_STS_SW_INT_) { - SMC_ACK_INT(lp, INT_STS_SW_INT_); + SMC_ACK_INT(INT_STS_SW_INT_); mask &= ~INT_EN_SW_INT_EN_; } /* Handle various error conditions */ if (status & INT_STS_RXE_) { - SMC_ACK_INT(lp, INT_STS_RXE_); + SMC_ACK_INT(INT_STS_RXE_); dev->stats.rx_errors++; } if (status & INT_STS_RXDFH_INT_) { - SMC_ACK_INT(lp, INT_STS_RXDFH_INT_); - dev->stats.rx_dropped+=SMC_GET_RX_DROP(lp); + SMC_ACK_INT(INT_STS_RXDFH_INT_); + dev->stats.rx_dropped+=SMC_GET_RX_DROP(); } /* Undocumented interrupt-what is the right thing to do here? */ if (status & INT_STS_RXDF_INT_) { - SMC_ACK_INT(lp, INT_STS_RXDF_INT_); + SMC_ACK_INT(INT_STS_RXDF_INT_); } /* Rx Data FIFO exceeds set level */ if (status & INT_STS_RDFL_) { if (IS_REV_A(lp->revision)) { rx_overrun=1; - SMC_GET_MAC_CR(lp, cr); + SMC_GET_MAC_CR(cr); cr &= ~MAC_CR_RXEN_; - SMC_SET_MAC_CR(lp, cr); + SMC_SET_MAC_CR(cr); DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); dev->stats.rx_errors++; dev->stats.rx_fifo_errors++; } - SMC_ACK_INT(lp, INT_STS_RDFL_); + SMC_ACK_INT(INT_STS_RDFL_); } if (status & INT_STS_RDFO_) { if (!IS_REV_A(lp->revision)) { - SMC_GET_MAC_CR(lp, cr); + SMC_GET_MAC_CR(cr); cr &= ~MAC_CR_RXEN_; - SMC_SET_MAC_CR(lp, cr); + SMC_SET_MAC_CR(cr); rx_overrun=1; DBG(SMC_DEBUG_RX, "%s: RX overrun\n", dev->name); dev->stats.rx_errors++; dev->stats.rx_fifo_errors++; } - SMC_ACK_INT(lp, INT_STS_RDFO_); + SMC_ACK_INT(INT_STS_RDFO_); } /* Handle receive condition */ if ((status & INT_STS_RSFL_) || rx_overrun) { unsigned int fifo; DBG(SMC_DEBUG_RX, "%s: RX irq\n", dev->name); - fifo = SMC_GET_RX_FIFO_INF(lp); + fifo = SMC_GET_RX_FIFO_INF(); pkts = (fifo & RX_FIFO_INF_RXSUSED_) >> 16; DBG(SMC_DEBUG_RX, "%s: Rx FIFO pkts %d, bytes %d\n", dev->name, pkts, fifo & 0xFFFF ); @@ -1100,61 +1166,61 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA active\n", dev->name); /* The DMA is already running so up the IRQ threshold */ - fifo = SMC_GET_FIFO_INT(lp) & ~0xFF; + fifo = SMC_GET_FIFO_INT() & ~0xFF; fifo |= pkts & 0xFF; DBG(SMC_DEBUG_RX, "%s: Setting RX stat FIFO threshold to %d\n", dev->name, fifo & 0xff); - SMC_SET_FIFO_INT(lp, fifo); + SMC_SET_FIFO_INT(fifo); } else #endif smc911x_rcv(dev); } - SMC_ACK_INT(lp, INT_STS_RSFL_); + SMC_ACK_INT(INT_STS_RSFL_); } /* Handle transmit FIFO available */ if (status & INT_STS_TDFA_) { DBG(SMC_DEBUG_TX, "%s: TX data FIFO space available irq\n", dev->name); - SMC_SET_FIFO_TDA(lp, 0xFF); + SMC_SET_FIFO_TDA(0xFF); lp->tx_throttle = 0; #ifdef SMC_USE_DMA if (!lp->txdma_active) #endif netif_wake_queue(dev); - SMC_ACK_INT(lp, INT_STS_TDFA_); + SMC_ACK_INT(INT_STS_TDFA_); } /* Handle transmit done condition */ #if 1 if (status & (INT_STS_TSFL_ | INT_STS_GPT_INT_)) { DBG(SMC_DEBUG_TX | SMC_DEBUG_MISC, "%s: Tx stat FIFO limit (%d) /GPT irq\n", - dev->name, (SMC_GET_FIFO_INT(lp) & 0x00ff0000) >> 16); + dev->name, (SMC_GET_FIFO_INT() & 0x00ff0000) >> 16); smc911x_tx(dev); - SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000); - SMC_ACK_INT(lp, INT_STS_TSFL_); - SMC_ACK_INT(lp, INT_STS_TSFL_ | INT_STS_GPT_INT_); + SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); + SMC_ACK_INT(INT_STS_TSFL_); + SMC_ACK_INT(INT_STS_TSFL_ | INT_STS_GPT_INT_); } #else if (status & INT_STS_TSFL_) { DBG(SMC_DEBUG_TX, "%s: TX status FIFO limit (%d) irq \n", dev->name, ); smc911x_tx(dev); - SMC_ACK_INT(lp, INT_STS_TSFL_); + SMC_ACK_INT(INT_STS_TSFL_); } if (status & INT_STS_GPT_INT_) { DBG(SMC_DEBUG_RX, "%s: IRQ_CFG 0x%08x FIFO_INT 0x%08x RX_CFG 0x%08x\n", dev->name, - SMC_GET_IRQ_CFG(lp), - SMC_GET_FIFO_INT(lp), - SMC_GET_RX_CFG(lp)); + SMC_GET_IRQ_CFG(), + SMC_GET_FIFO_INT(), + SMC_GET_RX_CFG()); DBG(SMC_DEBUG_RX, "%s: Rx Stat FIFO Used 0x%02x " "Data FIFO Used 0x%04x Stat FIFO 0x%08x\n", dev->name, - (SMC_GET_RX_FIFO_INF(lp) & 0x00ff0000) >> 16, - SMC_GET_RX_FIFO_INF(lp) & 0xffff, - SMC_GET_RX_STS_FIFO_PEEK(lp)); - SMC_SET_GPT_CFG(lp, GPT_CFG_TIMER_EN_ | 10000); - SMC_ACK_INT(lp, INT_STS_GPT_INT_); + (SMC_GET_RX_FIFO_INF() & 0x00ff0000) >> 16, + SMC_GET_RX_FIFO_INF() & 0xffff, + SMC_GET_RX_STS_FIFO_PEEK()); + SMC_SET_GPT_CFG(GPT_CFG_TIMER_EN_ | 10000); + SMC_ACK_INT(INT_STS_GPT_INT_); } #endif @@ -1162,12 +1228,12 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) if (status & INT_STS_PHY_INT_) { DBG(SMC_DEBUG_MISC, "%s: PHY irq\n", dev->name); smc911x_phy_interrupt(dev); - SMC_ACK_INT(lp, INT_STS_PHY_INT_); + SMC_ACK_INT(INT_STS_PHY_INT_); } } while (--timeout); /* restore mask state */ - SMC_SET_INT_EN(lp, mask); + SMC_SET_INT_EN(mask); DBG(SMC_DEBUG_MISC, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); @@ -1269,28 +1335,32 @@ static void smc911x_poll_controller(struct net_device *dev) static void smc911x_timeout(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int status, mask; unsigned long flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); spin_lock_irqsave(&lp->lock, flags); - status = SMC_GET_INT(lp); - mask = SMC_GET_INT_EN(lp); + status = SMC_GET_INT(); + mask = SMC_GET_INT_EN(); spin_unlock_irqrestore(&lp->lock, flags); DBG(SMC_DEBUG_MISC, "%s: INT 0x%02x MASK 0x%02x \n", dev->name, status, mask); /* Dump the current TX FIFO contents and restart */ - mask = SMC_GET_TX_CFG(lp); - SMC_SET_TX_CFG(lp, mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_); + mask = SMC_GET_TX_CFG(); + SMC_SET_TX_CFG(mask | TX_CFG_TXS_DUMP_ | TX_CFG_TXD_DUMP_); /* * Reconfiguring the PHY doesn't seem like a bad idea here, but * smc911x_phy_configure() calls msleep() which calls schedule_timeout() * which calls schedule(). Hence we use a work queue. */ - if (lp->phy_type != 0) - schedule_work(&lp->phy_configure); + if (lp->phy_type != 0) { + if (schedule_work(&lp->phy_configure)) { + lp->work_pending = 1; + } + } /* We can accept TX packets again */ dev->trans_start = jiffies; @@ -1306,6 +1376,7 @@ static void smc911x_timeout(struct net_device *dev) static void smc911x_set_multicast_list(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int multicast_table[2]; unsigned int mcr, update_multicast = 0; unsigned long flags; @@ -1313,7 +1384,7 @@ static void smc911x_set_multicast_list(struct net_device *dev) DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CR(lp, mcr); + SMC_GET_MAC_CR(mcr); spin_unlock_irqrestore(&lp->lock, flags); if (dev->flags & IFF_PROMISC) { @@ -1390,13 +1461,13 @@ static void smc911x_set_multicast_list(struct net_device *dev) } spin_lock_irqsave(&lp->lock, flags); - SMC_SET_MAC_CR(lp, mcr); + SMC_SET_MAC_CR(mcr); if (update_multicast) { DBG(SMC_DEBUG_MISC, "%s: update mcast hash table 0x%08x 0x%08x\n", dev->name, multicast_table[0], multicast_table[1]); - SMC_SET_HASHL(lp, multicast_table[0]); - SMC_SET_HASHH(lp, multicast_table[1]); + SMC_SET_HASHL(multicast_table[0]); + SMC_SET_HASHH(multicast_table[1]); } spin_unlock_irqrestore(&lp->lock, flags); } @@ -1460,8 +1531,16 @@ static int smc911x_close(struct net_device *dev) if (lp->phy_type != 0) { /* We need to ensure that no calls to * smc911x_phy_configure are pending. + + * flush_scheduled_work() cannot be called because we + * are running with the netlink semaphore held (from + * devinet_ioctl()) and the pending work queue + * contains linkwatch_event() (scheduled by + * netif_carrier_off() above). linkwatch_event() also + * wants the netlink semaphore. */ - cancel_work_sync(&lp->phy_configure); + while (lp->work_pending) + schedule(); smc911x_phy_powerdown(dev, lp->mii.phy_id); } @@ -1480,6 +1559,7 @@ static int smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) { struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int ret, status; unsigned long flags; @@ -1507,7 +1587,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) else cmd->transceiver = XCVR_EXTERNAL; cmd->port = 0; - SMC_GET_PHY_SPECIAL(lp, lp->mii.phy_id, status); + SMC_GET_PHY_SPECIAL(lp->mii.phy_id, status); cmd->duplex = (status & (PHY_SPECIAL_SPD_10FULL_ | PHY_SPECIAL_SPD_100FULL_)) ? DUPLEX_FULL : DUPLEX_HALF; @@ -1588,6 +1668,7 @@ static int smc911x_ethtool_getregslen(struct net_device *dev) static void smc911x_ethtool_getregs(struct net_device *dev, struct ethtool_regs* regs, void *buf) { + unsigned long ioaddr = dev->base_addr; struct smc911x_local *lp = netdev_priv(dev); unsigned long flags; u32 reg,i,j=0; @@ -1595,17 +1676,17 @@ static void smc911x_ethtool_getregs(struct net_device *dev, regs->version = lp->version; for(i=ID_REV;i<=E2P_CMD;i+=4) { - data[j++] = SMC_inl(lp, i); + data[j++] = SMC_inl(ioaddr,i); } for(i=MAC_CR;i<=WUCSR;i++) { spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MAC_CSR(lp, i, reg); + SMC_GET_MAC_CSR(i, reg); spin_unlock_irqrestore(&lp->lock, flags); data[j++] = reg; } for(i=0;i<=31;i++) { spin_lock_irqsave(&lp->lock, flags); - SMC_GET_MII(lp, i, lp->mii.phy_id, reg); + SMC_GET_MII(i, lp->mii.phy_id, reg); spin_unlock_irqrestore(&lp->lock, flags); data[j++] = reg & 0xFFFF; } @@ -1613,11 +1694,11 @@ static void smc911x_ethtool_getregs(struct net_device *dev, static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; unsigned int timeout; int e2p_cmd; - e2p_cmd = SMC_GET_E2P_CMD(lp); + e2p_cmd = SMC_GET_E2P_CMD(); for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) { if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) { PRINTK("%s: %s timeout waiting for EEPROM to respond\n", @@ -1625,7 +1706,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) return -EFAULT; } mdelay(1); - e2p_cmd = SMC_GET_E2P_CMD(lp); + e2p_cmd = SMC_GET_E2P_CMD(); } if (timeout == 0) { PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n", @@ -1638,12 +1719,12 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev, int cmd, int addr) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int ret; if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) return ret; - SMC_SET_E2P_CMD(lp, E2P_CMD_EPC_BUSY_ | + SMC_SET_E2P_CMD(E2P_CMD_EPC_BUSY_ | ((cmd) & (0x7<<28)) | ((addr) & 0xFF)); return 0; @@ -1652,24 +1733,24 @@ static inline int smc911x_ethtool_write_eeprom_cmd(struct net_device *dev, static inline int smc911x_ethtool_read_eeprom_byte(struct net_device *dev, u8 *data) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int ret; if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) return ret; - *data = SMC_GET_E2P_DATA(lp); + *data = SMC_GET_E2P_DATA(); return 0; } static inline int smc911x_ethtool_write_eeprom_byte(struct net_device *dev, u8 data) { - struct smc911x_local *lp = netdev_priv(dev); + unsigned long ioaddr = dev->base_addr; int ret; if ((ret = smc911x_ethtool_wait_eeprom_ready(dev))!=0) return ret; - SMC_SET_E2P_DATA(lp, data); + SMC_SET_E2P_DATA(data); return 0; } @@ -1736,9 +1817,8 @@ static const struct ethtool_ops smc911x_ethtool_ops = { * This routine has a simple purpose -- make the SMC chip generate an * interrupt, so an auto-detect routine can detect it, and find the IRQ, */ -static int __init smc911x_findirq(struct net_device *dev) +static int __init smc911x_findirq(unsigned long ioaddr) { - struct smc911x_local *lp = netdev_priv(dev); int timeout = 20; unsigned long cookie; @@ -1750,7 +1830,7 @@ static int __init smc911x_findirq(struct net_device *dev) * Force a SW interrupt */ - SMC_SET_INT_EN(lp, INT_EN_SW_INT_EN_); + SMC_SET_INT_EN(INT_EN_SW_INT_EN_); /* * Wait until positive that the interrupt has been generated @@ -1758,7 +1838,7 @@ static int __init smc911x_findirq(struct net_device *dev) do { int int_status; udelay(10); - int_status = SMC_GET_INT_EN(lp); + int_status = SMC_GET_INT_EN(); if (int_status & INT_EN_SW_INT_EN_) break; /* got the interrupt */ } while (--timeout); @@ -1771,7 +1851,7 @@ static int __init smc911x_findirq(struct net_device *dev) */ /* and disable all interrupts again */ - SMC_SET_INT_EN(lp, 0); + SMC_SET_INT_EN(0); /* and return what I found */ return probe_irq_off(cookie); @@ -1800,18 +1880,17 @@ static int __init smc911x_findirq(struct net_device *dev) * o actually GRAB the irq. * o GRAB the region */ -static int __init smc911x_probe(struct net_device *dev) +static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr) { struct smc911x_local *lp = netdev_priv(dev); int i, retval; unsigned int val, chip_id, revision; const char *version_string; - unsigned long irq_flags; DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); /* First, see if the endian word is recognized */ - val = SMC_GET_BYTE_TEST(lp); + val = SMC_GET_BYTE_TEST(); DBG(SMC_DEBUG_MISC, "%s: endian probe returned 0x%04x\n", CARDNAME, val); if (val != 0x87654321) { printk(KERN_ERR "Invalid chip endian 0x08%x\n",val); @@ -1824,7 +1903,7 @@ static int __init smc911x_probe(struct net_device *dev) * recognize. These might need to be added to later, * as future revisions could be added. */ - chip_id = SMC_GET_PN(lp); + chip_id = SMC_GET_PN(); DBG(SMC_DEBUG_MISC, "%s: id probe returned 0x%04x\n", CARDNAME, chip_id); for(i=0;chip_ids[i].id != 0; i++) { if (chip_ids[i].id == chip_id) break; @@ -1836,7 +1915,7 @@ static int __init smc911x_probe(struct net_device *dev) } version_string = chip_ids[i].name; - revision = SMC_GET_REV(lp); + revision = SMC_GET_REV(); DBG(SMC_DEBUG_MISC, "%s: revision = 0x%04x\n", CARDNAME, revision); /* At this point I'll assume that the chip is an SMC911x. */ @@ -1850,6 +1929,7 @@ static int __init smc911x_probe(struct net_device *dev) } /* fill in some of the fields */ + dev->base_addr = ioaddr; lp->version = chip_ids[i].id; lp->revision = revision; lp->tx_fifo_kb = tx_fifo_kb; @@ -1908,7 +1988,7 @@ static int __init smc911x_probe(struct net_device *dev) spin_lock_init(&lp->lock); /* Get the MAC address */ - SMC_GET_MAC_ADDR(lp, dev->dev_addr); + SMC_GET_MAC_ADDR(dev->dev_addr); /* now, reset the chip, and put it into a known state */ smc911x_reset(dev); @@ -1925,7 +2005,7 @@ static int __init smc911x_probe(struct net_device *dev) trials = 3; while (trials--) { - dev->irq = smc911x_findirq(dev); + dev->irq = smc911x_findirq(ioaddr); if (dev->irq) break; /* kick the card and try again */ @@ -1973,15 +2053,9 @@ static int __init smc911x_probe(struct net_device *dev) lp->ctl_rfduplx = 1; lp->ctl_rspeed = 100; -#ifdef SMC_DYNAMIC_BUS_CONFIG - irq_flags = lp->cfg.irq_flags; -#else - irq_flags = IRQF_SHARED | SMC_IRQ_SENSE; -#endif - /* Grab the IRQ */ retval = request_irq(dev->irq, &smc911x_interrupt, - irq_flags, dev->name, dev); + IRQF_SHARED | SMC_IRQ_SENSE, dev->name, dev); if (retval) goto err_out; @@ -2051,7 +2125,6 @@ static int __init smc911x_probe(struct net_device *dev) */ static int smc911x_drv_probe(struct platform_device *pdev) { - struct smc91x_platdata *pd = pdev->dev.platform_data; struct net_device *ndev; struct resource *res; struct smc911x_local *lp; @@ -2085,13 +2158,6 @@ static int smc911x_drv_probe(struct platform_device *pdev) ndev->irq = platform_get_irq(pdev, 0); lp = netdev_priv(ndev); lp->netdev = ndev; -#ifdef SMC_DYNAMIC_BUS_CONFIG - if (!pd) { - ret = -EINVAL; - goto release_both; - } - memcpy(&lp->cfg, pd, sizeof(lp->cfg)); -#endif addr = ioremap(res->start, SMC911X_IO_EXTENT); if (!addr) { @@ -2100,9 +2166,7 @@ static int smc911x_drv_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ndev); - lp->base = addr; - ndev->base_addr = res->start; - ret = smc911x_probe(ndev); + ret = smc911x_probe(ndev, (unsigned long)addr); if (ret != 0) { platform_set_drvdata(pdev, NULL); iounmap(addr); @@ -2126,7 +2190,6 @@ static int smc911x_drv_probe(struct platform_device *pdev) static int smc911x_drv_remove(struct platform_device *pdev) { struct net_device *ndev = platform_get_drvdata(pdev); - struct smc911x_local *lp = netdev_priv(ndev); struct resource *res; DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); @@ -2138,6 +2201,7 @@ static int smc911x_drv_remove(struct platform_device *pdev) #ifdef SMC_USE_DMA { + struct smc911x_local *lp = netdev_priv(ndev); if (lp->rxdma != -1) { SMC_DMA_FREE(dev, lp->rxdma); } @@ -2146,7 +2210,7 @@ static int smc911x_drv_remove(struct platform_device *pdev) } } #endif - iounmap(lp->base); + iounmap((void *)ndev->base_addr); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, SMC911X_IO_EXTENT); @@ -2157,7 +2221,7 @@ static int smc911x_drv_remove(struct platform_device *pdev) static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state) { struct net_device *ndev = platform_get_drvdata(dev); - struct smc911x_local *lp = netdev_priv(ndev); + unsigned long ioaddr = ndev->base_addr; DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); if (ndev) { @@ -2166,7 +2230,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state) smc911x_shutdown(ndev); #if POWER_DOWN /* Set D2 - Energy detect only setting */ - SMC_SET_PMT_CTRL(lp, 2<<12); + SMC_SET_PMT_CTRL(2<<12); #endif } } diff --git a/trunk/drivers/net/smc911x.h b/trunk/drivers/net/smc911x.h index 76c17c28fab4..7defa63b9c74 100644 --- a/trunk/drivers/net/smc911x.h +++ b/trunk/drivers/net/smc911x.h @@ -29,7 +29,6 @@ #ifndef _SMC911X_H_ #define _SMC911X_H_ -#include /* * Use the DMA feature on PXA chips */ @@ -39,160 +38,42 @@ #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_FALLING #elif defined(CONFIG_SH_MAGIC_PANEL_R2) + #define SMC_USE_SH_DMA 0 #define SMC_USE_16BIT 0 #define SMC_USE_32BIT 1 #define SMC_IRQ_SENSE IRQF_TRIGGER_LOW -#else -/* - * Default configuration - */ - -#define SMC_DYNAMIC_BUS_CONFIG #endif -/* store this information for the driver.. */ -struct smc911x_local { - /* - * If I have to wait until the DMA is finished and ready to reload a - * packet, I will store the skbuff here. Then, the DMA will send it - * out and free it. - */ - struct sk_buff *pending_tx_skb; - - /* version/revision of the SMC911x chip */ - u16 version; - u16 revision; - - /* FIFO sizes */ - int tx_fifo_kb; - int tx_fifo_size; - int rx_fifo_size; - int afc_cfg; - - /* Contains the current active receive/phy mode */ - int ctl_rfduplx; - int ctl_rspeed; - - u32 msg_enable; - u32 phy_type; - struct mii_if_info mii; - - /* work queue */ - struct work_struct phy_configure; - - int tx_throttle; - spinlock_t lock; - - struct net_device *netdev; - -#ifdef SMC_USE_DMA - /* DMA needs the physical address of the chip */ - u_long physaddr; - int rxdma; - int txdma; - int rxdma_active; - int txdma_active; - struct sk_buff *current_rx_skb; - struct sk_buff *current_tx_skb; - struct device *dev; -#endif - void __iomem *base; -#ifdef SMC_DYNAMIC_BUS_CONFIG - struct smc911x_platdata cfg; -#endif -}; /* * Define the bus width specific IO macros */ -#ifdef SMC_DYNAMIC_BUS_CONFIG -static inline unsigned int SMC_inl(struct smc911x_local *lp, int reg) -{ - void __iomem *ioaddr = lp->base + reg; - - if (lp->cfg.flags & SMC911X_USE_32BIT) - return readl(ioaddr); - - if (lp->cfg.flags & SMC911X_USE_16BIT) - return readw(ioaddr) | (readw(ioaddr + 2) << 16); - - BUG(); -} - -static inline void SMC_outl(unsigned int value, struct smc911x_local *lp, - int reg) -{ - void __iomem *ioaddr = lp->base + reg; - - if (lp->cfg.flags & SMC911X_USE_32BIT) { - writel(value, ioaddr); - return; - } - - if (lp->cfg.flags & SMC911X_USE_16BIT) { - writew(value & 0xffff, ioaddr); - writew(value >> 16, ioaddr + 2); - return; - } - - BUG(); -} - -static inline void SMC_insl(struct smc911x_local *lp, int reg, - void *addr, unsigned int count) -{ - void __iomem *ioaddr = lp->base + reg; - - if (lp->cfg.flags & SMC911X_USE_32BIT) { - readsl(ioaddr, addr, count); - return; - } - - if (lp->cfg.flags & SMC911X_USE_16BIT) { - readsw(ioaddr, addr, count * 2); - return; - } - - BUG(); -} - -static inline void SMC_outsl(struct smc911x_local *lp, int reg, - void *addr, unsigned int count) -{ - void __iomem *ioaddr = lp->base + reg; - - if (lp->cfg.flags & SMC911X_USE_32BIT) { - writesl(ioaddr, addr, count); - return; - } - - if (lp->cfg.flags & SMC911X_USE_16BIT) { - writesw(ioaddr, addr, count * 2); - return; - } - - BUG(); -} -#else #if SMC_USE_16BIT -#define SMC_inl(lp, r) ((readw((lp)->base + (r)) & 0xFFFF) + (readw((lp)->base + (r) + 2) << 16)) -#define SMC_outl(v, lp, r) \ +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) ((SMC_inw(a, r) & 0xFFFF)+(SMC_inw(a+2, r)<<16)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outw(v, a, r) writew(v, (a) + (r)) +#define SMC_outl(v, a, r) \ do{ \ - writew(v & 0xFFFF, (lp)->base + (r)); \ - writew(v >> 16, (lp)->base + (r) + 2); \ + writel(v & 0xFFFF, (a) + (r)); \ + writel(v >> 16, (a) + (r) + 2); \ } while (0) -#define SMC_insl(lp, r, p, l) readsw((short*)((lp)->base + (r)), p, l*2) -#define SMC_outsl(lp, r, p, l) writesw((short*)((lp)->base + (r)), p, l*2) +#define SMC_insl(a, r, p, l) readsw((short*)((a) + (r)), p, l*2) +#define SMC_outsl(a, r, p, l) writesw((short*)((a) + (r)), p, l*2) #elif SMC_USE_32BIT -#define SMC_inl(lp, r) readl((lp)->base + (r)) -#define SMC_outl(v, lp, r) writel(v, (lp)->base + (r)) -#define SMC_insl(lp, r, p, l) readsl((int*)((lp)->base + (r)), p, l) -#define SMC_outsl(lp, r, p, l) writesl((int*)((lp)->base + (r)), p, l) +#define SMC_inb(a, r) readb((a) + (r)) +#define SMC_inw(a, r) readw((a) + (r)) +#define SMC_inl(a, r) readl((a) + (r)) +#define SMC_outb(v, a, r) writeb(v, (a) + (r)) +#define SMC_outl(v, a, r) writel(v, (a) + (r)) +#define SMC_insl(a, r, p, l) readsl((int*)((a) + (r)), p, l) +#define SMC_outsl(a, r, p, l) writesl((int*)((a) + (r)), p, l) #endif /* SMC_USE_16BIT */ -#endif /* SMC_DYNAMIC_BUS_CONFIG */ + #ifdef SMC_USE_PXA_DMA @@ -229,22 +110,22 @@ static int rx_dmalen, tx_dmalen; #ifdef SMC_insl #undef SMC_insl -#define SMC_insl(lp, r, p, l) \ - smc_pxa_dma_insl(lp, lp->physaddr, r, lp->rxdma, p, l) +#define SMC_insl(a, r, p, l) \ + smc_pxa_dma_insl(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l) static inline void -smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr, +smc_pxa_dma_insl(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len) { /* 64 bit alignment is required for memory to memory DMA */ if ((long)buf & 4) { - *((u32 *)buf) = SMC_inl(lp, reg); + *((u32 *)buf) = SMC_inl(ioaddr, reg); buf += 4; len--; } len *= 4; - rx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_FROM_DEVICE); + rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); rx_dmalen = len; DCSR(dma) = DCSR_NODESC; DTADR(dma) = rx_dmabuf; @@ -255,24 +136,52 @@ smc_pxa_dma_insl(struct smc911x_local *lp, u_long physaddr, } #endif +#ifdef SMC_insw +#undef SMC_insw +#define SMC_insw(a, r, p, l) \ + smc_pxa_dma_insw(lp->dev, a, lp->physaddr, r, lp->rxdma, p, l) + +static inline void +smc_pxa_dma_insw(struct device *dev, u_long ioaddr, u_long physaddr, + int reg, int dma, u_char *buf, int len) +{ + /* 64 bit alignment is required for memory to memory DMA */ + while ((long)buf & 6) { + *((u16 *)buf) = SMC_inw(ioaddr, reg); + buf += 2; + len--; + } + + len *= 2; + rx_dmabuf = dma_map_single(dev, buf, len, DMA_FROM_DEVICE); + rx_dmalen = len; + DCSR(dma) = DCSR_NODESC; + DTADR(dma) = rx_dmabuf; + DSADR(dma) = physaddr + reg; + DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 | + DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & rx_dmalen)); + DCSR(dma) = DCSR_NODESC | DCSR_RUN; +} +#endif + #ifdef SMC_outsl #undef SMC_outsl -#define SMC_outsl(lp, r, p, l) \ - smc_pxa_dma_outsl(lp, lp->physaddr, r, lp->txdma, p, l) +#define SMC_outsl(a, r, p, l) \ + smc_pxa_dma_outsl(lp->dev, a, lp->physaddr, r, lp->txdma, p, l) static inline void -smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr, +smc_pxa_dma_outsl(struct device *dev, u_long ioaddr, u_long physaddr, int reg, int dma, u_char *buf, int len) { /* 64 bit alignment is required for memory to memory DMA */ if ((long)buf & 4) { - SMC_outl(*((u32 *)buf), lp, reg); + SMC_outl(*((u32 *)buf), ioaddr, reg); buf += 4; len--; } len *= 4; - tx_dmabuf = dma_map_single(lp->dev, buf, len, DMA_TO_DEVICE); + tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); tx_dmalen = len; DCSR(dma) = DCSR_NODESC; DSADR(dma) = tx_dmabuf; @@ -282,6 +191,35 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr, DCSR(dma) = DCSR_NODESC | DCSR_RUN; } #endif + +#ifdef SMC_outsw +#undef SMC_outsw +#define SMC_outsw(a, r, p, l) \ + smc_pxa_dma_outsw(lp->dev, a, lp->physaddr, r, lp->txdma, p, l) + +static inline void +smc_pxa_dma_outsw(struct device *dev, u_long ioaddr, u_long physaddr, + int reg, int dma, u_char *buf, int len) +{ + /* 64 bit alignment is required for memory to memory DMA */ + while ((long)buf & 6) { + SMC_outw(*((u16 *)buf), ioaddr, reg); + buf += 2; + len--; + } + + len *= 2; + tx_dmabuf = dma_map_single(dev, buf, len, DMA_TO_DEVICE); + tx_dmalen = len; + DCSR(dma) = DCSR_NODESC; + DSADR(dma) = tx_dmabuf; + DTADR(dma) = physaddr + reg; + DCMD(dma) = (DCMD_INCSRCADDR | DCMD_BURST32 | + DCMD_WIDTH2 | DCMD_ENDIRQEN | (DCMD_LENGTH & tx_dmalen)); + DCSR(dma) = DCSR_NODESC | DCSR_RUN; +} +#endif + #endif /* SMC_USE_PXA_DMA */ @@ -691,213 +629,213 @@ static const struct chip_id chip_ids[] = { * capabilities. Please use those and not the in/out primitives. */ /* FIFO read/write macros */ -#define SMC_PUSH_DATA(lp, p, l) SMC_outsl( lp, TX_DATA_FIFO, p, (l) >> 2 ) -#define SMC_PULL_DATA(lp, p, l) SMC_insl ( lp, RX_DATA_FIFO, p, (l) >> 2 ) -#define SMC_SET_TX_FIFO(lp, x) SMC_outl( x, lp, TX_DATA_FIFO ) -#define SMC_GET_RX_FIFO(lp) SMC_inl( lp, RX_DATA_FIFO ) +#define SMC_PUSH_DATA(p, l) SMC_outsl( ioaddr, TX_DATA_FIFO, p, (l) >> 2 ) +#define SMC_PULL_DATA(p, l) SMC_insl ( ioaddr, RX_DATA_FIFO, p, (l) >> 2 ) +#define SMC_SET_TX_FIFO(x) SMC_outl( x, ioaddr, TX_DATA_FIFO ) +#define SMC_GET_RX_FIFO() SMC_inl( ioaddr, RX_DATA_FIFO ) /* I/O mapped register read/write macros */ -#define SMC_GET_TX_STS_FIFO(lp) SMC_inl( lp, TX_STATUS_FIFO ) -#define SMC_GET_RX_STS_FIFO(lp) SMC_inl( lp, RX_STATUS_FIFO ) -#define SMC_GET_RX_STS_FIFO_PEEK(lp) SMC_inl( lp, RX_STATUS_FIFO_PEEK ) -#define SMC_GET_PN(lp) (SMC_inl( lp, ID_REV ) >> 16) -#define SMC_GET_REV(lp) (SMC_inl( lp, ID_REV ) & 0xFFFF) -#define SMC_GET_IRQ_CFG(lp) SMC_inl( lp, INT_CFG ) -#define SMC_SET_IRQ_CFG(lp, x) SMC_outl( x, lp, INT_CFG ) -#define SMC_GET_INT(lp) SMC_inl( lp, INT_STS ) -#define SMC_ACK_INT(lp, x) SMC_outl( x, lp, INT_STS ) -#define SMC_GET_INT_EN(lp) SMC_inl( lp, INT_EN ) -#define SMC_SET_INT_EN(lp, x) SMC_outl( x, lp, INT_EN ) -#define SMC_GET_BYTE_TEST(lp) SMC_inl( lp, BYTE_TEST ) -#define SMC_SET_BYTE_TEST(lp, x) SMC_outl( x, lp, BYTE_TEST ) -#define SMC_GET_FIFO_INT(lp) SMC_inl( lp, FIFO_INT ) -#define SMC_SET_FIFO_INT(lp, x) SMC_outl( x, lp, FIFO_INT ) -#define SMC_SET_FIFO_TDA(lp, x) \ +#define SMC_GET_TX_STS_FIFO() SMC_inl( ioaddr, TX_STATUS_FIFO ) +#define SMC_GET_RX_STS_FIFO() SMC_inl( ioaddr, RX_STATUS_FIFO ) +#define SMC_GET_RX_STS_FIFO_PEEK() SMC_inl( ioaddr, RX_STATUS_FIFO_PEEK ) +#define SMC_GET_PN() (SMC_inl( ioaddr, ID_REV ) >> 16) +#define SMC_GET_REV() (SMC_inl( ioaddr, ID_REV ) & 0xFFFF) +#define SMC_GET_IRQ_CFG() SMC_inl( ioaddr, INT_CFG ) +#define SMC_SET_IRQ_CFG(x) SMC_outl( x, ioaddr, INT_CFG ) +#define SMC_GET_INT() SMC_inl( ioaddr, INT_STS ) +#define SMC_ACK_INT(x) SMC_outl( x, ioaddr, INT_STS ) +#define SMC_GET_INT_EN() SMC_inl( ioaddr, INT_EN ) +#define SMC_SET_INT_EN(x) SMC_outl( x, ioaddr, INT_EN ) +#define SMC_GET_BYTE_TEST() SMC_inl( ioaddr, BYTE_TEST ) +#define SMC_SET_BYTE_TEST(x) SMC_outl( x, ioaddr, BYTE_TEST ) +#define SMC_GET_FIFO_INT() SMC_inl( ioaddr, FIFO_INT ) +#define SMC_SET_FIFO_INT(x) SMC_outl( x, ioaddr, FIFO_INT ) +#define SMC_SET_FIFO_TDA(x) \ do { \ unsigned long __flags; \ int __mask; \ local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<24); \ - SMC_SET_FIFO_INT( (lp), __mask | (x)<<24 ); \ + __mask = SMC_GET_FIFO_INT() & ~(0xFF<<24); \ + SMC_SET_FIFO_INT( __mask | (x)<<24 ); \ local_irq_restore(__flags); \ } while (0) -#define SMC_SET_FIFO_TSL(lp, x) \ +#define SMC_SET_FIFO_TSL(x) \ do { \ unsigned long __flags; \ int __mask; \ local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<16); \ - SMC_SET_FIFO_INT( (lp), __mask | (((x) & 0xFF)<<16)); \ + __mask = SMC_GET_FIFO_INT() & ~(0xFF<<16); \ + SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<16)); \ local_irq_restore(__flags); \ } while (0) -#define SMC_SET_FIFO_RSA(lp, x) \ +#define SMC_SET_FIFO_RSA(x) \ do { \ unsigned long __flags; \ int __mask; \ local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT((lp)) & ~(0xFF<<8); \ - SMC_SET_FIFO_INT( (lp), __mask | (((x) & 0xFF)<<8)); \ + __mask = SMC_GET_FIFO_INT() & ~(0xFF<<8); \ + SMC_SET_FIFO_INT( __mask | (((x) & 0xFF)<<8)); \ local_irq_restore(__flags); \ } while (0) -#define SMC_SET_FIFO_RSL(lp, x) \ +#define SMC_SET_FIFO_RSL(x) \ do { \ unsigned long __flags; \ int __mask; \ local_irq_save(__flags); \ - __mask = SMC_GET_FIFO_INT((lp)) & ~0xFF; \ - SMC_SET_FIFO_INT( (lp),__mask | ((x) & 0xFF)); \ + __mask = SMC_GET_FIFO_INT() & ~0xFF; \ + SMC_SET_FIFO_INT( __mask | ((x) & 0xFF)); \ local_irq_restore(__flags); \ } while (0) -#define SMC_GET_RX_CFG(lp) SMC_inl( lp, RX_CFG ) -#define SMC_SET_RX_CFG(lp, x) SMC_outl( x, lp, RX_CFG ) -#define SMC_GET_TX_CFG(lp) SMC_inl( lp, TX_CFG ) -#define SMC_SET_TX_CFG(lp, x) SMC_outl( x, lp, TX_CFG ) -#define SMC_GET_HW_CFG(lp) SMC_inl( lp, HW_CFG ) -#define SMC_SET_HW_CFG(lp, x) SMC_outl( x, lp, HW_CFG ) -#define SMC_GET_RX_DP_CTRL(lp) SMC_inl( lp, RX_DP_CTRL ) -#define SMC_SET_RX_DP_CTRL(lp, x) SMC_outl( x, lp, RX_DP_CTRL ) -#define SMC_GET_PMT_CTRL(lp) SMC_inl( lp, PMT_CTRL ) -#define SMC_SET_PMT_CTRL(lp, x) SMC_outl( x, lp, PMT_CTRL ) -#define SMC_GET_GPIO_CFG(lp) SMC_inl( lp, GPIO_CFG ) -#define SMC_SET_GPIO_CFG(lp, x) SMC_outl( x, lp, GPIO_CFG ) -#define SMC_GET_RX_FIFO_INF(lp) SMC_inl( lp, RX_FIFO_INF ) -#define SMC_SET_RX_FIFO_INF(lp, x) SMC_outl( x, lp, RX_FIFO_INF ) -#define SMC_GET_TX_FIFO_INF(lp) SMC_inl( lp, TX_FIFO_INF ) -#define SMC_SET_TX_FIFO_INF(lp, x) SMC_outl( x, lp, TX_FIFO_INF ) -#define SMC_GET_GPT_CFG(lp) SMC_inl( lp, GPT_CFG ) -#define SMC_SET_GPT_CFG(lp, x) SMC_outl( x, lp, GPT_CFG ) -#define SMC_GET_RX_DROP(lp) SMC_inl( lp, RX_DROP ) -#define SMC_SET_RX_DROP(lp, x) SMC_outl( x, lp, RX_DROP ) -#define SMC_GET_MAC_CMD(lp) SMC_inl( lp, MAC_CSR_CMD ) -#define SMC_SET_MAC_CMD(lp, x) SMC_outl( x, lp, MAC_CSR_CMD ) -#define SMC_GET_MAC_DATA(lp) SMC_inl( lp, MAC_CSR_DATA ) -#define SMC_SET_MAC_DATA(lp, x) SMC_outl( x, lp, MAC_CSR_DATA ) -#define SMC_GET_AFC_CFG(lp) SMC_inl( lp, AFC_CFG ) -#define SMC_SET_AFC_CFG(lp, x) SMC_outl( x, lp, AFC_CFG ) -#define SMC_GET_E2P_CMD(lp) SMC_inl( lp, E2P_CMD ) -#define SMC_SET_E2P_CMD(lp, x) SMC_outl( x, lp, E2P_CMD ) -#define SMC_GET_E2P_DATA(lp) SMC_inl( lp, E2P_DATA ) -#define SMC_SET_E2P_DATA(lp, x) SMC_outl( x, lp, E2P_DATA ) +#define SMC_GET_RX_CFG() SMC_inl( ioaddr, RX_CFG ) +#define SMC_SET_RX_CFG(x) SMC_outl( x, ioaddr, RX_CFG ) +#define SMC_GET_TX_CFG() SMC_inl( ioaddr, TX_CFG ) +#define SMC_SET_TX_CFG(x) SMC_outl( x, ioaddr, TX_CFG ) +#define SMC_GET_HW_CFG() SMC_inl( ioaddr, HW_CFG ) +#define SMC_SET_HW_CFG(x) SMC_outl( x, ioaddr, HW_CFG ) +#define SMC_GET_RX_DP_CTRL() SMC_inl( ioaddr, RX_DP_CTRL ) +#define SMC_SET_RX_DP_CTRL(x) SMC_outl( x, ioaddr, RX_DP_CTRL ) +#define SMC_GET_PMT_CTRL() SMC_inl( ioaddr, PMT_CTRL ) +#define SMC_SET_PMT_CTRL(x) SMC_outl( x, ioaddr, PMT_CTRL ) +#define SMC_GET_GPIO_CFG() SMC_inl( ioaddr, GPIO_CFG ) +#define SMC_SET_GPIO_CFG(x) SMC_outl( x, ioaddr, GPIO_CFG ) +#define SMC_GET_RX_FIFO_INF() SMC_inl( ioaddr, RX_FIFO_INF ) +#define SMC_SET_RX_FIFO_INF(x) SMC_outl( x, ioaddr, RX_FIFO_INF ) +#define SMC_GET_TX_FIFO_INF() SMC_inl( ioaddr, TX_FIFO_INF ) +#define SMC_SET_TX_FIFO_INF(x) SMC_outl( x, ioaddr, TX_FIFO_INF ) +#define SMC_GET_GPT_CFG() SMC_inl( ioaddr, GPT_CFG ) +#define SMC_SET_GPT_CFG(x) SMC_outl( x, ioaddr, GPT_CFG ) +#define SMC_GET_RX_DROP() SMC_inl( ioaddr, RX_DROP ) +#define SMC_SET_RX_DROP(x) SMC_outl( x, ioaddr, RX_DROP ) +#define SMC_GET_MAC_CMD() SMC_inl( ioaddr, MAC_CSR_CMD ) +#define SMC_SET_MAC_CMD(x) SMC_outl( x, ioaddr, MAC_CSR_CMD ) +#define SMC_GET_MAC_DATA() SMC_inl( ioaddr, MAC_CSR_DATA ) +#define SMC_SET_MAC_DATA(x) SMC_outl( x, ioaddr, MAC_CSR_DATA ) +#define SMC_GET_AFC_CFG() SMC_inl( ioaddr, AFC_CFG ) +#define SMC_SET_AFC_CFG(x) SMC_outl( x, ioaddr, AFC_CFG ) +#define SMC_GET_E2P_CMD() SMC_inl( ioaddr, E2P_CMD ) +#define SMC_SET_E2P_CMD(x) SMC_outl( x, ioaddr, E2P_CMD ) +#define SMC_GET_E2P_DATA() SMC_inl( ioaddr, E2P_DATA ) +#define SMC_SET_E2P_DATA(x) SMC_outl( x, ioaddr, E2P_DATA ) /* MAC register read/write macros */ -#define SMC_GET_MAC_CSR(lp,a,v) \ +#define SMC_GET_MAC_CSR(a,v) \ do { \ - while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_CMD((lp),MAC_CSR_CMD_CSR_BUSY_ | \ + while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ + SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | \ MAC_CSR_CMD_R_NOT_W_ | (a) ); \ - while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ - v = SMC_GET_MAC_DATA((lp)); \ + while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ + v = SMC_GET_MAC_DATA(); \ } while (0) -#define SMC_SET_MAC_CSR(lp,a,v) \ +#define SMC_SET_MAC_CSR(a,v) \ do { \ - while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_DATA((lp), v); \ - SMC_SET_MAC_CMD((lp), MAC_CSR_CMD_CSR_BUSY_ | (a) ); \ - while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ + while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ + SMC_SET_MAC_DATA(v); \ + SMC_SET_MAC_CMD(MAC_CSR_CMD_CSR_BUSY_ | (a) ); \ + while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ } while (0) -#define SMC_GET_MAC_CR(lp, x) SMC_GET_MAC_CSR( (lp), MAC_CR, x ) -#define SMC_SET_MAC_CR(lp, x) SMC_SET_MAC_CSR( (lp), MAC_CR, x ) -#define SMC_GET_ADDRH(lp, x) SMC_GET_MAC_CSR( (lp), ADDRH, x ) -#define SMC_SET_ADDRH(lp, x) SMC_SET_MAC_CSR( (lp), ADDRH, x ) -#define SMC_GET_ADDRL(lp, x) SMC_GET_MAC_CSR( (lp), ADDRL, x ) -#define SMC_SET_ADDRL(lp, x) SMC_SET_MAC_CSR( (lp), ADDRL, x ) -#define SMC_GET_HASHH(lp, x) SMC_GET_MAC_CSR( (lp), HASHH, x ) -#define SMC_SET_HASHH(lp, x) SMC_SET_MAC_CSR( (lp), HASHH, x ) -#define SMC_GET_HASHL(lp, x) SMC_GET_MAC_CSR( (lp), HASHL, x ) -#define SMC_SET_HASHL(lp, x) SMC_SET_MAC_CSR( (lp), HASHL, x ) -#define SMC_GET_MII_ACC(lp, x) SMC_GET_MAC_CSR( (lp), MII_ACC, x ) -#define SMC_SET_MII_ACC(lp, x) SMC_SET_MAC_CSR( (lp), MII_ACC, x ) -#define SMC_GET_MII_DATA(lp, x) SMC_GET_MAC_CSR( (lp), MII_DATA, x ) -#define SMC_SET_MII_DATA(lp, x) SMC_SET_MAC_CSR( (lp), MII_DATA, x ) -#define SMC_GET_FLOW(lp, x) SMC_GET_MAC_CSR( (lp), FLOW, x ) -#define SMC_SET_FLOW(lp, x) SMC_SET_MAC_CSR( (lp), FLOW, x ) -#define SMC_GET_VLAN1(lp, x) SMC_GET_MAC_CSR( (lp), VLAN1, x ) -#define SMC_SET_VLAN1(lp, x) SMC_SET_MAC_CSR( (lp), VLAN1, x ) -#define SMC_GET_VLAN2(lp, x) SMC_GET_MAC_CSR( (lp), VLAN2, x ) -#define SMC_SET_VLAN2(lp, x) SMC_SET_MAC_CSR( (lp), VLAN2, x ) -#define SMC_SET_WUFF(lp, x) SMC_SET_MAC_CSR( (lp), WUFF, x ) -#define SMC_GET_WUCSR(lp, x) SMC_GET_MAC_CSR( (lp), WUCSR, x ) -#define SMC_SET_WUCSR(lp, x) SMC_SET_MAC_CSR( (lp), WUCSR, x ) +#define SMC_GET_MAC_CR(x) SMC_GET_MAC_CSR( MAC_CR, x ) +#define SMC_SET_MAC_CR(x) SMC_SET_MAC_CSR( MAC_CR, x ) +#define SMC_GET_ADDRH(x) SMC_GET_MAC_CSR( ADDRH, x ) +#define SMC_SET_ADDRH(x) SMC_SET_MAC_CSR( ADDRH, x ) +#define SMC_GET_ADDRL(x) SMC_GET_MAC_CSR( ADDRL, x ) +#define SMC_SET_ADDRL(x) SMC_SET_MAC_CSR( ADDRL, x ) +#define SMC_GET_HASHH(x) SMC_GET_MAC_CSR( HASHH, x ) +#define SMC_SET_HASHH(x) SMC_SET_MAC_CSR( HASHH, x ) +#define SMC_GET_HASHL(x) SMC_GET_MAC_CSR( HASHL, x ) +#define SMC_SET_HASHL(x) SMC_SET_MAC_CSR( HASHL, x ) +#define SMC_GET_MII_ACC(x) SMC_GET_MAC_CSR( MII_ACC, x ) +#define SMC_SET_MII_ACC(x) SMC_SET_MAC_CSR( MII_ACC, x ) +#define SMC_GET_MII_DATA(x) SMC_GET_MAC_CSR( MII_DATA, x ) +#define SMC_SET_MII_DATA(x) SMC_SET_MAC_CSR( MII_DATA, x ) +#define SMC_GET_FLOW(x) SMC_GET_MAC_CSR( FLOW, x ) +#define SMC_SET_FLOW(x) SMC_SET_MAC_CSR( FLOW, x ) +#define SMC_GET_VLAN1(x) SMC_GET_MAC_CSR( VLAN1, x ) +#define SMC_SET_VLAN1(x) SMC_SET_MAC_CSR( VLAN1, x ) +#define SMC_GET_VLAN2(x) SMC_GET_MAC_CSR( VLAN2, x ) +#define SMC_SET_VLAN2(x) SMC_SET_MAC_CSR( VLAN2, x ) +#define SMC_SET_WUFF(x) SMC_SET_MAC_CSR( WUFF, x ) +#define SMC_GET_WUCSR(x) SMC_GET_MAC_CSR( WUCSR, x ) +#define SMC_SET_WUCSR(x) SMC_SET_MAC_CSR( WUCSR, x ) /* PHY register read/write macros */ -#define SMC_GET_MII(lp,a,phy,v) \ +#define SMC_GET_MII(a,phy,v) \ do { \ u32 __v; \ do { \ - SMC_GET_MII_ACC((lp), __v); \ + SMC_GET_MII_ACC(__v); \ } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_SET_MII_ACC( (lp), ((phy)<<11) | ((a)<<6) | \ + SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \ MII_ACC_MII_BUSY_); \ do { \ - SMC_GET_MII_ACC( (lp), __v); \ + SMC_GET_MII_ACC(__v); \ } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_GET_MII_DATA((lp), v); \ + SMC_GET_MII_DATA(v); \ } while (0) -#define SMC_SET_MII(lp,a,phy,v) \ +#define SMC_SET_MII(a,phy,v) \ do { \ u32 __v; \ do { \ - SMC_GET_MII_ACC((lp), __v); \ + SMC_GET_MII_ACC(__v); \ } while ( __v & MII_ACC_MII_BUSY_ ); \ - SMC_SET_MII_DATA((lp), v); \ - SMC_SET_MII_ACC( (lp), ((phy)<<11) | ((a)<<6) | \ + SMC_SET_MII_DATA(v); \ + SMC_SET_MII_ACC( ((phy)<<11) | ((a)<<6) | \ MII_ACC_MII_BUSY_ | \ MII_ACC_MII_WRITE_ ); \ do { \ - SMC_GET_MII_ACC((lp), __v); \ + SMC_GET_MII_ACC(__v); \ } while ( __v & MII_ACC_MII_BUSY_ ); \ } while (0) -#define SMC_GET_PHY_BMCR(lp,phy,x) SMC_GET_MII( (lp), MII_BMCR, phy, x ) -#define SMC_SET_PHY_BMCR(lp,phy,x) SMC_SET_MII( (lp), MII_BMCR, phy, x ) -#define SMC_GET_PHY_BMSR(lp,phy,x) SMC_GET_MII( (lp), MII_BMSR, phy, x ) -#define SMC_GET_PHY_ID1(lp,phy,x) SMC_GET_MII( (lp), MII_PHYSID1, phy, x ) -#define SMC_GET_PHY_ID2(lp,phy,x) SMC_GET_MII( (lp), MII_PHYSID2, phy, x ) -#define SMC_GET_PHY_MII_ADV(lp,phy,x) SMC_GET_MII( (lp), MII_ADVERTISE, phy, x ) -#define SMC_SET_PHY_MII_ADV(lp,phy,x) SMC_SET_MII( (lp), MII_ADVERTISE, phy, x ) -#define SMC_GET_PHY_MII_LPA(lp,phy,x) SMC_GET_MII( (lp), MII_LPA, phy, x ) -#define SMC_SET_PHY_MII_LPA(lp,phy,x) SMC_SET_MII( (lp), MII_LPA, phy, x ) -#define SMC_GET_PHY_CTRL_STS(lp,phy,x) SMC_GET_MII( (lp), PHY_MODE_CTRL_STS, phy, x ) -#define SMC_SET_PHY_CTRL_STS(lp,phy,x) SMC_SET_MII( (lp), PHY_MODE_CTRL_STS, phy, x ) -#define SMC_GET_PHY_INT_SRC(lp,phy,x) SMC_GET_MII( (lp), PHY_INT_SRC, phy, x ) -#define SMC_SET_PHY_INT_SRC(lp,phy,x) SMC_SET_MII( (lp), PHY_INT_SRC, phy, x ) -#define SMC_GET_PHY_INT_MASK(lp,phy,x) SMC_GET_MII( (lp), PHY_INT_MASK, phy, x ) -#define SMC_SET_PHY_INT_MASK(lp,phy,x) SMC_SET_MII( (lp), PHY_INT_MASK, phy, x ) -#define SMC_GET_PHY_SPECIAL(lp,phy,x) SMC_GET_MII( (lp), PHY_SPECIAL, phy, x ) +#define SMC_GET_PHY_BMCR(phy,x) SMC_GET_MII( MII_BMCR, phy, x ) +#define SMC_SET_PHY_BMCR(phy,x) SMC_SET_MII( MII_BMCR, phy, x ) +#define SMC_GET_PHY_BMSR(phy,x) SMC_GET_MII( MII_BMSR, phy, x ) +#define SMC_GET_PHY_ID1(phy,x) SMC_GET_MII( MII_PHYSID1, phy, x ) +#define SMC_GET_PHY_ID2(phy,x) SMC_GET_MII( MII_PHYSID2, phy, x ) +#define SMC_GET_PHY_MII_ADV(phy,x) SMC_GET_MII( MII_ADVERTISE, phy, x ) +#define SMC_SET_PHY_MII_ADV(phy,x) SMC_SET_MII( MII_ADVERTISE, phy, x ) +#define SMC_GET_PHY_MII_LPA(phy,x) SMC_GET_MII( MII_LPA, phy, x ) +#define SMC_SET_PHY_MII_LPA(phy,x) SMC_SET_MII( MII_LPA, phy, x ) +#define SMC_GET_PHY_CTRL_STS(phy,x) SMC_GET_MII( PHY_MODE_CTRL_STS, phy, x ) +#define SMC_SET_PHY_CTRL_STS(phy,x) SMC_SET_MII( PHY_MODE_CTRL_STS, phy, x ) +#define SMC_GET_PHY_INT_SRC(phy,x) SMC_GET_MII( PHY_INT_SRC, phy, x ) +#define SMC_SET_PHY_INT_SRC(phy,x) SMC_SET_MII( PHY_INT_SRC, phy, x ) +#define SMC_GET_PHY_INT_MASK(phy,x) SMC_GET_MII( PHY_INT_MASK, phy, x ) +#define SMC_SET_PHY_INT_MASK(phy,x) SMC_SET_MII( PHY_INT_MASK, phy, x ) +#define SMC_GET_PHY_SPECIAL(phy,x) SMC_GET_MII( PHY_SPECIAL, phy, x ) /* Misc read/write macros */ #ifndef SMC_GET_MAC_ADDR -#define SMC_GET_MAC_ADDR(lp, addr) \ +#define SMC_GET_MAC_ADDR(addr) \ do { \ unsigned int __v; \ \ - SMC_GET_MAC_CSR((lp), ADDRL, __v); \ + SMC_GET_MAC_CSR(ADDRL, __v); \ addr[0] = __v; addr[1] = __v >> 8; \ addr[2] = __v >> 16; addr[3] = __v >> 24; \ - SMC_GET_MAC_CSR((lp), ADDRH, __v); \ + SMC_GET_MAC_CSR(ADDRH, __v); \ addr[4] = __v; addr[5] = __v >> 8; \ } while (0) #endif -#define SMC_SET_MAC_ADDR(lp, addr) \ +#define SMC_SET_MAC_ADDR(addr) \ do { \ - SMC_SET_MAC_CSR((lp), ADDRL, \ + SMC_SET_MAC_CSR(ADDRL, \ addr[0] | \ (addr[1] << 8) | \ (addr[2] << 16) | \ (addr[3] << 24)); \ - SMC_SET_MAC_CSR((lp), ADDRH, addr[4]|(addr[5] << 8));\ + SMC_SET_MAC_CSR(ADDRH, addr[4]|(addr[5] << 8));\ } while (0) -#define SMC_WRITE_EEPROM_CMD(lp, cmd, addr) \ +#define SMC_WRITE_EEPROM_CMD(cmd, addr) \ do { \ - while (SMC_GET_E2P_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ - SMC_SET_MAC_CMD((lp), MAC_CSR_CMD_R_NOT_W_ | a ); \ - while (SMC_GET_MAC_CMD((lp)) & MAC_CSR_CMD_CSR_BUSY_); \ + while (SMC_GET_E2P_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ + SMC_SET_MAC_CMD(MAC_CSR_CMD_R_NOT_W_ | a ); \ + while (SMC_GET_MAC_CMD() & MAC_CSR_CMD_CSR_BUSY_); \ } while (0) #endif /* _SMC911X_H_ */ diff --git a/trunk/drivers/net/smc91x.c b/trunk/drivers/net/smc91x.c index f2051b209da2..a188e33484e6 100644 --- a/trunk/drivers/net/smc91x.c +++ b/trunk/drivers/net/smc91x.c @@ -1016,8 +1016,15 @@ static void smc_phy_powerdown(struct net_device *dev) /* We need to ensure that no calls to smc_phy_configure are pending. + + flush_scheduled_work() cannot be called because we are + running with the netlink semaphore held (from + devinet_ioctl()) and the pending work queue contains + linkwatch_event() (scheduled by netif_carrier_off() + above). linkwatch_event() also wants the netlink semaphore. */ - cancel_work_sync(&lp->phy_configure); + while(lp->work_pending) + yield(); bmcr = smc_phy_read(dev, phy, MII_BMCR); smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); @@ -1154,6 +1161,7 @@ static void smc_phy_configure(struct work_struct *work) smc_phy_configure_exit: SMC_SELECT_BANK(lp, 2); spin_unlock_irq(&lp->lock); + lp->work_pending = 0; } /* @@ -1381,8 +1389,11 @@ static void smc_timeout(struct net_device *dev) * smc_phy_configure() calls msleep() which calls schedule_timeout() * which calls schedule(). Hence we use a work queue. */ - if (lp->phy_type != 0) - schedule_work(&lp->phy_configure); + if (lp->phy_type != 0) { + if (schedule_work(&lp->phy_configure)) { + lp->work_pending = 1; + } + } /* We can accept TX packets again */ dev->trans_start = jiffies; diff --git a/trunk/drivers/net/smc91x.h b/trunk/drivers/net/smc91x.h index 8606818653f8..69e97a1cb1c4 100644 --- a/trunk/drivers/net/smc91x.h +++ b/trunk/drivers/net/smc91x.h @@ -93,14 +93,14 @@ #define SMC_insw(a, r, p, l) insw ((unsigned long *)((a) + (r)), p, l) # endif /* check if the mac in reg is valid */ -#define SMC_GET_MAC_ADDR(lp, addr) \ +#define SMC_GET_MAC_ADDR(addr) \ do { \ unsigned int __v; \ - __v = SMC_inw(ioaddr, ADDR0_REG(lp)); \ + __v = SMC_inw(ioaddr, ADDR0_REG); \ addr[0] = __v; addr[1] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR1_REG(lp)); \ + __v = SMC_inw(ioaddr, ADDR1_REG); \ addr[2] = __v; addr[3] = __v >> 8; \ - __v = SMC_inw(ioaddr, ADDR2_REG(lp)); \ + __v = SMC_inw(ioaddr, ADDR2_REG); \ addr[4] = __v; addr[5] = __v >> 8; \ if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) { \ random_ether_addr(addr); \ diff --git a/trunk/drivers/net/sunlance.c b/trunk/drivers/net/sunlance.c index 4e994f87469e..26ade68aeabf 100644 --- a/trunk/drivers/net/sunlance.c +++ b/trunk/drivers/net/sunlance.c @@ -915,11 +915,15 @@ static void build_fake_packet(struct lance_private *lp) lp->tx_new = TX_NEXT(entry); } +struct net_device *last_dev; + static int lance_open(struct net_device *dev) { struct lance_private *lp = netdev_priv(dev); int status = 0; + last_dev = dev; + STOP_LANCE(lp); if (request_irq(dev->irq, &lance_interrupt, IRQF_SHARED, diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index af8d2c436efd..55670b5eb611 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -731,7 +731,7 @@ static void tulip_down (struct net_device *dev) void __iomem *ioaddr = tp->base_addr; unsigned long flags; - cancel_work_sync(&tp->media_work); + flush_scheduled_work(); #ifdef CONFIG_TULIP_NAPI napi_disable(&tp->napi); diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index 68e198bd538b..0604f3faf043 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -154,16 +154,6 @@ config USB_NET_AX8817X This driver creates an interface named "ethX", where X depends on what other networking devices you have in use. -config USB_HSO - tristate "Option USB High Speed Mobile Devices" - depends on USB && RFKILL - default n - help - Choose this option if you have an Option HSDPA/HSUPA card. - These cards support downlink speeds of 7.2Mbps or greater. - - To compile this driver as a module, choose M here: the - module will be called hso. config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)" diff --git a/trunk/drivers/net/usb/Makefile b/trunk/drivers/net/usb/Makefile index 24800c157f98..595a539f8384 100644 --- a/trunk/drivers/net/usb/Makefile +++ b/trunk/drivers/net/usb/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_RTL8150) += rtl8150.o -obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o diff --git a/trunk/drivers/net/usb/hso.c b/trunk/drivers/net/usb/hso.c deleted file mode 100644 index 031d07b105af..000000000000 --- a/trunk/drivers/net/usb/hso.c +++ /dev/null @@ -1,2836 +0,0 @@ -/****************************************************************************** - * - * Driver for Option High Speed Mobile Devices. - * - * Copyright (C) 2008 Option International - * Copyright (C) 2007 Andrew Bird (Sphere Systems Ltd) - * - * Copyright (C) 2008 Greg Kroah-Hartman - * Copyright (C) 2008 Novell, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA - * - * - *****************************************************************************/ - -/****************************************************************************** - * - * Description of the device: - * - * Interface 0: Contains the IP network interface on the bulk end points. - * The multiplexed serial ports are using the interrupt and - * control endpoints. - * Interrupt contains a bitmap telling which multiplexed - * serialport needs servicing. - * - * Interface 1: Diagnostics port, uses bulk only, do not submit urbs until the - * port is opened, as this have a huge impact on the network port - * throughput. - * - * Interface 2: Standard modem interface - circuit switched interface, should - * not be used. - * - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define DRIVER_VERSION "1.2" -#define MOD_AUTHOR "Option Wireless" -#define MOD_DESCRIPTION "USB High Speed Option driver" -#define MOD_LICENSE "GPL" - -#define HSO_MAX_NET_DEVICES 10 -#define HSO__MAX_MTU 2048 -#define DEFAULT_MTU 1500 -#define DEFAULT_MRU 1500 - -#define CTRL_URB_RX_SIZE 1024 -#define CTRL_URB_TX_SIZE 64 - -#define BULK_URB_RX_SIZE 4096 -#define BULK_URB_TX_SIZE 8192 - -#define MUX_BULK_RX_BUF_SIZE HSO__MAX_MTU -#define MUX_BULK_TX_BUF_SIZE HSO__MAX_MTU -#define MUX_BULK_RX_BUF_COUNT 4 -#define USB_TYPE_OPTION_VENDOR 0x20 - -/* These definitions are used with the struct hso_net flags element */ -/* - use *_bit operations on it. (bit indices not values.) */ -#define HSO_NET_RUNNING 0 - -#define HSO_NET_TX_TIMEOUT (HZ*10) - -/* Serial port defines and structs. */ -#define HSO_SERIAL_FLAG_RX_SENT 0 - -#define HSO_SERIAL_MAGIC 0x48534f31 - -/* Number of ttys to handle */ -#define HSO_SERIAL_TTY_MINORS 256 - -#define MAX_RX_URBS 2 - -#define get_serial_by_tty(x) \ - (x ? (struct hso_serial *)x->driver_data : NULL) - -/*****************************************************************************/ -/* Debugging functions */ -/*****************************************************************************/ -#define D__(lvl_, fmt, arg...) \ - do { \ - printk(lvl_ "[%d:%s]: " fmt "\n", \ - __LINE__, __func__, ## arg); \ - } while (0) - -#define D_(lvl, args...) \ - do { \ - if (lvl & debug) \ - D__(KERN_INFO, args); \ - } while (0) - -#define D1(args...) D_(0x01, ##args) -#define D2(args...) D_(0x02, ##args) -#define D3(args...) D_(0x04, ##args) -#define D4(args...) D_(0x08, ##args) -#define D5(args...) D_(0x10, ##args) - -/*****************************************************************************/ -/* Enumerators */ -/*****************************************************************************/ -enum pkt_parse_state { - WAIT_IP, - WAIT_DATA, - WAIT_SYNC -}; - -/*****************************************************************************/ -/* Structs */ -/*****************************************************************************/ - -struct hso_shared_int { - struct usb_endpoint_descriptor *intr_endp; - void *shared_intr_buf; - struct urb *shared_intr_urb; - struct usb_device *usb; - int use_count; - int ref_count; - struct mutex shared_int_lock; -}; - -struct hso_net { - struct hso_device *parent; - struct net_device *net; - struct rfkill *rfkill; - - struct usb_endpoint_descriptor *in_endp; - struct usb_endpoint_descriptor *out_endp; - - struct urb *mux_bulk_rx_urb_pool[MUX_BULK_RX_BUF_COUNT]; - struct urb *mux_bulk_tx_urb; - void *mux_bulk_rx_buf_pool[MUX_BULK_RX_BUF_COUNT]; - void *mux_bulk_tx_buf; - - struct sk_buff *skb_rx_buf; - struct sk_buff *skb_tx_buf; - - enum pkt_parse_state rx_parse_state; - spinlock_t net_lock; - - unsigned short rx_buf_size; - unsigned short rx_buf_missing; - struct iphdr rx_ip_hdr; - - unsigned long flags; -}; - -struct hso_serial { - struct hso_device *parent; - int magic; - u8 minor; - - struct hso_shared_int *shared_int; - - /* rx/tx urb could be either a bulk urb or a control urb depending - on which serial port it is used on. */ - struct urb *rx_urb[MAX_RX_URBS]; - u8 num_rx_urbs; - u8 *rx_data[MAX_RX_URBS]; - u16 rx_data_length; /* should contain allocated length */ - - struct urb *tx_urb; - u8 *tx_data; - u8 *tx_buffer; - u16 tx_data_length; /* should contain allocated length */ - u16 tx_data_count; - u16 tx_buffer_count; - struct usb_ctrlrequest ctrl_req_tx; - struct usb_ctrlrequest ctrl_req_rx; - - struct usb_endpoint_descriptor *in_endp; - struct usb_endpoint_descriptor *out_endp; - - unsigned long flags; - u8 rts_state; - u8 dtr_state; - unsigned tx_urb_used:1; - - /* from usb_serial_port */ - struct tty_struct *tty; - int open_count; - spinlock_t serial_lock; - - int (*write_data) (struct hso_serial *serial); -}; - -struct hso_device { - union { - struct hso_serial *dev_serial; - struct hso_net *dev_net; - } port_data; - - u32 port_spec; - - u8 is_active; - u8 usb_gone; - struct work_struct async_get_intf; - struct work_struct async_put_intf; - - struct usb_device *usb; - struct usb_interface *interface; - - struct device *dev; - struct kref ref; - struct mutex mutex; -}; - -/* Type of interface */ -#define HSO_INTF_MASK 0xFF00 -#define HSO_INTF_MUX 0x0100 -#define HSO_INTF_BULK 0x0200 - -/* Type of port */ -#define HSO_PORT_MASK 0xFF -#define HSO_PORT_NO_PORT 0x0 -#define HSO_PORT_CONTROL 0x1 -#define HSO_PORT_APP 0x2 -#define HSO_PORT_GPS 0x3 -#define HSO_PORT_PCSC 0x4 -#define HSO_PORT_APP2 0x5 -#define HSO_PORT_GPS_CONTROL 0x6 -#define HSO_PORT_MSD 0x7 -#define HSO_PORT_VOICE 0x8 -#define HSO_PORT_DIAG2 0x9 -#define HSO_PORT_DIAG 0x10 -#define HSO_PORT_MODEM 0x11 -#define HSO_PORT_NETWORK 0x12 - -/* Additional device info */ -#define HSO_INFO_MASK 0xFF000000 -#define HSO_INFO_CRC_BUG 0x01000000 - -/*****************************************************************************/ -/* Prototypes */ -/*****************************************************************************/ -/* Serial driver functions */ -static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear); -static void ctrl_callback(struct urb *urb); -static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial); -static void hso_kick_transmit(struct hso_serial *serial); -/* Helper functions */ -static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, - struct usb_device *usb, gfp_t gfp); -static void log_usb_status(int status, const char *function); -static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, - int type, int dir); -static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports); -static void hso_free_interface(struct usb_interface *intf); -static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags); -static int hso_stop_serial_device(struct hso_device *hso_dev); -static int hso_start_net_device(struct hso_device *hso_dev); -static void hso_free_shared_int(struct hso_shared_int *shared_int); -static int hso_stop_net_device(struct hso_device *hso_dev); -static void hso_serial_ref_free(struct kref *ref); -static void async_get_intf(struct work_struct *data); -static void async_put_intf(struct work_struct *data); -static int hso_put_activity(struct hso_device *hso_dev); -static int hso_get_activity(struct hso_device *hso_dev); - -/*****************************************************************************/ -/* Helping functions */ -/*****************************************************************************/ - -/* #define DEBUG */ - -#define dev2net(x) (x->port_data.dev_net) -#define dev2ser(x) (x->port_data.dev_serial) - -/* Debugging functions */ -#ifdef DEBUG -static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, - unsigned int len) -{ - u8 i = 0; - - printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len); - - for (i = 0; i < len; i++) { - if (!(i % 16)) - printk("\n 0x%03x: ", i); - printk("%02x ", (unsigned char)buf[i]); - } - printk("\n"); -} - -#define DUMP(buf_, len_) \ - dbg_dump(__LINE__, __func__, buf_, len_) - -#define DUMP1(buf_, len_) \ - do { \ - if (0x01 & debug) \ - DUMP(buf_, len_); \ - } while (0) -#else -#define DUMP(buf_, len_) -#define DUMP1(buf_, len_) -#endif - -/* module parameters */ -static int debug; -static int tty_major; -static int disable_net; - -/* driver info */ -static const char driver_name[] = "hso"; -static const char tty_filename[] = "ttyHS"; -static const char *version = __FILE__ ": " DRIVER_VERSION " " MOD_AUTHOR; -/* the usb driver itself (registered in hso_init) */ -static struct usb_driver hso_driver; -/* serial structures */ -static struct tty_driver *tty_drv; -static struct hso_device *serial_table[HSO_SERIAL_TTY_MINORS]; -static struct hso_device *network_table[HSO_MAX_NET_DEVICES]; -static spinlock_t serial_table_lock; -static struct ktermios *hso_serial_termios[HSO_SERIAL_TTY_MINORS]; -static struct ktermios *hso_serial_termios_locked[HSO_SERIAL_TTY_MINORS]; - -static const s32 default_port_spec[] = { - HSO_INTF_MUX | HSO_PORT_NETWORK, - HSO_INTF_BULK | HSO_PORT_DIAG, - HSO_INTF_BULK | HSO_PORT_MODEM, - 0 -}; - -static const s32 icon321_port_spec[] = { - HSO_INTF_MUX | HSO_PORT_NETWORK, - HSO_INTF_BULK | HSO_PORT_DIAG2, - HSO_INTF_BULK | HSO_PORT_MODEM, - HSO_INTF_BULK | HSO_PORT_DIAG, - 0 -}; - -#define default_port_device(vendor, product) \ - USB_DEVICE(vendor, product), \ - .driver_info = (kernel_ulong_t)default_port_spec - -#define icon321_port_device(vendor, product) \ - USB_DEVICE(vendor, product), \ - .driver_info = (kernel_ulong_t)icon321_port_spec - -/* list of devices we support */ -static const struct usb_device_id hso_ids[] = { - {default_port_device(0x0af0, 0x6711)}, - {default_port_device(0x0af0, 0x6731)}, - {default_port_device(0x0af0, 0x6751)}, - {default_port_device(0x0af0, 0x6771)}, - {default_port_device(0x0af0, 0x6791)}, - {default_port_device(0x0af0, 0x6811)}, - {default_port_device(0x0af0, 0x6911)}, - {default_port_device(0x0af0, 0x6951)}, - {default_port_device(0x0af0, 0x6971)}, - {default_port_device(0x0af0, 0x7011)}, - {default_port_device(0x0af0, 0x7031)}, - {default_port_device(0x0af0, 0x7051)}, - {default_port_device(0x0af0, 0x7071)}, - {default_port_device(0x0af0, 0x7111)}, - {default_port_device(0x0af0, 0x7211)}, - {default_port_device(0x0af0, 0x7251)}, - {default_port_device(0x0af0, 0x7271)}, - {default_port_device(0x0af0, 0x7311)}, - {default_port_device(0x0af0, 0xc031)}, /* Icon-Edge */ - {icon321_port_device(0x0af0, 0xd013)}, /* Module HSxPA */ - {icon321_port_device(0x0af0, 0xd031)}, /* Icon-321 */ - {default_port_device(0x0af0, 0xd033)}, /* Icon-322 */ - {USB_DEVICE(0x0af0, 0x7301)}, /* GE40x */ - {USB_DEVICE(0x0af0, 0x7361)}, /* GE40x */ - {USB_DEVICE(0x0af0, 0x7401)}, /* GI 0401 */ - {USB_DEVICE(0x0af0, 0x7501)}, /* GTM 382 */ - {USB_DEVICE(0x0af0, 0x7601)}, /* GE40x */ - {} -}; -MODULE_DEVICE_TABLE(usb, hso_ids); - -/* Sysfs attribute */ -static ssize_t hso_sysfs_show_porttype(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct hso_device *hso_dev = dev->driver_data; - char *port_name; - - if (!hso_dev) - return 0; - - switch (hso_dev->port_spec & HSO_PORT_MASK) { - case HSO_PORT_CONTROL: - port_name = "Control"; - break; - case HSO_PORT_APP: - port_name = "Application"; - break; - case HSO_PORT_APP2: - port_name = "Application2"; - break; - case HSO_PORT_GPS: - port_name = "GPS"; - break; - case HSO_PORT_GPS_CONTROL: - port_name = "GPS Control"; - break; - case HSO_PORT_PCSC: - port_name = "PCSC"; - break; - case HSO_PORT_DIAG: - port_name = "Diagnostic"; - break; - case HSO_PORT_DIAG2: - port_name = "Diagnostic2"; - break; - case HSO_PORT_MODEM: - port_name = "Modem"; - break; - case HSO_PORT_NETWORK: - port_name = "Network"; - break; - default: - port_name = "Unknown"; - break; - } - - return sprintf(buf, "%s\n", port_name); -} -static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL); - -/* converts mux value to a port spec value */ -static u32 hso_mux_to_port(int mux) -{ - u32 result; - - switch (mux) { - case 0x1: - result = HSO_PORT_CONTROL; - break; - case 0x2: - result = HSO_PORT_APP; - break; - case 0x4: - result = HSO_PORT_PCSC; - break; - case 0x8: - result = HSO_PORT_GPS; - break; - case 0x10: - result = HSO_PORT_APP2; - break; - default: - result = HSO_PORT_NO_PORT; - } - return result; -} - -/* converts port spec value to a mux value */ -static u32 hso_port_to_mux(int port) -{ - u32 result; - - switch (port & HSO_PORT_MASK) { - case HSO_PORT_CONTROL: - result = 0x0; - break; - case HSO_PORT_APP: - result = 0x1; - break; - case HSO_PORT_PCSC: - result = 0x2; - break; - case HSO_PORT_GPS: - result = 0x3; - break; - case HSO_PORT_APP2: - result = 0x4; - break; - default: - result = 0x0; - } - return result; -} - -static struct hso_serial *get_serial_by_shared_int_and_type( - struct hso_shared_int *shared_int, - int mux) -{ - int i, port; - - port = hso_mux_to_port(mux); - - for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { - if (serial_table[i] - && (dev2ser(serial_table[i])->shared_int == shared_int) - && ((serial_table[i]->port_spec & HSO_PORT_MASK) == port)) { - return dev2ser(serial_table[i]); - } - } - - return NULL; -} - -static struct hso_serial *get_serial_by_index(unsigned index) -{ - struct hso_serial *serial; - unsigned long flags; - - if (!serial_table[index]) - return NULL; - spin_lock_irqsave(&serial_table_lock, flags); - serial = dev2ser(serial_table[index]); - spin_unlock_irqrestore(&serial_table_lock, flags); - - return serial; -} - -static int get_free_serial_index(void) -{ - int index; - unsigned long flags; - - spin_lock_irqsave(&serial_table_lock, flags); - for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) { - if (serial_table[index] == NULL) { - spin_unlock_irqrestore(&serial_table_lock, flags); - return index; - } - } - spin_unlock_irqrestore(&serial_table_lock, flags); - - printk(KERN_ERR "%s: no free serial devices in table\n", __func__); - return -1; -} - -static void set_serial_by_index(unsigned index, struct hso_serial *serial) -{ - unsigned long flags; - spin_lock_irqsave(&serial_table_lock, flags); - if (serial) - serial_table[index] = serial->parent; - else - serial_table[index] = NULL; - spin_unlock_irqrestore(&serial_table_lock, flags); -} - -/* log a meaningfull explanation of an USB status */ -static void log_usb_status(int status, const char *function) -{ - char *explanation; - - switch (status) { - case -ENODEV: - explanation = "no device"; - break; - case -ENOENT: - explanation = "endpoint not enabled"; - break; - case -EPIPE: - explanation = "endpoint stalled"; - break; - case -ENOSPC: - explanation = "not enough bandwidth"; - break; - case -ESHUTDOWN: - explanation = "device disabled"; - break; - case -EHOSTUNREACH: - explanation = "device suspended"; - break; - case -EINVAL: - case -EAGAIN: - case -EFBIG: - case -EMSGSIZE: - explanation = "internal error"; - break; - default: - explanation = "unknown status"; - break; - } - D1("%s: received USB status - %s (%d)", function, explanation, status); -} - -/* Network interface functions */ - -/* called when net interface is brought up by ifconfig */ -static int hso_net_open(struct net_device *net) -{ - struct hso_net *odev = netdev_priv(net); - unsigned long flags = 0; - - if (!odev) { - dev_err(&net->dev, "No net device !\n"); - return -ENODEV; - } - - odev->skb_tx_buf = NULL; - - /* setup environment */ - spin_lock_irqsave(&odev->net_lock, flags); - odev->rx_parse_state = WAIT_IP; - odev->rx_buf_size = 0; - odev->rx_buf_missing = sizeof(struct iphdr); - spin_unlock_irqrestore(&odev->net_lock, flags); - - hso_start_net_device(odev->parent); - - /* We are up and running. */ - set_bit(HSO_NET_RUNNING, &odev->flags); - - /* Tell the kernel we are ready to start receiving from it */ - netif_start_queue(net); - - return 0; -} - -/* called when interface is brought down by ifconfig */ -static int hso_net_close(struct net_device *net) -{ - struct hso_net *odev = netdev_priv(net); - - /* we don't need the queue anymore */ - netif_stop_queue(net); - /* no longer running */ - clear_bit(HSO_NET_RUNNING, &odev->flags); - - hso_stop_net_device(odev->parent); - - /* done */ - return 0; -} - -/* USB tells is xmit done, we should start the netqueue again */ -static void write_bulk_callback(struct urb *urb) -{ - struct hso_net *odev = urb->context; - int status = urb->status; - - /* Sanity check */ - if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) { - dev_err(&urb->dev->dev, "%s: device not running\n", __func__); - return; - } - - /* Do we still have a valid kernel network device? */ - if (!netif_device_present(odev->net)) { - dev_err(&urb->dev->dev, "%s: net device not present\n", - __func__); - return; - } - - /* log status, but don't act on it, we don't need to resubmit anything - * anyhow */ - if (status) - log_usb_status(status, __func__); - - hso_put_activity(odev->parent); - - /* Tell the network interface we are ready for another frame */ - netif_wake_queue(odev->net); -} - -/* called by kernel when we need to transmit a packet */ -static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net) -{ - struct hso_net *odev = netdev_priv(net); - int result; - - /* Tell the kernel, "No more frames 'til we are done with this one." */ - netif_stop_queue(net); - if (hso_get_activity(odev->parent) == -EAGAIN) { - odev->skb_tx_buf = skb; - return 0; - } - - /* log if asked */ - DUMP1(skb->data, skb->len); - /* Copy it from kernel memory to OUR memory */ - memcpy(odev->mux_bulk_tx_buf, skb->data, skb->len); - D1("len: %d/%d", skb->len, MUX_BULK_TX_BUF_SIZE); - - /* Fill in the URB for shipping it out. */ - usb_fill_bulk_urb(odev->mux_bulk_tx_urb, - odev->parent->usb, - usb_sndbulkpipe(odev->parent->usb, - odev->out_endp-> - bEndpointAddress & 0x7F), - odev->mux_bulk_tx_buf, skb->len, write_bulk_callback, - odev); - - /* Deal with the Zero Length packet problem, I hope */ - odev->mux_bulk_tx_urb->transfer_flags |= URB_ZERO_PACKET; - - /* Send the URB on its merry way. */ - result = usb_submit_urb(odev->mux_bulk_tx_urb, GFP_ATOMIC); - if (result) { - dev_warn(&odev->parent->interface->dev, - "failed mux_bulk_tx_urb %d", result); - net->stats.tx_errors++; - netif_start_queue(net); - } else { - net->stats.tx_packets++; - net->stats.tx_bytes += skb->len; - /* And tell the kernel when the last transmit started. */ - net->trans_start = jiffies; - } - dev_kfree_skb(skb); - /* we're done */ - return result; -} - -static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) -{ - struct hso_net *odev = netdev_priv(net); - - strncpy(info->driver, driver_name, ETHTOOL_BUSINFO_LEN); - strncpy(info->version, DRIVER_VERSION, ETHTOOL_BUSINFO_LEN); - usb_make_path(odev->parent->usb, info->bus_info, sizeof info->bus_info); -} - -static struct ethtool_ops ops = { - .get_drvinfo = hso_get_drvinfo, - .get_link = ethtool_op_get_link -}; - -/* called when a packet did not ack after watchdogtimeout */ -static void hso_net_tx_timeout(struct net_device *net) -{ - struct hso_net *odev = netdev_priv(net); - - if (!odev) - return; - - /* Tell syslog we are hosed. */ - dev_warn(&net->dev, "Tx timed out.\n"); - - /* Tear the waiting frame off the list */ - if (odev->mux_bulk_tx_urb - && (odev->mux_bulk_tx_urb->status == -EINPROGRESS)) - usb_unlink_urb(odev->mux_bulk_tx_urb); - - /* Update statistics */ - net->stats.tx_errors++; -} - -/* make a real packet from the received USB buffer */ -static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, - unsigned int count, unsigned char is_eop) -{ - unsigned short temp_bytes; - unsigned short buffer_offset = 0; - unsigned short frame_len; - unsigned char *tmp_rx_buf; - - /* log if needed */ - D1("Rx %d bytes", count); - DUMP(ip_pkt, min(128, (int)count)); - - while (count) { - switch (odev->rx_parse_state) { - case WAIT_IP: - /* waiting for IP header. */ - /* wanted bytes - size of ip header */ - temp_bytes = - (count < - odev->rx_buf_missing) ? count : odev-> - rx_buf_missing; - - memcpy(((unsigned char *)(&odev->rx_ip_hdr)) + - odev->rx_buf_size, ip_pkt + buffer_offset, - temp_bytes); - - odev->rx_buf_size += temp_bytes; - buffer_offset += temp_bytes; - odev->rx_buf_missing -= temp_bytes; - count -= temp_bytes; - - if (!odev->rx_buf_missing) { - /* header is complete allocate an sk_buffer and - * continue to WAIT_DATA */ - frame_len = ntohs(odev->rx_ip_hdr.tot_len); - - if ((frame_len > DEFAULT_MRU) || - (frame_len < sizeof(struct iphdr))) { - dev_err(&odev->net->dev, - "Invalid frame (%d) length\n", - frame_len); - odev->rx_parse_state = WAIT_SYNC; - continue; - } - /* Allocate an sk_buff */ - odev->skb_rx_buf = dev_alloc_skb(frame_len); - if (!odev->skb_rx_buf) { - /* We got no receive buffer. */ - D1("could not allocate memory"); - odev->rx_parse_state = WAIT_SYNC; - return; - } - /* Here's where it came from */ - odev->skb_rx_buf->dev = odev->net; - - /* Copy what we got so far. make room for iphdr - * after tail. */ - tmp_rx_buf = - skb_put(odev->skb_rx_buf, - sizeof(struct iphdr)); - memcpy(tmp_rx_buf, (char *)&(odev->rx_ip_hdr), - sizeof(struct iphdr)); - - /* ETH_HLEN */ - odev->rx_buf_size = sizeof(struct iphdr); - - /* Filip actually use .tot_len */ - odev->rx_buf_missing = - frame_len - sizeof(struct iphdr); - odev->rx_parse_state = WAIT_DATA; - } - break; - - case WAIT_DATA: - temp_bytes = (count < odev->rx_buf_missing) - ? count : odev->rx_buf_missing; - - /* Copy the rest of the bytes that are left in the - * buffer into the waiting sk_buf. */ - /* Make room for temp_bytes after tail. */ - tmp_rx_buf = skb_put(odev->skb_rx_buf, temp_bytes); - memcpy(tmp_rx_buf, ip_pkt + buffer_offset, temp_bytes); - - odev->rx_buf_missing -= temp_bytes; - count -= temp_bytes; - buffer_offset += temp_bytes; - odev->rx_buf_size += temp_bytes; - if (!odev->rx_buf_missing) { - /* Packet is complete. Inject into stack. */ - /* We have IP packet here */ - odev->skb_rx_buf->protocol = - __constant_htons(ETH_P_IP); - /* don't check it */ - odev->skb_rx_buf->ip_summed = - CHECKSUM_UNNECESSARY; - - skb_reset_mac_header(odev->skb_rx_buf); - - /* Ship it off to the kernel */ - netif_rx(odev->skb_rx_buf); - /* No longer our buffer. */ - odev->skb_rx_buf = NULL; - - /* update out statistics */ - odev->net->stats.rx_packets++; - - odev->net->stats.rx_bytes += odev->rx_buf_size; - - odev->rx_buf_size = 0; - odev->rx_buf_missing = sizeof(struct iphdr); - odev->rx_parse_state = WAIT_IP; - } - break; - - case WAIT_SYNC: - D1(" W_S"); - count = 0; - break; - default: - D1(" "); - count--; - break; - } - } - - /* Recovery mechanism for WAIT_SYNC state. */ - if (is_eop) { - if (odev->rx_parse_state == WAIT_SYNC) { - odev->rx_parse_state = WAIT_IP; - odev->rx_buf_size = 0; - odev->rx_buf_missing = sizeof(struct iphdr); - } - } -} - -/* Moving data from usb to kernel (in interrupt state) */ -static void read_bulk_callback(struct urb *urb) -{ - struct hso_net *odev = urb->context; - struct net_device *net; - int result; - int status = urb->status; - - /* is al ok? (Filip: Who's Al ?) */ - if (status) { - log_usb_status(status, __func__); - return; - } - - /* Sanity check */ - if (!odev || !test_bit(HSO_NET_RUNNING, &odev->flags)) { - D1("BULK IN callback but driver is not active!"); - return; - } - usb_mark_last_busy(urb->dev); - - net = odev->net; - - if (!netif_device_present(net)) { - /* Somebody killed our network interface... */ - return; - } - - if (odev->parent->port_spec & HSO_INFO_CRC_BUG) { - u32 rest; - u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = urb->actual_length % odev->in_endp->wMaxPacketSize; - if (((rest == 5) || (rest == 6)) - && !memcmp(((u8 *) urb->transfer_buffer) + - urb->actual_length - 4, crc_check, 4)) { - urb->actual_length -= 4; - } - } - - /* do we even have a packet? */ - if (urb->actual_length) { - /* Handle the IP stream, add header and push it onto network - * stack if the packet is complete. */ - spin_lock(&odev->net_lock); - packetizeRx(odev, urb->transfer_buffer, urb->actual_length, - (urb->transfer_buffer_length > - urb->actual_length) ? 1 : 0); - spin_unlock(&odev->net_lock); - } - - /* We are done with this URB, resubmit it. Prep the USB to wait for - * another frame. Reuse same as received. */ - usb_fill_bulk_urb(urb, - odev->parent->usb, - usb_rcvbulkpipe(odev->parent->usb, - odev->in_endp-> - bEndpointAddress & 0x7F), - urb->transfer_buffer, MUX_BULK_RX_BUF_SIZE, - read_bulk_callback, odev); - - /* Give this to the USB subsystem so it can tell us when more data - * arrives. */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) - dev_warn(&odev->parent->interface->dev, - "%s failed submit mux_bulk_rx_urb %d", __func__, - result); -} - -/* Serial driver functions */ - -static void _hso_serial_set_termios(struct tty_struct *tty, - struct ktermios *old) -{ - struct hso_serial *serial = get_serial_by_tty(tty); - struct ktermios *termios; - - if ((!tty) || (!tty->termios) || (!serial)) { - printk(KERN_ERR "%s: no tty structures", __func__); - return; - } - - D4("port %d", serial->minor); - - /* - * The default requirements for this device are: - */ - termios = tty->termios; - termios->c_iflag &= - ~(IGNBRK /* disable ignore break */ - | BRKINT /* disable break causes interrupt */ - | PARMRK /* disable mark parity errors */ - | ISTRIP /* disable clear high bit of input characters */ - | INLCR /* disable translate NL to CR */ - | IGNCR /* disable ignore CR */ - | ICRNL /* disable translate CR to NL */ - | IXON); /* disable enable XON/XOFF flow control */ - - /* disable postprocess output characters */ - termios->c_oflag &= ~OPOST; - - termios->c_lflag &= - ~(ECHO /* disable echo input characters */ - | ECHONL /* disable echo new line */ - | ICANON /* disable erase, kill, werase, and rprnt - special characters */ - | ISIG /* disable interrupt, quit, and suspend special - characters */ - | IEXTEN); /* disable non-POSIX special characters */ - - termios->c_cflag &= - ~(CSIZE /* no size */ - | PARENB /* disable parity bit */ - | CBAUD /* clear current baud rate */ - | CBAUDEX); /* clear current buad rate */ - - termios->c_cflag |= CS8; /* character size 8 bits */ - - /* baud rate 115200 */ - tty_encode_baud_rate(serial->tty, 115200, 115200); - - /* - * Force low_latency on; otherwise the pushes are scheduled; - * this is bad as it opens up the possibility of dropping bytes - * on the floor. We don't want to drop bytes on the floor. :) - */ - serial->tty->low_latency = 1; - return; -} - -/* open the requested serial port */ -static int hso_serial_open(struct tty_struct *tty, struct file *filp) -{ - struct hso_serial *serial = get_serial_by_index(tty->index); - int result; - - /* sanity check */ - if (serial == NULL || serial->magic != HSO_SERIAL_MAGIC) { - tty->driver_data = NULL; - D1("Failed to open port"); - return -ENODEV; - } - - mutex_lock(&serial->parent->mutex); - result = usb_autopm_get_interface(serial->parent->interface); - if (result < 0) - goto err_out; - - D1("Opening %d", serial->minor); - kref_get(&serial->parent->ref); - - /* setup */ - tty->driver_data = serial; - serial->tty = tty; - - /* check for port allready opened, if not set the termios */ - serial->open_count++; - if (serial->open_count == 1) { - tty->low_latency = 1; - serial->flags = 0; - /* Force default termio settings */ - _hso_serial_set_termios(tty, NULL); - result = hso_start_serial_device(serial->parent, GFP_KERNEL); - if (result) { - hso_stop_serial_device(serial->parent); - serial->open_count--; - kref_put(&serial->parent->ref, hso_serial_ref_free); - } - } else { - D1("Port was already open"); - } - - usb_autopm_put_interface(serial->parent->interface); - - /* done */ - if (result) - hso_serial_tiocmset(tty, NULL, TIOCM_RTS | TIOCM_DTR, 0); -err_out: - mutex_unlock(&serial->parent->mutex); - return result; -} - -/* close the requested serial port */ -static void hso_serial_close(struct tty_struct *tty, struct file *filp) -{ - struct hso_serial *serial = tty->driver_data; - u8 usb_gone; - - D1("Closing serial port"); - - mutex_lock(&serial->parent->mutex); - usb_gone = serial->parent->usb_gone; - - if (!usb_gone) - usb_autopm_get_interface(serial->parent->interface); - - /* reset the rts and dtr */ - /* do the actual close */ - serial->open_count--; - if (serial->open_count <= 0) { - kref_put(&serial->parent->ref, hso_serial_ref_free); - serial->open_count = 0; - if (serial->tty) { - serial->tty->driver_data = NULL; - serial->tty = NULL; - } - if (!usb_gone) - hso_stop_serial_device(serial->parent); - } - if (!usb_gone) - usb_autopm_put_interface(serial->parent->interface); - mutex_unlock(&serial->parent->mutex); -} - -/* close the requested serial port */ -static int hso_serial_write(struct tty_struct *tty, const unsigned char *buf, - int count) -{ - struct hso_serial *serial = get_serial_by_tty(tty); - int space, tx_bytes; - unsigned long flags; - - /* sanity check */ - if (serial == NULL) { - printk(KERN_ERR "%s: serial is NULL\n", __func__); - return -ENODEV; - } - - spin_lock_irqsave(&serial->serial_lock, flags); - - space = serial->tx_data_length - serial->tx_buffer_count; - tx_bytes = (count < space) ? count : space; - - if (!tx_bytes) - goto out; - - memcpy(serial->tx_buffer + serial->tx_buffer_count, buf, tx_bytes); - serial->tx_buffer_count += tx_bytes; - -out: - spin_unlock_irqrestore(&serial->serial_lock, flags); - - hso_kick_transmit(serial); - /* done */ - return tx_bytes; -} - -/* how much room is there for writing */ -static int hso_serial_write_room(struct tty_struct *tty) -{ - struct hso_serial *serial = get_serial_by_tty(tty); - int room; - unsigned long flags; - - spin_lock_irqsave(&serial->serial_lock, flags); - room = serial->tx_data_length - serial->tx_buffer_count; - spin_unlock_irqrestore(&serial->serial_lock, flags); - - /* return free room */ - return room; -} - -/* setup the term */ -static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) -{ - struct hso_serial *serial = get_serial_by_tty(tty); - unsigned long flags; - - if (old) - D5("Termios called with: cflags new[%d] - old[%d]", - tty->termios->c_cflag, old->c_cflag); - - /* the actual setup */ - spin_lock_irqsave(&serial->serial_lock, flags); - if (serial->open_count) - _hso_serial_set_termios(tty, old); - else - tty->termios = old; - spin_unlock_irqrestore(&serial->serial_lock, flags); - - /* done */ - return; -} - -/* how many characters in the buffer */ -static int hso_serial_chars_in_buffer(struct tty_struct *tty) -{ - struct hso_serial *serial = get_serial_by_tty(tty); - int chars; - unsigned long flags; - - /* sanity check */ - if (serial == NULL) - return 0; - - spin_lock_irqsave(&serial->serial_lock, flags); - chars = serial->tx_buffer_count; - spin_unlock_irqrestore(&serial->serial_lock, flags); - - return chars; -} - -static int hso_serial_tiocmget(struct tty_struct *tty, struct file *file) -{ - unsigned int value; - struct hso_serial *serial = get_serial_by_tty(tty); - unsigned long flags; - - /* sanity check */ - if (!serial) { - D1("no tty structures"); - return -EINVAL; - } - - spin_lock_irqsave(&serial->serial_lock, flags); - value = ((serial->rts_state) ? TIOCM_RTS : 0) | - ((serial->dtr_state) ? TIOCM_DTR : 0); - spin_unlock_irqrestore(&serial->serial_lock, flags); - - return value; -} - -static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, - unsigned int set, unsigned int clear) -{ - int val = 0; - unsigned long flags; - int if_num; - struct hso_serial *serial = get_serial_by_tty(tty); - - /* sanity check */ - if (!serial) { - D1("no tty structures"); - return -EINVAL; - } - if_num = serial->parent->interface->altsetting->desc.bInterfaceNumber; - - spin_lock_irqsave(&serial->serial_lock, flags); - if (set & TIOCM_RTS) - serial->rts_state = 1; - if (set & TIOCM_DTR) - serial->dtr_state = 1; - - if (clear & TIOCM_RTS) - serial->rts_state = 0; - if (clear & TIOCM_DTR) - serial->dtr_state = 0; - - if (serial->dtr_state) - val |= 0x01; - if (serial->rts_state) - val |= 0x02; - - spin_unlock_irqrestore(&serial->serial_lock, flags); - - return usb_control_msg(serial->parent->usb, - usb_rcvctrlpipe(serial->parent->usb, 0), 0x22, - 0x21, val, if_num, NULL, 0, - USB_CTRL_SET_TIMEOUT); -} - -/* starts a transmit */ -static void hso_kick_transmit(struct hso_serial *serial) -{ - u8 *temp; - unsigned long flags; - int res; - - spin_lock_irqsave(&serial->serial_lock, flags); - if (!serial->tx_buffer_count) - goto out; - - if (serial->tx_urb_used) - goto out; - - /* Wakeup USB interface if necessary */ - if (hso_get_activity(serial->parent) == -EAGAIN) - goto out; - - /* Switch pointers around to avoid memcpy */ - temp = serial->tx_buffer; - serial->tx_buffer = serial->tx_data; - serial->tx_data = temp; - serial->tx_data_count = serial->tx_buffer_count; - serial->tx_buffer_count = 0; - - /* If temp is set, it means we switched buffers */ - if (temp && serial->write_data) { - res = serial->write_data(serial); - if (res >= 0) - serial->tx_urb_used = 1; - } -out: - spin_unlock_irqrestore(&serial->serial_lock, flags); -} - -/* make a request (for reading and writing data to muxed serial port) */ -static int mux_device_request(struct hso_serial *serial, u8 type, u16 port, - struct urb *ctrl_urb, - struct usb_ctrlrequest *ctrl_req, - u8 *ctrl_urb_data, u32 size) -{ - int result; - int pipe; - - /* Sanity check */ - if (!serial || !ctrl_urb || !ctrl_req) { - printk(KERN_ERR "%s: Wrong arguments\n", __func__); - return -EINVAL; - } - - /* initialize */ - ctrl_req->wValue = 0; - ctrl_req->wIndex = hso_port_to_mux(port); - ctrl_req->wLength = size; - - if (type == USB_CDC_GET_ENCAPSULATED_RESPONSE) { - /* Reading command */ - ctrl_req->bRequestType = USB_DIR_IN | - USB_TYPE_OPTION_VENDOR | - USB_RECIP_INTERFACE; - ctrl_req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; - pipe = usb_rcvctrlpipe(serial->parent->usb, 0); - } else { - /* Writing command */ - ctrl_req->bRequestType = USB_DIR_OUT | - USB_TYPE_OPTION_VENDOR | - USB_RECIP_INTERFACE; - ctrl_req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; - pipe = usb_sndctrlpipe(serial->parent->usb, 0); - } - /* syslog */ - D2("%s command (%02x) len: %d, port: %d", - type == USB_CDC_GET_ENCAPSULATED_RESPONSE ? "Read" : "Write", - ctrl_req->bRequestType, ctrl_req->wLength, port); - - /* Load ctrl urb */ - ctrl_urb->transfer_flags = 0; - usb_fill_control_urb(ctrl_urb, - serial->parent->usb, - pipe, - (u8 *) ctrl_req, - ctrl_urb_data, size, ctrl_callback, serial); - /* Send it on merry way */ - result = usb_submit_urb(ctrl_urb, GFP_ATOMIC); - if (result) { - dev_err(&ctrl_urb->dev->dev, - "%s failed submit ctrl_urb %d type %d", __func__, - result, type); - return result; - } - - /* done */ - return size; -} - -/* called by intr_callback when read occurs */ -static int hso_mux_serial_read(struct hso_serial *serial) -{ - if (!serial) - return -EINVAL; - - /* clean data */ - memset(serial->rx_data[0], 0, CTRL_URB_RX_SIZE); - /* make the request */ - - if (serial->num_rx_urbs != 1) { - dev_err(&serial->parent->interface->dev, - "ERROR: mux'd reads with multiple buffers " - "not possible\n"); - return 0; - } - return mux_device_request(serial, - USB_CDC_GET_ENCAPSULATED_RESPONSE, - serial->parent->port_spec & HSO_PORT_MASK, - serial->rx_urb[0], - &serial->ctrl_req_rx, - serial->rx_data[0], serial->rx_data_length); -} - -/* used for muxed serial port callback (muxed serial read) */ -static void intr_callback(struct urb *urb) -{ - struct hso_shared_int *shared_int = urb->context; - struct hso_serial *serial; - unsigned char *port_req; - int status = urb->status; - int i; - - usb_mark_last_busy(urb->dev); - - /* sanity check */ - if (!shared_int) - return; - - /* status check */ - if (status) { - log_usb_status(status, __func__); - return; - } - D4("\n--- Got intr callback 0x%02X ---", status); - - /* what request? */ - port_req = urb->transfer_buffer; - D4(" port_req = 0x%.2X\n", *port_req); - /* loop over all muxed ports to find the one sending this */ - for (i = 0; i < 8; i++) { - /* max 8 channels on MUX */ - if (*port_req & (1 << i)) { - serial = get_serial_by_shared_int_and_type(shared_int, - (1 << i)); - if (serial != NULL) { - D1("Pending read interrupt on port %d\n", i); - if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT, - &serial->flags)) { - /* Setup and send a ctrl req read on - * port i */ - hso_mux_serial_read(serial); - } else { - D1("Already pending a read on " - "port %d\n", i); - } - } - } - } - /* Resubmit interrupt urb */ - hso_mux_submit_intr_urb(shared_int, urb->dev, GFP_ATOMIC); -} - -/* called for writing to muxed serial port */ -static int hso_mux_serial_write_data(struct hso_serial *serial) -{ - if (NULL == serial) - return -EINVAL; - - return mux_device_request(serial, - USB_CDC_SEND_ENCAPSULATED_COMMAND, - serial->parent->port_spec & HSO_PORT_MASK, - serial->tx_urb, - &serial->ctrl_req_tx, - serial->tx_data, serial->tx_data_count); -} - -/* write callback for Diag and CS port */ -static void hso_std_serial_write_bulk_callback(struct urb *urb) -{ - struct hso_serial *serial = urb->context; - int status = urb->status; - - /* sanity check */ - if (!serial) { - D1("serial == NULL"); - return; - } - - spin_lock(&serial->serial_lock); - serial->tx_urb_used = 0; - spin_unlock(&serial->serial_lock); - if (status) { - log_usb_status(status, __func__); - return; - } - hso_put_activity(serial->parent); - tty_wakeup(serial->tty); - hso_kick_transmit(serial); - - D1(" "); - return; -} - -/* called for writing diag or CS serial port */ -static int hso_std_serial_write_data(struct hso_serial *serial) -{ - int count = serial->tx_data_count; - int result; - - usb_fill_bulk_urb(serial->tx_urb, - serial->parent->usb, - usb_sndbulkpipe(serial->parent->usb, - serial->out_endp-> - bEndpointAddress & 0x7F), - serial->tx_data, serial->tx_data_count, - hso_std_serial_write_bulk_callback, serial); - - result = usb_submit_urb(serial->tx_urb, GFP_ATOMIC); - if (result) { - dev_warn(&serial->parent->usb->dev, - "Failed to submit urb - res %d\n", result); - return result; - } - - return count; -} - -/* callback after read or write on muxed serial port */ -static void ctrl_callback(struct urb *urb) -{ - struct hso_serial *serial = urb->context; - struct usb_ctrlrequest *req; - int status = urb->status; - - /* sanity check */ - if (!serial) - return; - - spin_lock(&serial->serial_lock); - serial->tx_urb_used = 0; - spin_unlock(&serial->serial_lock); - if (status) { - log_usb_status(status, __func__); - return; - } - - /* what request? */ - req = (struct usb_ctrlrequest *)(urb->setup_packet); - D4("\n--- Got muxed ctrl callback 0x%02X ---", status); - D4("Actual length of urb = %d\n", urb->actual_length); - DUMP1(urb->transfer_buffer, urb->actual_length); - - if (req->bRequestType == - (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) { - /* response to a read command */ - if (serial->open_count > 0) { - /* handle RX data the normal way */ - put_rxbuf_data(urb, serial); - } - - /* Re issue a read as long as we receive data. */ - if (urb->actual_length != 0) - hso_mux_serial_read(serial); - else - clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags); - } else { - hso_put_activity(serial->parent); - tty_wakeup(serial->tty); - /* response to a write command */ - hso_kick_transmit(serial); - } -} - -/* handle RX data for serial port */ -static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial) -{ - struct tty_struct *tty = serial->tty; - - /* Sanity check */ - if (urb == NULL || serial == NULL) { - D1("serial = NULL"); - return; - } - - /* Push data to tty */ - if (tty && urb->actual_length) { - D1("data to push to tty"); - tty_insert_flip_string(tty, urb->transfer_buffer, - urb->actual_length); - tty_flip_buffer_push(tty); - } -} - -/* read callback for Diag and CS port */ -static void hso_std_serial_read_bulk_callback(struct urb *urb) -{ - struct hso_serial *serial = urb->context; - int result; - int status = urb->status; - - /* sanity check */ - if (!serial) { - D1("serial == NULL"); - return; - } else if (status) { - log_usb_status(status, __func__); - return; - } - - D4("\n--- Got serial_read_bulk callback %02x ---", status); - D1("Actual length = %d\n", urb->actual_length); - DUMP1(urb->transfer_buffer, urb->actual_length); - - /* Anyone listening? */ - if (serial->open_count == 0) - return; - - if (status == 0) { - if (serial->parent->port_spec & HSO_INFO_CRC_BUG) { - u32 rest; - u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = - urb->actual_length % - serial->in_endp->wMaxPacketSize; - if (((rest == 5) || (rest == 6)) - && !memcmp(((u8 *) urb->transfer_buffer) + - urb->actual_length - 4, crc_check, 4)) { - urb->actual_length -= 4; - } - } - /* Valid data, handle RX data */ - put_rxbuf_data(urb, serial); - } else if (status == -ENOENT || status == -ECONNRESET) { - /* Unlinked - check for throttled port. */ - D2("Port %d, successfully unlinked urb", serial->minor); - } else { - D2("Port %d, status = %d for read urb", serial->minor, status); - return; - } - - usb_mark_last_busy(urb->dev); - - /* We are done with this URB, resubmit it. Prep the USB to wait for - * another frame */ - usb_fill_bulk_urb(urb, serial->parent->usb, - usb_rcvbulkpipe(serial->parent->usb, - serial->in_endp-> - bEndpointAddress & 0x7F), - urb->transfer_buffer, serial->rx_data_length, - hso_std_serial_read_bulk_callback, serial); - /* Give this to the USB subsystem so it can tell us when more data - * arrives. */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d", - __func__, result); - } -} - -/* Base driver functions */ - -static void hso_log_port(struct hso_device *hso_dev) -{ - char *port_type; - char port_dev[20]; - - switch (hso_dev->port_spec & HSO_PORT_MASK) { - case HSO_PORT_CONTROL: - port_type = "Control"; - break; - case HSO_PORT_APP: - port_type = "Application"; - break; - case HSO_PORT_GPS: - port_type = "GPS"; - break; - case HSO_PORT_GPS_CONTROL: - port_type = "GPS control"; - break; - case HSO_PORT_APP2: - port_type = "Application2"; - break; - case HSO_PORT_PCSC: - port_type = "PCSC"; - break; - case HSO_PORT_DIAG: - port_type = "Diagnostic"; - break; - case HSO_PORT_DIAG2: - port_type = "Diagnostic2"; - break; - case HSO_PORT_MODEM: - port_type = "Modem"; - break; - case HSO_PORT_NETWORK: - port_type = "Network"; - break; - default: - port_type = "Unknown"; - break; - } - if ((hso_dev->port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { - sprintf(port_dev, "%s", dev2net(hso_dev)->net->name); - } else - sprintf(port_dev, "/dev/%s%d", tty_filename, - dev2ser(hso_dev)->minor); - - dev_dbg(&hso_dev->interface->dev, "HSO: Found %s port %s\n", - port_type, port_dev); -} - -static int hso_start_net_device(struct hso_device *hso_dev) -{ - int i, result = 0; - struct hso_net *hso_net = dev2net(hso_dev); - - if (!hso_net) - return -ENODEV; - - /* send URBs for all read buffers */ - for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { - - /* Prep a receive URB */ - usb_fill_bulk_urb(hso_net->mux_bulk_rx_urb_pool[i], - hso_dev->usb, - usb_rcvbulkpipe(hso_dev->usb, - hso_net->in_endp-> - bEndpointAddress & 0x7F), - hso_net->mux_bulk_rx_buf_pool[i], - MUX_BULK_RX_BUF_SIZE, read_bulk_callback, - hso_net); - - /* Put it out there so the device can send us stuff */ - result = usb_submit_urb(hso_net->mux_bulk_rx_urb_pool[i], - GFP_NOIO); - if (result) - dev_warn(&hso_dev->usb->dev, - "%s failed mux_bulk_rx_urb[%d] %d\n", __func__, - i, result); - } - - return result; -} - -static int hso_stop_net_device(struct hso_device *hso_dev) -{ - int i; - struct hso_net *hso_net = dev2net(hso_dev); - - if (!hso_net) - return -ENODEV; - - for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { - if (hso_net->mux_bulk_rx_urb_pool[i]) - usb_kill_urb(hso_net->mux_bulk_rx_urb_pool[i]); - - } - if (hso_net->mux_bulk_tx_urb) - usb_kill_urb(hso_net->mux_bulk_tx_urb); - - return 0; -} - -static int hso_start_serial_device(struct hso_device *hso_dev, gfp_t flags) -{ - int i, result = 0; - struct hso_serial *serial = dev2ser(hso_dev); - - if (!serial) - return -ENODEV; - - /* If it is not the MUX port fill in and submit a bulk urb (already - * allocated in hso_serial_start) */ - if (!(serial->parent->port_spec & HSO_INTF_MUX)) { - for (i = 0; i < serial->num_rx_urbs; i++) { - usb_fill_bulk_urb(serial->rx_urb[i], - serial->parent->usb, - usb_rcvbulkpipe(serial->parent->usb, - serial->in_endp-> - bEndpointAddress & - 0x7F), - serial->rx_data[i], - serial->rx_data_length, - hso_std_serial_read_bulk_callback, - serial); - result = usb_submit_urb(serial->rx_urb[i], flags); - if (result) { - dev_warn(&serial->parent->usb->dev, - "Failed to submit urb - res %d\n", - result); - break; - } - } - } else { - mutex_lock(&serial->shared_int->shared_int_lock); - if (!serial->shared_int->use_count) { - result = - hso_mux_submit_intr_urb(serial->shared_int, - hso_dev->usb, flags); - } - serial->shared_int->use_count++; - mutex_unlock(&serial->shared_int->shared_int_lock); - } - - return result; -} - -static int hso_stop_serial_device(struct hso_device *hso_dev) -{ - int i; - struct hso_serial *serial = dev2ser(hso_dev); - - if (!serial) - return -ENODEV; - - for (i = 0; i < serial->num_rx_urbs; i++) { - if (serial->rx_urb[i]) - usb_kill_urb(serial->rx_urb[i]); - } - - if (serial->tx_urb) - usb_kill_urb(serial->tx_urb); - - if (serial->shared_int) { - mutex_lock(&serial->shared_int->shared_int_lock); - if (serial->shared_int->use_count && - (--serial->shared_int->use_count == 0)) { - struct urb *urb; - - urb = serial->shared_int->shared_intr_urb; - if (urb) - usb_kill_urb(urb); - } - mutex_unlock(&serial->shared_int->shared_int_lock); - } - - return 0; -} - -static void hso_serial_common_free(struct hso_serial *serial) -{ - int i; - - if (serial->parent->dev) - device_remove_file(serial->parent->dev, &dev_attr_hsotype); - - tty_unregister_device(tty_drv, serial->minor); - - for (i = 0; i < serial->num_rx_urbs; i++) { - /* unlink and free RX URB */ - usb_free_urb(serial->rx_urb[i]); - /* free the RX buffer */ - kfree(serial->rx_data[i]); - } - - /* unlink and free TX URB */ - usb_free_urb(serial->tx_urb); - kfree(serial->tx_data); -} - -static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, - int rx_size, int tx_size) -{ - struct device *dev; - int minor; - int i; - - minor = get_free_serial_index(); - if (minor < 0) - goto exit; - - /* register our minor number */ - serial->parent->dev = tty_register_device(tty_drv, minor, - &serial->parent->interface->dev); - dev = serial->parent->dev; - dev->driver_data = serial->parent; - i = device_create_file(dev, &dev_attr_hsotype); - - /* fill in specific data for later use */ - serial->minor = minor; - serial->magic = HSO_SERIAL_MAGIC; - spin_lock_init(&serial->serial_lock); - serial->num_rx_urbs = num_urbs; - - /* RX, allocate urb and initialize */ - - /* prepare our RX buffer */ - serial->rx_data_length = rx_size; - for (i = 0; i < serial->num_rx_urbs; i++) { - serial->rx_urb[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!serial->rx_urb[i]) { - dev_err(dev, "Could not allocate urb?\n"); - goto exit; - } - serial->rx_urb[i]->transfer_buffer = NULL; - serial->rx_urb[i]->transfer_buffer_length = 0; - serial->rx_data[i] = kzalloc(serial->rx_data_length, - GFP_KERNEL); - if (!serial->rx_data[i]) { - dev_err(dev, "%s - Out of memory\n", __func__); - goto exit; - } - } - - /* TX, allocate urb and initialize */ - serial->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!serial->tx_urb) { - dev_err(dev, "Could not allocate urb?\n"); - goto exit; - } - serial->tx_urb->transfer_buffer = NULL; - serial->tx_urb->transfer_buffer_length = 0; - /* prepare our TX buffer */ - serial->tx_data_count = 0; - serial->tx_buffer_count = 0; - serial->tx_data_length = tx_size; - serial->tx_data = kzalloc(serial->tx_data_length, GFP_KERNEL); - if (!serial->tx_data) { - dev_err(dev, "%s - Out of memory", __func__); - goto exit; - } - serial->tx_buffer = kzalloc(serial->tx_data_length, GFP_KERNEL); - if (!serial->tx_buffer) { - dev_err(dev, "%s - Out of memory", __func__); - goto exit; - } - - return 0; -exit: - hso_serial_common_free(serial); - return -1; -} - -/* Frees a general hso device */ -static void hso_free_device(struct hso_device *hso_dev) -{ - kfree(hso_dev); -} - -/* Creates a general hso device */ -static struct hso_device *hso_create_device(struct usb_interface *intf, - int port_spec) -{ - struct hso_device *hso_dev; - - hso_dev = kzalloc(sizeof(*hso_dev), GFP_ATOMIC); - if (!hso_dev) - return NULL; - - hso_dev->port_spec = port_spec; - hso_dev->usb = interface_to_usbdev(intf); - hso_dev->interface = intf; - kref_init(&hso_dev->ref); - mutex_init(&hso_dev->mutex); - - INIT_WORK(&hso_dev->async_get_intf, async_get_intf); - INIT_WORK(&hso_dev->async_put_intf, async_put_intf); - - return hso_dev; -} - -/* Removes a network device in the network device table */ -static int remove_net_device(struct hso_device *hso_dev) -{ - int i; - - for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { - if (network_table[i] == hso_dev) { - network_table[i] = NULL; - break; - } - } - if (i == HSO_MAX_NET_DEVICES) - return -1; - return 0; -} - -/* Frees our network device */ -static void hso_free_net_device(struct hso_device *hso_dev) -{ - int i; - struct hso_net *hso_net = dev2net(hso_dev); - - if (!hso_net) - return; - - /* start freeing */ - for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { - usb_free_urb(hso_net->mux_bulk_rx_urb_pool[i]); - kfree(hso_net->mux_bulk_rx_buf_pool[i]); - } - usb_free_urb(hso_net->mux_bulk_tx_urb); - kfree(hso_net->mux_bulk_tx_buf); - - remove_net_device(hso_net->parent); - - if (hso_net->net) { - unregister_netdev(hso_net->net); - free_netdev(hso_net->net); - } - - hso_free_device(hso_dev); -} - -/* initialize the network interface */ -static void hso_net_init(struct net_device *net) -{ - struct hso_net *hso_net = netdev_priv(net); - - D1("sizeof hso_net is %d", (int)sizeof(*hso_net)); - - /* fill in the other fields */ - net->open = hso_net_open; - net->stop = hso_net_close; - net->hard_start_xmit = hso_net_start_xmit; - net->tx_timeout = hso_net_tx_timeout; - net->watchdog_timeo = HSO_NET_TX_TIMEOUT; - net->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST; - net->type = ARPHRD_NONE; - net->mtu = DEFAULT_MTU - 14; - net->tx_queue_len = 10; - SET_ETHTOOL_OPS(net, &ops); - - /* and initialize the semaphore */ - spin_lock_init(&hso_net->net_lock); -} - -/* Adds a network device in the network device table */ -static int add_net_device(struct hso_device *hso_dev) -{ - int i; - - for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { - if (network_table[i] == NULL) { - network_table[i] = hso_dev; - break; - } - } - if (i == HSO_MAX_NET_DEVICES) - return -1; - return 0; -} - -static int hso_radio_toggle(void *data, enum rfkill_state state) -{ - struct hso_device *hso_dev = data; - int enabled = (state == RFKILL_STATE_ON); - int rv; - - mutex_lock(&hso_dev->mutex); - if (hso_dev->usb_gone) - rv = 0; - else - rv = usb_control_msg(hso_dev->usb, usb_rcvctrlpipe(hso_dev->usb, 0), - enabled ? 0x82 : 0x81, 0x40, 0, 0, NULL, 0, - USB_CTRL_SET_TIMEOUT); - mutex_unlock(&hso_dev->mutex); - return rv; -} - -/* Creates and sets up everything for rfkill */ -static void hso_create_rfkill(struct hso_device *hso_dev, - struct usb_interface *interface) -{ - struct hso_net *hso_net = dev2net(hso_dev); - struct device *dev = hso_dev->dev; - char *rfkn; - - hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev, - RFKILL_TYPE_WLAN); - if (!hso_net->rfkill) { - dev_err(dev, "%s - Out of memory", __func__); - return; - } - rfkn = kzalloc(20, GFP_KERNEL); - if (!rfkn) { - rfkill_free(hso_net->rfkill); - dev_err(dev, "%s - Out of memory", __func__); - return; - } - snprintf(rfkn, 20, "hso-%d", - interface->altsetting->desc.bInterfaceNumber); - hso_net->rfkill->name = rfkn; - hso_net->rfkill->state = RFKILL_STATE_ON; - hso_net->rfkill->data = hso_dev; - hso_net->rfkill->toggle_radio = hso_radio_toggle; - if (rfkill_register(hso_net->rfkill) < 0) { - kfree(rfkn); - hso_net->rfkill->name = NULL; - rfkill_free(hso_net->rfkill); - dev_err(dev, "%s - Failed to register rfkill", __func__); - return; - } -} - -/* Creates our network device */ -static struct hso_device *hso_create_net_device(struct usb_interface *interface) -{ - int result, i; - struct net_device *net; - struct hso_net *hso_net; - struct hso_device *hso_dev; - - hso_dev = hso_create_device(interface, HSO_INTF_MUX | HSO_PORT_NETWORK); - if (!hso_dev) - return NULL; - - /* allocate our network device, then we can put in our private data */ - /* call hso_net_init to do the basic initialization */ - net = alloc_netdev(sizeof(struct hso_net), "hso%d", hso_net_init); - if (!net) { - dev_err(&interface->dev, "Unable to create ethernet device\n"); - goto exit; - } - - hso_net = netdev_priv(net); - - hso_dev->port_data.dev_net = hso_net; - hso_net->net = net; - hso_net->parent = hso_dev; - - hso_net->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, - USB_DIR_IN); - if (!hso_net->in_endp) { - dev_err(&interface->dev, "Can't find BULK IN endpoint\n"); - goto exit; - } - hso_net->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, - USB_DIR_OUT); - if (!hso_net->out_endp) { - dev_err(&interface->dev, "Can't find BULK OUT endpoint\n"); - goto exit; - } - SET_NETDEV_DEV(net, &interface->dev); - - /* registering our net device */ - result = register_netdev(net); - if (result) { - dev_err(&interface->dev, "Failed to register device\n"); - goto exit; - } - - /* start allocating */ - for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { - hso_net->mux_bulk_rx_urb_pool[i] = usb_alloc_urb(0, GFP_KERNEL); - if (!hso_net->mux_bulk_rx_urb_pool[i]) { - dev_err(&interface->dev, "Could not allocate rx urb\n"); - goto exit; - } - hso_net->mux_bulk_rx_buf_pool[i] = kzalloc(MUX_BULK_RX_BUF_SIZE, - GFP_KERNEL); - if (!hso_net->mux_bulk_rx_buf_pool[i]) { - dev_err(&interface->dev, "Could not allocate rx buf\n"); - goto exit; - } - } - hso_net->mux_bulk_tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!hso_net->mux_bulk_tx_urb) { - dev_err(&interface->dev, "Could not allocate tx urb\n"); - goto exit; - } - hso_net->mux_bulk_tx_buf = kzalloc(MUX_BULK_TX_BUF_SIZE, GFP_KERNEL); - if (!hso_net->mux_bulk_tx_buf) { - dev_err(&interface->dev, "Could not allocate tx buf\n"); - goto exit; - } - - add_net_device(hso_dev); - - hso_log_port(hso_dev); - - hso_create_rfkill(hso_dev, interface); - - return hso_dev; -exit: - hso_free_net_device(hso_dev); - return NULL; -} - -/* Frees an AT channel ( goes for both mux and non-mux ) */ -static void hso_free_serial_device(struct hso_device *hso_dev) -{ - struct hso_serial *serial = dev2ser(hso_dev); - - if (!serial) - return; - set_serial_by_index(serial->minor, NULL); - - hso_serial_common_free(serial); - - if (serial->shared_int) { - mutex_lock(&serial->shared_int->shared_int_lock); - if (--serial->shared_int->ref_count == 0) - hso_free_shared_int(serial->shared_int); - else - mutex_unlock(&serial->shared_int->shared_int_lock); - } - kfree(serial); - hso_free_device(hso_dev); -} - -/* Creates a bulk AT channel */ -static struct hso_device *hso_create_bulk_serial_device( - struct usb_interface *interface, int port) -{ - struct hso_device *hso_dev; - struct hso_serial *serial; - int num_urbs; - - hso_dev = hso_create_device(interface, port); - if (!hso_dev) - return NULL; - - serial = kzalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) - goto exit; - - serial->parent = hso_dev; - hso_dev->port_data.dev_serial = serial; - - if (port & HSO_PORT_MODEM) - num_urbs = 2; - else - num_urbs = 1; - - if (hso_serial_common_create(serial, num_urbs, BULK_URB_RX_SIZE, - BULK_URB_TX_SIZE)) - goto exit; - - serial->in_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, - USB_DIR_IN); - if (!serial->in_endp) { - dev_err(&interface->dev, "Failed to find BULK IN ep\n"); - goto exit; - } - - if (! - (serial->out_endp = - hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) { - dev_err(&interface->dev, "Failed to find BULK IN ep\n"); - goto exit; - } - - serial->write_data = hso_std_serial_write_data; - - /* and record this serial */ - set_serial_by_index(serial->minor, serial); - - /* setup the proc dirs and files if needed */ - hso_log_port(hso_dev); - - /* done, return it */ - return hso_dev; -exit: - if (hso_dev && serial) - hso_serial_common_free(serial); - kfree(serial); - hso_free_device(hso_dev); - return NULL; -} - -/* Creates a multiplexed AT channel */ -static -struct hso_device *hso_create_mux_serial_device(struct usb_interface *interface, - int port, - struct hso_shared_int *mux) -{ - struct hso_device *hso_dev; - struct hso_serial *serial; - int port_spec; - - port_spec = HSO_INTF_MUX; - port_spec &= ~HSO_PORT_MASK; - - port_spec |= hso_mux_to_port(port); - if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NO_PORT) - return NULL; - - hso_dev = hso_create_device(interface, port_spec); - if (!hso_dev) - return NULL; - - serial = kzalloc(sizeof(*serial), GFP_KERNEL); - if (!serial) - goto exit; - - hso_dev->port_data.dev_serial = serial; - serial->parent = hso_dev; - - if (hso_serial_common_create - (serial, 1, CTRL_URB_RX_SIZE, CTRL_URB_TX_SIZE)) - goto exit; - - serial->tx_data_length--; - serial->write_data = hso_mux_serial_write_data; - - serial->shared_int = mux; - mutex_lock(&serial->shared_int->shared_int_lock); - serial->shared_int->ref_count++; - mutex_unlock(&serial->shared_int->shared_int_lock); - - /* and record this serial */ - set_serial_by_index(serial->minor, serial); - - /* setup the proc dirs and files if needed */ - hso_log_port(hso_dev); - - /* done, return it */ - return hso_dev; - -exit: - if (serial) { - tty_unregister_device(tty_drv, serial->minor); - kfree(serial); - } - if (hso_dev) - hso_free_device(hso_dev); - return NULL; - -} - -static void hso_free_shared_int(struct hso_shared_int *mux) -{ - usb_free_urb(mux->shared_intr_urb); - kfree(mux->shared_intr_buf); - mutex_unlock(&mux->shared_int_lock); - kfree(mux); -} - -static -struct hso_shared_int *hso_create_shared_int(struct usb_interface *interface) -{ - struct hso_shared_int *mux = kzalloc(sizeof(*mux), GFP_KERNEL); - - if (!mux) - return NULL; - - mux->intr_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_INT, - USB_DIR_IN); - if (!mux->intr_endp) { - dev_err(&interface->dev, "Can't find INT IN endpoint\n"); - goto exit; - } - - mux->shared_intr_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!mux->shared_intr_urb) { - dev_err(&interface->dev, "Could not allocate intr urb?"); - goto exit; - } - mux->shared_intr_buf = kzalloc(mux->intr_endp->wMaxPacketSize, - GFP_KERNEL); - if (!mux->shared_intr_buf) { - dev_err(&interface->dev, "Could not allocate intr buf?"); - goto exit; - } - - mutex_init(&mux->shared_int_lock); - - return mux; - -exit: - kfree(mux->shared_intr_buf); - usb_free_urb(mux->shared_intr_urb); - kfree(mux); - return NULL; -} - -/* Gets the port spec for a certain interface */ -static int hso_get_config_data(struct usb_interface *interface) -{ - struct usb_device *usbdev = interface_to_usbdev(interface); - u8 config_data[17]; - u32 if_num = interface->altsetting->desc.bInterfaceNumber; - s32 result; - - if (usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), - 0x86, 0xC0, 0, 0, config_data, 17, - USB_CTRL_SET_TIMEOUT) != 0x11) { - return -EIO; - } - - switch (config_data[if_num]) { - case 0x0: - result = 0; - break; - case 0x1: - result = HSO_PORT_DIAG; - break; - case 0x2: - result = HSO_PORT_GPS; - break; - case 0x3: - result = HSO_PORT_GPS_CONTROL; - break; - case 0x4: - result = HSO_PORT_APP; - break; - case 0x5: - result = HSO_PORT_APP2; - break; - case 0x6: - result = HSO_PORT_CONTROL; - break; - case 0x7: - result = HSO_PORT_NETWORK; - break; - case 0x8: - result = HSO_PORT_MODEM; - break; - case 0x9: - result = HSO_PORT_MSD; - break; - case 0xa: - result = HSO_PORT_PCSC; - break; - case 0xb: - result = HSO_PORT_VOICE; - break; - default: - result = 0; - } - - if (result) - result |= HSO_INTF_BULK; - - if (config_data[16] & 0x1) - result |= HSO_INFO_CRC_BUG; - - return result; -} - -/* called once for each interface upon device insertion */ -static int hso_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - int mux, i, if_num, port_spec; - unsigned char port_mask; - struct hso_device *hso_dev = NULL; - struct hso_shared_int *shared_int; - struct hso_device *tmp_dev = NULL; - - if_num = interface->altsetting->desc.bInterfaceNumber; - - /* Get the interface/port specification from either driver_info or from - * the device itself */ - if (id->driver_info) - port_spec = ((u32 *)(id->driver_info))[if_num]; - else - port_spec = hso_get_config_data(interface); - - if (interface->cur_altsetting->desc.bInterfaceClass != 0xFF) { - dev_err(&interface->dev, "Not our interface\n"); - return -ENODEV; - } - /* Check if we need to switch to alt interfaces prior to port - * configuration */ - if (interface->num_altsetting > 1) - usb_set_interface(interface_to_usbdev(interface), if_num, 1); - interface->needs_remote_wakeup = 1; - - /* Allocate new hso device(s) */ - switch (port_spec & HSO_INTF_MASK) { - case HSO_INTF_MUX: - if ((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) { - /* Create the network device */ - if (!disable_net) { - hso_dev = hso_create_net_device(interface); - if (!hso_dev) - goto exit; - tmp_dev = hso_dev; - } - } - - if (hso_get_mux_ports(interface, &port_mask)) - /* TODO: de-allocate everything */ - goto exit; - - shared_int = hso_create_shared_int(interface); - if (!shared_int) - goto exit; - - for (i = 1, mux = 0; i < 0x100; i = i << 1, mux++) { - if (port_mask & i) { - hso_dev = hso_create_mux_serial_device( - interface, i, shared_int); - if (!hso_dev) - goto exit; - } - } - - if (tmp_dev) - hso_dev = tmp_dev; - break; - - case HSO_INTF_BULK: - /* It's a regular bulk interface */ - if (((port_spec & HSO_PORT_MASK) == HSO_PORT_NETWORK) - && !disable_net) - hso_dev = hso_create_net_device(interface); - else - hso_dev = - hso_create_bulk_serial_device(interface, port_spec); - if (!hso_dev) - goto exit; - break; - default: - goto exit; - } - - usb_driver_claim_interface(&hso_driver, interface, hso_dev); - - /* save our data pointer in this device */ - usb_set_intfdata(interface, hso_dev); - - /* done */ - return 0; -exit: - hso_free_interface(interface); - return -ENODEV; -} - -/* device removed, cleaning up */ -static void hso_disconnect(struct usb_interface *interface) -{ - hso_free_interface(interface); - - /* remove reference of our private data */ - usb_set_intfdata(interface, NULL); - - usb_driver_release_interface(&hso_driver, interface); -} - -static void async_get_intf(struct work_struct *data) -{ - struct hso_device *hso_dev = - container_of(data, struct hso_device, async_get_intf); - usb_autopm_get_interface(hso_dev->interface); -} - -static void async_put_intf(struct work_struct *data) -{ - struct hso_device *hso_dev = - container_of(data, struct hso_device, async_put_intf); - usb_autopm_put_interface(hso_dev->interface); -} - -static int hso_get_activity(struct hso_device *hso_dev) -{ - if (hso_dev->usb->state == USB_STATE_SUSPENDED) { - if (!hso_dev->is_active) { - hso_dev->is_active = 1; - schedule_work(&hso_dev->async_get_intf); - } - } - - if (hso_dev->usb->state != USB_STATE_CONFIGURED) - return -EAGAIN; - - usb_mark_last_busy(hso_dev->usb); - - return 0; -} - -static int hso_put_activity(struct hso_device *hso_dev) -{ - if (hso_dev->usb->state != USB_STATE_SUSPENDED) { - if (hso_dev->is_active) { - hso_dev->is_active = 0; - schedule_work(&hso_dev->async_put_intf); - return -EAGAIN; - } - } - hso_dev->is_active = 0; - return 0; -} - -/* called by kernel when we need to suspend device */ -static int hso_suspend(struct usb_interface *iface, pm_message_t message) -{ - int i, result; - - /* Stop all serial ports */ - for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { - if (serial_table[i] && (serial_table[i]->interface == iface)) { - result = hso_stop_serial_device(serial_table[i]); - if (result) - goto out; - } - } - - /* Stop all network ports */ - for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { - if (network_table[i] && - (network_table[i]->interface == iface)) { - result = hso_stop_net_device(network_table[i]); - if (result) - goto out; - } - } - -out: - return 0; -} - -/* called by kernel when we need to resume device */ -static int hso_resume(struct usb_interface *iface) -{ - int i, result = 0; - struct hso_net *hso_net; - - /* Start all serial ports */ - for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { - if (serial_table[i] && (serial_table[i]->interface == iface)) { - if (dev2ser(serial_table[i])->open_count) { - result = - hso_start_serial_device(serial_table[i], GFP_NOIO); - hso_kick_transmit(dev2ser(serial_table[i])); - if (result) - goto out; - } - } - } - - /* Start all network ports */ - for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { - if (network_table[i] && - (network_table[i]->interface == iface)) { - hso_net = dev2net(network_table[i]); - /* First transmit any lingering data, then restart the - * device. */ - if (hso_net->skb_tx_buf) { - dev_dbg(&iface->dev, - "Transmitting lingering data\n"); - hso_net_start_xmit(hso_net->skb_tx_buf, - hso_net->net); - } - result = hso_start_net_device(network_table[i]); - if (result) - goto out; - } - } - -out: - return result; -} - -static void hso_serial_ref_free(struct kref *ref) -{ - struct hso_device *hso_dev = container_of(ref, struct hso_device, ref); - - hso_free_serial_device(hso_dev); -} - -static void hso_free_interface(struct usb_interface *interface) -{ - struct hso_serial *hso_dev; - int i; - - for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) { - if (serial_table[i] - && (serial_table[i]->interface == interface)) { - hso_dev = dev2ser(serial_table[i]); - if (hso_dev->tty) - tty_hangup(hso_dev->tty); - mutex_lock(&hso_dev->parent->mutex); - hso_dev->parent->usb_gone = 1; - mutex_unlock(&hso_dev->parent->mutex); - kref_put(&serial_table[i]->ref, hso_serial_ref_free); - } - } - - for (i = 0; i < HSO_MAX_NET_DEVICES; i++) { - if (network_table[i] - && (network_table[i]->interface == interface)) { - struct rfkill *rfk = dev2net(network_table[i])->rfkill; - /* hso_stop_net_device doesn't stop the net queue since - * traffic needs to start it again when suspended */ - netif_stop_queue(dev2net(network_table[i])->net); - hso_stop_net_device(network_table[i]); - cancel_work_sync(&network_table[i]->async_put_intf); - cancel_work_sync(&network_table[i]->async_get_intf); - if(rfk) - rfkill_unregister(rfk); - hso_free_net_device(network_table[i]); - } - } -} - -/* Helper functions */ - -/* Get the endpoint ! */ -static struct usb_endpoint_descriptor *hso_get_ep(struct usb_interface *intf, - int type, int dir) -{ - int i; - struct usb_host_interface *iface = intf->cur_altsetting; - struct usb_endpoint_descriptor *endp; - - for (i = 0; i < iface->desc.bNumEndpoints; i++) { - endp = &iface->endpoint[i].desc; - if (((endp->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == dir) && - ((endp->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == type)) - return endp; - } - - return NULL; -} - -/* Get the byte that describes which ports are enabled */ -static int hso_get_mux_ports(struct usb_interface *intf, unsigned char *ports) -{ - int i; - struct usb_host_interface *iface = intf->cur_altsetting; - - if (iface->extralen == 3) { - *ports = iface->extra[2]; - return 0; - } - - for (i = 0; i < iface->desc.bNumEndpoints; i++) { - if (iface->endpoint[i].extralen == 3) { - *ports = iface->endpoint[i].extra[2]; - return 0; - } - } - - return -1; -} - -/* interrupt urb needs to be submitted, used for serial read of muxed port */ -static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int, - struct usb_device *usb, gfp_t gfp) -{ - int result; - - usb_fill_int_urb(shared_int->shared_intr_urb, usb, - usb_rcvintpipe(usb, - shared_int->intr_endp->bEndpointAddress & 0x7F), - shared_int->shared_intr_buf, - shared_int->intr_endp->wMaxPacketSize, - intr_callback, shared_int, - shared_int->intr_endp->bInterval); - - result = usb_submit_urb(shared_int->shared_intr_urb, gfp); - if (result) - dev_warn(&usb->dev, "%s failed mux_intr_urb %d", __func__, - result); - - return result; -} - -/* operations setup of the serial interface */ -static struct tty_operations hso_serial_ops = { - .open = hso_serial_open, - .close = hso_serial_close, - .write = hso_serial_write, - .write_room = hso_serial_write_room, - .set_termios = hso_serial_set_termios, - .chars_in_buffer = hso_serial_chars_in_buffer, - .tiocmget = hso_serial_tiocmget, - .tiocmset = hso_serial_tiocmset, -}; - -static struct usb_driver hso_driver = { - .name = driver_name, - .probe = hso_probe, - .disconnect = hso_disconnect, - .id_table = hso_ids, - .suspend = hso_suspend, - .resume = hso_resume, - .supports_autosuspend = 1, -}; - -static int __init hso_init(void) -{ - int i; - int result; - - /* put it in the log */ - printk(KERN_INFO "hso: %s\n", version); - - /* Initialise the serial table semaphore and table */ - spin_lock_init(&serial_table_lock); - for (i = 0; i < HSO_SERIAL_TTY_MINORS; i++) - serial_table[i] = NULL; - - /* allocate our driver using the proper amount of supported minors */ - tty_drv = alloc_tty_driver(HSO_SERIAL_TTY_MINORS); - if (!tty_drv) - return -ENOMEM; - - /* fill in all needed values */ - tty_drv->magic = TTY_DRIVER_MAGIC; - tty_drv->owner = THIS_MODULE; - tty_drv->driver_name = driver_name; - tty_drv->name = tty_filename; - - /* if major number is provided as parameter, use that one */ - if (tty_major) - tty_drv->major = tty_major; - - tty_drv->minor_start = 0; - tty_drv->num = HSO_SERIAL_TTY_MINORS; - tty_drv->type = TTY_DRIVER_TYPE_SERIAL; - tty_drv->subtype = SERIAL_TYPE_NORMAL; - tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; - tty_drv->init_termios = tty_std_termios; - tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; - tty_drv->termios = hso_serial_termios; - tty_drv->termios_locked = hso_serial_termios_locked; - tty_set_operations(tty_drv, &hso_serial_ops); - - /* register the tty driver */ - result = tty_register_driver(tty_drv); - if (result) { - printk(KERN_ERR "%s - tty_register_driver failed(%d)\n", - __func__, result); - return result; - } - - /* register this module as an usb driver */ - result = usb_register(&hso_driver); - if (result) { - printk(KERN_ERR "Could not register hso driver? error: %d\n", - result); - /* cleanup serial interface */ - tty_unregister_driver(tty_drv); - return result; - } - - /* done */ - return 0; -} - -static void __exit hso_exit(void) -{ - printk(KERN_INFO "hso: unloaded\n"); - - tty_unregister_driver(tty_drv); - /* deregister the usb driver */ - usb_deregister(&hso_driver); -} - -/* Module definitions */ -module_init(hso_init); -module_exit(hso_exit); - -MODULE_AUTHOR(MOD_AUTHOR); -MODULE_DESCRIPTION(MOD_DESCRIPTION); -MODULE_LICENSE(MOD_LICENSE); -MODULE_INFO(Version, DRIVER_VERSION); - -/* change the debug level (eg: insmod hso.ko debug=0x04) */ -MODULE_PARM_DESC(debug, "Level of debug [0x01 | 0x02 | 0x04 | 0x08 | 0x10]"); -module_param(debug, int, S_IRUGO | S_IWUSR); - -/* set the major tty number (eg: insmod hso.ko tty_major=245) */ -MODULE_PARM_DESC(tty_major, "Set the major tty number"); -module_param(tty_major, int, S_IRUGO | S_IWUSR); - -/* disable network interface (eg: insmod hso.ko disable_net=1) */ -MODULE_PARM_DESC(disable_net, "Disable the network interface"); -module_param(disable_net, int, S_IRUGO | S_IWUSR); diff --git a/trunk/drivers/net/usb/kaweth.c b/trunk/drivers/net/usb/kaweth.c index 7c66b052f55a..0dcfc0310264 100644 --- a/trunk/drivers/net/usb/kaweth.c +++ b/trunk/drivers/net/usb/kaweth.c @@ -706,7 +706,7 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) usb_kill_urb(kaweth->rx_urb); usb_kill_urb(kaweth->tx_urb); - cancel_delayed_work_sync(&kaweth->lowmem_work); + flush_scheduled_work(); /* a scheduled work may have resubmitted, we hit them again */ diff --git a/trunk/drivers/net/virtio_net.c b/trunk/drivers/net/virtio_net.c index 4452306d5328..5450eac9e263 100644 --- a/trunk/drivers/net/virtio_net.c +++ b/trunk/drivers/net/virtio_net.c @@ -44,15 +44,11 @@ struct virtnet_info /* The skb we couldn't send because buffers were full. */ struct sk_buff *last_xmit_skb; - /* If we need to free in a timer, this is it. */ - struct timer_list xmit_free_timer; - /* Number of input buffers, and max we've ever had. */ unsigned int num, max; /* For cleaning up after transmission. */ struct tasklet_struct tasklet; - bool free_in_tasklet; /* Receive & send queues. */ struct sk_buff_head recv; @@ -76,7 +72,7 @@ static void skb_xmit_done(struct virtqueue *svq) /* Suppress further interrupts. */ svq->vq_ops->disable_cb(svq); - /* We were probably waiting for more output buffers. */ + /* We were waiting for more output buffers. */ netif_wake_queue(vi->dev); /* Make sure we re-xmit last_xmit_skb: if there are no more packets @@ -98,7 +94,9 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, BUG_ON(len > MAX_PACKET_LEN); skb_trim(skb, len); - + skb->protocol = eth_type_trans(skb, dev); + pr_debug("Receiving skb proto 0x%04x len %i type %i\n", + ntohs(skb->protocol), skb->len, skb->pkt_type); dev->stats.rx_bytes += skb->len; dev->stats.rx_packets++; @@ -108,10 +106,6 @@ static void receive_skb(struct net_device *dev, struct sk_buff *skb, goto frame_err; } - skb->protocol = eth_type_trans(skb, dev); - pr_debug("Receiving skb proto 0x%04x len %i type %i\n", - ntohs(skb->protocol), skb->len, skb->pkt_type); - if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { pr_debug("GSO!\n"); switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { @@ -244,25 +238,9 @@ static void free_old_xmit_skbs(struct virtnet_info *vi) } } -/* If the virtio transport doesn't always notify us when all in-flight packets - * are consumed, we fall back to using this function on a timer to free them. */ -static void xmit_free(unsigned long data) -{ - struct virtnet_info *vi = (void *)data; - - netif_tx_lock(vi->dev); - - free_old_xmit_skbs(vi); - - if (!skb_queue_empty(&vi->send)) - mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); - - netif_tx_unlock(vi->dev); -} - static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) { - int num, err; + int num; struct scatterlist sg[2+MAX_SKB_FRAGS]; struct virtio_net_hdr *hdr; const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; @@ -305,11 +283,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) vnet_hdr_to_sg(sg, skb); num = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; - err = vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); - if (!err && !vi->free_in_tasklet) - mod_timer(&vi->xmit_free_timer, jiffies + (HZ/10)); - - return err; + return vi->svq->vq_ops->add_buf(vi->svq, sg, num, 0, skb); } static void xmit_tasklet(unsigned long data) @@ -321,8 +295,6 @@ static void xmit_tasklet(unsigned long data) vi->svq->vq_ops->kick(vi->svq); vi->last_xmit_skb = NULL; } - if (vi->free_in_tasklet) - free_old_xmit_skbs(vi); netif_tx_unlock_bh(vi->dev); } @@ -463,10 +435,6 @@ static int virtnet_probe(struct virtio_device *vdev) vi->vdev = vdev; vdev->priv = vi; - /* If they give us a callback when all buffers are done, we don't need - * the timer. */ - vi->free_in_tasklet = virtio_has_feature(vdev,VIRTIO_F_NOTIFY_ON_EMPTY); - /* We expect two virtqueues, receive then send. */ vi->rvq = vdev->config->find_vq(vdev, 0, skb_recv_done); if (IS_ERR(vi->rvq)) { @@ -486,9 +454,6 @@ static int virtnet_probe(struct virtio_device *vdev) tasklet_init(&vi->tasklet, xmit_tasklet, (unsigned long)vi); - if (!vi->free_in_tasklet) - setup_timer(&vi->xmit_free_timer, xmit_free, (unsigned long)vi); - err = register_netdev(dev); if (err) { pr_debug("virtio_net: registering device failed\n"); @@ -526,9 +491,6 @@ static void virtnet_remove(struct virtio_device *vdev) /* Stop all the virtqueues. */ vdev->config->reset(vdev); - if (!vi->free_in_tasklet) - del_timer_sync(&vi->xmit_free_timer); - /* Free our skbs in send and recv queues, if any. */ while ((skb = __skb_dequeue(&vi->recv)) != NULL) { kfree_skb(skb); @@ -552,7 +514,7 @@ static struct virtio_device_id id_table[] = { static unsigned int features[] = { VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, - VIRTIO_NET_F_HOST_ECN, VIRTIO_F_NOTIFY_ON_EMPTY, + VIRTIO_NET_F_HOST_ECN, }; static struct virtio_driver virtio_net = { diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index 22e1e9a1fb73..fdf5aa8b8429 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -673,19 +673,6 @@ config ADM8211 Thanks to Infineon-ADMtek for their support of this driver. -config MAC80211_HWSIM - tristate "Simulated radio testing tool for mac80211" - depends on MAC80211 && WLAN_80211 - ---help--- - This driver is a developer testing tool that can be used to test - IEEE 802.11 networking stack (mac80211) functionality. This is not - needed for normal wireless LAN usage and is only for testing. See - Documentation/networking/mac80211_hwsim for more information on how - to use this tool. - - To compile this driver as a module, choose M here: the module will be - called mac80211_hwsim. If unsure, say N. - source "drivers/net/wireless/p54/Kconfig" source "drivers/net/wireless/ath5k/Kconfig" source "drivers/net/wireless/iwlwifi/Kconfig" diff --git a/trunk/drivers/net/wireless/Makefile b/trunk/drivers/net/wireless/Makefile index 54a4f6f1db67..2c343aae38d4 100644 --- a/trunk/drivers/net/wireless/Makefile +++ b/trunk/drivers/net/wireless/Makefile @@ -62,5 +62,3 @@ obj-$(CONFIG_RT2X00) += rt2x00/ obj-$(CONFIG_P54_COMMON) += p54/ obj-$(CONFIG_ATH5K) += ath5k/ - -obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index e30f8b79ea89..1e1446bf4b48 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -4561,13 +4561,22 @@ static ssize_t proc_read( struct file *file, size_t len, loff_t *offset ) { - struct proc_data *priv = file->private_data; + loff_t pos = *offset; + struct proc_data *priv = (struct proc_data*)file->private_data; if (!priv->rbuffer) return -EINVAL; - return simple_read_from_buffer(buffer, len, offset, priv->rbuffer, - priv->readlen); + if (pos < 0) + return -EINVAL; + if (pos >= priv->readlen) + return 0; + if (len > priv->readlen - pos) + len = priv->readlen - pos; + if (copy_to_user(buffer, priv->rbuffer + pos, len)) + return -EFAULT; + *offset = pos + len; + return len; } /* diff --git a/trunk/drivers/net/wireless/b43/b43.h b/trunk/drivers/net/wireless/b43/b43.h index 532365f5ecef..239e71c3d1b1 100644 --- a/trunk/drivers/net/wireless/b43/b43.h +++ b/trunk/drivers/net/wireless/b43/b43.h @@ -649,6 +649,7 @@ struct b43_pio { /* Context information for a noise calculation (Link Quality). */ struct b43_noise_calculation { + u8 channel_at_start; bool calculation_running; u8 nr_samples; s8 samples[8][4]; diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 8a09a1db08db..b4eadd908bea 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -795,49 +795,24 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, { struct b43_dmaring *ring; int err; + int nr_slots; dma_addr_t dma_test; ring = kzalloc(sizeof(*ring), GFP_KERNEL); if (!ring) goto out; + ring->type = type; - ring->nr_slots = B43_RXRING_SLOTS; + nr_slots = B43_RXRING_SLOTS; if (for_tx) - ring->nr_slots = B43_TXRING_SLOTS; + nr_slots = B43_TXRING_SLOTS; - ring->meta = kcalloc(ring->nr_slots, sizeof(struct b43_dmadesc_meta), + ring->meta = kcalloc(nr_slots, sizeof(struct b43_dmadesc_meta), GFP_KERNEL); if (!ring->meta) goto err_kfree_ring; - - ring->type = type; - ring->dev = dev; - ring->mmio_base = b43_dmacontroller_base(type, controller_index); - ring->index = controller_index; - if (type == B43_DMA_64BIT) - ring->ops = &dma64_ops; - else - ring->ops = &dma32_ops; if (for_tx) { - ring->tx = 1; - ring->current_slot = -1; - } else { - if (ring->index == 0) { - ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; - ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; - } else if (ring->index == 3) { - ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; - ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; - } else - B43_WARN_ON(1); - } - spin_lock_init(&ring->lock); -#ifdef CONFIG_B43_DEBUG - ring->last_injected_overflow = jiffies; -#endif - - if (for_tx) { - ring->txhdr_cache = kcalloc(ring->nr_slots, + ring->txhdr_cache = kcalloc(nr_slots, b43_txhdr_size(dev), GFP_KERNEL); if (!ring->txhdr_cache) @@ -853,7 +828,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, b43_txhdr_size(dev), 1)) { /* ugh realloc */ kfree(ring->txhdr_cache); - ring->txhdr_cache = kcalloc(ring->nr_slots, + ring->txhdr_cache = kcalloc(nr_slots, b43_txhdr_size(dev), GFP_KERNEL | GFP_DMA); if (!ring->txhdr_cache) @@ -878,6 +853,32 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, DMA_TO_DEVICE); } + ring->dev = dev; + ring->nr_slots = nr_slots; + ring->mmio_base = b43_dmacontroller_base(type, controller_index); + ring->index = controller_index; + if (type == B43_DMA_64BIT) + ring->ops = &dma64_ops; + else + ring->ops = &dma32_ops; + if (for_tx) { + ring->tx = 1; + ring->current_slot = -1; + } else { + if (ring->index == 0) { + ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; + ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; + } else if (ring->index == 3) { + ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; + ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; + } else + B43_WARN_ON(1); + } + spin_lock_init(&ring->lock); +#ifdef CONFIG_B43_DEBUG + ring->last_injected_overflow = jiffies; +#endif + err = alloc_ringmemory(ring); if (err) goto err_kfree_txhdr_cache; diff --git a/trunk/drivers/net/wireless/b43/main.c b/trunk/drivers/net/wireless/b43/main.c index 7bca8e981512..1e31e0bca744 100644 --- a/trunk/drivers/net/wireless/b43/main.c +++ b/trunk/drivers/net/wireless/b43/main.c @@ -1145,6 +1145,7 @@ static void b43_generate_noise_sample(struct b43_wldev *dev) b43_jssi_write(dev, 0x7F7F7F7F); b43_write32(dev, B43_MMIO_MACCMD, b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE); + B43_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel); } static void b43_calculate_link_quality(struct b43_wldev *dev) @@ -1153,6 +1154,7 @@ static void b43_calculate_link_quality(struct b43_wldev *dev) if (dev->noisecalc.calculation_running) return; + dev->noisecalc.channel_at_start = dev->phy.channel; dev->noisecalc.calculation_running = 1; dev->noisecalc.nr_samples = 0; @@ -1169,16 +1171,9 @@ static void handle_irq_noise(struct b43_wldev *dev) /* Bottom half of Link Quality calculation. */ - /* Possible race condition: It might be possible that the user - * changed to a different channel in the meantime since we - * started the calculation. We ignore that fact, since it's - * not really that much of a problem. The background noise is - * an estimation only anyway. Slightly wrong results will get damped - * by the averaging of the 8 sample rounds. Additionally the - * value is shortlived. So it will be replaced by the next noise - * calculation round soon. */ - B43_WARN_ON(!dev->noisecalc.calculation_running); + if (dev->noisecalc.channel_at_start != phy->channel) + goto drop_calculation; *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); if (noise[0] == 0x7F || noise[1] == 0x7F || noise[2] == 0x7F || noise[3] == 0x7F) @@ -1219,10 +1214,11 @@ static void handle_irq_noise(struct b43_wldev *dev) average -= 48; dev->stats.link_noise = average; + drop_calculation: dev->noisecalc.calculation_running = 0; return; } -generate_new: + generate_new: b43_generate_noise_sample(dev); } diff --git a/trunk/drivers/net/wireless/hostap/hostap_main.c b/trunk/drivers/net/wireless/hostap/hostap_main.c index f7aec9309d04..20d387f6658c 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_main.c +++ b/trunk/drivers/net/wireless/hostap/hostap_main.c @@ -682,13 +682,7 @@ static int prism2_close(struct net_device *dev) netif_device_detach(dev); } - cancel_work_sync(&local->reset_queue); - cancel_work_sync(&local->set_multicast_list_queue); - cancel_work_sync(&local->set_tim_queue); -#ifndef PRISM2_NO_STATION_MODES - cancel_work_sync(&local->info_queue); -#endif - cancel_work_sync(&local->comms_qual_update); + flush_scheduled_work(); module_put(local->hw_module); diff --git a/trunk/drivers/net/wireless/iwlwifi/Kconfig b/trunk/drivers/net/wireless/iwlwifi/Kconfig index a382c0078923..5f3e849043f7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Kconfig +++ b/trunk/drivers/net/wireless/iwlwifi/Kconfig @@ -14,6 +14,15 @@ config IWLWIFI_LEDS bool default n +config IWLWIFI_RUN_TIME_CALIB + bool + depends on IWLCORE + default n + ---help--- + This option will enable run time calibration for the iwlwifi driver. + These calibrations are Sensitivity and Chain Noise. + + config IWLWIFI_RFKILL boolean "IWLWIFI RF kill support" depends on IWLCORE @@ -45,6 +54,14 @@ config IWL4965 say M here and read . The module will be called iwl4965.ko. +config IWL4965_HT + bool "Enable 802.11n HT features in iwl4965 driver" + depends on EXPERIMENTAL + depends on IWL4965 + ---help--- + This option enables IEEE 802.11n High Throughput features + for the iwl4965 driver. + config IWL4965_LEDS bool "Enable LEDS features in iwl4965 driver" depends on IWL4965 @@ -59,6 +76,15 @@ config IWL4965_SPECTRUM_MEASUREMENT ---help--- This option will enable spectrum measurement for the iwl4965 driver. +config IWL4965_RUN_TIME_CALIB + bool "Enable run time Calibration for 4965 NIC" + select IWLWIFI_RUN_TIME_CALIB + depends on IWL4965 + default y + ---help--- + This option will enable run time calibration for the iwl4965 driver. + These calibrations are Sensitivity and Chain Noise. If unsure, say yes + config IWLWIFI_DEBUG bool "Enable full debugging output in iwl4965 driver" depends on IWL4965 @@ -92,6 +118,16 @@ config IWL5000 This option enables support for Intel Wireless WiFi Link 5000AGN Family Dependency on 4965 is temporary +config IWL5000_RUN_TIME_CALIB + bool "Enable run time Calibration for 5000 NIC" + select IWLWIFI_RUN_TIME_CALIB + depends on IWL5000 + default y + ---help--- + This option will enable run time calibration for the iwl5000 driver. + These calibrations are Sensitivity and Chain Noise. If unsure, say yes + + config IWLWIFI_DEBUGFS bool "Iwlwifi debugfs support" depends on IWLCORE && IWLWIFI_DEBUG && MAC80211_DEBUGFS diff --git a/trunk/drivers/net/wireless/iwlwifi/Makefile b/trunk/drivers/net/wireless/iwlwifi/Makefile index 1f52b92f08b5..5c73eede7193 100644 --- a/trunk/drivers/net/wireless/iwlwifi/Makefile +++ b/trunk/drivers/net/wireless/iwlwifi/Makefile @@ -1,10 +1,10 @@ obj-$(CONFIG_IWLCORE) += iwlcore.o iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o -iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o -iwlcore-objs += iwl-scan.o +iwlcore-objs += iwl-rx.o iwl-tx.o iwl-sta.o iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o +iwlcore-$(CONFIG_IWLWIFI_RUN_TIME_CALIB) += iwl-calib.o obj-$(CONFIG_IWL3945) += iwl3945.o iwl3945-objs := iwl3945-base.o iwl-3945.o iwl-3945-rs.o diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c index 63f20370032d..0ba6889dfd41 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-3945.c @@ -388,7 +388,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, u32 print_dump = 0; /* set to 1 to dump all frames' contents */ u32 hundred = 0; u32 dataframe = 0; - __le16 fc; + u16 fc; u16 seq_ctl; u16 channel; u16 phy_flags; @@ -407,7 +407,7 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, u8 *data = IWL_RX_DATA(pkt); /* MAC header */ - fc = header->frame_control; + fc = le16_to_cpu(header->frame_control); seq_ctl = le16_to_cpu(header->seq_ctrl); /* metadata */ @@ -431,8 +431,8 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, /* if data frame is to us and all is good, * (optionally) print summary for only 1 out of every 100 */ - if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == - cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { + if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == + (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { dataframe = 1; if (!group100) print_summary = 1; /* print each frame */ @@ -455,13 +455,13 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, if (hundred) title = "100Frames"; - else if (ieee80211_has_retry(fc)) + else if (fc & IEEE80211_FCTL_RETRY) title = "Retry"; - else if (ieee80211_is_assoc_resp(fc)) + else if (ieee80211_is_assoc_response(fc)) title = "AscRsp"; - else if (ieee80211_is_reassoc_resp(fc)) + else if (ieee80211_is_reassoc_response(fc)) title = "RasRsp"; - else if (ieee80211_is_probe_resp(fc)) { + else if (ieee80211_is_probe_response(fc)) { title = "PrbRsp"; print_dump = 1; /* dump frame contents */ } else if (ieee80211_is_beacon(fc)) { @@ -490,14 +490,14 @@ static void iwl3945_dbg_report_frame(struct iwl3945_priv *priv, if (dataframe) IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " "len=%u, rssi=%d, chnl=%d, rate=%u, \n", - title, le16_to_cpu(fc), header->addr1[5], + title, fc, header->addr1[5], length, rssi, channel, rate); else { /* src/dst addresses assume managed mode */ IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " "src=0x%02x, rssi=%u, tim=%lu usec, " "phy=0x%02x, chnl=%d\n", - title, le16_to_cpu(fc), header->addr1[5], + title, fc, header->addr1[5], header->addr3[5], rssi, tsf_low - priv->scan_start_tsf, phy_flags, channel); @@ -971,7 +971,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, u8 rts_retry_limit; u8 data_retry_limit; __le32 tx_flags; - __le16 fc = hdr->frame_control; + u16 fc = le16_to_cpu(hdr->frame_control); rate = iwl3945_rates[rate_index].plcp; tx_flags = cmd->cmd.tx.tx_flags; @@ -996,7 +996,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, else rts_retry_limit = 7; - if (ieee80211_is_probe_resp(fc)) { + if (ieee80211_is_probe_response(fc)) { data_retry_limit = 3; if (data_retry_limit < rts_retry_limit) rts_retry_limit = data_retry_limit; @@ -1006,12 +1006,12 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv, if (priv->data_retry_limit != -1) data_retry_limit = priv->data_retry_limit; - if (ieee80211_is_mgmt(fc)) { - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + switch (fc & IEEE80211_FCTL_STYPE) { + case IEEE80211_STYPE_AUTH: + case IEEE80211_STYPE_DEAUTH: + case IEEE80211_STYPE_ASSOC_REQ: + case IEEE80211_STYPE_REASSOC_REQ: if (tx_flags & TX_CMD_FLG_RTS_MSK) { tx_flags &= ~TX_CMD_FLG_RTS_MSK; tx_flags |= TX_CMD_FLG_CTS_MSK; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 10f630e1afa6..fc118335b60f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-hw.h @@ -82,7 +82,7 @@ */ #define IWL_CMD_QUEUE_NUM 4 #define IWL_CMD_FIFO_NUM 4 -#define IWL49_FIRST_AMPDU_QUEUE 7 +#define IWL_BACK_QUEUE_FIRST_ID 7 /* Tx rates */ #define IWL_CCK_RATES 4 @@ -793,6 +793,19 @@ enum { /********************* END TXPOWER *****************************************/ +static inline u8 iwl4965_hw_get_rate(__le32 rate_n_flags) +{ + return le32_to_cpu(rate_n_flags) & 0xFF; +} +static inline u32 iwl4965_hw_get_rate_n_flags(__le32 rate_n_flags) +{ + return le32_to_cpu(rate_n_flags) & 0x1FFFF; +} +static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) +{ + return cpu_to_le32(flags|(u16)rate); +} + /** * Tx/Rx Queues diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index 202303117285..d8f2b4d33fd9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.c @@ -38,7 +38,6 @@ #include "../net/mac80211/rate.h" #include "iwl-dev.h" -#include "iwl-sta.h" #include "iwl-core.h" #include "iwl-helpers.h" @@ -106,6 +105,8 @@ struct iwl4965_scale_tbl_info { struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ }; +#ifdef CONFIG_IWL4965_HT + struct iwl4965_traffic_load { unsigned long time_stamp; /* age of the oldest statistics */ u32 packet_count[TID_QUEUE_MAX_SIZE]; /* packet count in this time @@ -117,6 +118,8 @@ struct iwl4965_traffic_load { u8 head; /* start of the circular buffer */ }; +#endif /* CONFIG_IWL4965_HT */ + /** * struct iwl4965_lq_sta -- driver's rate scaling private structure * @@ -154,12 +157,16 @@ struct iwl4965_lq_sta { struct iwl_link_quality_cmd lq; struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */ +#ifdef CONFIG_IWL4965_HT struct iwl4965_traffic_load load[TID_MAX_LOAD_COUNT]; u8 tx_agg_tid_en; +#endif #ifdef CONFIG_MAC80211_DEBUGFS struct dentry *rs_sta_dbgfs_scale_table_file; struct dentry *rs_sta_dbgfs_stats_table_file; +#ifdef CONFIG_IWL4965_HT struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; +#endif u32 dbg_fixed_rate; #endif struct iwl_priv *drv; @@ -249,6 +256,7 @@ static inline u8 rs_is_valid_ant(u8 valid_antenna, u8 ant_type) return ((ant_type & valid_antenna) == ant_type); } +#ifdef CONFIG_IWL4965_HT /* * removes the old data from the statistics. All data that is older than * TID_MAX_TIME_DIFF, will be deleted. @@ -274,21 +282,21 @@ static void rs_tl_rm_old_stats(struct iwl4965_traffic_load *tl, u32 curr_time) * increment traffic load value for tid and also remove * any old values if passed the certain time period */ -static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, - struct ieee80211_hdr *hdr) +static void rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, + struct ieee80211_hdr *hdr) { u32 curr_time = jiffies_to_msecs(jiffies); u32 time_diff; s32 index; struct iwl4965_traffic_load *tl = NULL; - __le16 fc = hdr->frame_control; + u16 fc = le16_to_cpu(hdr->frame_control); u8 tid; - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); + if (ieee80211_is_qos_data(fc)) { + u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); tid = qc[0] & 0xf; } else - return MAX_TID_COUNT; + return; tl = &lq_data->load[tid]; @@ -301,7 +309,7 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, tl->queue_count = 1; tl->head = 0; tl->packet_count[0] = 1; - return MAX_TID_COUNT; + return; } time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); @@ -318,8 +326,6 @@ static u8 rs_tl_add_packet(struct iwl4965_lq_sta *lq_data, if ((index + 1) > tl->queue_count) tl->queue_count = index + 1; - - return tid; } /* @@ -383,6 +389,8 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); } +#endif /* CONFIG_IWLWIFI_HT */ + static inline int get_num_of_ant_from_rate(u32 rate_n_flags) { return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) + @@ -537,7 +545,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags, u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags); u8 mcs; - *rate_idx = iwl_hwrate_to_plcp_idx(rate_n_flags); + *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags); if (*rate_idx == IWL_RATE_INVALID) { *rate_idx = -1; @@ -618,6 +626,7 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, /* FIXME:RS: in 4965 we don't use greenfield at all */ /* FIXME:RS: don't use greenfield for now in TX */ +/* #ifdef CONFIG_IWL4965_HT */ #if 0 static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) { @@ -625,11 +634,12 @@ static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf priv->current_ht_config.is_green_field && !priv->current_ht_config.non_GF_STA_present); } -#endif +#else static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf) { return 0; } +#endif /* CONFIG_IWL4965_HT */ /** * rs_get_supported_rates - get the available rates @@ -794,7 +804,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, struct iwl4965_scale_tbl_info tbl_type; struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; u8 active_index = 0; - __le16 fc = hdr->frame_control; + u16 fc = le16_to_cpu(hdr->frame_control); s32 tpt = 0; IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n"); @@ -1040,6 +1050,7 @@ static void rs_set_expected_tpt_table(struct iwl4965_lq_sta *lq_sta, tbl->expected_tpt = expected_tpt_G; } +#ifdef CONFIG_IWL4965_HT /* * Find starting rate for new "search" high-throughput mode of modulation. * Goal is to find lowest expected rate (under perfect conditions) that is @@ -1141,10 +1152,12 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, return new_rate; } +#endif /* CONFIG_IWL4965_HT */ /* * Set up search table for MIMO */ +#ifdef CONFIG_IWL4965_HT static int rs_switch_to_mimo2(struct iwl_priv *priv, struct iwl4965_lq_sta *lq_sta, struct ieee80211_conf *conf, @@ -1208,6 +1221,16 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, tbl->current_rate, is_green); return 0; } +#else +static int rs_switch_to_mimo2(struct iwl_priv *priv, + struct iwl4965_lq_sta *lq_sta, + struct ieee80211_conf *conf, + struct sta_info *sta, + struct iwl4965_scale_tbl_info *tbl, int index) +{ + return -1; +} +#endif /*CONFIG_IWL4965_HT */ /* * Set up search table for SISO @@ -1218,6 +1241,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, struct sta_info *sta, struct iwl4965_scale_tbl_info *tbl, int index) { +#ifdef CONFIG_IWL4965_HT u16 rate_mask; u8 is_green = lq_sta->is_green; s32 rate; @@ -1267,6 +1291,9 @@ static int rs_switch_to_siso(struct iwl_priv *priv, IWL_DEBUG_RATE("LQ: Switch to new mcs %X index is green %X\n", tbl->current_rate, is_green); return 0; +#else + return -1; +#endif /*CONFIG_IWL4965_HT */ } /* @@ -1651,8 +1678,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, int high_tpt = IWL_INVALID_VALUE; u32 fail_count; s8 scale_action = 0; - __le16 fc; - u16 rate_mask; + u16 fc, rate_mask; u8 update_lq = 0; struct iwl4965_lq_sta *lq_sta; struct iwl4965_scale_tbl_info *tbl, *tbl1; @@ -1663,11 +1689,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, u8 done_search = 0; u16 high_low; s32 sr; +#ifdef CONFIG_IWL4965_HT u8 tid = MAX_TID_COUNT; +#endif IWL_DEBUG_RATE("rate scale calculate new rate for skb\n"); - fc = hdr->frame_control; + fc = le16_to_cpu(hdr->frame_control); if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1)) { /* Send management frames and broadcast/multicast data using * lowest rate. */ @@ -1684,8 +1712,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, } lq_sta = (struct iwl4965_lq_sta *)sta->rate_ctrl_priv; - tid = rs_tl_add_packet(lq_sta, hdr); - +#ifdef CONFIG_IWL4965_HT + rs_tl_add_packet(lq_sta, hdr); +#endif /* * Select rate-scale / modulation-mode table to work with in * the rest of this function: "search" if searching for better @@ -1813,7 +1842,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, tbl = &(lq_sta->lq_info[active_tbl]); /* Revert to "active" rate and throughput info */ - index = iwl_hwrate_to_plcp_idx(tbl->current_rate); + index = iwl4965_hwrate_to_plcp_idx( + tbl->current_rate); current_tpt = lq_sta->last_tpt; /* Need to set up a new rate table in uCode */ @@ -1967,7 +1997,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, rs_rate_scale_clear_window(&(tbl->win[i])); /* Use new "search" start rate */ - index = iwl_hwrate_to_plcp_idx(tbl->current_rate); + index = iwl4965_hwrate_to_plcp_idx( + tbl->current_rate); IWL_DEBUG_RATE("Switch current mcs: %X index: %d\n", tbl->current_rate, index); @@ -1982,7 +2013,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, * before next round of mode comparisons. */ tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]); if (is_legacy(tbl1->lq_type) && +#ifdef CONFIG_IWL4965_HT (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) && +#endif (lq_sta->action_counter >= 1)) { lq_sta->action_counter = 0; IWL_DEBUG_RATE("LQ: STAY in legacy table\n"); @@ -1994,12 +2027,14 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, * mode for a while before next round of mode comparisons. */ if (lq_sta->enable_counter && (lq_sta->action_counter >= IWL_ACTION_LIMIT)) { +#ifdef CONFIG_IWL4965_HT if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && (lq_sta->tx_agg_tid_en & (1 << tid)) && (tid != MAX_TID_COUNT)) { IWL_DEBUG_RATE("try to aggregate tid %d\n", tid); rs_tl_turn_on_agg(priv, tid, lq_sta, sta); } +#endif /*CONFIG_IWL4965_HT */ lq_sta->action_counter = 0; rs_set_stay_in_table(priv, 0, lq_sta); } @@ -2101,7 +2136,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct sta_info *sta; - __le16 fc; + u16 fc; struct iwl_priv *priv = (struct iwl_priv *)priv_rate; struct iwl4965_lq_sta *lq_sta; @@ -2113,7 +2148,7 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, /* Send management frames and broadcast/multicast data using lowest * rate. */ - fc = hdr->frame_control; + fc = le16_to_cpu(hdr->frame_control); if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || !sta || !sta->rate_ctrl_priv) { sel->rate_idx = rate_lowest_index(local, sband, sta); @@ -2244,23 +2279,30 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000); lq_sta->active_rate_basic = priv->active_rate_basic; lq_sta->band = priv->band; +#ifdef CONFIG_IWL4965_HT /* * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), * supp_rates[] does not; shift to convert format, force 9 MBits off. */ - lq_sta->active_siso_rate = conf->ht_conf.supp_mcs_set[0] << 1; - lq_sta->active_siso_rate |= conf->ht_conf.supp_mcs_set[0] & 0x1; + lq_sta->active_siso_rate = + priv->current_ht_config.supp_mcs_set[0] << 1; + lq_sta->active_siso_rate |= + priv->current_ht_config.supp_mcs_set[0] & 0x1; lq_sta->active_siso_rate &= ~((u16)0x2); lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE; /* Same here */ - lq_sta->active_mimo2_rate = conf->ht_conf.supp_mcs_set[1] << 1; - lq_sta->active_mimo2_rate |= conf->ht_conf.supp_mcs_set[1] & 0x1; + lq_sta->active_mimo2_rate = + priv->current_ht_config.supp_mcs_set[1] << 1; + lq_sta->active_mimo2_rate |= + priv->current_ht_config.supp_mcs_set[1] & 0x1; lq_sta->active_mimo2_rate &= ~((u16)0x2); lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; - lq_sta->active_mimo3_rate = conf->ht_conf.supp_mcs_set[2] << 1; - lq_sta->active_mimo3_rate |= conf->ht_conf.supp_mcs_set[2] & 0x1; + lq_sta->active_mimo3_rate = + priv->current_ht_config.supp_mcs_set[2] << 1; + lq_sta->active_mimo3_rate |= + priv->current_ht_config.supp_mcs_set[2] & 0x1; lq_sta->active_mimo3_rate &= ~((u16)0x2); lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE; @@ -2275,6 +2317,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, /* as default allow aggregation for all tids */ lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; +#endif /*CONFIG_IWL4965_HT*/ #ifdef CONFIG_MAC80211_DEBUGFS lq_sta->drv = priv; #endif @@ -2592,9 +2635,11 @@ static void rs_add_debugfs(void *priv, void *priv_sta, lq_sta->rs_sta_dbgfs_stats_table_file = debugfs_create_file("rate_stats_table", 0600, dir, lq_sta, &rs_sta_dbgfs_stats_table_ops); +#ifdef CONFIG_IWL4965_HT lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file = debugfs_create_u8("tx_agg_tid_enable", 0600, dir, &lq_sta->tx_agg_tid_en); +#endif } @@ -2603,7 +2648,9 @@ static void rs_remove_debugfs(void *priv, void *priv_sta) struct iwl4965_lq_sta *lq_sta = priv_sta; debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file); debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file); +#ifdef CONFIG_IWL4965_HT debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file); +#endif } #endif diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.h index cbd126418490..1dd4124227a5 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965-rs.h @@ -286,6 +286,8 @@ static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index) return rate; } +extern int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags); + /** * iwl4965_fill_rs_info - Fill an output text buffer with the rate representation * diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c index ab5027345a01..aee7014bcb94 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -46,9 +46,6 @@ #include "iwl-calib.h" #include "iwl-sta.h" -static int iwl4965_send_tx_power(struct iwl_priv *priv); -static int iwl4965_hw_get_temperature(const struct iwl_priv *priv); - /* module parameters */ static struct iwl_mod_params iwl4965_mod_params = { .num_of_queues = IWL49_NUM_QUEUES, @@ -284,7 +281,7 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv) } /* Calculate temperature */ - priv->temperature = iwl4965_hw_get_temperature(priv); + priv->temperature = iwl4965_get_temperature(priv); /* Send pointers to protocol/runtime uCode image ... init code will * load and launch runtime uCode, which will send us another "Alive" @@ -308,6 +305,60 @@ static int is_fat_channel(__le32 rxon_flags) (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); } +int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) +{ + int idx = 0; + + /* 4965 HT rate format */ + if (rate_n_flags & RATE_MCS_HT_MSK) { + idx = (rate_n_flags & 0xff); + + if (idx >= IWL_RATE_MIMO2_6M_PLCP) + idx = idx - IWL_RATE_MIMO2_6M_PLCP; + + idx += IWL_FIRST_OFDM_RATE; + /* skip 9M not supported in ht*/ + if (idx >= IWL_RATE_9M_INDEX) + idx += 1; + if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) + return idx; + + /* 4965 legacy rate format, search for match in table */ + } else { + for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) + if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) + return idx; + } + + return -1; +} + +/** + * translate ucode response to mac80211 tx status control values + */ +void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, + struct ieee80211_tx_info *control) +{ + int rate_index; + + control->antenna_sel_tx = + ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); + if (rate_n_flags & RATE_MCS_HT_MSK) + control->flags |= IEEE80211_TX_CTL_OFDM_HT; + if (rate_n_flags & RATE_MCS_GF_MSK) + control->flags |= IEEE80211_TX_CTL_GREEN_FIELD; + if (rate_n_flags & RATE_MCS_FAT_MSK) + control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH; + if (rate_n_flags & RATE_MCS_DUP_MSK) + control->flags |= IEEE80211_TX_CTL_DUP_DATA; + if (rate_n_flags & RATE_MCS_SGI_MSK) + control->flags |= IEEE80211_TX_CTL_SHORT_GI; + rate_index = iwl4965_hwrate_to_plcp_idx(rate_n_flags); + if (control->band == IEEE80211_BAND_5GHZ) + rate_index -= IWL_FIRST_OFDM_RATE; + control->tx_rate_idx = rate_index; +} + /* * EEPROM handlers */ @@ -557,6 +608,52 @@ static int iwl4965_apm_reset(struct iwl_priv *priv) #define REG_RECALIB_PERIOD (60) +/** + * iwl4965_bg_statistics_periodic - Timer callback to queue statistics + * + * This callback is provided in order to send a statistics request. + * + * This timer function is continually reset to execute within + * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION + * was received. We need to ensure we receive the statistics in order + * to update the temperature used for calibrating the TXPOWER. + */ +static void iwl4965_bg_statistics_periodic(unsigned long data) +{ + struct iwl_priv *priv = (struct iwl_priv *)data; + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + iwl_send_statistics_request(priv, CMD_ASYNC); +} + +void iwl4965_rf_kill_ct_config(struct iwl_priv *priv) +{ + struct iwl4965_ct_kill_config cmd; + unsigned long flags; + int ret = 0; + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, + CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); + spin_unlock_irqrestore(&priv->lock, flags); + + cmd.critical_temperature_R = + cpu_to_le32(priv->hw_params.ct_kill_threshold); + + ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, + sizeof(cmd), &cmd); + if (ret) + IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); + else + IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " + "critical temperature is %d\n", + cmd.critical_temperature_R); +} + +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB + /* Reset differential Rx gains in NIC to prepare for chain noise calibration. * Called after every association, but this runs only once! * ... once chain noise is calibrated the first time, it's good forever. */ @@ -644,6 +741,30 @@ static void iwl4965_gain_computation(struct iwl_priv *priv, data->beacon_count = 0; } +static void iwl4965_bg_sensitivity_work(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, + sensitivity_work); + + mutex_lock(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status) || + test_bit(STATUS_SCANNING, &priv->status)) { + mutex_unlock(&priv->mutex); + return; + } + + if (priv->start_calib) { + iwl_chain_noise_calibration(priv, &priv->statistics); + + iwl_sensitivity_calibration(priv, &priv->statistics); + } + + mutex_unlock(&priv->mutex); + return; +} +#endif /*CONFIG_IWL4965_RUN_TIME_CALIB*/ + static void iwl4965_bg_txpower_work(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, @@ -662,7 +783,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) /* Regardless of if we are assocaited, we must reconfigure the * TX power since frames can be sent on non-radar channels while * not associated */ - iwl4965_send_tx_power(priv); + iwl4965_hw_reg_send_txpower(priv); /* Update last_temperature to keep is_calib_needed from running * when it isn't needed... */ @@ -722,7 +843,7 @@ static const u16 default_queue_to_tx_fifo[] = { IWL_TX_FIFO_HCCA_2 }; -static int iwl4965_alive_notify(struct iwl_priv *priv) +int iwl4965_alive_notify(struct iwl_priv *priv) { u32 a; int i = 0; @@ -799,6 +920,7 @@ static int iwl4965_alive_notify(struct iwl_priv *priv) return ret; } +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB static struct iwl_sensitivity_ranges iwl4965_sensitivity = { .min_nrg_cck = 97, .max_nrg_cck = 0, @@ -821,13 +943,14 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = { .nrg_th_cck = 100, .nrg_th_ofdm = 100, }; +#endif /** * iwl4965_hw_set_hw_params * * Called when initializing driver */ -static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) +int iwl4965_hw_set_hw_params(struct iwl_priv *priv) { if ((priv->cfg->mod_params->num_of_queues > IWL49_NUM_QUEUES) || @@ -838,7 +961,6 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) } priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; - priv->hw_params.first_ampdu_q = IWL49_FIRST_AMPDU_QUEUE; priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; @@ -861,7 +983,9 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.valid_rx_ant = ANT_A | ANT_B; priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB priv->hw_params.sens = &iwl4965_sensitivity; +#endif return 0; } @@ -877,6 +1001,11 @@ static int iwl4965_set_power(struct iwl_priv *priv, cmd, NULL); return ret; } +int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power) +{ + IWL_ERROR("TODO: Implement iwl4965_hw_reg_set_txpower!\n"); + return -EINVAL; +} static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res) { @@ -927,6 +1056,20 @@ static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage, return comp; } +static const struct iwl_channel_info * +iwl4965_get_channel_txpower_info(struct iwl_priv *priv, + enum ieee80211_band band, u16 channel) +{ + const struct iwl_channel_info *ch_info; + + ch_info = iwl_get_channel_info(priv, band, channel); + + if (!is_channel_valid(ch_info)) + return NULL; + + return ch_info; +} + static s32 iwl4965_get_tx_atten_grp(u16 channel) { if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH && @@ -1350,17 +1493,30 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, s32 factory_actual_pwr[2]; s32 power_index; + /* Sanity check requested level (dBm) */ + if (priv->user_txpower_limit < IWL_TX_POWER_TARGET_POWER_MIN) { + IWL_WARNING("Requested user TXPOWER %d below limit.\n", + priv->user_txpower_limit); + return -EINVAL; + } + if (priv->user_txpower_limit > IWL_TX_POWER_TARGET_POWER_MAX) { + IWL_WARNING("Requested user TXPOWER %d above limit.\n", + priv->user_txpower_limit); + return -EINVAL; + } + /* user_txpower_limit is in dBm, convert to half-dBm (half-dB units * are used for indexing into txpower table) */ - user_target_power = 2 * priv->tx_power_user_lmt; + user_target_power = 2 * priv->user_txpower_limit; /* Get current (RXON) channel, band, width */ + ch_info = + iwl4965_get_channel_txpower_info(priv, priv->band, channel); + IWL_DEBUG_TXPOWER("chan %d band %d is_fat %d\n", channel, band, is_fat); - ch_info = iwl_get_channel_info(priv, priv->band, channel); - - if (!is_channel_valid(ch_info)) + if (!ch_info) return -EINVAL; /* get txatten group, used to select 1) thermal txpower adjustment @@ -1561,12 +1717,12 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, } /** - * iwl4965_send_tx_power - Configure the TXPOWER level user limit + * iwl4965_hw_reg_send_txpower - Configure the TXPOWER level user limit * * Uses the active RXON for channel, band, and characteristics (fat, high) - * The power limit is taken from priv->tx_power_user_lmt. + * The power limit is taken from priv->user_txpower_limit. */ -static int iwl4965_send_tx_power(struct iwl_priv *priv) +int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv) { struct iwl4965_txpowertable_cmd cmd = { 0 }; int ret; @@ -1692,6 +1848,11 @@ static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv) return le32_to_cpu(s->rb_closed) & 0xFFF; } +int iwl4965_hw_get_temperature(struct iwl_priv *priv) +{ + return priv->temperature; +} + unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, struct iwl_frame *frame, u8 rate) { @@ -1714,10 +1875,10 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, if ((rate == IWL_RATE_1M_PLCP) || (rate >= IWL_RATE_2M_PLCP)) tx_beacon_cmd->tx.rate_n_flags = - iwl_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); + iwl4965_hw_set_rate_n_flags(rate, RATE_MCS_CCK_MSK); else tx_beacon_cmd->tx.rate_n_flags = - iwl_hw_set_rate_n_flags(rate, 0); + iwl4965_hw_set_rate_n_flags(rate, 0); tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK | TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK); @@ -1789,12 +1950,12 @@ static s32 sign_extend(u32 oper, int index) } /** - * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin) + * iwl4965_get_temperature - return the calibrated temperature (in Kelvin) * @statistics: Provides the temperature reading from the uCode * * A return of <0 indicates bogus data in the statistics */ -static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) +int iwl4965_get_temperature(const struct iwl_priv *priv) { s32 temperature; s32 vt; @@ -1829,7 +1990,8 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) vt = sign_extend( le32_to_cpu(priv->statistics.general.temperature), 23); - IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt); + IWL_DEBUG_TEMP("Calib values R[1-3]: %d %d %d R4: %d\n", + R1, R2, R3, vt); if (R3 == R1) { IWL_ERROR("Calibration conflict R1 == R3\n"); @@ -1840,10 +2002,11 @@ static int iwl4965_hw_get_temperature(const struct iwl_priv *priv) * Add offset to center the adjustment around 0 degrees Centigrade. */ temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2); temperature /= (R3 - R1); - temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET; + temperature = (temperature * 97) / 100 + + TEMPERATURE_CALIB_KELVIN_OFFSET; - IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", - temperature, KELVIN_TO_CELSIUS(temperature)); + IWL_DEBUG_TEMP("Calibrated temperature: %dK, %dC\n", temperature, + KELVIN_TO_CELSIUS(temperature)); return temperature; } @@ -1960,7 +2123,9 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) { iwl4965_rx_calc_noise(priv); - queue_work(priv->workqueue, &priv->run_time_calib_work); +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB + queue_work(priv->workqueue, &priv->sensitivity_work); +#endif } iwl_leds_background(priv); @@ -1971,7 +2136,7 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, if (!change) return; - temp = iwl4965_hw_get_temperature(priv); + temp = iwl4965_get_temperature(priv); if (temp < 0) return; @@ -1990,9 +2155,8 @@ void iwl4965_hw_rx_statistics(struct iwl_priv *priv, priv->temperature = temp; set_bit(STATUS_TEMPERATURE, &priv->status); - if (!priv->disable_tx_power_cal && - unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && - iwl4965_is_temp_calib_needed(priv)) + if (unlikely(!test_bit(STATUS_SCANNING, &priv->status)) && + iwl4965_is_temp_calib_needed(priv)) queue_work(priv->workqueue, &priv->txpower_work); } @@ -2388,7 +2552,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, u32 print_dump = 0; /* set to 1 to dump all frames' contents */ u32 hundred = 0; u32 dataframe = 0; - __le16 fc; + u16 fc; u16 seq_ctl; u16 channel; u16 phy_flags; @@ -2411,7 +2575,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, return; /* MAC header */ - fc = header->frame_control; + fc = le16_to_cpu(header->frame_control); seq_ctl = le16_to_cpu(header->seq_ctrl); /* metadata */ @@ -2436,8 +2600,8 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, /* if data frame is to us and all is good, * (optionally) print summary for only 1 out of every 100 */ - if (to_us && (fc & ~cpu_to_le16(IEEE80211_FCTL_PROTECTED)) == - cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { + if (to_us && (fc & ~IEEE80211_FCTL_PROTECTED) == + (IEEE80211_FCTL_FROMDS | IEEE80211_FTYPE_DATA)) { dataframe = 1; if (!group100) print_summary = 1; /* print each frame */ @@ -2461,13 +2625,13 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, if (hundred) title = "100Frames"; - else if (ieee80211_has_retry(fc)) + else if (fc & IEEE80211_FCTL_RETRY) title = "Retry"; - else if (ieee80211_is_assoc_resp(fc)) + else if (ieee80211_is_assoc_response(fc)) title = "AscRsp"; - else if (ieee80211_is_reassoc_resp(fc)) + else if (ieee80211_is_reassoc_response(fc)) title = "RasRsp"; - else if (ieee80211_is_probe_resp(fc)) { + else if (ieee80211_is_probe_response(fc)) { title = "PrbRsp"; print_dump = 1; /* dump frame contents */ } else if (ieee80211_is_beacon(fc)) { @@ -2484,7 +2648,7 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, else title = "Frame"; - rate_idx = iwl_hwrate_to_plcp_idx(rate_sym); + rate_idx = iwl4965_hwrate_to_plcp_idx(rate_sym); if (unlikely(rate_idx == -1)) bitrate = 0; else @@ -2496,14 +2660,14 @@ static void iwl4965_dbg_report_frame(struct iwl_priv *priv, if (dataframe) IWL_DEBUG_RX("%s: mhd=0x%04x, dst=0x%02x, " "len=%u, rssi=%d, chnl=%d, rate=%u, \n", - title, le16_to_cpu(fc), header->addr1[5], + title, fc, header->addr1[5], length, rssi, channel, bitrate); else { /* src/dst addresses assume managed mode */ IWL_DEBUG_RX("%s: 0x%04x, dst=0x%02x, " "src=0x%02x, rssi=%u, tim=%lu usec, " "phy=0x%02x, chnl=%d\n", - title, le16_to_cpu(fc), header->addr1[5], + title, fc, header->addr1[5], header->addr3[5], rssi, tsf_low - priv->scan_start_tsf, phy_flags, channel); @@ -2549,7 +2713,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, rx_status.band = (rx_start->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ? IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ; rx_status.rate_idx = - iwl_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); + iwl4965_hwrate_to_plcp_idx(le32_to_cpu(rx_start->rate_n_flags)); if (rx_status.band == IEEE80211_BAND_5GHZ) rx_status.rate_idx -= IWL_FIRST_OFDM_RATE; @@ -2655,6 +2819,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, break; case IEEE80211_FTYPE_CTL: +#ifdef CONFIG_IWL4965_HT switch (fc & IEEE80211_FCTL_STYPE) { case IEEE80211_STYPE_BACK_REQ: IWL_DEBUG_HT("IEEE80211_STYPE_BACK_REQ arrived\n"); @@ -2664,6 +2829,7 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, default: break; } +#endif break; case IEEE80211_FTYPE_DATA: { @@ -2697,6 +2863,8 @@ void iwl4965_rx_reply_rx(struct iwl_priv *priv, } } +#ifdef CONFIG_IWL4965_HT + /** * iwl4965_tx_status_reply_compressed_ba - Update tx status from block-ack * @@ -2758,7 +2926,7 @@ static int iwl4965_tx_status_reply_compressed_ba(struct iwl_priv *priv, info->flags |= IEEE80211_TX_STAT_AMPDU; info->status.ampdu_ack_map = successes; info->status.ampdu_ack_len = agg->frame_count; - iwl_hwrate_to_tx_control(priv, agg->rate_n_flags, info); + iwl4965_hwrate_to_tx_control(priv, agg->rate_n_flags, info); IWL_DEBUG_TX_REPLY("Bitmap %llx\n", (unsigned long long)bitmap); @@ -2780,7 +2948,7 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv, } /** - * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE + * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID * priv->lock must be held by the caller */ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, @@ -2788,9 +2956,9 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, { int ret = 0; - if (IWL49_FIRST_AMPDU_QUEUE > txq_id) { + if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { IWL_WARNING("queue number too small: %d, must be > %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE); + txq_id, IWL_BACK_QUEUE_FIRST_ID); return -EINVAL; } @@ -2878,7 +3046,7 @@ static void iwl4965_rx_reply_compressed_ba(struct iwl_priv *priv, if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { /* calculate mac80211 ampdu sw queue to wake */ int ampdu_q = - scd_flow - priv->hw_params.first_ampdu_q + priv->hw->queues; + scd_flow - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); priv->stations[ba_resp->sta_id]. tid[ba_resp->tid].tfds_in_queue -= freed; @@ -2923,7 +3091,7 @@ static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, /** * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue * - * NOTE: txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE, + * NOTE: txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID, * i.e. it must be one of the higher queues used for aggregation */ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, @@ -2933,9 +3101,9 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, int ret; u16 ra_tid; - if (IWL49_FIRST_AMPDU_QUEUE > txq_id) + if (IWL_BACK_QUEUE_FIRST_ID > txq_id) IWL_WARNING("queue number too small: %d, must be > %d\n", - txq_id, IWL49_FIRST_AMPDU_QUEUE); + txq_id, IWL_BACK_QUEUE_FIRST_ID); ra_tid = BUILD_RAxTID(sta_id, tid); @@ -2986,6 +3154,10 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id, return 0; } +#endif /* CONFIG_IWL4965_HT */ + + +#ifdef CONFIG_IWL4965_HT static int iwl4965_rx_agg_start(struct iwl_priv *priv, const u8 *addr, int tid, u16 ssn) { @@ -3059,6 +3231,8 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, } return 0; } +#endif /* CONFIG_IWL4965_HT */ + static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len) { @@ -3088,9 +3262,13 @@ static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) return (u16)sizeof(struct iwl4965_addsta_cmd); } +#ifdef CONFIG_IWL4965_HT static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) { - return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN; + __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + + tx_resp->frame_count); + return le32_to_cpu(*scd_ssn) & MAX_SN; + } /** @@ -3098,29 +3276,32 @@ static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp) */ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, - struct iwl4965_tx_resp *tx_resp, - int txq_id, u16 start_idx) + struct iwl4965_tx_resp_agg *tx_resp, + u16 start_idx) { u16 status; - struct agg_tx_status *frame_status = tx_resp->u.agg_status; + struct agg_tx_status *frame_status = &tx_resp->status; struct ieee80211_tx_info *info = NULL; struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; + int i, sh; + int txq_id, idx; u16 seq; + if (agg->wait_for_ba) IWL_DEBUG_TX_REPLY("got tx response w/o block-ack\n"); agg->frame_count = tx_resp->frame_count; agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); agg->bitmap = 0; /* # frames attempted by Tx command */ if (agg->frame_count == 1) { /* Only one frame was attempted; no block-ack will arrive */ status = le16_to_cpu(frame_status[0].status); - idx = start_idx; + seq = le16_to_cpu(frame_status[0].sequence); + idx = SEQ_TO_INDEX(seq); + txq_id = SEQ_TO_QUEUE(seq); /* FIXME: code repetition */ IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", @@ -3131,12 +3312,15 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= iwl_is_tx_success(status)? IEEE80211_TX_STAT_ACK : 0; - iwl_hwrate_to_tx_control(priv, rate_n_flags, info); + iwl4965_hwrate_to_tx_control(priv, + le32_to_cpu(tx_resp->rate_n_flags), + info); /* FIXME: code repetition end */ IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); + IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", + iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); agg->wait_for_ba = 0; } else { @@ -3194,6 +3378,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, agg->bitmap = bitmap; agg->start_idx = start; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", agg->frame_count, agg->start_idx, (unsigned long long)agg->bitmap); @@ -3203,6 +3388,7 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv, } return 0; } +#endif /** * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response @@ -3217,11 +3403,13 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, struct iwl_tx_queue *txq = &priv->txq[txq_id]; struct ieee80211_tx_info *info; struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; - u32 status = le32_to_cpu(tx_resp->u.status); + u32 status = le32_to_cpu(tx_resp->status); +#ifdef CONFIG_IWL4965_HT int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; - __le16 fc; + u16 fc; struct ieee80211_hdr *hdr; u8 *qc = NULL; +#endif if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " @@ -3234,10 +3422,11 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); memset(&info->status, 0, sizeof(info->status)); +#ifdef CONFIG_IWL4965_HT hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); - fc = hdr->frame_control; - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); + fc = le16_to_cpu(hdr->frame_control); + if (ieee80211_is_qos_data(fc)) { + qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); tid = qc[0] & 0xf; } @@ -3256,7 +3445,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, agg = &priv->stations[sta_id].tid[tid].agg; - iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); + iwl4965_tx_status_reply_tx(priv, agg, + (struct iwl4965_tx_resp_agg *)tx_resp, index); if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { /* TODO: send BAR */ @@ -3274,7 +3464,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, txq_id >= 0 && priv->mac80211_registered && agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { /* calculate mac80211 ampdu sw queue to wake */ - ampdu_q = txq_id - IWL49_FIRST_AMPDU_QUEUE + + ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; if (agg->state == IWL_AGG_OFF) ieee80211_wake_queue(priv->hw, txq_id); @@ -3284,32 +3474,32 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, iwl_txq_check_empty(priv, sta_id, tid, txq_id); } } else { - info->status.retry_count = tx_resp->failure_frame; - info->flags |= - iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; - iwl_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " - "0x%x retries %d\n", txq_id, - iwl_get_tx_fail_reason(status), - status, le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); - - if (index != -1) { - int freed = iwl_tx_queue_reclaim(priv, txq_id, index); - if (tid != MAX_TID_COUNT) +#endif /* CONFIG_IWL4965_HT */ + + info->status.retry_count = tx_resp->failure_frame; + info->flags |= iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; + iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), + info); + + IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " + "retries %d\n", txq_id, iwl_get_tx_fail_reason(status), + status, le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); + + IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); +#ifdef CONFIG_IWL4965_HT + if (index != -1) { + int freed = iwl_tx_queue_reclaim(priv, txq_id, index); + if (tid != MAX_TID_COUNT) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; - if (iwl_queue_space(&txq->q) > txq->q.low_mark && + if (iwl_queue_space(&txq->q) > txq->q.low_mark && (txq_id >= 0) && priv->mac80211_registered) ieee80211_wake_queue(priv->hw, txq_id); - if (tid != MAX_TID_COUNT) + if (tid != MAX_TID_COUNT) iwl_txq_check_empty(priv, sta_id, tid, txq_id); - } } + } +#endif /* CONFIG_IWL4965_HT */ if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); @@ -3323,18 +3513,28 @@ static void iwl4965_rx_handler_setup(struct iwl_priv *priv) priv->rx_handlers[REPLY_RX] = iwl4965_rx_reply_rx; /* Tx response */ priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx; - /* block ack */ + +#ifdef CONFIG_IWL4965_HT priv->rx_handlers[REPLY_COMPRESSED_BA] = iwl4965_rx_reply_compressed_ba; +#endif /* CONFIG_IWL4965_HT */ } -static void iwl4965_setup_deferred_work(struct iwl_priv *priv) +void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv) { INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work); +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB + INIT_WORK(&priv->sensitivity_work, iwl4965_bg_sensitivity_work); +#endif + init_timer(&priv->statistics_periodic); + priv->statistics_periodic.data = (unsigned long)priv; + priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; } -static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) +void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv) { - cancel_work_sync(&priv->txpower_work); + del_timer_sync(&priv->statistics_periodic); + + cancel_delayed_work(&priv->init_alive_start); } @@ -3345,8 +3545,10 @@ static struct iwl_hcmd_ops iwl4965_hcmd = { static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { .get_hcmd_size = iwl4965_get_hcmd_size, .build_addsta_hcmd = iwl4965_build_addsta_hcmd, +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB .chain_noise_reset = iwl4965_chain_noise_reset, .gain_computation = iwl4965_gain_computation, +#endif }; static struct iwl_lib_ops iwl4965_lib = { @@ -3356,11 +3558,11 @@ static struct iwl_lib_ops iwl4965_lib = { .shared_mem_rx_idx = iwl4965_shared_mem_rx_idx, .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, .txq_set_sched = iwl4965_txq_set_sched, +#ifdef CONFIG_IWL4965_HT .txq_agg_enable = iwl4965_txq_agg_enable, .txq_agg_disable = iwl4965_txq_agg_disable, +#endif .rx_handler_setup = iwl4965_rx_handler_setup, - .setup_deferred_work = iwl4965_setup_deferred_work, - .cancel_deferred_work = iwl4965_cancel_deferred_work, .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, .alive_notify = iwl4965_alive_notify, .init_alive_start = iwl4965_init_alive_start, @@ -3388,8 +3590,8 @@ static struct iwl_lib_ops iwl4965_lib = { .check_version = iwl4965_eeprom_check_version, .query_addr = iwlcore_eeprom_query_addr, }, + .radio_kill_sw = iwl4965_radio_kill_sw, .set_power = iwl4965_set_power, - .send_tx_power = iwl4965_send_tx_power, .update_chain_flags = iwl4965_update_chain_flags, }; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h b/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h index 4efe0c06b5b2..9e557ce315b7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000-hw.h @@ -81,7 +81,7 @@ #define IWL50_QUEUE_SIZE 256 #define IWL50_CMD_FIFO_NUM 7 #define IWL50_NUM_QUEUES 20 -#define IWL50_FIRST_AMPDU_QUEUE 10 +#define IWL50_BACK_QUEUE_FIRST_ID 10 #define IWL_sta_id_POS 12 #define IWL_sta_id_LEN 4 diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index 438c3812c390..7e525ad45135 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -41,7 +41,6 @@ #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-io.h" -#include "iwl-sta.h" #include "iwl-helpers.h" #include "iwl-5000-hw.h" @@ -301,6 +300,8 @@ static int iwl5000_eeprom_check_version(struct iwl_priv *priv) } +#ifdef CONFIG_IWL5000_RUN_TIME_CALIB + static void iwl5000_gain_computation(struct iwl_priv *priv, u32 average_noise[NUM_RX_CHAINS], u16 min_average_noise_antenna_i, @@ -353,6 +354,7 @@ static void iwl5000_gain_computation(struct iwl_priv *priv, data->beacon_count = 0; } + static void iwl5000_chain_noise_reset(struct iwl_priv *priv) { struct iwl_chain_noise_data *data = &priv->chain_noise_data; @@ -391,6 +393,10 @@ static struct iwl_sensitivity_ranges iwl5000_sensitivity = { .nrg_th_ofdm = 95, }; +#endif /* CONFIG_IWL5000_RUN_TIME_CALIB */ + + + static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, size_t offset) { @@ -826,7 +832,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) } priv->hw_params.max_txq_num = priv->cfg->mod_params->num_of_queues; - priv->hw_params.first_ampdu_q = IWL50_FIRST_AMPDU_QUEUE; priv->hw_params.sw_crypto = priv->cfg->mod_params->sw_crypto; priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; @@ -842,7 +847,9 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; priv->hw_params.fat_channel = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ); +#ifdef CONFIG_IWL5000_RUN_TIME_CALIB priv->hw_params.sens = &iwl5000_sensitivity; +#endif switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { case CSR_HW_REV_TYPE_5100: @@ -977,135 +984,6 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, } } -static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, - u16 txq_id) -{ - u32 tbl_dw_addr; - u32 tbl_dw; - u16 scd_q2ratid; - - scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK; - - tbl_dw_addr = priv->scd_base_addr + - IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id); - - tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr); - - if (txq_id & 0x1) - tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); - else - tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - - iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw); - - return 0; -} -static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id) -{ - /* Simply stop the queue, but don't change any configuration; - * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(priv, - IWL50_SCD_QUEUE_STATUS_BITS(txq_id), - (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)| - (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); -} - -static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, - int tx_fifo, int sta_id, int tid, u16 ssn_idx) -{ - unsigned long flags; - int ret; - u16 ra_tid; - - if (IWL50_FIRST_AMPDU_QUEUE > txq_id) - IWL_WARNING("queue number too small: %d, must be > %d\n", - txq_id, IWL50_FIRST_AMPDU_QUEUE); - - ra_tid = BUILD_RAxTID(sta_id, tid); - - /* Modify device's station table to Tx this TID */ - iwl_sta_modify_enable_tid_tx(priv, sta_id, tid); - - spin_lock_irqsave(&priv->lock, flags); - ret = iwl_grab_nic_access(priv); - if (ret) { - spin_unlock_irqrestore(&priv->lock, flags); - return ret; - } - - /* Stop this Tx queue before configuring it */ - iwl5000_tx_queue_stop_scheduler(priv, txq_id); - - /* Map receiver-address / traffic-ID to this queue */ - iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id); - - /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx); - - /* Set up Tx window size and frame limit for this queue */ - iwl_write_targ_mem(priv, priv->scd_base_addr + - IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + - sizeof(u32), - ((SCD_WIN_SIZE << - IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & - IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | - ((SCD_FRAME_LIMIT << - IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & - IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - - iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id)); - - /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ - iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); - - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - return 0; -} - -static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) -{ - int ret; - - if (IWL50_FIRST_AMPDU_QUEUE > txq_id) { - IWL_WARNING("queue number too small: %d, must be > %d\n", - txq_id, IWL50_FIRST_AMPDU_QUEUE); - return -EINVAL; - } - - ret = iwl_grab_nic_access(priv); - if (ret) - return ret; - - iwl5000_tx_queue_stop_scheduler(priv, txq_id); - - iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id)); - - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); - /* supposes that ssn_idx is valid (!= 0xFFF) */ - iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx); - - iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id)); - iwl_txq_ctx_deactivate(priv, txq_id); - iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); - - iwl_release_nic_access(priv); - - return 0; -} - static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data) { u16 size = (u16)sizeof(struct iwl_addsta_cmd); @@ -1126,21 +1004,23 @@ static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) static inline u32 iwl5000_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) { - return le32_to_cpup((__le32*)&tx_resp->status + - tx_resp->frame_count) & MAX_SN; + __le32 *scd_ssn = (__le32 *)((u32 *)&tx_resp->status + + tx_resp->frame_count); + return le32_to_cpu(*scd_ssn) & MAX_SN; + } static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, struct iwl_ht_agg *agg, struct iwl5000_tx_resp *tx_resp, - int txq_id, u16 start_idx) + u16 start_idx) { u16 status; struct agg_tx_status *frame_status = &tx_resp->status; struct ieee80211_tx_info *info = NULL; struct ieee80211_hdr *hdr = NULL; - u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); - int i, sh, idx; + int i, sh; + int txq_id, idx; u16 seq; if (agg->wait_for_ba) @@ -1148,14 +1028,16 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, agg->frame_count = tx_resp->frame_count; agg->start_idx = start_idx; - agg->rate_n_flags = rate_n_flags; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); agg->bitmap = 0; /* # frames attempted by Tx command */ if (agg->frame_count == 1) { /* Only one frame was attempted; no block-ack will arrive */ status = le16_to_cpu(frame_status[0].status); - idx = start_idx; + seq = le16_to_cpu(frame_status[0].sequence); + idx = SEQ_TO_INDEX(seq); + txq_id = SEQ_TO_QUEUE(seq); /* FIXME: code repetition */ IWL_DEBUG_TX_REPLY("FrameCnt = %d, StartIdx=%d idx=%d\n", @@ -1166,13 +1048,15 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, info->flags &= ~IEEE80211_TX_CTL_AMPDU; info->flags |= iwl_is_tx_success(status)? IEEE80211_TX_STAT_ACK : 0; - iwl_hwrate_to_tx_control(priv, rate_n_flags, info); - + iwl4965_hwrate_to_tx_control(priv, + le32_to_cpu(tx_resp->rate_n_flags), + info); /* FIXME: code repetition end */ IWL_DEBUG_TX_REPLY("1 Frame 0x%x failure :%d\n", status & 0xff, tx_resp->failure_frame); - IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", rate_n_flags); + IWL_DEBUG_TX_REPLY("Rate Info rate_n_flags=%x\n", + iwl4965_hw_get_rate_n_flags(tx_resp->rate_n_flags)); agg->wait_for_ba = 0; } else { @@ -1230,6 +1114,7 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv, agg->bitmap = bitmap; agg->start_idx = start; + agg->rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags); IWL_DEBUG_TX_REPLY("Frames %d start_idx=%d bitmap=0x%llx\n", agg->frame_count, agg->start_idx, (unsigned long long)agg->bitmap); @@ -1251,9 +1136,12 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, struct ieee80211_tx_info *info; struct iwl5000_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; u32 status = le16_to_cpu(tx_resp->status.status); +#ifdef CONFIG_IWL4965_HT int tid = MAX_TID_COUNT, sta_id = IWL_INVALID_STATION; + u16 fc; struct ieee80211_hdr *hdr; u8 *qc = NULL; +#endif if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { IWL_ERROR("Read index for DMA queue txq_id (%d) index %d " @@ -1266,9 +1154,11 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb[0]); memset(&info->status, 0, sizeof(info->status)); +#ifdef CONFIG_IWL4965_HT hdr = iwl_tx_queue_get_hdr(priv, txq_id, index); - if (ieee80211_is_data_qos(hdr->frame_control)) { - qc = ieee80211_get_qos_ctl(hdr); + fc = le16_to_cpu(hdr->frame_control); + if (ieee80211_is_qos_data(fc)) { + qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); tid = qc[0] & 0xf; } @@ -1287,7 +1177,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, agg = &priv->stations[sta_id].tid[tid].agg; - iwl5000_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index); + iwl5000_tx_status_reply_tx(priv, agg, tx_resp, index); if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status)) { /* TODO: send BAR */ @@ -1305,7 +1195,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, txq_id >= 0 && priv->mac80211_registered && agg->state != IWL_EMPTYING_HW_QUEUE_DELBA) { /* calculate mac80211 ampdu sw queue to wake */ - ampdu_q = txq_id - IWL50_FIRST_AMPDU_QUEUE + + ampdu_q = txq_id - IWL_BACK_QUEUE_FIRST_ID + priv->hw->queues; if (agg->state == IWL_AGG_OFF) ieee80211_wake_queue(priv->hw, txq_id); @@ -1315,31 +1205,32 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv, iwl_txq_check_empty(priv, sta_id, tid, txq_id); } } else { - info->status.retry_count = tx_resp->failure_frame; - info->flags = - iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; - iwl_hwrate_to_tx_control(priv, - le32_to_cpu(tx_resp->rate_n_flags), - info); - - IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags " - "0x%x retries %d\n", txq_id, - iwl_get_tx_fail_reason(status), - status, le32_to_cpu(tx_resp->rate_n_flags), - tx_resp->failure_frame); - - IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); - if (index != -1) { - int freed = iwl_tx_queue_reclaim(priv, txq_id, index); - if (tid != MAX_TID_COUNT) +#endif /* CONFIG_IWL4965_HT */ + + info->status.retry_count = tx_resp->failure_frame; + info->flags = iwl_is_tx_success(status) ? IEEE80211_TX_STAT_ACK : 0; + iwl4965_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), + info); + + IWL_DEBUG_TX("Tx queue %d Status %s (0x%08x) rate_n_flags 0x%x " + "retries %d\n", txq_id, iwl_get_tx_fail_reason(status), + status, le32_to_cpu(tx_resp->rate_n_flags), + tx_resp->failure_frame); + + IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); +#ifdef CONFIG_IWL4965_HT + if (index != -1) { + int freed = iwl_tx_queue_reclaim(priv, txq_id, index); + if (tid != MAX_TID_COUNT) priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; - if (iwl_queue_space(&txq->q) > txq->q.low_mark && + if (iwl_queue_space(&txq->q) > txq->q.low_mark && (txq_id >= 0) && priv->mac80211_registered) ieee80211_wake_queue(priv->hw, txq_id); - if (tid != MAX_TID_COUNT) + if (tid != MAX_TID_COUNT) iwl_txq_check_empty(priv, sta_id, tid, txq_id); - } } + } +#endif /* CONFIG_IWL4965_HT */ if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) IWL_ERROR("TODO: Implement Tx ABORT REQUIRED!!!\n"); @@ -1351,12 +1242,6 @@ static u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len) return len; } -static void iwl5000_setup_deferred_work(struct iwl_priv *priv) -{ - /* in 5000 the tx power calibration is done in uCode */ - priv->disable_tx_power_cal = 1; -} - static void iwl5000_rx_handler_setup(struct iwl_priv *priv) { /* init calibration handlers */ @@ -1420,19 +1305,6 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv) return ret; } -static int iwl5000_send_tx_power(struct iwl_priv *priv) -{ - struct iwl5000_tx_power_dbm_cmd tx_power_cmd; - - /* half dBm need to multiply */ - tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt); - tx_power_cmd.flags = 0; - tx_power_cmd.srv_chan_lmt = IWL50_TX_POWER_AUTO; - return iwl_send_cmd_pdu_async(priv, REPLY_TX_POWER_DBM_CMD, - sizeof(tx_power_cmd), &tx_power_cmd, - NULL); -} - static struct iwl_hcmd_ops iwl5000_hcmd = { .rxon_assoc = iwl5000_send_rxon_assoc, @@ -1441,8 +1313,10 @@ static struct iwl_hcmd_ops iwl5000_hcmd = { static struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = { .get_hcmd_size = iwl5000_get_hcmd_size, .build_addsta_hcmd = iwl5000_build_addsta_hcmd, +#ifdef CONFIG_IWL5000_RUN_TIME_CALIB .gain_computation = iwl5000_gain_computation, .chain_noise_reset = iwl5000_chain_noise_reset, +#endif }; static struct iwl_lib_ops iwl5000_lib = { @@ -1453,15 +1327,11 @@ static struct iwl_lib_ops iwl5000_lib = { .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl, .txq_set_sched = iwl5000_txq_set_sched, - .txq_agg_enable = iwl5000_txq_agg_enable, - .txq_agg_disable = iwl5000_txq_agg_disable, .rx_handler_setup = iwl5000_rx_handler_setup, - .setup_deferred_work = iwl5000_setup_deferred_work, .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr, .load_ucode = iwl5000_load_ucode, .init_alive_start = iwl5000_init_alive_start, .alive_notify = iwl5000_alive_notify, - .send_tx_power = iwl5000_send_tx_power, .apm_ops = { .init = iwl5000_apm_init, .reset = iwl5000_apm_reset, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.c b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.c index 48f58000b64b..a6c7f0d9a414 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.c @@ -60,11 +60,13 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ +#include #include #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-calib.h" +#include "iwl-eeprom.h" /* "false alarms" are signals that our DSP tries to lock onto, * but then determines that they are either noise, or transmissions @@ -433,6 +435,8 @@ void iwl_init_sensitivity(struct iwl_priv *priv) data = &(priv->sensitivity_data); if (ranges == NULL) + /* can happen if IWLWIFI_RUN_TIME_CALIB is selected + * but no IWLXXXX_RUN_TIME_CALIB for specific is selected */ return; memset(data, 0, sizeof(struct iwl_sensitivity_data)); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h index 5524a29e22d8..b8e57c59eac8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-calib.h @@ -62,10 +62,16 @@ #ifndef __iwl_calib_h__ #define __iwl_calib_h__ -#include "iwl-dev.h" +#include +#include +#include + +#include +#include "iwl-eeprom.h" #include "iwl-core.h" -#include "iwl-commands.h" +#include "iwl-dev.h" +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB void iwl_chain_noise_calibration(struct iwl_priv *priv, struct iwl4965_notif_statistics *stat_resp); void iwl_sensitivity_calibration(struct iwl_priv *priv, @@ -80,5 +86,24 @@ static inline void iwl_chain_noise_reset(struct iwl_priv *priv) priv->cfg->ops->utils->chain_noise_reset) priv->cfg->ops->utils->chain_noise_reset(priv); } +#else +static inline void iwl_chain_noise_calibration(struct iwl_priv *priv, + struct iwl4965_notif_statistics *stat_resp) +{ +} +static inline void iwl_sensitivity_calibration(struct iwl_priv *priv, + struct iwl4965_notif_statistics *resp) +{ +} +static inline void iwl_init_sensitivity(struct iwl_priv *priv) +{ +} +static inline void iwl_chain_noise_reset(struct iwl_priv *priv) +{ +} +static inline void iwl_reset_run_time_calib(struct iwl_priv *priv) +{ +} +#endif #endif /* __iwl_calib_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h index 920dfc1b2db2..fb6f5ffb9f1d 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -126,7 +126,6 @@ enum { /* Miscellaneous commands */ QUIET_NOTIFICATION = 0x96, /* not used */ REPLY_TX_PWR_TABLE_CMD = 0x97, - REPLY_TX_POWER_DBM_CMD = 0x98, MEASURE_ABORT_NOTIFICATION = 0x99, /* not used */ /* Bluetooth device coexistance config command */ @@ -281,7 +280,16 @@ struct iwl_cmd_header { #define RATE_MCS_ANT_C_MSK 0x10000 #define RATE_MCS_ANT_ABC_MSK 0x1C000 -#define RATE_MCS_ANT_INIT_IND 1 + +/** + * struct iwl4965_tx_power - txpower format used in REPLY_SCAN_CMD + * + * Scan uses only one transmitter, so only one analog/dsp gain pair is needed. + */ +struct iwl4965_tx_power { + u8 tx_gain; /* gain for analog radio */ + u8 dsp_atten; /* gain for DSP */ +} __attribute__ ((packed)); #define POWER_TABLE_NUM_ENTRIES 33 #define POWER_TABLE_NUM_HT_OFDM_ENTRIES 32 @@ -331,17 +339,6 @@ struct iwl4965_tx_power_db { struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES]; } __attribute__ ((packed)); -/** - * Commad REPLY_TX_POWER_DBM_CMD = 0x98 - * struct iwl5000_tx_power_dbm_cmd - */ -#define IWL50_TX_POWER_AUTO 0x7f -struct iwl5000_tx_power_dbm_cmd { - s8 global_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ - u8 flags; - s8 srv_chan_lmt; /*in half-dBm (e.g. 30 = 15 dBm) */ - u8 reserved; -} __attribute__ ((packed)); /****************************************************************************** * (0a) @@ -993,7 +990,6 @@ struct iwl_wep_cmd { #define WEP_KEY_WEP_TYPE 1 #define WEP_KEYS_MAX 4 #define WEP_INVALID_OFFSET 0xff -#define WEP_KEY_LEN_64 5 #define WEP_KEY_LEN_128 13 /****************************************************************************** @@ -1485,10 +1481,21 @@ struct iwl4965_tx_resp { * table entry used for all frames in the new agg. * 31-16: Sequence # for this frame's Tx cmd (not SSN!) */ - union { - __le32 status; - struct agg_tx_status agg_status[0]; /* for each agg frame */ - } u; + __le32 status; /* TX status (for aggregation status of 1st frame) */ +} __attribute__ ((packed)); + +struct iwl4965_tx_resp_agg { + u8 frame_count; /* 1 no aggregation, >1 aggregation */ + u8 reserved1; + u8 failure_rts; + u8 failure_frame; + __le32 rate_n_flags; + __le16 wireless_media_time; + __le16 reserved3; + __le32 pa_power1; + __le32 pa_power2; + struct agg_tx_status status; /* TX status (for aggregation status */ + /* of 1st frame) */ } __attribute__ ((packed)); struct iwl5000_tx_resp { @@ -2078,7 +2085,7 @@ struct iwl4965_card_state_notif { #define RF_CARD_DISABLED 0x04 #define RXON_CARD_DISABLED 0x10 -struct iwl_ct_kill_config { +struct iwl4965_ct_kill_config { __le32 reserved; __le32 critical_temperature_M; __le32 critical_temperature_R; @@ -2091,7 +2098,7 @@ struct iwl_ct_kill_config { *****************************************************************************/ /** - * struct iwl_scan_channel - entry in REPLY_SCAN_CMD channel table + * struct iwl4965_scan_channel - entry in REPLY_SCAN_CMD channel table * * One for each channel in the scan list. * Each channel can independently select: @@ -2101,7 +2108,7 @@ struct iwl_ct_kill_config { * quiet_plcp_th, good_CRC_th) * * To avoid uCode errors, make sure the following are true (see comments - * under struct iwl_scan_cmd about max_out_time and quiet_time): + * under struct iwl4965_scan_cmd about max_out_time and quiet_time): * 1) If using passive_dwell (i.e. passive_dwell != 0): * active_dwell <= passive_dwell (< max_out_time if max_out_time != 0) * 2) quiet_time <= active_dwell @@ -2109,7 +2116,7 @@ struct iwl_ct_kill_config { * passive_dwell < max_out_time * active_dwell < max_out_time */ -struct iwl_scan_channel { +struct iwl4965_scan_channel { /* * type is defined as: * 0:0 1 = active, 0 = passive @@ -2119,20 +2126,19 @@ struct iwl_scan_channel { */ u8 type; u8 channel; /* band is selected by iwl4965_scan_cmd "flags" field */ - u8 tx_gain; /* gain for analog radio */ - u8 dsp_atten; /* gain for DSP */ + struct iwl4965_tx_power tpc; __le16 active_dwell; /* in 1024-uSec TU (time units), typ 5-50 */ __le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */ } __attribute__ ((packed)); /** - * struct iwl_ssid_ie - directed scan network information element + * struct iwl4965_ssid_ie - directed scan network information element * * Up to 4 of these may appear in REPLY_SCAN_CMD, selected by "type" field * in struct iwl4965_scan_channel; each channel may select different ssids from * among the 4 entries. SSID IEs get transmitted in reverse order of entry. */ -struct iwl_ssid_ie { +struct iwl4965_ssid_ie { u8 id; u8 len; u8 ssid[32]; @@ -2193,9 +2199,9 @@ struct iwl_ssid_ie { * Driver must use separate scan commands for 2.4 vs. 5 GHz bands. * * To avoid uCode errors, see timing restrictions described under - * struct iwl_scan_channel. + * struct iwl4965_scan_channel. */ -struct iwl_scan_cmd { +struct iwl4965_scan_cmd { __le16 len; u8 reserved0; u8 channel_count; /* # channels in channel list */ @@ -2219,7 +2225,7 @@ struct iwl_scan_cmd { struct iwl_tx_cmd tx_cmd; /* For directed active scans (set to all-0s otherwise) */ - struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX]; + struct iwl4965_ssid_ie direct_scan[PROBE_OPTION_MAX]; /* * Probe request frame, followed by channel list. @@ -2247,14 +2253,14 @@ struct iwl_scan_cmd { /* * REPLY_SCAN_CMD = 0x80 (response) */ -struct iwl_scanreq_notification { +struct iwl4965_scanreq_notification { __le32 status; /* 1: okay, 2: cannot fulfill request */ } __attribute__ ((packed)); /* * SCAN_START_NOTIFICATION = 0x82 (notification only, not a command) */ -struct iwl_scanstart_notification { +struct iwl4965_scanstart_notification { __le32 tsf_low; __le32 tsf_high; __le32 beacon_timer; @@ -2271,7 +2277,7 @@ struct iwl_scanstart_notification { /* * SCAN_RESULTS_NOTIFICATION = 0x83 (notification only, not a command) */ -struct iwl_scanresults_notification { +struct iwl4965_scanresults_notification { u8 channel; u8 band; u8 reserved[2]; @@ -2283,7 +2289,7 @@ struct iwl_scanresults_notification { /* * SCAN_COMPLETE_NOTIFICATION = 0x84 (notification only, not a command) */ -struct iwl_scancomplete_notification { +struct iwl4965_scancomplete_notification { u8 scanned_channels; u8 status; u8 reserved; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c index eb74a40a62eb..61716ba90427 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.c @@ -85,63 +85,6 @@ const struct iwl_rate_info iwl_rates[IWL_RATE_COUNT] = { }; EXPORT_SYMBOL(iwl_rates); -/** - * translate ucode response to mac80211 tx status control values - */ -void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, - struct ieee80211_tx_info *control) -{ - int rate_index; - - control->antenna_sel_tx = - ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS); - if (rate_n_flags & RATE_MCS_HT_MSK) - control->flags |= IEEE80211_TX_CTL_OFDM_HT; - if (rate_n_flags & RATE_MCS_GF_MSK) - control->flags |= IEEE80211_TX_CTL_GREEN_FIELD; - if (rate_n_flags & RATE_MCS_FAT_MSK) - control->flags |= IEEE80211_TX_CTL_40_MHZ_WIDTH; - if (rate_n_flags & RATE_MCS_DUP_MSK) - control->flags |= IEEE80211_TX_CTL_DUP_DATA; - if (rate_n_flags & RATE_MCS_SGI_MSK) - control->flags |= IEEE80211_TX_CTL_SHORT_GI; - rate_index = iwl_hwrate_to_plcp_idx(rate_n_flags); - if (control->band == IEEE80211_BAND_5GHZ) - rate_index -= IWL_FIRST_OFDM_RATE; - control->tx_rate_idx = rate_index; -} -EXPORT_SYMBOL(iwl_hwrate_to_tx_control); - -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags) -{ - int idx = 0; - - /* HT rate format */ - if (rate_n_flags & RATE_MCS_HT_MSK) { - idx = (rate_n_flags & 0xff); - - if (idx >= IWL_RATE_MIMO2_6M_PLCP) - idx = idx - IWL_RATE_MIMO2_6M_PLCP; - - idx += IWL_FIRST_OFDM_RATE; - /* skip 9M not supported in ht*/ - if (idx >= IWL_RATE_9M_INDEX) - idx += 1; - if ((idx >= IWL_FIRST_OFDM_RATE) && (idx <= IWL_LAST_OFDM_RATE)) - return idx; - - /* legacy rate format, search for match in table */ - } else { - for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++) - if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF)) - return idx; - } - - return -1; -} -EXPORT_SYMBOL(iwl_hwrate_to_plcp_idx); - - const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; EXPORT_SYMBOL(iwl_bcast_addr); @@ -378,6 +321,7 @@ void iwl_reset_qos(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_reset_qos); +#ifdef CONFIG_IWL4965_HT #define MAX_BIT_RATE_40_MHZ 0x96; /* 150 Mbps */ #define MAX_BIT_RATE_20_MHZ 0x48; /* 72 Mbps */ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, @@ -430,6 +374,13 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, ht_info->supp_mcs_set[12] |= ((tx_chains_num - 1) << 2); } } +#else +static inline void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, + struct ieee80211_ht_info *ht_info, + enum ieee80211_band band) +{ +} +#endif /* CONFIG_IWL4965_HT */ static void iwlcore_init_hw_rates(struct iwl_priv *priv, struct ieee80211_rate *rates) @@ -535,10 +486,28 @@ static int iwlcore_init_geos(struct iwl_priv *priv) if (ch->flags & EEPROM_CHANNEL_RADAR) geo_ch->flags |= IEEE80211_CHAN_RADAR; - geo_ch->flags |= ch->fat_extension_channel; + switch (ch->fat_extension_channel) { + case HT_IE_EXT_CHANNEL_ABOVE: + /* only above is allowed, disable below */ + geo_ch->flags |= IEEE80211_CHAN_NO_FAT_BELOW; + break; + case HT_IE_EXT_CHANNEL_BELOW: + /* only below is allowed, disable above */ + geo_ch->flags |= IEEE80211_CHAN_NO_FAT_ABOVE; + break; + case HT_IE_EXT_CHANNEL_NONE: + /* fat not allowed: disable both*/ + geo_ch->flags |= (IEEE80211_CHAN_NO_FAT_ABOVE | + IEEE80211_CHAN_NO_FAT_BELOW); + break; + case HT_IE_EXT_CHANNEL_MAX: + /* both above and below are permitted */ + break; + } - if (ch->max_power_avg > priv->tx_power_channel_lmt) - priv->tx_power_channel_lmt = ch->max_power_avg; + if (ch->max_power_avg > priv->max_channel_txpower_limit) + priv->max_channel_txpower_limit = + ch->max_power_avg; } else { geo_ch->flags |= IEEE80211_CHAN_DISABLED; } @@ -546,7 +515,7 @@ static int iwlcore_init_geos(struct iwl_priv *priv) /* Save flags for reg domain usage */ geo_ch->orig_flags = geo_ch->flags; - IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", + IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n", ch->channel, geo_ch->center_freq, is_channel_a_band(ch) ? "5.2" : "2.4", geo_ch->flags & IEEE80211_CHAN_DISABLED ? @@ -584,6 +553,7 @@ static void iwlcore_free_geos(struct iwl_priv *priv) clear_bit(STATUS_GEO_CONFIGURED, &priv->status); } +#ifdef CONFIG_IWL4965_HT static u8 is_single_rx_stream(struct iwl_priv *priv) { return !priv->current_ht_config.is_ht || @@ -591,7 +561,6 @@ static u8 is_single_rx_stream(struct iwl_priv *priv) (priv->current_ht_config.supp_mcs_set[2] == 0)) || priv->ps_mode == IWL_MIMO_PS_STATIC; } - static u8 iwl_is_channel_extension(struct iwl_priv *priv, enum ieee80211_band band, u16 channel, u8 extension_chan_offset) @@ -602,12 +571,12 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv, if (!is_channel_valid(ch_info)) return 0; - if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) - return !(ch_info->fat_extension_channel & - IEEE80211_CHAN_NO_FAT_ABOVE); - else if (extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) - return !(ch_info->fat_extension_channel & - IEEE80211_CHAN_NO_FAT_BELOW); + if (extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE) + return 0; + + if ((ch_info->fat_extension_channel == extension_chan_offset) || + (ch_info->fat_extension_channel == HT_IE_EXT_CHANNEL_MAX)) + return 1; return 0; } @@ -619,7 +588,7 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, if ((!iwl_ht_conf->is_ht) || (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) || - (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE)) + (iwl_ht_conf->extension_chan_offset == IWL_EXT_CHANNEL_OFFSET_NONE)) return 0; if (sta_ht_inf) { @@ -653,18 +622,19 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) IWL_DEBUG_ASSOC("control diff than current %d %d\n", le16_to_cpu(rxon->channel), ht_info->control_channel); + rxon->channel = cpu_to_le16(ht_info->control_channel); return; } /* Note: control channel is opposite of extension channel */ switch (ht_info->extension_chan_offset) { - case IEEE80211_HT_IE_CHA_SEC_ABOVE: + case IWL_EXT_CHANNEL_OFFSET_ABOVE: rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK); break; - case IEEE80211_HT_IE_CHA_SEC_BELOW: + case IWL_EXT_CHANNEL_OFFSET_BELOW: rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK; break; - case IEEE80211_HT_IE_CHA_SEC_NONE: + case IWL_EXT_CHANNEL_OFFSET_NONE: default: rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK; break; @@ -690,6 +660,13 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) } EXPORT_SYMBOL(iwl_set_rxon_ht); +#else +static inline u8 is_single_rx_stream(struct iwl_priv *priv) +{ + return 1; +} +#endif /*CONFIG_IWL4965_HT */ + /* * Determine how many receiver/antenna chains to use. * More provides better reception via diversity. Fewer saves power. @@ -814,8 +791,10 @@ int iwl_setup_mac(struct iwl_priv *priv) IEEE80211_HW_NOISE_DBM; /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; +#ifdef CONFIG_IWL4965_HT /* Enhanced value; more queues, to support 11n aggregation */ hw->ampdu_queues = 12; +#endif /* CONFIG_IWL4965_HT */ hw->conf.beacon_int = 100; @@ -874,7 +853,6 @@ int iwl_init_drv(struct iwl_priv *priv) /* Choose which receivers/antennas to use */ iwl_set_rxon_chain(priv); - iwl_init_scan_params(priv); if (priv->cfg->mod_params->enable_qos) priv->qos_data.qos_enable = 1; @@ -889,7 +867,7 @@ int iwl_init_drv(struct iwl_priv *priv) priv->rates_mask = IWL_RATES_MASK; /* If power management is turned on, default to AC mode */ priv->power_mode = IWL_POWER_AC; - priv->tx_power_user_lmt = IWL_TX_POWER_TARGET_POWER_MAX; + priv->user_txpower_limit = IWL_DEFAULT_TX_POWER; ret = iwl_init_channel_map(priv); if (ret) { @@ -928,34 +906,6 @@ void iwl_free_calib_results(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_free_calib_results); -int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) -{ - int ret = 0; - if (tx_power < IWL_TX_POWER_TARGET_POWER_MIN) { - IWL_WARNING("Requested user TXPOWER %d below limit.\n", - priv->tx_power_user_lmt); - return -EINVAL; - } - - if (tx_power > IWL_TX_POWER_TARGET_POWER_MAX) { - IWL_WARNING("Requested user TXPOWER %d above limit.\n", - priv->tx_power_user_lmt); - return -EINVAL; - } - - if (priv->tx_power_user_lmt != tx_power) - force = true; - - priv->tx_power_user_lmt = tx_power; - - if (force && priv->cfg->ops->lib->send_tx_power) - ret = priv->cfg->ops->lib->send_tx_power(priv); - - return ret; -} -EXPORT_SYMBOL(iwl_set_tx_power); - - void iwl_uninit_drv(struct iwl_priv *priv) { iwl_free_calib_results(priv); @@ -965,6 +915,35 @@ void iwl_uninit_drv(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_uninit_drv); +/* Low level driver call this function to update iwlcore with + * driver status. + */ +int iwlcore_low_level_notify(struct iwl_priv *priv, + enum iwlcore_card_notify notify) +{ + int ret; + switch (notify) { + case IWLCORE_INIT_EVT: + ret = iwl_rfkill_init(priv); + if (ret) + IWL_ERROR("Unable to initialize RFKILL system. " + "Ignoring error: %d\n", ret); + iwl_power_initialize(priv); + break; + case IWLCORE_START_EVT: + iwl_power_update_mode(priv, 1); + break; + case IWLCORE_STOP_EVT: + break; + case IWLCORE_REMOVE_EVT: + iwl_rfkill_unregister(priv); + break; + } + + return 0; +} +EXPORT_SYMBOL(iwlcore_low_level_notify); + int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags) { u32 stat_flags = 0; @@ -1225,14 +1204,12 @@ void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, ptr += sizeof(u32); time = iwl_read_targ_mem(priv, ptr); ptr += sizeof(u32); - if (mode == 0) { - /* data, ev */ - IWL_ERROR("EVT_LOG:0x%08x:%04u\n", time, ev); - } else { + if (mode == 0) + IWL_ERROR("0x%08x\t%04u\n", time, ev); /* data, ev */ + else { data = iwl_read_targ_mem(priv, ptr); ptr += sizeof(u32); - IWL_ERROR("EVT_LOGT:%010u:0x%08x:%04u\n", - time, data, ev); + IWL_ERROR("%010u\t0x%08x\t%04u\n", time, data, ev); } } } @@ -1295,114 +1272,4 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv) } EXPORT_SYMBOL(iwl_dump_nic_event_log); -void iwl_rf_kill_ct_config(struct iwl_priv *priv) -{ - struct iwl_ct_kill_config cmd; - unsigned long flags; - int ret = 0; - - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, - CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); - spin_unlock_irqrestore(&priv->lock, flags); - - cmd.critical_temperature_R = - cpu_to_le32(priv->hw_params.ct_kill_threshold); - - ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, - sizeof(cmd), &cmd); - if (ret) - IWL_ERROR("REPLY_CT_KILL_CONFIG_CMD failed\n"); - else - IWL_DEBUG_INFO("REPLY_CT_KILL_CONFIG_CMD succeeded, " - "critical temperature is %d\n", - cmd.critical_temperature_R); -} -EXPORT_SYMBOL(iwl_rf_kill_ct_config); - -/* - * CARD_STATE_CMD - * - * Use: Sets the device's internal card state to enable, disable, or halt - * - * When in the 'enable' state the card operates as normal. - * When in the 'disable' state, the card enters into a low power mode. - * When in the 'halt' state, the card is shut down and must be fully - * restarted to come back on. - */ -static int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) -{ - struct iwl_host_cmd cmd = { - .id = REPLY_CARD_STATE_CMD, - .len = sizeof(u32), - .data = &flags, - .meta.flags = meta_flag, - }; - - return iwl_send_cmd(priv, &cmd); -} - -void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv) -{ - unsigned long flags; - - if (test_bit(STATUS_RF_KILL_SW, &priv->status)) - return; - - IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO OFF\n"); - - iwl_scan_cancel(priv); - /* FIXME: This is a workaround for AP */ - if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, - CSR_UCODE_SW_BIT_RFKILL); - spin_unlock_irqrestore(&priv->lock, flags); - /* call the host command only if no hw rf-kill set */ - if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && - iwl_is_ready(priv)) - iwl_send_card_state(priv, - CARD_STATE_CMD_DISABLE, 0); - set_bit(STATUS_RF_KILL_SW, &priv->status); - /* make sure mac80211 stop sending Tx frame */ - if (priv->mac80211_registered) - ieee80211_stop_queues(priv->hw); - } -} -EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio); -int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv) -{ - unsigned long flags; - - if (!test_bit(STATUS_RF_KILL_SW, &priv->status)) - return 0; - - IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO ON\n"); - - spin_lock_irqsave(&priv->lock, flags); - iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - - clear_bit(STATUS_RF_KILL_SW, &priv->status); - spin_unlock_irqrestore(&priv->lock, flags); - - /* wake up ucode */ - msleep(10); - - spin_lock_irqsave(&priv->lock, flags); - iwl_read32(priv, CSR_UCODE_DRV_GP1); - if (!iwl_grab_nic_access(priv)) - iwl_release_nic_access(priv); - spin_unlock_irqrestore(&priv->lock, flags); - - if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { - IWL_DEBUG_RF_KILL("Can not turn radio back on - " - "disabled by HW switch\n"); - return 0; - } - - if (priv->is_open) - queue_work(priv->workqueue, &priv->restart); - return 1; -} -EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index 2838093b4459..6b5af7afbb25 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -88,11 +88,13 @@ struct iwl_hcmd_ops { struct iwl_hcmd_utils_ops { u16 (*get_hcmd_size)(u8 cmd_id, u16 len); u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data); +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB void (*gain_computation)(struct iwl_priv *priv, u32 *average_noise, u16 min_average_noise_antennat_i, u32 min_average_noise); void (*chain_noise_reset)(struct iwl_priv *priv); +#endif }; struct iwl_lib_ops { @@ -109,17 +111,15 @@ struct iwl_lib_ops { void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv, struct iwl_tx_queue *txq); void (*txq_set_sched)(struct iwl_priv *priv, u32 mask); +#ifdef CONFIG_IWL4965_HT /* aggregations */ int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo, int sta_id, int tid, u16 ssn_idx); int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx, u8 tx_fifo); +#endif /* CONFIG_IWL4965_HT */ /* setup Rx handler */ void (*rx_handler_setup)(struct iwl_priv *priv); - /* setup deferred work */ - void (*setup_deferred_work)(struct iwl_priv *priv); - /* cancel deferred work */ - void (*cancel_deferred_work)(struct iwl_priv *priv); /* alive notification after init uCode load */ void (*init_alive_start)(struct iwl_priv *priv); /* alive notification */ @@ -128,6 +128,8 @@ struct iwl_lib_ops { int (*is_valid_rtc_data_addr)(u32 addr); /* 1st ucode load */ int (*load_ucode)(struct iwl_priv *priv); + /* rfkill */ + void (*radio_kill_sw)(struct iwl_priv *priv, int disable_radio); /* power management */ struct { int (*init)(struct iwl_priv *priv); @@ -138,7 +140,6 @@ struct iwl_lib_ops { } apm_ops; /* power */ int (*set_power)(struct iwl_priv *priv, void *cmd); - int (*send_tx_power) (struct iwl_priv *priv); void (*update_chain_flags)(struct iwl_priv *priv); /* eeprom operations (as defined in iwl-eeprom.h) */ struct iwl_eeprom_ops eeprom_ops; @@ -232,53 +233,11 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv); int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, dma_addr_t addr, u16 len); int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); +#ifdef CONFIG_IWL4965_HT int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn); int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid); int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); - -/***************************************************** - * TX power - ****************************************************/ -int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force); - -/***************************************************** - * RF -Kill - here and not in iwl-rfkill.h to be available when - * RF-kill subsystem is not compiled. - ****************************************************/ -void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv); -int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv); - -/******************************************************************************* - * Rate - ******************************************************************************/ - -void iwl_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags, - struct ieee80211_tx_info *info); -int iwl_hwrate_to_plcp_idx(u32 rate_n_flags); - -static inline u8 iwl_hw_get_rate(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0xFF; -} -static inline u32 iwl_hw_get_rate_n_flags(__le32 rate_n_flags) -{ - return le32_to_cpu(rate_n_flags) & 0x1FFFF; -} -static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) -{ - return cpu_to_le32(flags|(u32)rate); -} - -/******************************************************************************* - * Scanning - ******************************************************************************/ -void iwl_init_scan_params(struct iwl_priv *priv); -int iwl_scan_cancel(struct iwl_priv *priv); -int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms); -const char *iwl_escape_essid(const char *essid, u8 essid_len); -int iwl_scan_initiate(struct iwl_priv *priv); -void iwl_setup_rx_scan_handlers(struct iwl_priv *priv); -void iwl_setup_scan_deferred_work(struct iwl_priv *priv); +#endif /***************************************************** * S e n d i n g H o s t C o m m a n d s * @@ -327,7 +286,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv); #define STATUS_POWER_PMI 16 #define STATUS_FW_ERROR 17 #define STATUS_CONF_PENDING 18 -#define STATUS_MODE_PENDING 19 static inline int iwl_is_ready(struct iwl_priv *priv) @@ -364,10 +322,19 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv) return iwl_is_ready(priv); } -extern void iwl_rf_kill_ct_config(struct iwl_priv *priv); + +enum iwlcore_card_notify { + IWLCORE_INIT_EVT = 0, + IWLCORE_START_EVT = 1, + IWLCORE_STOP_EVT = 2, + IWLCORE_REMOVE_EVT = 3, +}; + +int iwlcore_low_level_notify(struct iwl_priv *priv, + enum iwlcore_card_notify notify); extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags); extern int iwl_verify_ucode(struct iwl_priv *priv); -extern int iwl_send_lq_cmd(struct iwl_priv *priv, +int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_link_quality_cmd *lq, u8 flags); static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h b/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h index 58384805a494..11de561c7bf8 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -55,9 +55,10 @@ struct iwl_debugfs { struct dentry *file_log_event; } dbgfs_data_files; struct dir_rf_files { +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB struct dentry *file_disable_sensitivity; struct dentry *file_disable_chain_noise; - struct dentry *file_disable_tx_power; +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ } dbgfs_rf_files; u32 sram_offset; u32 sram_len; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c index ed948dc59b3d..29e16ba69cdb 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -255,18 +255,21 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); pos += scnprintf(buf + pos, bufsz - pos, "seq_num\t\ttxq_id"); +#ifdef CONFIG_IWL4965_HT pos += scnprintf(buf + pos, bufsz - pos, "\tframe_count\twait_for_ba\t"); pos += scnprintf(buf + pos, bufsz - pos, "start_idx\tbitmap0\t"); pos += scnprintf(buf + pos, bufsz - pos, "bitmap1\trate_n_flags"); +#endif pos += scnprintf(buf + pos, bufsz - pos, "\n"); for (j = 0; j < MAX_TID_COUNT; j++) { pos += scnprintf(buf + pos, bufsz - pos, "[%d]:\t\t%u", j, station->tid[j].seq_number); +#ifdef CONFIG_IWL4965_HT pos += scnprintf(buf + pos, bufsz - pos, "\t%u\t\t%u\t\t%u\t\t", station->tid[j].agg.txq_id, @@ -277,6 +280,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, station->tid[j].agg.start_idx, (unsigned long long)station->tid[j].agg.bitmap, station->tid[j].agg.rate_n_flags); +#endif pos += scnprintf(buf + pos, bufsz - pos, "\n"); } pos += scnprintf(buf + pos, bufsz - pos, "\n"); @@ -385,10 +389,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) DEBUGFS_ADD_FILE(stations, data); DEBUGFS_ADD_FILE(rx_statistics, data); DEBUGFS_ADD_FILE(tx_statistics, data); +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); DEBUGFS_ADD_BOOL(disable_chain_noise, rf, &priv->disable_chain_noise_cal); - DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal); +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ return 0; err: @@ -414,9 +419,10 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv) DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); DEBUGFS_REMOVE(priv->dbgfs->dir_data); +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); - DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ DEBUGFS_REMOVE(priv->dbgfs->dir_rf); DEBUGFS_REMOVE(priv->dbgfs->dir_drv); kfree(priv->dbgfs); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h index 81ff4c2c6a5a..802f1a12b1aa 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -29,8 +29,8 @@ * Please use iwl-4965-hw.h for hardware-related definitions. */ -#ifndef __iwl_dev_h__ -#define __iwl_dev_h__ +#ifndef __iwl_4965_h__ +#define __iwl_4965_h__ #include /* for struct pci_device_id */ #include @@ -157,11 +157,44 @@ struct iwl4965_channel_tgh_info { s64 last_radar_time; }; +/* current Tx power values to use, one for each rate for each channel. + * requested power is limited by: + * -- regulatory EEPROM limits for this channel + * -- hardware capabilities (clip-powers) + * -- spectrum management + * -- user preference (e.g. iwconfig) + * when requested power is set, base power index must also be set. */ +struct iwl4965_channel_power_info { + struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 base_power_index; /* gain index for power at factory temp. */ + s8 requested_power; /* power (dBm) requested for this chnl/rate */ +}; + +/* current scan Tx power values to use, one for each scan rate for each + * channel. */ +struct iwl4965_scan_power_info { + struct iwl4965_tx_power tpc; /* actual radio and DSP gain settings */ + s8 power_table_index; /* actual (compenst'd) index into gain table */ + s8 requested_power; /* scan pwr (dBm) requested for chnl/rate */ +}; + +/* For fat_extension_channel */ +enum { + HT_IE_EXT_CHANNEL_NONE = 0, + HT_IE_EXT_CHANNEL_ABOVE, + HT_IE_EXT_CHANNEL_INVALID, + HT_IE_EXT_CHANNEL_BELOW, + HT_IE_EXT_CHANNEL_MAX +}; + /* * One for each channel, holds all channel setup data * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant * with one another! */ +#define IWL4965_MAX_RATE (33) + struct iwl_channel_info { struct iwl4965_channel_tgd_info tgd; struct iwl4965_channel_tgh_info tgh; @@ -180,6 +213,11 @@ struct iwl_channel_info { u8 band_index; /* 0-4, maps channel to band1/2/3/4/5 */ enum ieee80211_band band; + /* Radio/DSP gain settings for each "normal" data Tx rate. + * These include, in addition to RF and DSP gain, a few fields for + * remembering/modifying gain settings (indexes). */ + struct iwl4965_channel_power_info power_info[IWL4965_MAX_RATE]; + /* FAT channel info */ s8 fat_max_power_avg; /* (dBm) regul. eeprom, normal Tx, any rate */ s8 fat_curr_txpow; /* (dBm) regulatory/spectrum/user (not h/w) */ @@ -187,6 +225,9 @@ struct iwl_channel_info { s8 fat_scan_power; /* (dBm) eeprom, direct scans, any rate */ u8 fat_flags; /* flags copied from EEPROM */ u8 fat_extension_channel; /* HT_IE_EXT_CHANNEL_* */ + + /* Radio/DSP gain settings for each scan rate, for directed scans. */ + struct iwl4965_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES]; }; struct iwl4965_clip_group { @@ -360,6 +401,7 @@ struct iwl_rx_queue { #define IWL_INVALID_RATE 0xFF #define IWL_INVALID_VALUE -1 +#ifdef CONFIG_IWL4965_HT /** * struct iwl_ht_agg -- aggregation status while waiting for block-ack * @txq_id: Tx queue used for Tx attempt @@ -388,11 +430,14 @@ struct iwl_ht_agg { u8 state; }; +#endif /* CONFIG_IWL4965_HT */ struct iwl_tid_data { u16 seq_number; u16 tfds_in_queue; +#ifdef CONFIG_IWL4965_HT struct iwl_ht_agg agg; +#endif /* CONFIG_IWL4965_HT */ }; struct iwl_hw_key { @@ -480,7 +525,7 @@ struct fw_desc { }; /* uCode file layout */ -struct iwl_ucode { +struct iwl4965_ucode { __le32 ver; /* major/minor/subminor */ __le32 inst_size; /* bytes of runtime instructions */ __le32 data_size; /* bytes of runtime data */ @@ -542,7 +587,6 @@ struct iwl_sensitivity_ranges { * @max_xxx_size: for ucode uses * @ct_kill_threshold: temperature threshold * @struct iwl_sensitivity_ranges: range of sensitivity values - * @first_ampdu_q: first HW queue available for ampdu */ struct iwl_hw_params { u16 max_txq_num; @@ -562,8 +606,9 @@ struct iwl_hw_params { u32 max_data_size; u32 max_bsm_size; u32 ct_kill_threshold; /* value in hw-dependent units */ +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB const struct iwl_sensitivity_ranges *sens; - u8 first_ampdu_q; +#endif }; #define HT_SHORT_GI_20MHZ (1 << 0) @@ -593,8 +638,15 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags, struct ieee80211_ht_info *ht_info); extern int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *header); +extern int iwl4965_power_init_handle(struct iwl_priv *priv); +extern void iwl4965_handle_data_packet_monitor(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb, + void *data, short len, + struct ieee80211_rx_status *stats, + u16 phy_flags); extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header); +extern int iwl4965_calc_db_from_ratio(int sig_ratio); extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, struct ieee80211_hdr *hdr, @@ -602,7 +654,18 @@ extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, extern void iwl4965_update_chain_flags(struct iwl_priv *priv); int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src); +int iwl4965_init_geos(struct iwl_priv *priv); +void iwl4965_free_geos(struct iwl_priv *priv); + extern const u8 iwl_bcast_addr[ETH_ALEN]; +int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); + +/* + * Currently used by iwl-3945-rs... look at restructuring so that it doesn't + * call this... todo... fix that. +*/ +extern u8 iwl4965_sync_station(struct iwl_priv *priv, int sta_id, + u16 tx_rate, u8 flags); /****************************************************************************** * @@ -620,16 +683,38 @@ extern const u8 iwl_bcast_addr[ETH_ALEN]; * iwl4965_mac_ <-- mac80211 callback * ****************************************************************************/ +extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); +extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); +extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); extern int iwl_rxq_stop(struct iwl_priv *priv); extern void iwl_txq_ctx_stop(struct iwl_priv *priv); +extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, struct iwl_frame *frame, u8 rate); +extern void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv, + struct iwl_cmd *cmd, + struct ieee80211_tx_info *info, + struct ieee80211_hdr *hdr, + int sta_id, int tx_id); +extern int iwl4965_hw_reg_send_txpower(struct iwl_priv *priv); +extern int iwl4965_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); extern void iwl4965_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); extern void iwl4965_disable_events(struct iwl_priv *priv); +extern int iwl4965_get_temperature(const struct iwl_priv *priv); extern void iwl4965_rx_reply_rx(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb); +/** + * iwl_find_station - Find station id for a given BSSID + * @bssid: MAC address of station ID to find + * + * NOTE: This should not be hardware specific but the code has + * not yet been merged into a single common layer for managing the + * station tables. + */ +extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid); + extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel); extern int iwl_queue_space(const struct iwl_queue *q); static inline int iwl_queue_used(const struct iwl_queue *q, int i) @@ -653,17 +738,37 @@ static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge) struct iwl_priv; +extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio); /* * Forward declare iwl-4965.c functions for iwl-base.c */ +extern int iwl4965_tx_queue_update_wr_ptr(struct iwl_priv *priv, + struct iwl_tx_queue *txq, + u16 byte_cnt); +extern int iwl4965_alive_notify(struct iwl_priv *priv); +extern void iwl4965_update_rate_scaling(struct iwl_priv *priv, u8 mode); extern void iwl4965_rf_kill_ct_config(struct iwl_priv *priv); - +extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, + u32 rate_n_flags, + struct ieee80211_tx_info *info); + +#ifdef CONFIG_IWL4965_HT +extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, + struct ieee80211_ht_info *ht_info, + enum ieee80211_band band); +void iwl4965_set_rxon_ht(struct iwl_priv *priv, + struct iwl_ht_info *ht_info); int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw, enum ieee80211_ampdu_mlme_action action, const u8 *addr, u16 tid, u16 *ssn); int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id); +#else +static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv, + struct ieee80211_ht_info *ht_info, + enum ieee80211_band band) {} +#endif /*CONFIG_IWL4965_HT */ /* Structures, enum, and defines specific to the 4965 */ #define IWL_KW_SIZE 0x1000 /*4k */ @@ -687,6 +792,11 @@ struct iwl_kw { #define IWL_OPERATION_MODE_MIXED 2 #define IWL_OPERATION_MODE_20MHZ 3 +#define IWL_EXT_CHANNEL_OFFSET_NONE 0 +#define IWL_EXT_CHANNEL_OFFSET_ABOVE 1 +#define IWL_EXT_CHANNEL_OFFSET_RESERVE1 2 +#define IWL_EXT_CHANNEL_OFFSET_BELOW 3 + #define IWL_TX_CRC_SIZE 4 #define IWL_TX_DELIMITER_SIZE 4 @@ -782,6 +892,7 @@ enum ucode_type { UCODE_RT }; +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB /* Sensitivity calib data */ struct iwl_sensitivity_data { u32 auto_corr_ofdm; @@ -823,6 +934,7 @@ struct iwl_chain_noise_data { u8 delta_gain_code[NUM_RX_CHAINS]; u8 radio_write; }; +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ #define EEPROM_SEM_TIMEOUT 10 /* milliseconds */ #define EEPROM_SEM_RETRY_LIMIT 1000 /* number of attempts (not time) */ @@ -894,8 +1006,7 @@ struct iwl_priv { int one_direct_scan; u8 direct_ssid_len; u8 direct_ssid[IW_ESSID_MAX_SIZE]; - struct iwl_scan_cmd *scan; - u32 scan_tx_ant[IEEE80211_NUM_BANDS]; + struct iwl4965_scan_cmd *scan; /* spinlock */ spinlock_t lock; /* protect general shared data */ @@ -956,11 +1067,15 @@ struct iwl_priv { u8 assoc_station_added; u8 use_ant_b_for_management_frame; /* Tx antenna selection */ u8 start_calib; +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB struct iwl_sensitivity_data sensitivity_data; struct iwl_chain_noise_data chain_noise_data; __le16 sensitivity_tbl[HD_TABLE_SIZE]; +#endif /*CONFIG_IWLWIFI_RUN_TIME_CALIB*/ +#ifdef CONFIG_IWL4965_HT struct iwl_ht_info current_ht_config; +#endif u8 last_phy_res[100]; /* Rate scaling data */ @@ -1082,11 +1197,15 @@ struct iwl_priv { struct delayed_work init_alive_start; struct delayed_work alive_start; + struct delayed_work activity_timer; + struct delayed_work thermal_periodic; + struct delayed_work gather_stats; struct delayed_work scan_check; struct delayed_work post_associate; - /* TX Power */ - s8 tx_power_user_lmt; - s8 tx_power_channel_lmt; + +#define IWL_DEFAULT_TX_POWER 0x0F + s8 user_txpower_limit; + s8 max_channel_txpower_limit; #ifdef CONFIG_PM u32 pm_state[16]; @@ -1104,10 +1223,13 @@ struct iwl_priv { #endif /* CONFIG_IWLWIFI_DEBUG */ struct work_struct txpower_work; +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB u32 disable_sens_cal; u32 disable_chain_noise_cal; - u32 disable_tx_power_cal; - struct work_struct run_time_calib_work; +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ +#ifdef CONFIG_IWL4965_RUN_TIME_CALIB + struct work_struct sensitivity_work; +#endif /* CONFIG_IWL4965_RUN_TIME_CALIB */ struct timer_list statistics_periodic; }; /*iwl_priv */ @@ -1128,6 +1250,18 @@ static inline const char *iwl_get_tx_fail_reason(u32 status) { return ""; } #endif +#ifdef CONFIG_IWL4965_HT +static inline int iwl_get_ra_sta_id(struct iwl_priv *priv, + struct ieee80211_hdr *hdr) +{ + if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { + return IWL_AP_ID; + } else { + u8 *da = ieee80211_get_DA(hdr); + return iwl_find_station(priv, da); + } +} + static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, int txq_id, int idx) { @@ -1136,6 +1270,7 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv, txb[idx].skb[0]->data; return NULL; } +#endif static inline int iwl_is_associated(struct iwl_priv *priv) @@ -1197,4 +1332,4 @@ extern const struct iwl_channel_info *iwl_get_channel_info( /* Requires full declaration of iwl_priv before including */ -#endif /* __iwl_dev_h__ */ +#endif /* __iwl4965_4965_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c index 4a08a1b50979..11f9d9557a0e 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -382,8 +382,8 @@ static int iwl_set_fat_chan_info(struct iwl_priv *priv, if (!is_channel_valid(ch_info)) return -1; - IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x %ddBm):" - " Ad-Hoc %ssupported\n", + IWL_DEBUG_INFO("FAT Ch. %d [%sGHz] %s%s%s%s%s(0x%02x" + " %ddBm): Ad-Hoc %ssupported\n", ch_info->channel, is_channel_a_band(ch_info) ? "5.2" : "2.4", @@ -470,11 +470,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) /* Copy the run-time flags so they are there even on * invalid channels */ ch_info->flags = eeprom_ch_info[ch].flags; - /* First write that fat is not enabled, and then enable - * one by one */ - ch_info->fat_extension_channel = - (IEEE80211_CHAN_NO_FAT_ABOVE | - IEEE80211_CHAN_NO_FAT_BELOW); if (!(is_channel_valid(ch_info))) { IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - " @@ -493,8 +488,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) ch_info->scan_power = eeprom_ch_info[ch].max_power_avg; ch_info->min_power = 0; - IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm):" - " Ad-Hoc %ssupported\n", + IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x" + " %ddBm): Ad-Hoc %ssupported\n", ch_info->channel, is_channel_a_band(ch_info) ? "5.2" : "2.4", @@ -515,8 +510,8 @@ int iwl_init_channel_map(struct iwl_priv *priv) /* Set the user_txpower_limit to the highest power * supported by any channel */ if (eeprom_ch_info[ch].max_power_avg > - priv->tx_power_user_lmt) - priv->tx_power_user_lmt = + priv->user_txpower_limit) + priv->user_txpower_limit = eeprom_ch_info[ch].max_power_avg; ch_info++; @@ -539,14 +534,12 @@ int iwl_init_channel_map(struct iwl_priv *priv) for (ch = 0; ch < eeprom_ch_count; ch++) { if ((band == 6) && - ((eeprom_ch_index[ch] == 5) || - (eeprom_ch_index[ch] == 6) || - (eeprom_ch_index[ch] == 7))) - /* both are allowed: above and below */ - fat_extension_chan = 0; + ((eeprom_ch_index[ch] == 5) || + (eeprom_ch_index[ch] == 6) || + (eeprom_ch_index[ch] == 7))) + fat_extension_chan = HT_IE_EXT_CHANNEL_MAX; else - fat_extension_chan = - IEEE80211_CHAN_NO_FAT_BELOW; + fat_extension_chan = HT_IE_EXT_CHANNEL_ABOVE; /* Set up driver's info for lower half */ iwl_set_fat_chan_info(priv, ieeeband, @@ -558,7 +551,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) iwl_set_fat_chan_info(priv, ieeeband, (eeprom_ch_index[ch] + 4), &(eeprom_ch_info[ch]), - IEEE80211_CHAN_NO_FAT_ABOVE); + HT_IE_EXT_CHANNEL_BELOW); } } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h b/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h index 41eed6793328..dedefa06ad8f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-helpers.h @@ -139,12 +139,123 @@ static inline void iwl_set_bits16(__le16 *dst, u8 pos, u8 len, int val) #define IWL_MASK(lo, hi) ((1 << (hi)) | ((1 << (hi)) - (1 << (lo)))) +#define IEEE80211_CHAN_W_RADAR_DETECT 0x00000010 + static inline struct ieee80211_conf *ieee80211_get_hw_conf( struct ieee80211_hw *hw) { return &hw->conf; } +#define QOS_CONTROL_LEN 2 + + +static inline int ieee80211_is_management(u16 fc) +{ + return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT; +} + +static inline int ieee80211_is_control(u16 fc) +{ + return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL; +} + +static inline int ieee80211_is_data(u16 fc) +{ + return (fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA; +} + +static inline int ieee80211_is_back_request(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BACK_REQ); +} + +static inline int ieee80211_is_probe_response(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP); +} + +static inline int ieee80211_is_probe_request(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_REQ); +} + +static inline int ieee80211_is_beacon(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON); +} + +static inline int ieee80211_is_atim(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ATIM); +} + +static inline int ieee80211_is_assoc_request(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); +} + +static inline int ieee80211_is_assoc_response(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_RESP); +} + +static inline int ieee80211_is_auth(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); +} + +static inline int ieee80211_is_deauth(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); +} + +static inline int ieee80211_is_disassoc(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ); +} + +static inline int ieee80211_is_reassoc_request(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ); +} + +static inline int ieee80211_is_reassoc_response(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_RESP); +} + +static inline int ieee80211_is_qos_data(u16 fc) +{ + return ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && + ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA); +} +/** + * ieee80211_get_qos_ctrl - get pointer to the QoS control field + * + * This function returns the pointer to 802.11 header QoS field (2 bytes) + * This function doesn't check whether hdr is a QoS hdr, use with care + * @hdr: struct ieee80211_hdr *hdr + * @hdr_len: header length + */ + +static inline u8 *ieee80211_get_qos_ctrl(struct ieee80211_hdr *hdr, int hdr_len) +{ + return ((u8 *) hdr + hdr_len - QOS_CONTROL_LEN); +} + static inline int iwl_check_bits(unsigned long field, unsigned long mask) { return ((field & mask) == mask) ? 1 : 0; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 5f098747cf95..59c8a716bd96 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.c @@ -55,13 +55,13 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) switch (state) { case RFKILL_STATE_ON: - iwl_radio_kill_sw_enable_radio(priv); + priv->cfg->ops->lib->radio_kill_sw(priv, 0); /* if HW rf-kill is set dont allow ON state */ if (iwl_is_rfkill(priv)) err = -EBUSY; break; case RFKILL_STATE_OFF: - iwl_radio_kill_sw_disable_radio(priv); + priv->cfg->ops->lib->radio_kill_sw(priv, 1); if (!iwl_is_rfkill(priv)) err = -EBUSY; break; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h index b3c04dba45cf..a7f04b855403 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rfkill.h @@ -33,6 +33,7 @@ struct iwl_priv; #include #include + #ifdef CONFIG_IWLWIFI_RFKILL struct iwl_rfkill_mngr { struct rfkill *rfkill; diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c index c24844802a88..cc61c937320f 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -451,6 +451,7 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { +#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_missed_beacon_notif *missed_beacon; @@ -464,5 +465,6 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv, if (!test_bit(STATUS_SCANNING, &priv->status)) iwl_init_sensitivity(priv); } +#endif /* CONFIG_IWLWIFI_RUN_TIME_CALIB */ } EXPORT_SYMBOL(iwl_rx_missed_beacon_notif); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c b/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c deleted file mode 100644 index 5ca181f7125d..000000000000 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-scan.c +++ /dev/null @@ -1,921 +0,0 @@ -/****************************************************************************** - * - * GPL LICENSE SUMMARY - * - * Copyright(c) 2008 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, - * USA - * - * The full GNU General Public License is included in this distribution - * in the file called LICENSE.GPL. - * - * Contact Information: - * Tomas Winkler - * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - *****************************************************************************/ -#include -#include - -#include "iwl-eeprom.h" -#include "iwl-dev.h" -#include "iwl-core.h" -#include "iwl-sta.h" -#include "iwl-io.h" -#include "iwl-helpers.h" - -/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after - * sending probe req. This should be set long enough to hear probe responses - * from more than one AP. */ -#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ -#define IWL_ACTIVE_DWELL_TIME_52 (10) - -/* For faster active scanning, scan will move to the next channel if fewer than - * PLCP_QUIET_THRESH packets are heard on this channel within - * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell - * time if it's a quiet channel (nothing responded to our probe, and there's - * no other traffic). - * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ -#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ -#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ - -/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. - * Must be set longer than active dwell time. - * For the most reliable scan, set > AP beacon interval (typically 100msec). */ -#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ -#define IWL_PASSIVE_DWELL_TIME_52 (10) -#define IWL_PASSIVE_DWELL_BASE (100) -#define IWL_CHANNEL_TUNE_TIME 5 - -static int scan_tx_ant[3] = { - RATE_MCS_ANT_A_MSK, RATE_MCS_ANT_B_MSK, RATE_MCS_ANT_C_MSK -}; - -static int iwl_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - - - -const char *iwl_escape_essid(const char *essid, u8 essid_len) -{ - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; - - if (iwl_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "", sizeof("")); - return escaped; - } - - essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else - *d++ = *s++; - } - *d = '\0'; - return escaped; -} -EXPORT_SYMBOL(iwl_escape_essid); - -/** - * iwl_scan_cancel - Cancel any currently executing HW scan - * - * NOTE: priv->mutex is not required before calling this function - */ -int iwl_scan_cancel(struct iwl_priv *priv) -{ - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCANNING, &priv->status); - return 0; - } - - if (test_bit(STATUS_SCANNING, &priv->status)) { - if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN("Queuing scan abort.\n"); - set_bit(STATUS_SCAN_ABORTING, &priv->status); - queue_work(priv->workqueue, &priv->abort_scan); - - } else - IWL_DEBUG_SCAN("Scan abort already in progress.\n"); - - return test_bit(STATUS_SCANNING, &priv->status); - } - - return 0; -} -EXPORT_SYMBOL(iwl_scan_cancel); -/** - * iwl_scan_cancel_timeout - Cancel any currently executing HW scan - * @ms: amount of time to wait (in milliseconds) for scan to abort - * - * NOTE: priv->mutex must be held before calling this function - */ -int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) -{ - unsigned long now = jiffies; - int ret; - - ret = iwl_scan_cancel(priv); - if (ret && ms) { - mutex_unlock(&priv->mutex); - while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && - test_bit(STATUS_SCANNING, &priv->status)) - msleep(1); - mutex_lock(&priv->mutex); - - return test_bit(STATUS_SCANNING, &priv->status); - } - - return ret; -} -EXPORT_SYMBOL(iwl_scan_cancel_timeout); - -static int iwl_send_scan_abort(struct iwl_priv *priv) -{ - int ret = 0; - struct iwl_rx_packet *res; - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_ABORT_CMD, - .meta.flags = CMD_WANT_SKB, - }; - - /* If there isn't a scan actively going on in the hardware - * then we are in between scan bands and not actually - * actively scanning, so don't send the abort command */ - if (!test_bit(STATUS_SCAN_HW, &priv->status)) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return 0; - } - - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) { - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - return ret; - } - - res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; - if (res->u.status != CAN_ABORT_STATUS) { - /* The scan abort will return 1 for success or - * 2 for "failure". A failure condition can be - * due to simply not being in an active scan which - * can occur if we send the scan abort before we - * the microcode has notified us that a scan is - * completed. */ - IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - clear_bit(STATUS_SCAN_HW, &priv->status); - } - - dev_kfree_skb_any(cmd.meta.u.skb); - - return ret; -} - - -/* Service response to REPLY_SCAN_CMD (0x80) */ -static void iwl_rx_reply_scan(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; - struct iwl_scanreq_notification *notif = - (struct iwl_scanreq_notification *)pkt->u.raw; - - IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); -#endif -} - -/* Service SCAN_START_NOTIFICATION (0x82) */ -static void iwl_rx_scan_start_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; - struct iwl_scanstart_notification *notif = - (struct iwl_scanstart_notification *)pkt->u.raw; - priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); - IWL_DEBUG_SCAN("Scan start: " - "%d [802.11%s] " - "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", - notif->channel, - notif->band ? "bg" : "a", - notif->tsf_high, - notif->tsf_low, notif->status, notif->beacon_timer); -} - -/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ -static void iwl_rx_scan_results_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ -#ifdef CONFIG_IWLWIFI_DEBUG - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; - struct iwl_scanresults_notification *notif = - (struct iwl_scanresults_notification *)pkt->u.raw; - - IWL_DEBUG_SCAN("Scan ch.res: " - "%d [802.11%s] " - "(TSF: 0x%08X:%08X) - %d " - "elapsed=%lu usec (%dms since last)\n", - notif->channel, - notif->band ? "bg" : "a", - le32_to_cpu(notif->tsf_high), - le32_to_cpu(notif->tsf_low), - le32_to_cpu(notif->statistics[0]), - le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, - jiffies_to_msecs(elapsed_jiffies - (priv->last_scan_jiffies, jiffies))); -#endif - - priv->last_scan_jiffies = jiffies; - priv->next_scan_jiffies = 0; -} - -/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ -static void iwl_rx_scan_complete_notif(struct iwl_priv *priv, - struct iwl_rx_mem_buffer *rxb) -{ - struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; - struct iwl_scancomplete_notification *scan_notif = (void *)pkt->u.raw; - - IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", - scan_notif->scanned_channels, - scan_notif->tsf_low, - scan_notif->tsf_high, scan_notif->status); - - /* The HW is no longer scanning */ - clear_bit(STATUS_SCAN_HW, &priv->status); - - /* The scan completion notification came in, so kill that timer... */ - cancel_delayed_work(&priv->scan_check); - - IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", - (priv->scan_bands == 2) ? "2.4" : "5.2", - jiffies_to_msecs(elapsed_jiffies - (priv->scan_pass_start, jiffies))); - - /* Remove this scanned band from the list - * of pending bands to scan */ - priv->scan_bands--; - - /* If a request to abort was given, or the scan did not succeed - * then we reset the scan state machine and terminate, - * re-queuing another scan if one has been requested */ - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_INFO("Aborted scan completed.\n"); - clear_bit(STATUS_SCAN_ABORTING, &priv->status); - } else { - /* If there are more bands on this scan pass reschedule */ - if (priv->scan_bands > 0) - goto reschedule; - } - - priv->last_scan_jiffies = jiffies; - priv->next_scan_jiffies = 0; - IWL_DEBUG_INFO("Setting scan to off\n"); - - clear_bit(STATUS_SCANNING, &priv->status); - - IWL_DEBUG_INFO("Scan took %dms\n", - jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies))); - - queue_work(priv->workqueue, &priv->scan_completed); - - return; - -reschedule: - priv->scan_pass_start = jiffies; - queue_work(priv->workqueue, &priv->request_scan); -} - -void iwl_setup_rx_scan_handlers(struct iwl_priv *priv) -{ - /* scan handlers */ - priv->rx_handlers[REPLY_SCAN_CMD] = iwl_rx_reply_scan; - priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl_rx_scan_start_notif; - priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = - iwl_rx_scan_results_notif; - priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = - iwl_rx_scan_complete_notif; -} -EXPORT_SYMBOL(iwl_setup_rx_scan_handlers); - -static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band) -{ - if (band == IEEE80211_BAND_5GHZ) - return IWL_ACTIVE_DWELL_TIME_52; - else - return IWL_ACTIVE_DWELL_TIME_24; -} - -static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, - enum ieee80211_band band) -{ - u16 active = iwl_get_active_dwell_time(priv, band); - u16 passive = (band != IEEE80211_BAND_5GHZ) ? - IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : - IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; - - if (iwl_is_associated(priv)) { - /* If we're associated, we clamp the maximum passive - * dwell time to be 98% of the beacon interval (minus - * 2 * channel tune time) */ - passive = priv->beacon_int; - if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) - passive = IWL_PASSIVE_DWELL_BASE; - passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; - } - - if (passive <= active) - passive = active + 1; - - return passive; -} - -static int iwl_get_channels_for_scan(struct iwl_priv *priv, - enum ieee80211_band band, - u8 is_active, u8 direct_mask, - struct iwl_scan_channel *scan_ch) -{ - const struct ieee80211_channel *channels = NULL; - const struct ieee80211_supported_band *sband; - const struct iwl_channel_info *ch_info; - u16 passive_dwell = 0; - u16 active_dwell = 0; - int added, i; - - sband = iwl_get_hw_mode(priv, band); - if (!sband) - return 0; - - channels = sband->channels; - - active_dwell = iwl_get_active_dwell_time(priv, band); - passive_dwell = iwl_get_passive_dwell_time(priv, band); - - for (i = 0, added = 0; i < sband->n_channels; i++) { - if (channels[i].flags & IEEE80211_CHAN_DISABLED) - continue; - - scan_ch->channel = - ieee80211_frequency_to_channel(channels[i].center_freq); - - ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); - if (!is_channel_valid(ch_info)) { - IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", - scan_ch->channel); - continue; - } - - if (!is_active || is_channel_passive(ch_info) || - (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) - scan_ch->type = 0; - else - scan_ch->type = 1; - - if (scan_ch->type & 1) - scan_ch->type |= (direct_mask << 1); - - scan_ch->active_dwell = cpu_to_le16(active_dwell); - scan_ch->passive_dwell = cpu_to_le16(passive_dwell); - - /* Set txpower levels to defaults */ - scan_ch->dsp_atten = 110; - - if (band == IEEE80211_BAND_5GHZ) - scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3; - else { - scan_ch->tx_gain = ((1 << 5) | (5 << 3)); - /* NOTE: if we were doing 6Mb OFDM for scans we'd use - * power level: - * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3; - */ - } - - IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", - scan_ch->channel, - (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", - (scan_ch->type & 1) ? - active_dwell : passive_dwell); - - scan_ch++; - added++; - } - - IWL_DEBUG_SCAN("total channels to scan %d \n", added); - return added; -} - -void iwl_init_scan_params(struct iwl_priv *priv) -{ - if (!priv->scan_tx_ant[IEEE80211_BAND_5GHZ]) - priv->scan_tx_ant[IEEE80211_BAND_5GHZ] = RATE_MCS_ANT_INIT_IND; - if (!priv->scan_tx_ant[IEEE80211_BAND_2GHZ]) - priv->scan_tx_ant[IEEE80211_BAND_2GHZ] = RATE_MCS_ANT_INIT_IND; -} - -int iwl_scan_initiate(struct iwl_priv *priv) -{ - if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { - IWL_ERROR("APs don't scan.\n"); - return 0; - } - - if (!iwl_is_ready_rf(priv)) { - IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); - return -EIO; - } - - if (test_bit(STATUS_SCANNING, &priv->status)) { - IWL_DEBUG_SCAN("Scan already in progress.\n"); - return -EAGAIN; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN("Scan request while abort pending. " - "Queuing.\n"); - return -EAGAIN; - } - - IWL_DEBUG_INFO("Starting scan...\n"); - priv->scan_bands = 2; - set_bit(STATUS_SCANNING, &priv->status); - priv->scan_start = jiffies; - priv->scan_pass_start = priv->scan_start; - - queue_work(priv->workqueue, &priv->request_scan); - - return 0; -} -EXPORT_SYMBOL(iwl_scan_initiate); - -#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) - -static void iwl_bg_scan_check(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, scan_check.work); - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - mutex_lock(&priv->mutex); - if (test_bit(STATUS_SCANNING, &priv->status) || - test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " - "adapter (%dms)\n", - jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); - - if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) - iwl_send_scan_abort(priv); - } - mutex_unlock(&priv->mutex); -} -/** - * iwl_supported_rate_to_ie - fill in the supported rate in IE field - * - * return : set the bit for each supported rate insert in ie - */ -static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, - u16 basic_rate, int *left) -{ - u16 ret_rates = 0, bit; - int i; - u8 *cnt = ie; - u8 *rates = ie + 1; - - for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { - if (bit & supported_rate) { - ret_rates |= bit; - rates[*cnt] = iwl_rates[i].ieee | - ((bit & basic_rate) ? 0x80 : 0x00); - (*cnt)++; - (*left)--; - if ((*left <= 0) || - (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) - break; - } - } - - return ret_rates; -} - - -static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, - u8 *pos, int *left) -{ - struct ieee80211_ht_cap *ht_cap; - - if (!sband || !sband->ht_info.ht_supported) - return; - - if (*left < sizeof(struct ieee80211_ht_cap)) - return; - - *pos++ = sizeof(struct ieee80211_ht_cap); - ht_cap = (struct ieee80211_ht_cap *) pos; - - ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); - memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); - ht_cap->ampdu_params_info = - (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | - ((sband->ht_info.ampdu_density << 2) & - IEEE80211_HT_CAP_AMPDU_DENSITY); - *left -= sizeof(struct ieee80211_ht_cap); -} - -/** - * iwl_fill_probe_req - fill in all required fields and IE for probe request - */ - -static u16 iwl_fill_probe_req(struct iwl_priv *priv, - enum ieee80211_band band, - struct ieee80211_mgmt *frame, - int left) -{ - int len = 0; - u8 *pos = NULL; - u16 active_rates, ret_rates, cck_rates, active_rate_basic; - const struct ieee80211_supported_band *sband = - iwl_get_hw_mode(priv, band); - - - /* Make sure there is enough space for the probe request, - * two mandatory IEs and the data */ - left -= 24; - if (left < 0) - return 0; - - frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); - memcpy(frame->sa, priv->mac_addr, ETH_ALEN); - memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); - frame->seq_ctrl = 0; - - len += 24; - - /* ...next IE... */ - pos = &frame->u.probe_req.variable[0]; - - /* fill in our indirect SSID IE */ - left -= 2; - if (left < 0) - return 0; - *pos++ = WLAN_EID_SSID; - *pos++ = 0; - - len += 2; - - /* fill in supported rate */ - left -= 2; - if (left < 0) - return 0; - - *pos++ = WLAN_EID_SUPP_RATES; - *pos = 0; - - /* exclude 60M rate */ - active_rates = priv->rates_mask; - active_rates &= ~IWL_RATE_60M_MASK; - - active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; - - cck_rates = IWL_CCK_RATES_MASK & active_rates; - ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, - active_rate_basic, &left); - active_rates &= ~ret_rates; - - ret_rates = iwl_supported_rate_to_ie(pos, active_rates, - active_rate_basic, &left); - active_rates &= ~ret_rates; - - len += 2 + *pos; - pos += (*pos) + 1; - - if (active_rates == 0) - goto fill_end; - - /* fill in supported extended rate */ - /* ...next IE... */ - left -= 2; - if (left < 0) - return 0; - /* ... fill it in... */ - *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos = 0; - iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left); - if (*pos > 0) { - len += 2 + *pos; - pos += (*pos) + 1; - } else { - pos--; - } - - fill_end: - - left -= 2; - if (left < 0) - return 0; - - *pos++ = WLAN_EID_HT_CAPABILITY; - *pos = 0; - iwl_ht_cap_to_ie(sband, pos, &left); - if (*pos > 0) - len += 2 + *pos; - - return (u16)len; -} - -static u32 iwl_scan_tx_ant(struct iwl_priv *priv, enum ieee80211_band band) -{ - int i, ind; - - ind = priv->scan_tx_ant[band]; - for (i = 0; i < priv->hw_params.tx_chains_num; i++) { - ind = (ind+1) >= priv->hw_params.tx_chains_num ? 0 : ind+1; - if (priv->hw_params.valid_tx_ant & (1 << ind)) { - priv->scan_tx_ant[band] = ind; - break; - } - } - - return scan_tx_ant[ind]; -} - - -static void iwl_bg_request_scan(struct work_struct *data) -{ - struct iwl_priv *priv = - container_of(data, struct iwl_priv, request_scan); - struct iwl_host_cmd cmd = { - .id = REPLY_SCAN_CMD, - .len = sizeof(struct iwl_scan_cmd), - .meta.flags = CMD_SIZE_HUGE, - }; - struct iwl_scan_cmd *scan; - struct ieee80211_conf *conf = NULL; - int ret = 0; - u32 tx_ant; - u16 cmd_len; - enum ieee80211_band band; - u8 direct_mask; - u8 rx_chain = 0x7; /* bitmap: ABC chains */ - - conf = ieee80211_get_hw_conf(priv->hw); - - mutex_lock(&priv->mutex); - - if (!iwl_is_ready(priv)) { - IWL_WARNING("request scan called when driver not ready.\n"); - goto done; - } - - /* Make sure the scan wasn't cancelled before this queued work - * was given the chance to run... */ - if (!test_bit(STATUS_SCANNING, &priv->status)) - goto done; - - /* This should never be called or scheduled if there is currently - * a scan active in the hardware. */ - if (test_bit(STATUS_SCAN_HW, &priv->status)) { - IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. " - "Ignoring second request.\n"); - ret = -EIO; - goto done; - } - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { - IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n"); - goto done; - } - - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n"); - goto done; - } - - if (iwl_is_rfkill(priv)) { - IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); - goto done; - } - - if (!test_bit(STATUS_READY, &priv->status)) { - IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n"); - goto done; - } - - if (!priv->scan_bands) { - IWL_DEBUG_HC("Aborting scan due to no requested bands\n"); - goto done; - } - - if (!priv->scan) { - priv->scan = kmalloc(sizeof(struct iwl_scan_cmd) + - IWL_MAX_SCAN_SIZE, GFP_KERNEL); - if (!priv->scan) { - ret = -ENOMEM; - goto done; - } - } - scan = priv->scan; - memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE); - - scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; - scan->quiet_time = IWL_ACTIVE_QUIET_TIME; - - if (iwl_is_associated(priv)) { - u16 interval = 0; - u32 extra; - u32 suspend_time = 100; - u32 scan_suspend_time = 100; - unsigned long flags; - - IWL_DEBUG_INFO("Scanning while associated...\n"); - - spin_lock_irqsave(&priv->lock, flags); - interval = priv->beacon_int; - spin_unlock_irqrestore(&priv->lock, flags); - - scan->suspend_time = 0; - scan->max_out_time = cpu_to_le32(200 * 1024); - if (!interval) - interval = suspend_time; - - extra = (suspend_time / interval) << 22; - scan_suspend_time = (extra | - ((suspend_time % interval) * 1024)); - scan->suspend_time = cpu_to_le32(scan_suspend_time); - IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n", - scan_suspend_time, interval); - } - - /* We should add the ability for user to lock to PASSIVE ONLY */ - if (priv->one_direct_scan) { - IWL_DEBUG_SCAN("Start direct scan for '%s'\n", - iwl_escape_essid(priv->direct_ssid, - priv->direct_ssid_len)); - scan->direct_scan[0].id = WLAN_EID_SSID; - scan->direct_scan[0].len = priv->direct_ssid_len; - memcpy(scan->direct_scan[0].ssid, - priv->direct_ssid, priv->direct_ssid_len); - direct_mask = 1; - } else if (!iwl_is_associated(priv) && priv->essid_len) { - IWL_DEBUG_SCAN("Start direct scan for '%s' (not associated)\n", - iwl_escape_essid(priv->essid, priv->essid_len)); - scan->direct_scan[0].id = WLAN_EID_SSID; - scan->direct_scan[0].len = priv->essid_len; - memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); - direct_mask = 1; - } else { - IWL_DEBUG_SCAN("Start indirect scan.\n"); - direct_mask = 0; - } - - scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; - scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; - scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; - - - switch (priv->scan_bands) { - case 2: - band = IEEE80211_BAND_2GHZ; - scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; - tx_ant = iwl_scan_tx_ant(priv, band); - if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) - scan->tx_cmd.rate_n_flags = - iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, - tx_ant); - else - scan->tx_cmd.rate_n_flags = - iwl_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, - tx_ant | - RATE_MCS_CCK_MSK); - scan->good_CRC_th = 0; - break; - - case 1: - band = IEEE80211_BAND_5GHZ; - tx_ant = iwl_scan_tx_ant(priv, band); - scan->tx_cmd.rate_n_flags = - iwl_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, - tx_ant); - scan->good_CRC_th = IWL_GOOD_CRC_TH; - - /* Force use of chains B and C (0x6) for scan Rx for 4965 - * Avoid A (0x1) because of its off-channel reception on A-band. - * MIMO is not used here, but value is required */ - if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) - rx_chain = 0x6; - - break; - default: - IWL_WARNING("Invalid scan band count\n"); - goto done; - } - - scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | - cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | - (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | - (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); - - cmd_len = iwl_fill_probe_req(priv, band, - (struct ieee80211_mgmt *)scan->data, - IWL_MAX_SCAN_SIZE - sizeof(*scan)); - - scan->tx_cmd.len = cpu_to_le16(cmd_len); - - if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) - scan->filter_flags = RXON_FILTER_PROMISC_MSK; - - scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | - RXON_FILTER_BCON_AWARE_MSK); - - if (direct_mask) - scan->channel_count = - iwl_get_channels_for_scan(priv, band, 1, /* active */ - direct_mask, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); - else - scan->channel_count = - iwl_get_channels_for_scan(priv, band, 0, /* passive */ - direct_mask, - (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); - if (scan->channel_count == 0) { - IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); - goto done; - } - - cmd.len += le16_to_cpu(scan->tx_cmd.len) + - scan->channel_count * sizeof(struct iwl_scan_channel); - cmd.data = scan; - scan->len = cpu_to_le16(cmd.len); - - set_bit(STATUS_SCAN_HW, &priv->status); - ret = iwl_send_cmd_sync(priv, &cmd); - if (ret) - goto done; - - queue_delayed_work(priv->workqueue, &priv->scan_check, - IWL_SCAN_CHECK_WATCHDOG); - - mutex_unlock(&priv->mutex); - return; - - done: - /* inform mac80211 scan aborted */ - queue_work(priv->workqueue, &priv->scan_completed); - mutex_unlock(&priv->mutex); -} - -static void iwl_bg_abort_scan(struct work_struct *work) -{ - struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); - - if (!iwl_is_ready(priv)) - return; - - mutex_lock(&priv->mutex); - - set_bit(STATUS_SCAN_ABORTING, &priv->status); - iwl_send_scan_abort(priv); - - mutex_unlock(&priv->mutex); -} - -void iwl_setup_scan_deferred_work(struct iwl_priv *priv) -{ - /* FIXME: move here when resolved PENDING - * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */ - INIT_WORK(&priv->request_scan, iwl_bg_request_scan); - INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); - INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); -} -EXPORT_SYMBOL(iwl_setup_scan_deferred_work); - diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c index f874e7d7b225..983f10760fb0 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -30,9 +30,11 @@ #include #include +#include "iwl-eeprom.h" #include "iwl-dev.h" #include "iwl-core.h" #include "iwl-sta.h" +#include "iwl-io.h" #include "iwl-helpers.h" @@ -72,17 +74,6 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr) } EXPORT_SYMBOL(iwl_find_station); -int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) -{ - if (priv->iw_mode == IEEE80211_IF_TYPE_STA) { - return IWL_AP_ID; - } else { - u8 *da = ieee80211_get_DA(hdr); - return iwl_find_station(priv, da); - } -} -EXPORT_SYMBOL(iwl_get_ra_sta_id); - static int iwl_add_sta_callback(struct iwl_priv *priv, struct iwl_cmd *cmd, struct sk_buff *skb) { @@ -114,6 +105,8 @@ static int iwl_add_sta_callback(struct iwl_priv *priv, return 1; } + + int iwl_send_add_sta(struct iwl_priv *priv, struct iwl_addsta_cmd *sta, u8 flags) { @@ -163,6 +156,8 @@ int iwl_send_add_sta(struct iwl_priv *priv, } EXPORT_SYMBOL(iwl_send_add_sta); +#ifdef CONFIG_IWL4965_HT + static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, struct ieee80211_ht_info *sta_ht_inf) { @@ -207,6 +202,12 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, done: return; } +#else +static inline void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index, + struct ieee80211_ht_info *sta_ht_info) +{ +} +#endif /** * iwl_add_station_flags - Add station to tables in driver and device @@ -279,6 +280,7 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap, } EXPORT_SYMBOL(iwl_add_station_flags); + static int iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr) { unsigned long flags; @@ -382,9 +384,9 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, return ret; } - /** * iwl_remove_station - Remove driver's knowledge of station. + * */ u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) { @@ -424,7 +426,7 @@ u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap) return 0; } EXPORT_SYMBOL(iwl_remove_station); -static int iwl_get_free_ucode_key_index(struct iwl_priv *priv) +int iwl_get_free_ucode_key_index(struct iwl_priv *priv) { int i; @@ -494,8 +496,6 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv, priv->default_wep_key--; memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); ret = iwl_send_static_wepkey_cmd(priv, 1); - IWL_DEBUG_WEP("Remove default WEP key: idx=%d ret=%d\n", - keyconf->keyidx, ret); spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; @@ -508,12 +508,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, int ret; unsigned long flags; - if (keyconf->keylen != WEP_KEY_LEN_128 && - keyconf->keylen != WEP_KEY_LEN_64) { - IWL_DEBUG_WEP("Bad WEP key length %d\n", keyconf->keylen); - return -EINVAL; - } - keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV; keyconf->hw_key_idx = HW_KEY_DEFAULT; priv->stations[IWL_AP_ID].keyinfo.alg = ALG_WEP; @@ -530,8 +524,6 @@ int iwl_set_default_wep_key(struct iwl_priv *priv, keyconf->keylen); ret = iwl_send_static_wepkey_cmd(priv, 0); - IWL_DEBUG_WEP("Set default WEP key: len=%d idx=%d ret=%d\n", - keyconf->keylen, keyconf->keyidx, ret); spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; @@ -678,9 +670,6 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, key_flags = le16_to_cpu(priv->stations[sta_id].sta.key.key_flags); keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3; - IWL_DEBUG_WEP("Remove dynamic key: idx=%d sta=%d\n", - keyconf->keyidx, sta_id); - if (keyconf->keyidx != keyidx) { /* We need to remove a key with index different that the one * in the uCode. This means that the key we need to remove has @@ -705,6 +694,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; + IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n"); ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); spin_unlock_irqrestore(&priv->sta_lock, flags); return ret; @@ -734,10 +724,6 @@ int iwl_set_dynamic_key(struct iwl_priv *priv, ret = -EINVAL; } - IWL_DEBUG_WEP("Set dynamic key: alg= %d len=%d idx=%d sta=%d ret=%d\n", - keyconf->alg, keyconf->keylen, keyconf->keyidx, - sta_id, ret); - return ret; } EXPORT_SYMBOL(iwl_set_dynamic_key); @@ -830,7 +816,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap) rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/ link_cmd.rs_table[i].rate_n_flags = - iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); + iwl4965_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags); r = iwl4965_get_prev_ieee_rate(r); } @@ -856,6 +842,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) u8 sta_id; /* Add station to device's station table */ +#ifdef CONFIG_IWL4965_HT struct ieee80211_conf *conf = &priv->hw->conf; struct ieee80211_ht_info *cur_ht_config = &conf->ht_conf; @@ -865,6 +852,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) sta_id = iwl_add_station_flags(priv, addr, is_ap, 0, cur_ht_config); else +#endif /* CONFIG_IWL4965_HT */ sta_id = iwl_add_station_flags(priv, addr, is_ap, 0, NULL); @@ -875,6 +863,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) } EXPORT_SYMBOL(iwl_rxon_add_station); + /** * iwl_get_sta_id - Find station's index within station table * @@ -932,6 +921,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) } EXPORT_SYMBOL(iwl_get_sta_id); + /** * iwl_sta_modify_enable_tid_tx - Enable Tx for this TID in station table */ @@ -950,3 +940,4 @@ void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid) } EXPORT_SYMBOL(iwl_sta_modify_enable_tid_tx); + diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h index b6bb209fdd58..3d55716f5301 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-sta.h @@ -32,24 +32,18 @@ #define HW_KEY_DYNAMIC 0 #define HW_KEY_DEFAULT 1 -/** - * iwl_find_station - Find station id for a given BSSID - * @bssid: MAC address of station ID to find - */ -u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid); - +int iwl_get_free_ucode_key_index(struct iwl_priv *priv); int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty); int iwl_remove_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key); + struct ieee80211_key_conf *key); int iwl_set_default_wep_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key); + struct ieee80211_key_conf *key); int iwl_set_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key, u8 sta_id); + struct ieee80211_key_conf *key, u8 sta_id); int iwl_remove_dynamic_key(struct iwl_priv *priv, - struct ieee80211_key_conf *key, u8 sta_id); + struct ieee80211_key_conf *key, u8 sta_id); int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap); u8 iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap); int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); void iwl_sta_modify_enable_tid_tx(struct iwl_priv *priv, int sta_id, int tid); -int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); #endif /* __iwl_sta_h__ */ diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c index 7296e2846ec3..cfe6f4b233dd 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -36,6 +36,8 @@ #include "iwl-io.h" #include "iwl-helpers.h" +#ifdef CONFIG_IWL4965_HT + static const u16 default_tid_to_tx_fifo[] = { IWL_TX_FIFO_AC1, IWL_TX_FIFO_AC0, @@ -56,6 +58,9 @@ static const u16 default_tid_to_tx_fifo[] = { IWL_TX_FIFO_AC3 }; +#endif /*CONFIG_IWL4965_HT */ + + /** * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] @@ -569,15 +574,15 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, struct ieee80211_hdr *hdr, int is_unicast, u8 std_id) { - __le16 fc = hdr->frame_control; + u16 fc = le16_to_cpu(hdr->frame_control); __le32 tx_flags = tx_cmd->tx_flags; tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { tx_flags |= TX_CMD_FLG_ACK_MSK; - if (ieee80211_is_mgmt(fc)) + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - if (ieee80211_is_probe_resp(fc) && + if (ieee80211_is_probe_response(fc) && !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) tx_flags |= TX_CMD_FLG_TSF_MSK; } else { @@ -585,16 +590,16 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; } - if (ieee80211_is_back_req(fc)) + if (ieee80211_is_back_request(fc)) tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; tx_cmd->sta_id = std_id; - if (ieee80211_has_morefrags(fc)) + if (ieee80211_get_morefrag(hdr)) tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); + if (ieee80211_is_qos_data(fc)) { + u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); tx_cmd->tid_tspec = qc[0] & 0xf; tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; } else { @@ -613,8 +618,9 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); - if (ieee80211_is_mgmt(fc)) { - if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || + (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3); else tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2); @@ -633,7 +639,7 @@ static void iwl_tx_cmd_build_basic(struct iwl_priv *priv, static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, struct iwl_tx_cmd *tx_cmd, struct ieee80211_tx_info *info, - __le16 fc, int sta_id, + u16 fc, int sta_id, int is_hcca) { u8 rts_retry_limit = 0; @@ -654,7 +660,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, rate_flags |= RATE_MCS_CCK_MSK; - if (ieee80211_is_probe_resp(fc)) { + if (ieee80211_is_probe_response(fc)) { data_retry_limit = 3; if (data_retry_limit < rts_retry_limit) rts_retry_limit = data_retry_limit; @@ -669,11 +675,11 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, tx_cmd->initial_rate_index = 0; tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; } else { - switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_DEAUTH): - case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): + switch (fc & IEEE80211_FCTL_STYPE) { + case IEEE80211_STYPE_AUTH: + case IEEE80211_STYPE_DEAUTH: + case IEEE80211_STYPE_ASSOC_REQ: + case IEEE80211_STYPE_REASSOC_REQ: if (tx_cmd->tx_flags & TX_CMD_FLG_RTS_MSK) { tx_cmd->tx_flags &= ~TX_CMD_FLG_RTS_MSK; tx_cmd->tx_flags |= TX_CMD_FLG_CTS_MSK; @@ -695,7 +701,7 @@ static void iwl_tx_cmd_build_rate(struct iwl_priv *priv, tx_cmd->rts_retry_limit = rts_retry_limit; tx_cmd->data_retry_limit = data_retry_limit; - tx_cmd->rate_n_flags = iwl_hw_set_rate_n_flags(rate_plcp, rate_flags); + tx_cmd->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags); } static void iwl_tx_cmd_build_hwcrypto(struct iwl_priv *priv, @@ -770,7 +776,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) u16 seq_number = 0; u8 id, hdr_len, unicast; u8 sta_id; - __le16 fc; + u16 fc; u8 wait_write_ptr = 0; u8 tid = 0; u8 *qc = NULL; @@ -797,19 +803,19 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) unicast = !is_multicast_ether_addr(hdr->addr1); id = 0; - fc = hdr->frame_control; + fc = le16_to_cpu(hdr->frame_control); #ifdef CONFIG_IWLWIFI_DEBUG if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); - else if (ieee80211_is_assoc_req(fc)) + else if (ieee80211_is_assoc_request(fc)) IWL_DEBUG_TX("Sending ASSOC frame\n"); - else if (ieee80211_is_reassoc_req(fc)) + else if (ieee80211_is_reassoc_request(fc)) IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif /* drop all data frame if we are not associated */ - if (ieee80211_is_data(fc) && + if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && (!iwl_is_associated(priv) || ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id) || !priv->assoc_station_added)) { @@ -819,7 +825,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) spin_unlock_irqrestore(&priv->lock, flags); - hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc)); + hdr_len = ieee80211_get_hdrlen(fc); /* Find (or create) index into station table for destination station */ sta_id = iwl_get_sta_id(priv, hdr); @@ -833,8 +839,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) IWL_DEBUG_TX("station Id %d\n", sta_id); - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); + if (ieee80211_is_qos_data(fc)) { + qc = ieee80211_get_qos_ctrl(hdr, hdr_len); tid = qc[0] & 0xf; seq_number = priv->stations[sta_id].tid[tid].seq_number & IEEE80211_SCTL_SEQ; @@ -842,10 +848,12 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) (hdr->seq_ctrl & __constant_cpu_to_le16(IEEE80211_SCTL_FRAG)); seq_number += 0x10; +#ifdef CONFIG_IWL4965_HT /* aggregation is on for this */ if (info->flags & IEEE80211_TX_CTL_AMPDU) txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; priv->stations[sta_id].tid[tid].tfds_in_queue++; +#endif /* CONFIG_IWL4965_HT */ } /* Descriptor for chosen Tx queue */ @@ -937,14 +945,14 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) /* set is_hcca to 0; it probably will never be implemented */ iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0); - iwl_update_tx_stats(priv, le16_to_cpu(fc), len); + iwl_update_tx_stats(priv, fc, len); scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + offsetof(struct iwl_tx_cmd, scratch); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_address(scratch_phys); - if (!ieee80211_has_morefrags(hdr->frame_control)) { + if (!ieee80211_get_morefrag(hdr)) { txq->need_update = 1; if (qc) priv->stations[sta_id].tid[tid].seq_number = seq_number; @@ -1188,6 +1196,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) } EXPORT_SYMBOL(iwl_tx_cmd_complete); + +#ifdef CONFIG_IWL4965_HT /* * Find first available (lowest unused) Tx Queue, mark it "active". * Called only when finding queue for aggregation. @@ -1349,6 +1359,7 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id) return 0; } EXPORT_SYMBOL(iwl_txq_check_empty); +#endif /* CONFIG_IWL4965_HT */ #ifdef CONFIG_IWLWIF_DEBUG #define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c index 47cf4b997f50..72279e07fe32 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2431,15 +2431,15 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, struct ieee80211_hdr *hdr, int is_unicast, u8 std_id) { - __le16 fc = hdr->frame_control; + u16 fc = le16_to_cpu(hdr->frame_control); __le32 tx_flags = cmd->cmd.tx.tx_flags; cmd->cmd.tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) { tx_flags |= TX_CMD_FLG_ACK_MSK; - if (ieee80211_is_mgmt(fc)) + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK; - if (ieee80211_is_probe_resp(fc) && + if (ieee80211_is_probe_response(fc) && !(le16_to_cpu(hdr->seq_ctrl) & 0xf)) tx_flags |= TX_CMD_FLG_TSF_MSK; } else { @@ -2448,11 +2448,11 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, } cmd->cmd.tx.sta_id = std_id; - if (ieee80211_has_morefrags(fc)) + if (ieee80211_get_morefrag(hdr)) tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK; - if (ieee80211_is_data_qos(fc)) { - u8 *qc = ieee80211_get_qos_ctl(hdr); + if (ieee80211_is_qos_data(fc)) { + u8 *qc = ieee80211_get_qos_ctrl(hdr, ieee80211_get_hdrlen(fc)); cmd->cmd.tx.tid_tspec = qc[0] & 0xf; tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK; } else { @@ -2471,8 +2471,9 @@ static void iwl3945_build_tx_cmd_basic(struct iwl3945_priv *priv, tx_flags |= TX_CMD_FLG_FULL_TXOP_PROT_MSK; tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK); - if (ieee80211_is_mgmt(fc)) { - if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc)) + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { + if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ || + (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ) cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(3); else cmd->cmd.tx.timeout.pm_frame_timeout = cpu_to_le16(2); @@ -2563,7 +2564,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) u8 sta_id; u8 tid = 0; u16 seq_number = 0; - __le16 fc; + u16 fc; u8 wait_write_ptr = 0; u8 *qc = NULL; unsigned long flags; @@ -2588,28 +2589,28 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) unicast = !is_multicast_ether_addr(hdr->addr1); id = 0; - fc = hdr->frame_control; + fc = le16_to_cpu(hdr->frame_control); #ifdef CONFIG_IWL3945_DEBUG if (ieee80211_is_auth(fc)) IWL_DEBUG_TX("Sending AUTH frame\n"); - else if (ieee80211_is_assoc_req(fc)) + else if (ieee80211_is_assoc_request(fc)) IWL_DEBUG_TX("Sending ASSOC frame\n"); - else if (ieee80211_is_reassoc_req(fc)) + else if (ieee80211_is_reassoc_request(fc)) IWL_DEBUG_TX("Sending REASSOC frame\n"); #endif /* drop all data frame if we are not associated */ if ((!iwl3945_is_associated(priv) || ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) && - ieee80211_is_data(fc)) { + ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n"); goto drop_unlock; } spin_unlock_irqrestore(&priv->lock, flags); - hdr_len = ieee80211_get_hdrlen(le16_to_cpu(fc)); + hdr_len = ieee80211_get_hdrlen(fc); /* Find (or create) index into station table for destination station */ sta_id = iwl3945_get_sta_id(priv, hdr); @@ -2623,8 +2624,8 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) IWL_DEBUG_RATE("station Id %d\n", sta_id); - if (ieee80211_is_data_qos(fc)) { - qc = ieee80211_get_qos_ctl(hdr); + if (ieee80211_is_qos_data(fc)) { + qc = ieee80211_get_qos_ctrl(hdr, hdr_len); tid = qc[0] & 0xf; seq_number = priv->stations[sta_id].tid[tid].seq_number & IEEE80211_SCTL_SEQ; @@ -2731,7 +2732,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_A_MSK; out_cmd->cmd.tx.tx_flags &= ~TX_CMD_FLG_ANT_B_MSK; - if (!ieee80211_has_morefrags(hdr->frame_control)) { + if (!ieee80211_get_morefrag(hdr)) { txq->need_update = 1; if (qc) { priv->stations[sta_id].tid[tid].seq_number = seq_number; @@ -2745,7 +2746,7 @@ static int iwl3945_tx_skb(struct iwl3945_priv *priv, struct sk_buff *skb) sizeof(out_cmd->cmd.tx)); iwl3945_print_hex_dump(IWL_DL_TX, (u8 *)out_cmd->cmd.tx.hdr, - ieee80211_get_hdrlen(le16_to_cpu(fc))); + ieee80211_get_hdrlen(fc)); /* Tell device the write index *just past* this latest filled TFD */ q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); @@ -2874,8 +2875,7 @@ static void iwl3945_radio_kill_sw(struct iwl3945_priv *priv, int disable_radio) return; } - if (priv->is_open) - queue_work(priv->workqueue, &priv->restart); + queue_work(priv->workqueue, &priv->restart); return; } diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c index f5911687671b..c71daec8c746 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -87,6 +87,46 @@ MODULE_VERSION(DRV_VERSION); MODULE_AUTHOR(DRV_COPYRIGHT); MODULE_LICENSE("GPL"); +static int iwl4965_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +static const char *iwl4965_escape_essid(const char *essid, u8 essid_len) +{ + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (iwl4965_is_empty_essid(essid, essid_len)) { + memcpy(escaped, "", sizeof("")); + return escaped; + } + + essid_len = min(essid_len, (u8) IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else + *d++ = *s++; + } + *d = '\0'; + return escaped; +} + /*************** STATION TABLE MANAGEMENT **** * mac80211 should be examined to determine if sta_info is duplicating * the functionality provided here @@ -327,9 +367,9 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv) /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ - rc = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + rc = iwl4965_hw_reg_send_txpower(priv); if (rc) { - IWL_ERROR("Error sending TX power (%d).\n", rc); + IWL_ERROR("Error setting Tx power (%d).\n", rc); return rc; } @@ -379,6 +419,69 @@ static int iwl4965_send_bt_config(struct iwl_priv *priv) sizeof(struct iwl4965_bt_cmd), &bt_cmd); } +static int iwl4965_send_scan_abort(struct iwl_priv *priv) +{ + int ret = 0; + struct iwl_rx_packet *res; + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_ABORT_CMD, + .meta.flags = CMD_WANT_SKB, + }; + + /* If there isn't a scan actively going on in the hardware + * then we are in between scan bands and not actually + * actively scanning, so don't send the abort command */ + if (!test_bit(STATUS_SCAN_HW, &priv->status)) { + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + return 0; + } + + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) { + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + return ret; + } + + res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; + if (res->u.status != CAN_ABORT_STATUS) { + /* The scan abort will return 1 for success or + * 2 for "failure". A failure condition can be + * due to simply not being in an active scan which + * can occur if we send the scan abort before we + * the microcode has notified us that a scan is + * completed. */ + IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + clear_bit(STATUS_SCAN_HW, &priv->status); + } + + dev_kfree_skb_any(cmd.meta.u.skb); + + return ret; +} + +/* + * CARD_STATE_CMD + * + * Use: Sets the device's internal card state to enable, disable, or halt + * + * When in the 'enable' state the card operates as normal. + * When in the 'disable' state, the card enters into a low power mode. + * When in the 'halt' state, the card is shut down and must be fully + * restarted to come back on. + */ +static int iwl4965_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag) +{ + struct iwl_host_cmd cmd = { + .id = REPLY_CARD_STATE_CMD, + .len = sizeof(u32), + .data = &flags, + .meta.flags = meta_flag, + }; + + return iwl_send_cmd(priv, &cmd); +} + static void iwl_clear_free_frames(struct iwl_priv *priv) { struct list_head *element; @@ -502,6 +605,36 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) * ******************************************************************************/ +/** + * iwl4965_supported_rate_to_ie - fill in the supported rate in IE field + * + * return : set the bit for each supported rate insert in ie + */ +static u16 iwl4965_supported_rate_to_ie(u8 *ie, u16 supported_rate, + u16 basic_rate, int *left) +{ + u16 ret_rates = 0, bit; + int i; + u8 *cnt = ie; + u8 *rates = ie + 1; + + for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { + if (bit & supported_rate) { + ret_rates |= bit; + rates[*cnt] = iwl_rates[i].ieee | + ((bit & basic_rate) ? 0x80 : 0x00); + (*cnt)++; + (*left)--; + if ((*left <= 0) || + (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) + break; + } + } + + return ret_rates; +} + +#ifdef CONFIG_IWL4965_HT static void iwl4965_ht_conf(struct iwl_priv *priv, struct ieee80211_bss_conf *bss_conf) { @@ -532,11 +665,9 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, iwl_conf->extension_chan_offset = ht_bss_conf->bss_cap & IEEE80211_HT_IE_CHA_SEC_OFFSET; /* If no above or below channel supplied disable FAT channel */ - if (iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_ABOVE && - iwl_conf->extension_chan_offset != IEEE80211_HT_IE_CHA_SEC_BELOW) { - iwl_conf->extension_chan_offset = IEEE80211_HT_IE_CHA_SEC_NONE; + if (iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_ABOVE && + iwl_conf->extension_chan_offset != IWL_EXT_CHANNEL_OFFSET_BELOW) iwl_conf->supported_chan_width = 0; - } iwl_conf->tx_mimo_ps_mode = (u8)((ht_conf->cap & IEEE80211_HT_CAP_MIMO_PS) >> 2); @@ -554,6 +685,151 @@ static void iwl4965_ht_conf(struct iwl_priv *priv, IWL_DEBUG_MAC80211("leave\n"); } +static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, + u8 *pos, int *left) +{ + struct ieee80211_ht_cap *ht_cap; + + if (!sband || !sband->ht_info.ht_supported) + return; + + if (*left < sizeof(struct ieee80211_ht_cap)) + return; + + *pos++ = sizeof(struct ieee80211_ht_cap); + ht_cap = (struct ieee80211_ht_cap *) pos; + + ht_cap->cap_info = cpu_to_le16(sband->ht_info.cap); + memcpy(ht_cap->supp_mcs_set, sband->ht_info.supp_mcs_set, 16); + ht_cap->ampdu_params_info = + (sband->ht_info.ampdu_factor & IEEE80211_HT_CAP_AMPDU_FACTOR) | + ((sband->ht_info.ampdu_density << 2) & + IEEE80211_HT_CAP_AMPDU_DENSITY); + *left -= sizeof(struct ieee80211_ht_cap); +} +#else +static inline void iwl4965_ht_conf(struct iwl_priv *priv, + struct ieee80211_bss_conf *bss_conf) +{ +} +static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband, + u8 *pos, int *left) +{ +} +#endif + + +/** + * iwl4965_fill_probe_req - fill in all required fields and IE for probe request + */ +static u16 iwl4965_fill_probe_req(struct iwl_priv *priv, + enum ieee80211_band band, + struct ieee80211_mgmt *frame, + int left, int is_direct) +{ + int len = 0; + u8 *pos = NULL; + u16 active_rates, ret_rates, cck_rates, active_rate_basic; + const struct ieee80211_supported_band *sband = + iwl_get_hw_mode(priv, band); + + /* Make sure there is enough space for the probe request, + * two mandatory IEs and the data */ + left -= 24; + if (left < 0) + return 0; + len += 24; + + frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); + memcpy(frame->da, iwl_bcast_addr, ETH_ALEN); + memcpy(frame->sa, priv->mac_addr, ETH_ALEN); + memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN); + frame->seq_ctrl = 0; + + /* fill in our indirect SSID IE */ + /* ...next IE... */ + + left -= 2; + if (left < 0) + return 0; + len += 2; + pos = &(frame->u.probe_req.variable[0]); + *pos++ = WLAN_EID_SSID; + *pos++ = 0; + + /* fill in our direct SSID IE... */ + if (is_direct) { + /* ...next IE... */ + left -= 2 + priv->essid_len; + if (left < 0) + return 0; + /* ... fill it in... */ + *pos++ = WLAN_EID_SSID; + *pos++ = priv->essid_len; + memcpy(pos, priv->essid, priv->essid_len); + pos += priv->essid_len; + len += 2 + priv->essid_len; + } + + /* fill in supported rate */ + /* ...next IE... */ + left -= 2; + if (left < 0) + return 0; + + /* ... fill it in... */ + *pos++ = WLAN_EID_SUPP_RATES; + *pos = 0; + + /* exclude 60M rate */ + active_rates = priv->rates_mask; + active_rates &= ~IWL_RATE_60M_MASK; + + active_rate_basic = active_rates & IWL_BASIC_RATES_MASK; + + cck_rates = IWL_CCK_RATES_MASK & active_rates; + ret_rates = iwl4965_supported_rate_to_ie(pos, cck_rates, + active_rate_basic, &left); + active_rates &= ~ret_rates; + + ret_rates = iwl4965_supported_rate_to_ie(pos, active_rates, + active_rate_basic, &left); + active_rates &= ~ret_rates; + + len += 2 + *pos; + pos += (*pos) + 1; + if (active_rates == 0) + goto fill_end; + + /* fill in supported extended rate */ + /* ...next IE... */ + left -= 2; + if (left < 0) + return 0; + /* ... fill it in... */ + *pos++ = WLAN_EID_EXT_SUPP_RATES; + *pos = 0; + iwl4965_supported_rate_to_ie(pos, active_rates, + active_rate_basic, &left); + if (*pos > 0) + len += 2 + *pos; + + fill_end: + /* fill in HT IE */ + left -= 2; + if (left < 0) + return 0; + + *pos++ = WLAN_EID_HT_CAPABILITY; + *pos = 0; + + iwl_ht_cap_to_ie(sband, pos, &left); + + if (*pos > 0) + len += 2 + *pos; + return (u16)len; +} + /* * QoS support */ @@ -586,8 +862,10 @@ static void iwl4965_activate_qos(struct iwl_priv *priv, u8 force) priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_UPDATE_EDCA_MSK; +#ifdef CONFIG_IWL4965_HT if (priv->current_ht_config.is_ht) priv->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK; +#endif /* CONFIG_IWL4965_HT */ spin_unlock_irqrestore(&priv->lock, flags); @@ -631,6 +909,60 @@ int iwl4965_is_network_packet(struct iwl_priv *priv, struct ieee80211_hdr *heade return 1; } + + +/** + * iwl4965_scan_cancel - Cancel any currently executing HW scan + * + * NOTE: priv->mutex is not required before calling this function + */ +static int iwl4965_scan_cancel(struct iwl_priv *priv) +{ + if (!test_bit(STATUS_SCAN_HW, &priv->status)) { + clear_bit(STATUS_SCANNING, &priv->status); + return 0; + } + + if (test_bit(STATUS_SCANNING, &priv->status)) { + if (!test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN("Queuing scan abort.\n"); + set_bit(STATUS_SCAN_ABORTING, &priv->status); + queue_work(priv->workqueue, &priv->abort_scan); + + } else + IWL_DEBUG_SCAN("Scan abort already in progress.\n"); + + return test_bit(STATUS_SCANNING, &priv->status); + } + + return 0; +} + +/** + * iwl4965_scan_cancel_timeout - Cancel any currently executing HW scan + * @ms: amount of time to wait (in milliseconds) for scan to abort + * + * NOTE: priv->mutex must be held before calling this function + */ +static int iwl4965_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms) +{ + unsigned long now = jiffies; + int ret; + + ret = iwl4965_scan_cancel(priv); + if (ret && ms) { + mutex_unlock(&priv->mutex); + while (!time_after(jiffies, now + msecs_to_jiffies(ms)) && + test_bit(STATUS_SCANNING, &priv->status)) + msleep(1); + mutex_lock(&priv->mutex); + + return test_bit(STATUS_SCANNING, &priv->status); + } + + return ret; +} + static void iwl4965_sequence_reset(struct iwl_priv *priv) { /* Reset ieee stats */ @@ -642,7 +974,7 @@ static void iwl4965_sequence_reset(struct iwl_priv *priv) priv->last_frag_num = -1; priv->last_packet_time = 0; - iwl_scan_cancel(priv); + iwl4965_scan_cancel(priv); } #define MAX_UCODE_BEACON_INTERVAL 4096 @@ -717,6 +1049,41 @@ static void iwl4965_setup_rxon_timing(struct iwl_priv *priv) le16_to_cpu(priv->rxon_timing.atim_window)); } +static int iwl4965_scan_initiate(struct iwl_priv *priv) +{ + if (priv->iw_mode == IEEE80211_IF_TYPE_AP) { + IWL_ERROR("APs don't scan.\n"); + return 0; + } + + if (!iwl_is_ready_rf(priv)) { + IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); + return -EIO; + } + + if (test_bit(STATUS_SCANNING, &priv->status)) { + IWL_DEBUG_SCAN("Scan already in progress.\n"); + return -EAGAIN; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_SCAN("Scan request while abort pending. " + "Queuing.\n"); + return -EAGAIN; + } + + IWL_DEBUG_INFO("Starting scan...\n"); + priv->scan_bands = 2; + set_bit(STATUS_SCANNING, &priv->status); + priv->scan_start = jiffies; + priv->scan_pass_start = priv->scan_start; + + queue_work(priv->workqueue, &priv->request_scan); + + return 0; +} + + static void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band) { @@ -821,10 +1188,21 @@ static void iwl4965_connection_init_rx_config(struct iwl_priv *priv) static int iwl4965_set_mode(struct iwl_priv *priv, int mode) { - priv->iw_mode = mode; + if (mode == IEEE80211_IF_TYPE_IBSS) { + const struct iwl_channel_info *ch_info; + + ch_info = iwl_get_channel_info(priv, + priv->band, + le16_to_cpu(priv->staging_rxon.channel)); + + if (!ch_info || !is_channel_ibss(ch_info)) { + IWL_ERROR("channel %d not IBSS channel\n", + le16_to_cpu(priv->staging_rxon.channel)); + return -EINVAL; + } + } - /* init channel/phymode to values given at driver init */ - iwl_set_rxon_channel(priv, IEEE80211_BAND_2GHZ, 6); + priv->iw_mode = mode; iwl4965_connection_init_rx_config(priv); memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN); @@ -836,7 +1214,7 @@ static int iwl4965_set_mode(struct iwl_priv *priv, int mode) return -EAGAIN; cancel_delayed_work(&priv->scan_check); - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl4965_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); return -EAGAIN; @@ -894,6 +1272,64 @@ static void iwl4965_set_rate(struct iwl_priv *priv) (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; } +void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio) +{ + unsigned long flags; + + if (!!disable_radio == test_bit(STATUS_RF_KILL_SW, &priv->status)) + return; + + IWL_DEBUG_RF_KILL("Manual SW RF KILL set to: RADIO %s\n", + disable_radio ? "OFF" : "ON"); + + if (disable_radio) { + iwl4965_scan_cancel(priv); + /* FIXME: This is a workaround for AP */ + if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_SET, + CSR_UCODE_SW_BIT_RFKILL); + spin_unlock_irqrestore(&priv->lock, flags); + /* call the host command only if no hw rf-kill set */ + if (!test_bit(STATUS_RF_KILL_HW, &priv->status) && + iwl_is_ready(priv)) + iwl4965_send_card_state(priv, + CARD_STATE_CMD_DISABLE, + 0); + set_bit(STATUS_RF_KILL_SW, &priv->status); + + /* make sure mac80211 stop sending Tx frame */ + if (priv->mac80211_registered) + ieee80211_stop_queues(priv->hw); + } + return; + } + + spin_lock_irqsave(&priv->lock, flags); + iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + + clear_bit(STATUS_RF_KILL_SW, &priv->status); + spin_unlock_irqrestore(&priv->lock, flags); + + /* wake up ucode */ + msleep(10); + + spin_lock_irqsave(&priv->lock, flags); + iwl_read32(priv, CSR_UCODE_DRV_GP1); + if (!iwl_grab_nic_access(priv)) + iwl_release_nic_access(priv); + spin_unlock_irqrestore(&priv->lock, flags); + + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) { + IWL_DEBUG_RF_KILL("Can not turn radio back on - " + "disabled by HW switch\n"); + return; + } + + queue_work(priv->workqueue, &priv->restart); + return; +} + #define IWL_PACKET_RETRY_TIME HZ int iwl4965_is_duplicate_packet(struct iwl_priv *priv, struct ieee80211_hdr *header) @@ -1225,37 +1661,17 @@ static void iwl4965_bg_beacon_update(struct work_struct *work) iwl4965_send_beacon_cmd(priv); } -/** - * iwl4965_bg_statistics_periodic - Timer callback to queue statistics - * - * This callback is provided in order to send a statistics request. - * - * This timer function is continually reset to execute within - * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION - * was received. We need to ensure we receive the statistics in order - * to update the temperature used for calibrating the TXPOWER. - */ -static void iwl4965_bg_statistics_periodic(unsigned long data) -{ - struct iwl_priv *priv = (struct iwl_priv *)data; - - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; - - iwl_send_statistics_request(priv, CMD_ASYNC); -} - static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) { #ifdef CONFIG_IWLWIFI_DEBUG struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; struct iwl4965_beacon_notif *beacon = &(pkt->u.beacon_status); - u8 rate = iwl_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); + u8 rate = iwl4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags); IWL_DEBUG_RX("beacon status %x retries %d iss %d " "tsf %d %d rate %d\n", - le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK, + le32_to_cpu(beacon->beacon_notify_hdr.status) & TX_STATUS_MSK, beacon->beacon_notify_hdr.failure_frame, le32_to_cpu(beacon->ibss_mgr_status), le32_to_cpu(beacon->high_tsf), @@ -1267,6 +1683,118 @@ static void iwl4965_rx_beacon_notif(struct iwl_priv *priv, queue_work(priv->workqueue, &priv->beacon_update); } +/* Service response to REPLY_SCAN_CMD (0x80) */ +static void iwl4965_rx_reply_scan(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ +#ifdef CONFIG_IWLWIFI_DEBUG + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_scanreq_notification *notif = + (struct iwl4965_scanreq_notification *)pkt->u.raw; + + IWL_DEBUG_RX("Scan request status = 0x%x\n", notif->status); +#endif +} + +/* Service SCAN_START_NOTIFICATION (0x82) */ +static void iwl4965_rx_scan_start_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_scanstart_notification *notif = + (struct iwl4965_scanstart_notification *)pkt->u.raw; + priv->scan_start_tsf = le32_to_cpu(notif->tsf_low); + IWL_DEBUG_SCAN("Scan start: " + "%d [802.11%s] " + "(TSF: 0x%08X:%08X) - %d (beacon timer %u)\n", + notif->channel, + notif->band ? "bg" : "a", + notif->tsf_high, + notif->tsf_low, notif->status, notif->beacon_timer); +} + +/* Service SCAN_RESULTS_NOTIFICATION (0x83) */ +static void iwl4965_rx_scan_results_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_scanresults_notification *notif = + (struct iwl4965_scanresults_notification *)pkt->u.raw; + + IWL_DEBUG_SCAN("Scan ch.res: " + "%d [802.11%s] " + "(TSF: 0x%08X:%08X) - %d " + "elapsed=%lu usec (%dms since last)\n", + notif->channel, + notif->band ? "bg" : "a", + le32_to_cpu(notif->tsf_high), + le32_to_cpu(notif->tsf_low), + le32_to_cpu(notif->statistics[0]), + le32_to_cpu(notif->tsf_low) - priv->scan_start_tsf, + jiffies_to_msecs(elapsed_jiffies + (priv->last_scan_jiffies, jiffies))); + + priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; +} + +/* Service SCAN_COMPLETE_NOTIFICATION (0x84) */ +static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, + struct iwl_rx_mem_buffer *rxb) +{ + struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; + struct iwl4965_scancomplete_notification *scan_notif = (void *)pkt->u.raw; + + IWL_DEBUG_SCAN("Scan complete: %d channels (TSF 0x%08X:%08X) - %d\n", + scan_notif->scanned_channels, + scan_notif->tsf_low, + scan_notif->tsf_high, scan_notif->status); + + /* The HW is no longer scanning */ + clear_bit(STATUS_SCAN_HW, &priv->status); + + /* The scan completion notification came in, so kill that timer... */ + cancel_delayed_work(&priv->scan_check); + + IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", + (priv->scan_bands == 2) ? "2.4" : "5.2", + jiffies_to_msecs(elapsed_jiffies + (priv->scan_pass_start, jiffies))); + + /* Remove this scanned band from the list + * of pending bands to scan */ + priv->scan_bands--; + + /* If a request to abort was given, or the scan did not succeed + * then we reset the scan state machine and terminate, + * re-queuing another scan if one has been requested */ + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_INFO("Aborted scan completed.\n"); + clear_bit(STATUS_SCAN_ABORTING, &priv->status); + } else { + /* If there are more bands on this scan pass reschedule */ + if (priv->scan_bands > 0) + goto reschedule; + } + + priv->last_scan_jiffies = jiffies; + priv->next_scan_jiffies = 0; + IWL_DEBUG_INFO("Setting scan to off\n"); + + clear_bit(STATUS_SCANNING, &priv->status); + + IWL_DEBUG_INFO("Scan took %dms\n", + jiffies_to_msecs(elapsed_jiffies(priv->scan_start, jiffies))); + + queue_work(priv->workqueue, &priv->scan_completed); + + return; + +reschedule: + priv->scan_pass_start = jiffies; + queue_work(priv->workqueue, &priv->request_scan); +} + /* Handle notification from uCode that card's power state is changing * due to software, hardware, or critical temperature RFKILL */ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, @@ -1327,7 +1855,7 @@ static void iwl4965_rx_card_state_notif(struct iwl_priv *priv, clear_bit(STATUS_RF_KILL_SW, &priv->status); if (!(flags & RXON_CARD_DISABLED)) - iwl_scan_cancel(priv); + iwl4965_scan_cancel(priv); if ((test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status)) || @@ -1377,9 +1905,13 @@ static void iwl4965_setup_rx_handlers(struct iwl_priv *priv) */ priv->rx_handlers[REPLY_STATISTICS_CMD] = iwl4965_hw_rx_statistics; priv->rx_handlers[STATISTICS_NOTIFICATION] = iwl4965_hw_rx_statistics; - - iwl_setup_rx_scan_handlers(priv); - + /* scan handlers */ + priv->rx_handlers[REPLY_SCAN_CMD] = iwl4965_rx_reply_scan; + priv->rx_handlers[SCAN_START_NOTIFICATION] = iwl4965_rx_scan_start_notif; + priv->rx_handlers[SCAN_RESULTS_NOTIFICATION] = + iwl4965_rx_scan_results_notif; + priv->rx_handlers[SCAN_COMPLETE_NOTIFICATION] = + iwl4965_rx_scan_complete_notif; /* status change handler */ priv->rx_handlers[CARD_STATE_NOTIFICATION] = iwl4965_rx_card_state_notif; @@ -1517,6 +2049,42 @@ void iwl_rx_handle(struct iwl_priv *priv) priv->rxq.read = i; iwl_rx_queue_restock(priv); } +/* Convert linear signal-to-noise ratio into dB */ +static u8 ratio2dB[100] = { +/* 0 1 2 3 4 5 6 7 8 9 */ + 0, 0, 6, 10, 12, 14, 16, 17, 18, 19, /* 00 - 09 */ + 20, 21, 22, 22, 23, 23, 24, 25, 26, 26, /* 10 - 19 */ + 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, /* 20 - 29 */ + 29, 30, 30, 30, 31, 31, 31, 31, 32, 32, /* 30 - 39 */ + 32, 32, 32, 33, 33, 33, 33, 33, 34, 34, /* 40 - 49 */ + 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, /* 50 - 59 */ + 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, /* 60 - 69 */ + 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, /* 70 - 79 */ + 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, /* 80 - 89 */ + 39, 39, 39, 39, 39, 40, 40, 40, 40, 40 /* 90 - 99 */ +}; + +/* Calculates a relative dB value from a ratio of linear + * (i.e. not dB) signal levels. + * Conversion assumes that levels are voltages (20*log), not powers (10*log). */ +int iwl4965_calc_db_from_ratio(int sig_ratio) +{ + /* 1000:1 or higher just report as 60 dB */ + if (sig_ratio >= 1000) + return 60; + + /* 100:1 or higher, divide by 10 and use table, + * add 20 dB to make up for divide by 10 */ + if (sig_ratio >= 100) + return (20 + (int)ratio2dB[sig_ratio/10]); + + /* We shouldn't see this */ + if (sig_ratio < 1) + return 0; + + /* Use table for ratios 1:1 - 99:1 */ + return (int)ratio2dB[sig_ratio]; +} #define PERFECT_RSSI (-20) /* dBm */ #define WORST_RSSI (-95) /* dBm */ @@ -1891,6 +2459,138 @@ static irqreturn_t iwl4965_isr(int irq, void *data) return IRQ_NONE; } +/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after + * sending probe req. This should be set long enough to hear probe responses + * from more than one AP. */ +#define IWL_ACTIVE_DWELL_TIME_24 (20) /* all times in msec */ +#define IWL_ACTIVE_DWELL_TIME_52 (10) + +/* For faster active scanning, scan will move to the next channel if fewer than + * PLCP_QUIET_THRESH packets are heard on this channel within + * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell + * time if it's a quiet channel (nothing responded to our probe, and there's + * no other traffic). + * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */ +#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */ +#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(5) /* msec */ + +/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel. + * Must be set longer than active dwell time. + * For the most reliable scan, set > AP beacon interval (typically 100msec). */ +#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */ +#define IWL_PASSIVE_DWELL_TIME_52 (10) +#define IWL_PASSIVE_DWELL_BASE (100) +#define IWL_CHANNEL_TUNE_TIME 5 + +static inline u16 iwl4965_get_active_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band) +{ + if (band == IEEE80211_BAND_5GHZ) + return IWL_ACTIVE_DWELL_TIME_52; + else + return IWL_ACTIVE_DWELL_TIME_24; +} + +static u16 iwl4965_get_passive_dwell_time(struct iwl_priv *priv, + enum ieee80211_band band) +{ + u16 active = iwl4965_get_active_dwell_time(priv, band); + u16 passive = (band != IEEE80211_BAND_5GHZ) ? + IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : + IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; + + if (iwl_is_associated(priv)) { + /* If we're associated, we clamp the maximum passive + * dwell time to be 98% of the beacon interval (minus + * 2 * channel tune time) */ + passive = priv->beacon_int; + if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) + passive = IWL_PASSIVE_DWELL_BASE; + passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; + } + + if (passive <= active) + passive = active + 1; + + return passive; +} + +static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, + enum ieee80211_band band, + u8 is_active, u8 direct_mask, + struct iwl4965_scan_channel *scan_ch) +{ + const struct ieee80211_channel *channels = NULL; + const struct ieee80211_supported_band *sband; + const struct iwl_channel_info *ch_info; + u16 passive_dwell = 0; + u16 active_dwell = 0; + int added, i; + + sband = iwl_get_hw_mode(priv, band); + if (!sband) + return 0; + + channels = sband->channels; + + active_dwell = iwl4965_get_active_dwell_time(priv, band); + passive_dwell = iwl4965_get_passive_dwell_time(priv, band); + + for (i = 0, added = 0; i < sband->n_channels; i++) { + if (channels[i].flags & IEEE80211_CHAN_DISABLED) + continue; + + scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); + + ch_info = iwl_get_channel_info(priv, band, + scan_ch->channel); + if (!is_channel_valid(ch_info)) { + IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", + scan_ch->channel); + continue; + } + + if (!is_active || is_channel_passive(ch_info) || + (channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) + scan_ch->type = 0; /* passive */ + else + scan_ch->type = 1; /* active */ + + if (scan_ch->type & 1) + scan_ch->type |= (direct_mask << 1); + + scan_ch->active_dwell = cpu_to_le16(active_dwell); + scan_ch->passive_dwell = cpu_to_le16(passive_dwell); + + /* Set txpower levels to defaults */ + scan_ch->tpc.dsp_atten = 110; + /* scan_pwr_info->tpc.dsp_atten; */ + + /*scan_pwr_info->tpc.tx_gain; */ + if (band == IEEE80211_BAND_5GHZ) + scan_ch->tpc.tx_gain = ((1 << 5) | (3 << 3)) | 3; + else { + scan_ch->tpc.tx_gain = ((1 << 5) | (5 << 3)); + /* NOTE: if we were doing 6Mb OFDM for scans we'd use + * power level: + * scan_ch->tpc.tx_gain = ((1 << 5) | (2 << 3)) | 3; + */ + } + + IWL_DEBUG_SCAN("Scanning %d [%s %d]\n", + scan_ch->channel, + (scan_ch->type & 1) ? "ACTIVE" : "PASSIVE", + (scan_ch->type & 1) ? + active_dwell : passive_dwell); + + scan_ch++; + added++; + } + + IWL_DEBUG_SCAN("total channels to scan %d \n", added); + return added; +} + /****************************************************************************** * * uCode download functions @@ -1921,7 +2621,7 @@ static void iwl4965_nic_start(struct iwl_priv *priv) */ static int iwl4965_read_ucode(struct iwl_priv *priv) { - struct iwl_ucode *ucode; + struct iwl4965_ucode *ucode; int ret; const struct firmware *ucode_raw; const char *name = priv->cfg->fw_name; @@ -2149,6 +2849,9 @@ static void iwl_alive_start(struct iwl_priv *priv) /* After the ALIVE response, we can send host commands to 4965 uCode */ set_bit(STATUS_ALIVE, &priv->status); + /* Clear out the uCode error bit if it is set */ + clear_bit(STATUS_FW_ERROR, &priv->status); + if (iwl_is_rfkill(priv)) return; @@ -2179,7 +2882,7 @@ static void iwl_alive_start(struct iwl_priv *priv) iwl4965_commit_rxon(priv); /* At this point, the NIC is initialized and operational */ - iwl_rf_kill_ct_config(priv); + iwl4965_rf_kill_ct_config(priv); iwl_leds_register(priv); @@ -2190,19 +2893,15 @@ static void iwl_alive_start(struct iwl_priv *priv) if (priv->error_recovering) iwl4965_error_recovery(priv); - iwl_power_update_mode(priv, 1); + iwlcore_low_level_notify(priv, IWLCORE_START_EVT); ieee80211_notify_mac(priv->hw, IEEE80211_NOTIFY_RE_ASSOC); - - if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status)) - iwl4965_set_mode(priv, priv->iw_mode); - return; restart: queue_work(priv->workqueue, &priv->restart); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv); +static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); static void __iwl4965_down(struct iwl_priv *priv) { @@ -2216,6 +2915,8 @@ static void __iwl4965_down(struct iwl_priv *priv) iwl_leds_unregister(priv); + iwlcore_low_level_notify(priv, IWLCORE_STOP_EVT); + iwlcore_clear_stations_table(priv); /* Unblock any waiting calls */ @@ -2304,7 +3005,7 @@ static void iwl4965_down(struct iwl_priv *priv) __iwl4965_down(priv); mutex_unlock(&priv->mutex); - iwl_cancel_deferred_work(priv); + iwl4965_cancel_deferred_work(priv); } #define MAX_HW_RESTARTS 5 @@ -2319,6 +3020,13 @@ static int __iwl4965_up(struct iwl_priv *priv) return -EIO; } + if (test_bit(STATUS_RF_KILL_SW, &priv->status)) { + IWL_WARNING("Radio disabled by SW RF kill (module " + "parameter)\n"); + iwl_rfkill_set_hw_state(priv); + return -ENODEV; + } + if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) { IWL_ERROR("ucode not available for device bringup\n"); return -EIO; @@ -2372,8 +3080,7 @@ static int __iwl4965_up(struct iwl_priv *priv) priv->ucode_data.len); /* We return success when we resume from suspend and rf_kill is on. */ - if (test_bit(STATUS_RF_KILL_HW, &priv->status) || - test_bit(STATUS_RF_KILL_SW, &priv->status)) + if (test_bit(STATUS_RF_KILL_HW, &priv->status)) return 0; for (i = 0; i < MAX_HW_RESTARTS; i++) { @@ -2390,9 +3097,6 @@ static int __iwl4965_up(struct iwl_priv *priv) continue; } - /* Clear out the uCode error bit if it is set */ - clear_bit(STATUS_FW_ERROR, &priv->status); - /* start card; "initialize" will load runtime ucode */ iwl4965_nic_start(priv); @@ -2403,7 +3107,6 @@ static int __iwl4965_up(struct iwl_priv *priv) set_bit(STATUS_EXIT_PENDING, &priv->status); __iwl4965_down(priv); - clear_bit(STATUS_EXIT_PENDING, &priv->status); /* tried to restart and config the device for as long as our * patience could withstand */ @@ -2483,45 +3186,255 @@ static void iwl4965_bg_set_monitor(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, set_monitor); - int ret; IWL_DEBUG(IWL_DL_STATE, "setting monitor mode\n"); mutex_lock(&priv->mutex); - ret = iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR); + if (!iwl_is_ready(priv)) + IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); + else + if (iwl4965_set_mode(priv, IEEE80211_IF_TYPE_MNTR) != 0) + IWL_ERROR("iwl4965_set_mode() failed\n"); - if (ret) { - if (ret == -EAGAIN) - IWL_DEBUG(IWL_DL_STATE, "leave - not ready\n"); - else - IWL_ERROR("iwl4965_set_mode() failed ret = %d\n", ret); - } + mutex_unlock(&priv->mutex); +} + +#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ) + +static void iwl4965_bg_scan_check(struct work_struct *data) +{ + struct iwl_priv *priv = + container_of(data, struct iwl_priv, scan_check.work); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + return; + + mutex_lock(&priv->mutex); + if (test_bit(STATUS_SCANNING, &priv->status) || + test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG(IWL_DL_SCAN, "Scan completion watchdog resetting " + "adapter (%dms)\n", + jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG)); + + if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) + iwl4965_send_scan_abort(priv); + } mutex_unlock(&priv->mutex); } -static void iwl_bg_run_time_calib_work(struct work_struct *work) +static void iwl4965_bg_request_scan(struct work_struct *data) { - struct iwl_priv *priv = container_of(work, struct iwl_priv, - run_time_calib_work); + struct iwl_priv *priv = + container_of(data, struct iwl_priv, request_scan); + struct iwl_host_cmd cmd = { + .id = REPLY_SCAN_CMD, + .len = sizeof(struct iwl4965_scan_cmd), + .meta.flags = CMD_SIZE_HUGE, + }; + struct iwl4965_scan_cmd *scan; + struct ieee80211_conf *conf = NULL; + u16 cmd_len; + enum ieee80211_band band; + u8 direct_mask; + int ret = 0; + + conf = ieee80211_get_hw_conf(priv->hw); mutex_lock(&priv->mutex); - if (test_bit(STATUS_EXIT_PENDING, &priv->status) || - test_bit(STATUS_SCANNING, &priv->status)) { - mutex_unlock(&priv->mutex); - return; + if (!iwl_is_ready(priv)) { + IWL_WARNING("request scan called when driver not ready.\n"); + goto done; + } + + /* Make sure the scan wasn't cancelled before this queued work + * was given the chance to run... */ + if (!test_bit(STATUS_SCANNING, &priv->status)) + goto done; + + /* This should never be called or scheduled if there is currently + * a scan active in the hardware. */ + if (test_bit(STATUS_SCAN_HW, &priv->status)) { + IWL_DEBUG_INFO("Multiple concurrent scan requests in parallel. " + "Ignoring second request.\n"); + ret = -EIO; + goto done; + } + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + IWL_DEBUG_SCAN("Aborting scan due to device shutdown\n"); + goto done; + } + + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { + IWL_DEBUG_HC("Scan request while abort pending. Queuing.\n"); + goto done; } - if (priv->start_calib) { - iwl_chain_noise_calibration(priv, &priv->statistics); + if (iwl_is_rfkill(priv)) { + IWL_DEBUG_HC("Aborting scan due to RF Kill activation\n"); + goto done; + } + + if (!test_bit(STATUS_READY, &priv->status)) { + IWL_DEBUG_HC("Scan request while uninitialized. Queuing.\n"); + goto done; + } + + if (!priv->scan_bands) { + IWL_DEBUG_HC("Aborting scan due to no requested bands\n"); + goto done; + } + + if (!priv->scan) { + priv->scan = kmalloc(sizeof(struct iwl4965_scan_cmd) + + IWL_MAX_SCAN_SIZE, GFP_KERNEL); + if (!priv->scan) { + ret = -ENOMEM; + goto done; + } + } + scan = priv->scan; + memset(scan, 0, sizeof(struct iwl4965_scan_cmd) + IWL_MAX_SCAN_SIZE); + + scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; + scan->quiet_time = IWL_ACTIVE_QUIET_TIME; + + if (iwl_is_associated(priv)) { + u16 interval = 0; + u32 extra; + u32 suspend_time = 100; + u32 scan_suspend_time = 100; + unsigned long flags; + + IWL_DEBUG_INFO("Scanning while associated...\n"); + + spin_lock_irqsave(&priv->lock, flags); + interval = priv->beacon_int; + spin_unlock_irqrestore(&priv->lock, flags); + + scan->suspend_time = 0; + scan->max_out_time = cpu_to_le32(200 * 1024); + if (!interval) + interval = suspend_time; + + extra = (suspend_time / interval) << 22; + scan_suspend_time = (extra | + ((suspend_time % interval) * 1024)); + scan->suspend_time = cpu_to_le32(scan_suspend_time); + IWL_DEBUG_SCAN("suspend_time 0x%X beacon interval %d\n", + scan_suspend_time, interval); + } + + /* We should add the ability for user to lock to PASSIVE ONLY */ + if (priv->one_direct_scan) { + IWL_DEBUG_SCAN + ("Kicking off one direct scan for '%s'\n", + iwl4965_escape_essid(priv->direct_ssid, + priv->direct_ssid_len)); + scan->direct_scan[0].id = WLAN_EID_SSID; + scan->direct_scan[0].len = priv->direct_ssid_len; + memcpy(scan->direct_scan[0].ssid, + priv->direct_ssid, priv->direct_ssid_len); + direct_mask = 1; + } else if (!iwl_is_associated(priv) && priv->essid_len) { + IWL_DEBUG_SCAN + ("Kicking off one direct scan for '%s' when not associated\n", + iwl4965_escape_essid(priv->essid, priv->essid_len)); + scan->direct_scan[0].id = WLAN_EID_SSID; + scan->direct_scan[0].len = priv->essid_len; + memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len); + direct_mask = 1; + } else { + IWL_DEBUG_SCAN("Kicking off one indirect scan.\n"); + direct_mask = 0; + } + + scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; + scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; + scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; + + + switch (priv->scan_bands) { + case 2: + scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; + scan->tx_cmd.rate_n_flags = + iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, + RATE_MCS_ANT_B_MSK|RATE_MCS_CCK_MSK); + + scan->good_CRC_th = 0; + band = IEEE80211_BAND_2GHZ; + break; + + case 1: + scan->tx_cmd.rate_n_flags = + iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, + RATE_MCS_ANT_B_MSK); + scan->good_CRC_th = IWL_GOOD_CRC_TH; + band = IEEE80211_BAND_5GHZ; + break; - iwl_sensitivity_calibration(priv, &priv->statistics); + default: + IWL_WARNING("Invalid scan band count\n"); + goto done; } + /* We don't build a direct scan probe request; the uCode will do + * that based on the direct_mask added to each channel entry */ + cmd_len = iwl4965_fill_probe_req(priv, band, + (struct ieee80211_mgmt *)scan->data, + IWL_MAX_SCAN_SIZE - sizeof(*scan), 0); + + scan->tx_cmd.len = cpu_to_le16(cmd_len); + /* select Rx chains */ + + /* Force use of chains B and C (0x6) for scan Rx. + * Avoid A (0x1) because of its off-channel reception on A-band. + * MIMO is not used here, but value is required to make uCode happy. */ + scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | + cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | + (0x6 << RXON_RX_CHAIN_FORCE_SEL_POS) | + (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS)); + + if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) + scan->filter_flags = RXON_FILTER_PROMISC_MSK; + + if (direct_mask) + scan->channel_count = + iwl4965_get_channels_for_scan( + priv, band, 1, /* active */ + direct_mask, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); + else + scan->channel_count = + iwl4965_get_channels_for_scan( + priv, band, 0, /* passive */ + direct_mask, + (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); + + scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK | + RXON_FILTER_BCON_AWARE_MSK); + cmd.len += le16_to_cpu(scan->tx_cmd.len) + + scan->channel_count * sizeof(struct iwl4965_scan_channel); + cmd.data = scan; + scan->len = cpu_to_le16(cmd.len); + + set_bit(STATUS_SCAN_HW, &priv->status); + ret = iwl_send_cmd_sync(priv, &cmd); + if (ret) + goto done; + + queue_delayed_work(priv->workqueue, &priv->scan_check, + IWL_SCAN_CHECK_WATCHDOG); + mutex_unlock(&priv->mutex); return; + + done: + /* inform mac80211 scan aborted */ + queue_work(priv->workqueue, &priv->scan_completed); + mutex_unlock(&priv->mutex); } static void iwl4965_bg_up(struct work_struct *data) @@ -2585,7 +3498,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) if (!priv->vif || !priv->is_open) return; - iwl_scan_cancel_timeout(priv, 200); + iwl4965_scan_cancel_timeout(priv, 200); conf = ieee80211_get_hw_conf(priv->hw); @@ -2602,9 +3515,10 @@ static void iwl4965_post_associate(struct iwl_priv *priv) priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; +#ifdef CONFIG_IWL4965_HT if (priv->current_ht_config.is_ht) iwl_set_rxon_ht(priv, &priv->current_ht_config); - +#endif /* CONFIG_IWL4965_HT*/ iwl_set_rxon_chain(priv); priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); @@ -2636,9 +3550,10 @@ static void iwl4965_post_associate(struct iwl_priv *priv) case IEEE80211_IF_TYPE_IBSS: - /* assume default assoc id */ - priv->assoc_id = 1; + /* clear out the station table */ + iwlcore_clear_stations_table(priv); + iwl_rxon_add_station(priv, iwl_bcast_addr, 0); iwl_rxon_add_station(priv, priv->bssid, 0); iwl4965_rate_scale_init(priv->hw, IWL_STA_ID); iwl4965_send_beacon_cmd(priv); @@ -2679,14 +3594,29 @@ static void iwl4965_bg_post_associate(struct work_struct *data) } +static void iwl4965_bg_abort_scan(struct work_struct *work) +{ + struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan); + + if (!iwl_is_ready(priv)) + return; + + mutex_lock(&priv->mutex); + + set_bit(STATUS_SCAN_ABORTING, &priv->status); + iwl4965_send_scan_abort(priv); + + mutex_unlock(&priv->mutex); +} + static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); -static void iwl_bg_scan_completed(struct work_struct *work) +static void iwl4965_bg_scan_completed(struct work_struct *work) { struct iwl_priv *priv = container_of(work, struct iwl_priv, scan_completed); - IWL_DEBUG_SCAN("SCAN complete scan\n"); + IWL_DEBUG(IWL_DL_SCAN, "SCAN complete scan\n"); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) return; @@ -2699,7 +3629,7 @@ static void iwl_bg_scan_completed(struct work_struct *work) /* Since setting the TXPOWER may have been deferred while * performing the scan, fire one off */ mutex_lock(&priv->mutex); - iwl_set_tx_power(priv, priv->tx_power_user_lmt, true); + iwl4965_hw_reg_send_txpower(priv); mutex_unlock(&priv->mutex); } @@ -2808,7 +3738,7 @@ static void iwl4965_mac_stop(struct ieee80211_hw *hw) * RXON_FILTER_ASSOC_MSK BIT */ mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); mutex_unlock(&priv->mutex); } @@ -2871,9 +3801,8 @@ static int iwl4965_mac_add_interface(struct ieee80211_hw *hw, memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN); } - if (iwl4965_set_mode(priv, conf->type) == -EAGAIN) - /* we are not ready, will run again when ready */ - set_bit(STATUS_MODE_PENDING, &priv->status); + if (iwl_is_ready(priv)) + iwl4965_set_mode(priv, conf->type); mutex_unlock(&priv->mutex); @@ -2901,14 +3830,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co priv->add_radiotap = !!(conf->flags & IEEE80211_CONF_RADIOTAP); - if (conf->radio_enabled && iwl_radio_kill_sw_enable_radio(priv)) { - IWL_DEBUG_MAC80211("leave - RF-KILL - waiting for uCode\n"); - goto out; - } - - if (!conf->radio_enabled) - iwl_radio_kill_sw_disable_radio(priv); - if (!iwl_is_ready(priv)) { IWL_DEBUG_MAC80211("leave - not ready\n"); ret = -EIO; @@ -2931,16 +3852,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co goto out; } - if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS && - !is_channel_ibss(ch_info)) { - IWL_ERROR("channel %d in band %d not IBSS channel\n", - conf->channel->hw_value, conf->channel->band); - ret = -EINVAL; - goto out; - } - spin_lock_irqsave(&priv->lock, flags); +#ifdef CONFIG_IWL4965_HT /* if we are switching from ht to 2.4 clear flags * from any ht related info since 2.4 does not * support ht */ @@ -2950,6 +3864,7 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co #endif ) priv->staging_rxon.flags = 0; +#endif /* CONFIG_IWL4965_HT */ iwl_set_rxon_channel(priv, conf->channel->band, channel); @@ -2969,6 +3884,9 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co } #endif + if (priv->cfg->ops->lib->radio_kill_sw) + priv->cfg->ops->lib->radio_kill_sw(priv, !conf->radio_enabled); + if (!conf->radio_enabled) { IWL_DEBUG_MAC80211("leave - radio disabled\n"); goto out; @@ -2980,11 +3898,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co goto out; } - IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n", - priv->tx_power_user_lmt, conf->power_level); - - iwl_set_tx_power(priv, conf->power_level, false); - iwl4965_set_rate(priv); if (memcmp(&priv->active_rxon, @@ -3121,7 +4034,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, !is_multicast_ether_addr(conf->bssid)) { /* If there is currently a HW scan going on in the background * then we need to cancel it else the RXON below will fail. */ - if (iwl_scan_cancel_timeout(priv, 100)) { + if (iwl4965_scan_cancel_timeout(priv, 100)) { IWL_WARNING("Aborted scan still in progress " "after 100ms\n"); IWL_DEBUG_MAC80211("leaving - scan abort failed.\n"); @@ -3146,7 +4059,7 @@ static int iwl4965_mac_config_interface(struct ieee80211_hw *hw, } } else { - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwl4965_commit_rxon(priv); } @@ -3204,7 +4117,7 @@ static void iwl4965_mac_remove_interface(struct ieee80211_hw *hw, mutex_lock(&priv->mutex); if (iwl_is_ready_rf(priv)) { - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); cancel_delayed_work(&priv->post_associate); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwl4965_commit_rxon(priv); @@ -3318,7 +4231,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) } if (len) { IWL_DEBUG_SCAN("direct scan for %s [%d]\n ", - iwl_escape_essid(ssid, len), (int)len); + iwl4965_escape_essid(ssid, len), (int)len); priv->one_direct_scan = 1; priv->direct_ssid_len = (u8) @@ -3327,7 +4240,7 @@ static int iwl4965_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len) } else priv->one_direct_scan = 0; - rc = iwl_scan_initiate(priv); + rc = iwl4965_scan_initiate(priv); IWL_DEBUG_MAC80211("leave\n"); @@ -3358,7 +4271,7 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw, return; } - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK); key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); @@ -3416,7 +4329,7 @@ static int iwl4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, } mutex_lock(&priv->mutex); - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); mutex_unlock(&priv->mutex); /* If we are getting WEP group key and we didn't receive any key mapping @@ -3576,9 +4489,11 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211("enter\n"); priv->lq_mngr.lq_ready = 0; +#ifdef CONFIG_IWL4965_HT spin_lock_irqsave(&priv->lock, flags); memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info)); spin_unlock_irqrestore(&priv->lock, flags); +#endif /* CONFIG_IWL4965_HT */ iwl_reset_qos(priv); @@ -3612,7 +4527,7 @@ static void iwl4965_mac_reset_tsf(struct ieee80211_hw *hw) * clear RXON_FILTER_ASSOC_MSK bit */ if (priv->iw_mode != IEEE80211_IF_TYPE_AP) { - iwl_scan_cancel_timeout(priv, 100); + iwl4965_scan_cancel_timeout(priv, 100); priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; iwl4965_commit_rxon(priv); } @@ -3668,7 +4583,7 @@ static int iwl4965_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk iwl_reset_qos(priv); - iwl4965_post_associate(priv); + queue_work(priv->workqueue, &priv->post_associate.work); mutex_unlock(&priv->mutex); @@ -3750,7 +4665,7 @@ static ssize_t show_temperature(struct device *d, if (!iwl_is_alive(priv)) return -EAGAIN; - return sprintf(buf, "%d\n", priv->temperature); + return sprintf(buf, "%d\n", iwl4965_hw_get_temperature(priv)); } static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); @@ -3768,7 +4683,7 @@ static ssize_t show_tx_power(struct device *d, struct device_attribute *attr, char *buf) { struct iwl_priv *priv = (struct iwl_priv *)d->driver_data; - return sprintf(buf, "%d\n", priv->tx_power_user_lmt); + return sprintf(buf, "%d\n", priv->user_txpower_limit); } static ssize_t store_tx_power(struct device *d, @@ -3784,7 +4699,7 @@ static ssize_t store_tx_power(struct device *d, printk(KERN_INFO DRV_NAME ": %s is not in decimal form.\n", buf); else - iwl_set_tx_power(priv, val, false); + iwl4965_hw_reg_set_txpower(priv, val); return count; } @@ -3809,7 +4724,7 @@ static ssize_t store_flags(struct device *d, mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.flags) != flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl4965_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.flags = 0x%04X\n", @@ -3844,7 +4759,7 @@ static ssize_t store_filter_flags(struct device *d, mutex_lock(&priv->mutex); if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { /* Cancel any currently running scans... */ - if (iwl_scan_cancel_timeout(priv, 100)) + if (iwl4965_scan_cancel_timeout(priv, 100)) IWL_WARNING("Could not cancel scan.\n"); else { IWL_DEBUG_INFO("Committing rxon.filter_flags = " @@ -4042,62 +4957,8 @@ static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, static ssize_t show_channels(struct device *d, struct device_attribute *attr, char *buf) { - - struct iwl_priv *priv = dev_get_drvdata(d); - struct ieee80211_channel *channels = NULL; - const struct ieee80211_supported_band *supp_band = NULL; - int len = 0, i; - int count = 0; - - if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) - return -EAGAIN; - - supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); - channels = supp_band->channels; - count = supp_band->n_channels; - - len += sprintf(&buf[len], - "Displaying %d channels in 2.4GHz band " - "(802.11bg):\n", count); - - for (i = 0; i < count; i++) - len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), - channels[i].max_power, - channels[i].flags & IEEE80211_CHAN_RADAR ? - " (IEEE 802.11h required)" : "", - (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) - || (channels[i].flags & - IEEE80211_CHAN_RADAR)) ? "" : - ", IBSS", - channels[i].flags & - IEEE80211_CHAN_PASSIVE_SCAN ? - "passive only" : "active/passive"); - - supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); - channels = supp_band->channels; - count = supp_band->n_channels; - - len += sprintf(&buf[len], "Displaying %d channels in 5.2GHz band " - "(802.11a):\n", count); - - for (i = 0; i < count; i++) - len += sprintf(&buf[len], "%d: %ddBm: BSS%s%s, %s.\n", - ieee80211_frequency_to_channel( - channels[i].center_freq), - channels[i].max_power, - channels[i].flags & IEEE80211_CHAN_RADAR ? - " (IEEE 802.11h required)" : "", - ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) - || (channels[i].flags & - IEEE80211_CHAN_RADAR)) ? "" : - ", IBSS", - channels[i].flags & - IEEE80211_CHAN_PASSIVE_SCAN ? - "passive only" : "active/passive"); - - return len; + /* all this shit doesn't belong into sysfs anyway */ + return 0; } static DEVICE_ATTR(channels, S_IRUSR, show_channels, NULL); @@ -4157,7 +5018,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL); * *****************************************************************************/ -static void iwl_setup_deferred_work(struct iwl_priv *priv) +static void iwl4965_setup_deferred_work(struct iwl_priv *priv) { priv->workqueue = create_workqueue(DRV_NAME); @@ -4166,40 +5027,32 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) INIT_WORK(&priv->up, iwl4965_bg_up); INIT_WORK(&priv->restart, iwl4965_bg_restart); INIT_WORK(&priv->rx_replenish, iwl4965_bg_rx_replenish); + INIT_WORK(&priv->scan_completed, iwl4965_bg_scan_completed); + INIT_WORK(&priv->request_scan, iwl4965_bg_request_scan); + INIT_WORK(&priv->abort_scan, iwl4965_bg_abort_scan); INIT_WORK(&priv->rf_kill, iwl4965_bg_rf_kill); INIT_WORK(&priv->beacon_update, iwl4965_bg_beacon_update); INIT_WORK(&priv->set_monitor, iwl4965_bg_set_monitor); - INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work); INIT_DELAYED_WORK(&priv->post_associate, iwl4965_bg_post_associate); INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); + INIT_DELAYED_WORK(&priv->scan_check, iwl4965_bg_scan_check); - /* FIXME : remove when resolved PENDING */ - INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); - iwl_setup_scan_deferred_work(priv); - - if (priv->cfg->ops->lib->setup_deferred_work) - priv->cfg->ops->lib->setup_deferred_work(priv); - - init_timer(&priv->statistics_periodic); - priv->statistics_periodic.data = (unsigned long)priv; - priv->statistics_periodic.function = iwl4965_bg_statistics_periodic; + iwl4965_hw_setup_deferred_work(priv); tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long)) iwl4965_irq_tasklet, (unsigned long)priv); } -static void iwl_cancel_deferred_work(struct iwl_priv *priv) +static void iwl4965_cancel_deferred_work(struct iwl_priv *priv) { - if (priv->cfg->ops->lib->cancel_deferred_work) - priv->cfg->ops->lib->cancel_deferred_work(priv); + iwl4965_hw_cancel_deferred_work(priv); cancel_delayed_work_sync(&priv->init_alive_start); cancel_delayed_work(&priv->scan_check); cancel_delayed_work(&priv->alive_start); cancel_delayed_work(&priv->post_associate); cancel_work_sync(&priv->beacon_update); - del_timer_sync(&priv->statistics_periodic); } static struct attribute *iwl4965_sysfs_entries[] = { @@ -4247,7 +5100,9 @@ static struct ieee80211_ops iwl4965_hw_ops = { .reset_tsf = iwl4965_mac_reset_tsf, .beacon_update = iwl4965_mac_beacon_update, .bss_info_changed = iwl4965_bss_info_changed, +#ifdef CONFIG_IWL4965_HT .ampdu_action = iwl4965_mac_ampdu_action, +#endif /* CONFIG_IWL4965_HT */ .hw_scan = iwl4965_mac_hw_scan }; @@ -4411,7 +5266,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e } - iwl_setup_deferred_work(priv); + iwl4965_setup_deferred_work(priv); iwl4965_setup_rx_handlers(priv); /******************** @@ -4432,11 +5287,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e if (err) IWL_ERROR("failed to create debugfs files\n"); - err = iwl_rfkill_init(priv); - if (err) - IWL_ERROR("Unable to initialize RFKILL system. " - "Ignoring error: %d\n", err); - iwl_power_initialize(priv); + /* notify iwlcore to init */ + iwlcore_low_level_notify(priv, IWLCORE_INIT_EVT); return 0; out_remove_sysfs: @@ -4499,7 +5351,8 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) } } - iwl_rfkill_unregister(priv); + iwlcore_low_level_notify(priv, IWLCORE_REMOVE_EVT); + iwl4965_dealloc_ucode_pci(priv); if (priv->rxq.bd) diff --git a/trunk/drivers/net/wireless/libertas/if_cs.c b/trunk/drivers/net/wireless/libertas/if_cs.c index cc70d53fadd3..873ab10a0786 100644 --- a/trunk/drivers/net/wireless/libertas/if_cs.c +++ b/trunk/drivers/net/wireless/libertas/if_cs.c @@ -159,9 +159,7 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r -/* - * First the bitmasks for the host/card interrupt/status registers: - */ +/* First the bitmasks for the host/card interrupt/status registers: */ #define IF_CS_BIT_TX 0x0001 #define IF_CS_BIT_RX 0x0002 #define IF_CS_BIT_COMMAND 0x0004 @@ -169,110 +167,35 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r #define IF_CS_BIT_EVENT 0x0010 #define IF_CS_BIT_MASK 0x001f - - -/* - * It's not really clear to me what the host status register is for. It - * needs to be set almost in union with "host int cause". The following - * bits from above are used: - * - * IF_CS_BIT_TX driver downloaded a data packet - * IF_CS_BIT_RX driver got a data packet - * IF_CS_BIT_COMMAND driver downloaded a command - * IF_CS_BIT_RESP not used (has some meaning with powerdown) - * IF_CS_BIT_EVENT driver read a host event - */ +/* And now the individual registers and assorted masks */ #define IF_CS_HOST_STATUS 0x00000000 -/* - * With the host int cause register can the host (that is, Linux) cause - * an interrupt in the firmware, to tell the firmware about those events: - * - * IF_CS_BIT_TX a data packet has been downloaded - * IF_CS_BIT_RX a received data packet has retrieved - * IF_CS_BIT_COMMAND a firmware block or a command has been downloaded - * IF_CS_BIT_RESP not used (has some meaning with powerdown) - * IF_CS_BIT_EVENT a host event (link lost etc) has been retrieved - */ #define IF_CS_HOST_INT_CAUSE 0x00000002 -/* - * The host int mask register is used to enable/disable interrupt. However, - * I have the suspicion that disabled interrupts are lost. - */ #define IF_CS_HOST_INT_MASK 0x00000004 -/* - * Used to send or receive data packets: - */ -#define IF_CS_WRITE 0x00000016 -#define IF_CS_WRITE_LEN 0x00000014 +#define IF_CS_HOST_WRITE 0x00000016 +#define IF_CS_HOST_WRITE_LEN 0x00000014 + +#define IF_CS_HOST_CMD 0x0000001A +#define IF_CS_HOST_CMD_LEN 0x00000018 + #define IF_CS_READ 0x00000010 #define IF_CS_READ_LEN 0x00000024 -/* - * Used to send commands (and to send firmware block) and to - * receive command responses: - */ -#define IF_CS_CMD 0x0000001A -#define IF_CS_CMD_LEN 0x00000018 -#define IF_CS_RESP 0x00000012 -#define IF_CS_RESP_LEN 0x00000030 +#define IF_CS_CARD_CMD 0x00000012 +#define IF_CS_CARD_CMD_LEN 0x00000030 -/* - * The card status registers shows what the card/firmware actually - * accepts: - * - * IF_CS_BIT_TX you may send a data packet - * IF_CS_BIT_RX you may retrieve a data packet - * IF_CS_BIT_COMMAND you may send a command - * IF_CS_BIT_RESP you may retrieve a command response - * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc) - * - * When reading this register several times, you will get back the same - * results --- with one exception: the IF_CS_BIT_EVENT clear itself - * automatically. - * - * Not that we don't rely on BIT_RX,_BIT_RESP or BIT_EVENT because - * we handle this via the card int cause register. - */ #define IF_CS_CARD_STATUS 0x00000020 #define IF_CS_CARD_STATUS_MASK 0x7f00 -/* - * The card int cause register is used by the card/firmware to notify us - * about the following events: - * - * IF_CS_BIT_TX a data packet has successfully been sentx - * IF_CS_BIT_RX a data packet has been received and can be retrieved - * IF_CS_BIT_COMMAND not used - * IF_CS_BIT_RESP the firmware has a command response for us - * IF_CS_BIT_EVENT the card has a event for use (link lost, snr low etc) - */ #define IF_CS_CARD_INT_CAUSE 0x00000022 -/* - * This is used to for handshaking with the card's bootloader/helper image - * to synchronize downloading of firmware blocks. - */ -#define IF_CS_SQ_READ_LOW 0x00000028 -#define IF_CS_SQ_HELPER_OK 0x10 +#define IF_CS_CARD_SQ_READ_LOW 0x00000028 +#define IF_CS_CARD_SQ_HELPER_OK 0x10 -/* - * The scratch register tells us ... - * - * IF_CS_SCRATCH_BOOT_OK the bootloader runs - * IF_CS_SCRATCH_HELPER_OK the helper firmware already runs - */ #define IF_CS_SCRATCH 0x0000003F -#define IF_CS_SCRATCH_BOOT_OK 0x00 -#define IF_CS_SCRATCH_HELPER_OK 0x5a -/* - * Used to detect ancient chips: - */ -#define IF_CS_PRODUCT_ID 0x0000001C -#define IF_CS_CF8385_B1_REV 0x12 /********************************************************************/ @@ -305,8 +228,8 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) /* Is hardware ready? */ while (1) { - u16 status = if_cs_read16(card, IF_CS_CARD_STATUS); - if (status & IF_CS_BIT_COMMAND) + u16 val = if_cs_read16(card, IF_CS_CARD_STATUS); + if (val & IF_CS_BIT_COMMAND) break; if (++loops > 100) { lbs_pr_err("card not ready for commands\n"); @@ -315,12 +238,12 @@ static int if_cs_send_cmd(struct lbs_private *priv, u8 *buf, u16 nb) mdelay(1); } - if_cs_write16(card, IF_CS_CMD_LEN, nb); + if_cs_write16(card, IF_CS_HOST_CMD_LEN, nb); - if_cs_write16_rep(card, IF_CS_CMD, buf, nb / 2); + if_cs_write16_rep(card, IF_CS_HOST_CMD, buf, nb / 2); /* Are we supposed to transfer an odd amount of bytes? */ if (nb & 1) - if_cs_write8(card, IF_CS_CMD, buf[nb-1]); + if_cs_write8(card, IF_CS_HOST_CMD, buf[nb-1]); /* "Assert the download over interrupt command in the Host * status register" */ @@ -351,12 +274,12 @@ static void if_cs_send_data(struct lbs_private *priv, u8 *buf, u16 nb) status = if_cs_read16(card, IF_CS_CARD_STATUS); BUG_ON((status & IF_CS_BIT_TX) == 0); - if_cs_write16(card, IF_CS_WRITE_LEN, nb); + if_cs_write16(card, IF_CS_HOST_WRITE_LEN, nb); /* write even number of bytes, then odd byte if necessary */ - if_cs_write16_rep(card, IF_CS_WRITE, buf, nb / 2); + if_cs_write16_rep(card, IF_CS_HOST_WRITE, buf, nb / 2); if (nb & 1) - if_cs_write8(card, IF_CS_WRITE, buf[nb-1]); + if_cs_write8(card, IF_CS_HOST_WRITE, buf[nb-1]); if_cs_write16(card, IF_CS_HOST_STATUS, IF_CS_BIT_TX); if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_TX); @@ -384,16 +307,16 @@ static int if_cs_receive_cmdres(struct lbs_private *priv, u8 *data, u32 *len) goto out; } - *len = if_cs_read16(priv->card, IF_CS_RESP_LEN); + *len = if_cs_read16(priv->card, IF_CS_CARD_CMD_LEN); if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) { lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len); goto out; } /* read even number of bytes, then odd byte if necessary */ - if_cs_read16_rep(priv->card, IF_CS_RESP, data, *len/sizeof(u16)); + if_cs_read16_rep(priv->card, IF_CS_CARD_CMD, data, *len/sizeof(u16)); if (*len & 1) - data[*len-1] = if_cs_read8(priv->card, IF_CS_RESP); + data[*len-1] = if_cs_read8(priv->card, IF_CS_CARD_CMD); /* This is a workaround for a firmware that reports too much * bytes */ @@ -456,8 +379,6 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) /* Ask card interrupt cause register if there is something for us */ cause = if_cs_read16(card, IF_CS_CARD_INT_CAUSE); - lbs_deb_cs("cause 0x%04x\n", cause); - if (cause == 0) { /* Not for us */ return IRQ_NONE; @@ -469,6 +390,10 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) return IRQ_HANDLED; } + /* Clear interrupt cause */ + if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK); + lbs_deb_cs("cause 0x%04x\n", cause); + if (cause & IF_CS_BIT_RX) { struct sk_buff *skb; lbs_deb_cs("rx packet\n"); @@ -501,15 +426,14 @@ static irqreturn_t if_cs_interrupt(int irq, void *data) } if (cause & IF_CS_BIT_EVENT) { - u16 status = if_cs_read16(priv->card, IF_CS_CARD_STATUS); + u16 event = if_cs_read16(priv->card, IF_CS_CARD_STATUS) + & IF_CS_CARD_STATUS_MASK; if_cs_write16(priv->card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_EVENT); - lbs_queue_event(priv, (status & IF_CS_CARD_STATUS_MASK) >> 8); + lbs_deb_cs("host event 0x%04x\n", event); + lbs_queue_event(priv, event >> 8 & 0xff); } - /* Clear interrupt cause */ - if_cs_write16(card, IF_CS_CARD_INT_CAUSE, cause & IF_CS_BIT_MASK); - lbs_deb_leave(LBS_DEB_CS); return IRQ_HANDLED; } @@ -540,11 +464,11 @@ static int if_cs_prog_helper(struct if_cs_card *card) /* "If the value is 0x5a, the firmware is already * downloaded successfully" */ - if (scratch == IF_CS_SCRATCH_HELPER_OK) + if (scratch == 0x5a) goto done; /* "If the value is != 00, it is invalid value of register */ - if (scratch != IF_CS_SCRATCH_BOOT_OK) { + if (scratch != 0x00) { ret = -ENODEV; goto done; } @@ -572,11 +496,11 @@ static int if_cs_prog_helper(struct if_cs_card *card) /* "write the number of bytes to be sent to the I/O Command * write length register" */ - if_cs_write16(card, IF_CS_CMD_LEN, count); + if_cs_write16(card, IF_CS_HOST_CMD_LEN, count); /* "write this to I/O Command port register as 16 bit writes */ if (count) - if_cs_write16_rep(card, IF_CS_CMD, + if_cs_write16_rep(card, IF_CS_HOST_CMD, &fw->data[sent], count >> 1); @@ -633,15 +557,15 @@ static int if_cs_prog_real(struct if_cs_card *card) } lbs_deb_cs("fw size %td\n", fw->size); - ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW, - IF_CS_SQ_HELPER_OK); + ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_SQ_READ_LOW, + IF_CS_CARD_SQ_HELPER_OK); if (ret < 0) { lbs_pr_err("helper firmware doesn't answer\n"); goto err_release; } for (sent = 0; sent < fw->size; sent += len) { - len = if_cs_read16(card, IF_CS_SQ_READ_LOW); + len = if_cs_read16(card, IF_CS_CARD_SQ_READ_LOW); if (len & 1) { retry++; lbs_pr_info("odd, need to retry this firmware block\n"); @@ -659,9 +583,9 @@ static int if_cs_prog_real(struct if_cs_card *card) } - if_cs_write16(card, IF_CS_CMD_LEN, len); + if_cs_write16(card, IF_CS_HOST_CMD_LEN, len); - if_cs_write16_rep(card, IF_CS_CMD, + if_cs_write16_rep(card, IF_CS_HOST_CMD, &fw->data[sent], (len+1) >> 1); if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); @@ -865,12 +789,6 @@ static int if_cs_probe(struct pcmcia_device *p_dev) p_dev->irq.AssignedIRQ, p_dev->io.BasePort1, p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1); - /* Check if we have a current silicon */ - if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) { - lbs_pr_err("old chips like 8385 rev B1 aren't supported\n"); - ret = -ENODEV; - goto out2; - } /* Load the firmware early, before calling into libertas.ko */ ret = if_cs_prog_helper(card); diff --git a/trunk/drivers/net/wireless/mac80211_hwsim.c b/trunk/drivers/net/wireless/mac80211_hwsim.c deleted file mode 100644 index 8da352ae6825..000000000000 --- a/trunk/drivers/net/wireless/mac80211_hwsim.c +++ /dev/null @@ -1,514 +0,0 @@ -/* - * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 - * Copyright (c) 2008, Jouni Malinen - * - * 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. - */ - -/* - * TODO: - * - IBSS mode simulation (Beacon transmission with competition for "air time") - * - IEEE 802.11a and 802.11n modes - * - RX filtering based on filter configuration (data->rx_filter) - */ - -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); -MODULE_LICENSE("GPL"); - -static int radios = 2; -module_param(radios, int, 0444); -MODULE_PARM_DESC(radios, "Number of simulated radios"); - - -static struct class *hwsim_class; - -static struct ieee80211_hw **hwsim_radios; -static int hwsim_radio_count; -static struct net_device *hwsim_mon; /* global monitor netdev */ - - -static const struct ieee80211_channel hwsim_channels[] = { - { .center_freq = 2412 }, - { .center_freq = 2417 }, - { .center_freq = 2422 }, - { .center_freq = 2427 }, - { .center_freq = 2432 }, - { .center_freq = 2437 }, - { .center_freq = 2442 }, - { .center_freq = 2447 }, - { .center_freq = 2452 }, - { .center_freq = 2457 }, - { .center_freq = 2462 }, - { .center_freq = 2467 }, - { .center_freq = 2472 }, - { .center_freq = 2484 }, -}; - -static const struct ieee80211_rate hwsim_rates[] = { - { .bitrate = 10 }, - { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, - { .bitrate = 60 }, - { .bitrate = 90 }, - { .bitrate = 120 }, - { .bitrate = 180 }, - { .bitrate = 240 }, - { .bitrate = 360 }, - { .bitrate = 480 }, - { .bitrate = 540 } -}; - -struct mac80211_hwsim_data { - struct device *dev; - struct ieee80211_supported_band band; - struct ieee80211_channel channels[ARRAY_SIZE(hwsim_channels)]; - struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)]; - - struct ieee80211_channel *channel; - int radio_enabled; - unsigned long beacon_int; /* in jiffies unit */ - unsigned int rx_filter; - int started; - struct timer_list beacon_timer; -}; - - -struct hwsim_radiotap_hdr { - struct ieee80211_radiotap_header hdr; - u8 rt_flags; - u8 rt_rate; - __le16 rt_channel; - __le16 rt_chbitmask; -} __attribute__ ((packed)); - - -static int hwsim_mon_xmit(struct sk_buff *skb, struct net_device *dev) -{ - /* TODO: allow packet injection */ - dev_kfree_skb(skb); - return 0; -} - - -static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw, - struct sk_buff *tx_skb) -{ - struct mac80211_hwsim_data *data = hw->priv; - struct sk_buff *skb; - struct hwsim_radiotap_hdr *hdr; - u16 flags; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_skb); - struct ieee80211_rate *txrate = ieee80211_get_tx_rate(hw, info); - - if (!netif_running(hwsim_mon)) - return; - - skb = skb_copy_expand(tx_skb, sizeof(*hdr), 0, GFP_ATOMIC); - if (skb == NULL) - return; - - hdr = (struct hwsim_radiotap_hdr *) skb_push(skb, sizeof(*hdr)); - hdr->hdr.it_version = PKTHDR_RADIOTAP_VERSION; - hdr->hdr.it_pad = 0; - hdr->hdr.it_len = cpu_to_le16(sizeof(*hdr)); - hdr->hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | - (1 << IEEE80211_RADIOTAP_RATE) | - (1 << IEEE80211_RADIOTAP_CHANNEL)); - hdr->rt_flags = 0; - hdr->rt_rate = txrate->bitrate / 5; - hdr->rt_channel = data->channel->center_freq; - flags = IEEE80211_CHAN_2GHZ; - if (txrate->flags & IEEE80211_RATE_ERP_G) - flags |= IEEE80211_CHAN_OFDM; - else - flags |= IEEE80211_CHAN_CCK; - hdr->rt_chbitmask = cpu_to_le16(flags); - - skb->dev = hwsim_mon; - skb_set_mac_header(skb, 0); - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -static int mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, - struct sk_buff *skb) -{ - struct mac80211_hwsim_data *data = hw->priv; - int i, ack = 0; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - struct ieee80211_rx_status rx_status; - - memset(&rx_status, 0, sizeof(rx_status)); - /* TODO: set mactime */ - rx_status.freq = data->channel->center_freq; - rx_status.band = data->channel->band; - rx_status.rate_idx = info->tx_rate_idx; - /* TODO: simulate signal strength (and optional packet drop) */ - - /* Copy skb to all enabled radios that are on the current frequency */ - for (i = 0; i < hwsim_radio_count; i++) { - struct mac80211_hwsim_data *data2; - struct sk_buff *nskb; - - if (hwsim_radios[i] == NULL || hwsim_radios[i] == hw) - continue; - data2 = hwsim_radios[i]->priv; - if (!data2->started || !data2->radio_enabled || - data->channel->center_freq != data2->channel->center_freq) - continue; - - nskb = skb_copy(skb, GFP_ATOMIC); - if (nskb == NULL) - continue; - - if (memcmp(hdr->addr1, hwsim_radios[i]->wiphy->perm_addr, - ETH_ALEN) == 0) - ack = 1; - ieee80211_rx_irqsafe(hwsim_radios[i], nskb, &rx_status); - } - - return ack; -} - - -static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - struct mac80211_hwsim_data *data = hw->priv; - int ack; - struct ieee80211_tx_info *txi; - - mac80211_hwsim_monitor_rx(hw, skb); - - if (skb->len < 10) { - /* Should not happen; just a sanity check for addr1 use */ - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - if (!data->radio_enabled) { - printk(KERN_DEBUG "%s: dropped TX frame since radio " - "disabled\n", wiphy_name(hw->wiphy)); - dev_kfree_skb(skb); - return NETDEV_TX_OK; - } - - ack = mac80211_hwsim_tx_frame(hw, skb); - - txi = IEEE80211_SKB_CB(skb); - memset(&txi->status, 0, sizeof(txi->status)); - if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { - if (ack) - txi->flags |= IEEE80211_TX_STAT_ACK; - else - txi->status.excessive_retries = 1; - } - ieee80211_tx_status_irqsafe(hw, skb); - return NETDEV_TX_OK; -} - - -static int mac80211_hwsim_start(struct ieee80211_hw *hw) -{ - struct mac80211_hwsim_data *data = hw->priv; - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); - data->started = 1; - return 0; -} - - -static void mac80211_hwsim_stop(struct ieee80211_hw *hw) -{ - struct mac80211_hwsim_data *data = hw->priv; - data->started = 0; - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); -} - - -static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw, - struct ieee80211_if_init_conf *conf) -{ - DECLARE_MAC_BUF(mac); - printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", - wiphy_name(hw->wiphy), __func__, conf->type, - print_mac(mac, conf->mac_addr)); - return 0; -} - - -static void mac80211_hwsim_remove_interface( - struct ieee80211_hw *hw, struct ieee80211_if_init_conf *conf) -{ - DECLARE_MAC_BUF(mac); - printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%s)\n", - wiphy_name(hw->wiphy), __func__, conf->type, - print_mac(mac, conf->mac_addr)); -} - - -static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, - struct ieee80211_vif *vif) -{ - struct ieee80211_hw *hw = arg; - struct sk_buff *skb; - struct ieee80211_tx_info *info; - - if (vif->type != IEEE80211_IF_TYPE_AP) - return; - - skb = ieee80211_beacon_get(hw, vif); - if (skb == NULL) - return; - info = IEEE80211_SKB_CB(skb); - - mac80211_hwsim_monitor_rx(hw, skb); - mac80211_hwsim_tx_frame(hw, skb); - dev_kfree_skb(skb); -} - - -static void mac80211_hwsim_beacon(unsigned long arg) -{ - struct ieee80211_hw *hw = (struct ieee80211_hw *) arg; - struct mac80211_hwsim_data *data = hw->priv; - - if (!data->started || !data->radio_enabled) - return; - - ieee80211_iterate_active_interfaces_atomic( - hw, mac80211_hwsim_beacon_tx, hw); - - data->beacon_timer.expires = jiffies + data->beacon_int; - add_timer(&data->beacon_timer); -} - - -static int mac80211_hwsim_config(struct ieee80211_hw *hw, - struct ieee80211_conf *conf) -{ - struct mac80211_hwsim_data *data = hw->priv; - - printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n", - wiphy_name(hw->wiphy), __func__, - conf->channel->center_freq, conf->radio_enabled, - conf->beacon_int); - - data->channel = conf->channel; - data->radio_enabled = conf->radio_enabled; - data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000; - if (data->beacon_int < 1) - data->beacon_int = 1; - - if (!data->started || !data->radio_enabled) - del_timer(&data->beacon_timer); - else - mod_timer(&data->beacon_timer, jiffies + data->beacon_int); - - return 0; -} - - -static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, - unsigned int changed_flags, - unsigned int *total_flags, - int mc_count, - struct dev_addr_list *mc_list) -{ - struct mac80211_hwsim_data *data = hw->priv; - - printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__); - - data->rx_filter = 0; - if (*total_flags & FIF_PROMISC_IN_BSS) - data->rx_filter |= FIF_PROMISC_IN_BSS; - if (*total_flags & FIF_ALLMULTI) - data->rx_filter |= FIF_ALLMULTI; - - *total_flags = data->rx_filter; -} - - - -static const struct ieee80211_ops mac80211_hwsim_ops = -{ - .tx = mac80211_hwsim_tx, - .start = mac80211_hwsim_start, - .stop = mac80211_hwsim_stop, - .add_interface = mac80211_hwsim_add_interface, - .remove_interface = mac80211_hwsim_remove_interface, - .config = mac80211_hwsim_config, - .configure_filter = mac80211_hwsim_configure_filter, -}; - - -static void mac80211_hwsim_free(void) -{ - int i; - - for (i = 0; i < hwsim_radio_count; i++) { - if (hwsim_radios[i]) { - struct mac80211_hwsim_data *data; - data = hwsim_radios[i]->priv; - ieee80211_unregister_hw(hwsim_radios[i]); - if (!IS_ERR(data->dev)) - device_unregister(data->dev); - ieee80211_free_hw(hwsim_radios[i]); - } - } - kfree(hwsim_radios); - class_destroy(hwsim_class); -} - - -static struct device_driver mac80211_hwsim_driver = { - .name = "mac80211_hwsim" -}; - - -static void hwsim_mon_setup(struct net_device *dev) -{ - dev->hard_start_xmit = hwsim_mon_xmit; - dev->destructor = free_netdev; - ether_setup(dev); - dev->tx_queue_len = 0; - dev->type = ARPHRD_IEEE80211_RADIOTAP; - memset(dev->dev_addr, 0, ETH_ALEN); - dev->dev_addr[0] = 0x12; -} - - -static int __init init_mac80211_hwsim(void) -{ - int i, err = 0; - u8 addr[ETH_ALEN]; - struct mac80211_hwsim_data *data; - struct ieee80211_hw *hw; - DECLARE_MAC_BUF(mac); - - if (radios < 1 || radios > 65535) - return -EINVAL; - - hwsim_radio_count = radios; - hwsim_radios = kcalloc(hwsim_radio_count, - sizeof(struct ieee80211_hw *), GFP_KERNEL); - if (hwsim_radios == NULL) - return -ENOMEM; - - hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim"); - if (IS_ERR(hwsim_class)) { - kfree(hwsim_radios); - return PTR_ERR(hwsim_class); - } - - memset(addr, 0, ETH_ALEN); - addr[0] = 0x02; - - for (i = 0; i < hwsim_radio_count; i++) { - printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n", - i); - hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops); - if (hw == NULL) { - printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw " - "failed\n"); - err = -ENOMEM; - goto failed; - } - hwsim_radios[i] = hw; - - data = hw->priv; - data->dev = device_create(hwsim_class, NULL, 0, "hwsim%d", i); - if (IS_ERR(data->dev)) { - printk(KERN_DEBUG "mac80211_hwsim: device_create " - "failed (%ld)\n", PTR_ERR(data->dev)); - err = -ENOMEM; - goto failed; - } - data->dev->driver = &mac80211_hwsim_driver; - dev_set_drvdata(data->dev, hw); - - SET_IEEE80211_DEV(hw, data->dev); - addr[3] = i >> 8; - addr[4] = i; - SET_IEEE80211_PERM_ADDR(hw, addr); - - hw->channel_change_time = 1; - hw->queues = 1; - - memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels)); - memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates)); - data->band.channels = data->channels; - data->band.n_channels = ARRAY_SIZE(hwsim_channels); - data->band.bitrates = data->rates; - data->band.n_bitrates = ARRAY_SIZE(hwsim_rates); - hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band; - - err = ieee80211_register_hw(hw); - if (err < 0) { - printk(KERN_DEBUG "mac80211_hwsim: " - "ieee80211_register_hw failed (%d)\n", err); - goto failed; - } - - printk(KERN_DEBUG "%s: hwaddr %s registered\n", - wiphy_name(hw->wiphy), - print_mac(mac, hw->wiphy->perm_addr)); - - setup_timer(&data->beacon_timer, mac80211_hwsim_beacon, - (unsigned long) hw); - } - - hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup); - if (hwsim_mon == NULL) - goto failed; - - rtnl_lock(); - - err = dev_alloc_name(hwsim_mon, hwsim_mon->name); - if (err < 0) { - goto failed_mon; - } - - err = register_netdevice(hwsim_mon); - if (err < 0) - goto failed_mon; - - rtnl_unlock(); - - return 0; - -failed_mon: - rtnl_unlock(); - free_netdev(hwsim_mon); - -failed: - mac80211_hwsim_free(); - return err; -} - - -static void __exit exit_mac80211_hwsim(void) -{ - printk(KERN_DEBUG "mac80211_hwsim: unregister %d radios\n", - hwsim_radio_count); - - unregister_netdev(hwsim_mon); - mac80211_hwsim_free(); -} - - -module_init(init_mac80211_hwsim); -module_exit(exit_mac80211_hwsim); diff --git a/trunk/drivers/net/wireless/rndis_wlan.c b/trunk/drivers/net/wireless/rndis_wlan.c index a36d2c85e26e..3954897d0678 100644 --- a/trunk/drivers/net/wireless/rndis_wlan.c +++ b/trunk/drivers/net/wireless/rndis_wlan.c @@ -310,11 +310,8 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, #define CAP_MODE_MASK 7 #define CAP_SUPPORT_TXPOWER 8 -#define WORK_LINK_UP (1<<0) -#define WORK_LINK_DOWN (1<<1) -#define WORK_SET_MULTICAST_LIST (1<<2) - -#define COMMAND_BUFFER_SIZE (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set)) +#define WORK_CONNECTION_EVENT (1<<0) +#define WORK_SET_MULTICAST_LIST (1<<1) /* RNDIS device private data */ struct rndis_wext_private { @@ -364,8 +361,6 @@ struct rndis_wext_private { u8 *wpa_ie; int wpa_cipher_pair; int wpa_cipher_group; - - u8 command_buffer[COMMAND_BUFFER_SIZE]; }; @@ -432,23 +427,18 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) buflen = *len + sizeof(*u.get); if (buflen < CONTROL_BUFFER_SIZE) buflen = CONTROL_BUFFER_SIZE; - - if (buflen > COMMAND_BUFFER_SIZE) { - u.buf = kmalloc(buflen, GFP_KERNEL); - if (!u.buf) - return -ENOMEM; - } else { - u.buf = priv->command_buffer; - } - - mutex_lock(&priv->command_lock); - + u.buf = kmalloc(buflen, GFP_KERNEL); + if (!u.buf) + return -ENOMEM; memset(u.get, 0, sizeof *u.get); u.get->msg_type = RNDIS_MSG_QUERY; u.get->msg_len = ccpu2(sizeof *u.get); u.get->oid = oid; + mutex_lock(&priv->command_lock); ret = rndis_command(dev, u.header); + mutex_unlock(&priv->command_lock); + if (ret == 0) { ret = le32_to_cpu(u.get_c->len); *len = (*len > ret) ? ret : *len; @@ -456,10 +446,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) ret = rndis_error_status(u.get_c->status); } - mutex_unlock(&priv->command_lock); - - if (u.buf != priv->command_buffer) - kfree(u.buf); + kfree(u.buf); return ret; } @@ -478,16 +465,9 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) buflen = len + sizeof(*u.set); if (buflen < CONTROL_BUFFER_SIZE) buflen = CONTROL_BUFFER_SIZE; - - if (buflen > COMMAND_BUFFER_SIZE) { - u.buf = kmalloc(buflen, GFP_KERNEL); - if (!u.buf) - return -ENOMEM; - } else { - u.buf = priv->command_buffer; - } - - mutex_lock(&priv->command_lock); + u.buf = kmalloc(buflen, GFP_KERNEL); + if (!u.buf) + return -ENOMEM; memset(u.set, 0, sizeof *u.set); u.set->msg_type = RNDIS_MSG_SET; @@ -498,14 +478,14 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) u.set->handle = ccpu2(0); memcpy(u.buf + sizeof(*u.set), data, len); + mutex_lock(&priv->command_lock); ret = rndis_command(dev, u.header); + mutex_unlock(&priv->command_lock); + if (ret == 0) ret = rndis_error_status(u.set_c->status); - mutex_unlock(&priv->command_lock); - - if (u.buf != priv->command_buffer) - kfree(u.buf); + kfree(u.buf); return ret; } @@ -640,7 +620,8 @@ static void dsconfig_to_freq(unsigned int dsconfig, struct iw_freq *freq) static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig) { if (freq->m < 1000 && freq->e == 0) { - if (freq->m >= 1 && freq->m <= ARRAY_SIZE(freq_chan)) + if (freq->m >= 1 && + freq->m <= (sizeof(freq_chan) / sizeof(freq_chan[0]))) *dsconfig = freq_chan[freq->m - 1] * 1000; else return -1; @@ -1178,9 +1159,10 @@ static int rndis_iw_get_range(struct net_device *dev, range->throughput = 11 * 1000 * 1000 / 2; } - range->num_channels = ARRAY_SIZE(freq_chan); + range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); - for (i = 0; i < ARRAY_SIZE(freq_chan) && i < IW_MAX_FREQUENCIES; i++) { + for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && + i < IW_MAX_FREQUENCIES; i++) { range->freq[i].i = i + 1; range->freq[i].m = freq_chan[i] * 100000; range->freq[i].e = 1; @@ -2231,9 +2213,7 @@ static void rndis_wext_worker(struct work_struct *work) int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; int ret, offset; - if (test_and_clear_bit(WORK_LINK_UP, &priv->work_pending)) { - netif_carrier_on(usbdev->net); - + if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { info = kzalloc(assoc_size, GFP_KERNEL); if (!info) goto get_bssid; @@ -2271,15 +2251,6 @@ static void rndis_wext_worker(struct work_struct *work) } } - if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { - netif_carrier_off(usbdev->net); - - evt.data.flags = 0; - evt.data.length = 0; - memset(evt.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); - } - if (test_and_clear_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) set_multicast_list(usbdev); } @@ -2289,24 +2260,29 @@ static void rndis_wext_set_multicast_list(struct net_device *dev) struct usbnet *usbdev = dev->priv; struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); - if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending)) - return; - set_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending); queue_work(priv->workqueue, &priv->work); } -static void rndis_wext_link_change(struct usbnet *usbdev, int state) +static void rndis_wext_link_change(struct usbnet *dev, int state) { - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); + union iwreq_data evt; - /* queue work to avoid recursive calls into rndis_command */ - set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); - queue_work(priv->workqueue, &priv->work); + if (state) { + /* queue work to avoid recursive calls into rndis_command */ + set_bit(WORK_CONNECTION_EVENT, &priv->work_pending); + queue_work(priv->workqueue, &priv->work); + } else { + evt.data.flags = 0; + evt.data.length = 0; + memset(evt.ap_addr.sa_data, 0, ETH_ALEN); + wireless_send_event(dev->net, SIOCGIWAP, &evt, NULL); + } } -static int rndis_wext_get_caps(struct usbnet *usbdev) +static int rndis_wext_get_caps(struct usbnet *dev) { struct { __le32 num_items; @@ -2314,18 +2290,18 @@ static int rndis_wext_get_caps(struct usbnet *usbdev) } networks_supported; int len, retval, i, n; __le32 tx_power; - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); /* determine if supports setting txpower */ len = sizeof(tx_power); - retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power, - &len); + retval = rndis_query_oid(dev, OID_802_11_TX_POWER_LEVEL, &tx_power, + &len); if (retval == 0 && le32_to_cpu(tx_power) != 0xFF) priv->caps |= CAP_SUPPORT_TXPOWER; /* determine supported modes */ len = sizeof(networks_supported); - retval = rndis_query_oid(usbdev, OID_802_11_NETWORK_TYPES_SUPPORTED, + retval = rndis_query_oid(dev, OID_802_11_NETWORK_TYPES_SUPPORTED, &networks_supported, &len); if (retval >= 0) { n = le32_to_cpu(networks_supported.num_items); @@ -2464,9 +2440,9 @@ static void rndis_update_wireless_stats(struct work_struct *work) } -static int bcm4320_early_init(struct usbnet *usbdev) +static int bcm4320_early_init(struct usbnet *dev) { - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); char buf[8]; /* Early initialization settings, setting these won't have effect @@ -2514,48 +2490,51 @@ static int bcm4320_early_init(struct usbnet *usbdev) else priv->param_workaround_interval = modparam_workaround_interval; - rndis_set_config_parameter_str(usbdev, "Country", priv->param_country); - rndis_set_config_parameter_str(usbdev, "FrameBursting", + rndis_set_config_parameter_str(dev, "Country", priv->param_country); + rndis_set_config_parameter_str(dev, "FrameBursting", priv->param_frameburst ? "1" : "0"); - rndis_set_config_parameter_str(usbdev, "Afterburner", + rndis_set_config_parameter_str(dev, "Afterburner", priv->param_afterburner ? "1" : "0"); sprintf(buf, "%d", priv->param_power_save); - rndis_set_config_parameter_str(usbdev, "PowerSaveMode", buf); + rndis_set_config_parameter_str(dev, "PowerSaveMode", buf); sprintf(buf, "%d", priv->param_power_output); - rndis_set_config_parameter_str(usbdev, "PwrOut", buf); + rndis_set_config_parameter_str(dev, "PwrOut", buf); sprintf(buf, "%d", priv->param_roamtrigger); - rndis_set_config_parameter_str(usbdev, "RoamTrigger", buf); + rndis_set_config_parameter_str(dev, "RoamTrigger", buf); sprintf(buf, "%d", priv->param_roamdelta); - rndis_set_config_parameter_str(usbdev, "RoamDelta", buf); + rndis_set_config_parameter_str(dev, "RoamDelta", buf); return 0; } -static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) +static int rndis_wext_bind(struct usbnet *dev, struct usb_interface *intf) { + struct net_device *net = dev->net; struct rndis_wext_private *priv; int retval, len; __le32 tmp; /* allocate rndis private data */ - priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); + priv = kmalloc(sizeof(struct rndis_wext_private), GFP_KERNEL); if (!priv) return -ENOMEM; /* These have to be initialized before calling generic_rndis_bind(). * Otherwise we'll be in big trouble in rndis_wext_early_init(). */ - usbdev->driver_priv = priv; + dev->driver_priv = priv; + memset(priv, 0, sizeof(*priv)); + memset(priv->name, 0, sizeof(priv->name)); strcpy(priv->name, "IEEE802.11"); - usbdev->net->wireless_handlers = &rndis_iw_handlers; - priv->usbdev = usbdev; + net->wireless_handlers = &rndis_iw_handlers; + priv->usbdev = dev; mutex_init(&priv->command_lock); spin_lock_init(&priv->stats_lock); /* try bind rndis_host */ - retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS); + retval = generic_rndis_bind(dev, intf, FLAG_RNDIS_PHYM_WIRELESS); if (retval < 0) goto fail; @@ -2566,21 +2545,20 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) * rndis_host wants to avoid all OID as much as possible * so do promisc/multicast handling in rndis_wext. */ - usbdev->net->set_multicast_list = rndis_wext_set_multicast_list; + dev->net->set_multicast_list = rndis_wext_set_multicast_list; tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST; - retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, + retval = rndis_set_oid(dev, OID_GEN_CURRENT_PACKET_FILTER, &tmp, sizeof(tmp)); len = sizeof(tmp); - retval = rndis_query_oid(usbdev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, - &len); + retval = rndis_query_oid(dev, OID_802_3_MAXIMUM_LIST_SIZE, &tmp, &len); priv->multicast_size = le32_to_cpu(tmp); if (retval < 0 || priv->multicast_size < 0) priv->multicast_size = 0; if (priv->multicast_size > 0) - usbdev->net->flags |= IFF_MULTICAST; + dev->net->flags |= IFF_MULTICAST; else - usbdev->net->flags &= ~IFF_MULTICAST; + dev->net->flags &= ~IFF_MULTICAST; priv->iwstats.qual.qual = 0; priv->iwstats.qual.level = 0; @@ -2590,13 +2568,12 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) | IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; - rndis_wext_get_caps(usbdev); - set_default_iw_params(usbdev); + rndis_wext_get_caps(dev); + set_default_iw_params(dev); /* turn radio on */ priv->radio_on = 1; - disassociate(usbdev, 1); - netif_carrier_off(usbdev->net); + disassociate(dev, 1); /* because rndis_command() sleeps we need to use workqueue */ priv->workqueue = create_singlethread_workqueue("rndis_wlan"); @@ -2613,12 +2590,12 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf) } -static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) +static void rndis_wext_unbind(struct usbnet *dev, struct usb_interface *intf) { - struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev); + struct rndis_wext_private *priv = get_rndis_wext_priv(dev); /* turn radio off */ - disassociate(usbdev, 0); + disassociate(dev, 0); cancel_delayed_work_sync(&priv->stats_work); cancel_work_sync(&priv->work); @@ -2629,13 +2606,13 @@ static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf) kfree(priv->wpa_ie); kfree(priv); - rndis_unbind(usbdev, intf); + rndis_unbind(dev, intf); } -static int rndis_wext_reset(struct usbnet *usbdev) +static int rndis_wext_reset(struct usbnet *dev) { - return deauthenticate(usbdev); + return deauthenticate(dev); } diff --git a/trunk/drivers/net/wireless/rt2x00/Kconfig b/trunk/drivers/net/wireless/rt2x00/Kconfig index 3a9b1d72caf8..0ace76149422 100644 --- a/trunk/drivers/net/wireless/rt2x00/Kconfig +++ b/trunk/drivers/net/wireless/rt2x00/Kconfig @@ -36,13 +36,12 @@ config RT2X00_LIB_FIRMWARE config RT2X00_LIB_RFKILL boolean depends on RT2X00_LIB - depends on INPUT select RFKILL select INPUT_POLLDEV config RT2X00_LIB_LEDS boolean - depends on RT2X00_LIB && NEW_LEDS + depends on RT2X00_LIB config RT2400PCI tristate "Ralink rt2400 (PCI/PCMCIA) support" @@ -57,7 +56,7 @@ config RT2400PCI config RT2400PCI_RFKILL bool "Ralink rt2400 rfkill support" - depends on RT2400PCI && INPUT + depends on RT2400PCI select RT2X00_LIB_RFKILL ---help--- This adds support for integrated rt2400 hardware that features a @@ -66,7 +65,7 @@ config RT2400PCI_RFKILL config RT2400PCI_LEDS bool "Ralink rt2400 leds support" - depends on RT2400PCI && NEW_LEDS + depends on RT2400PCI select LEDS_CLASS select RT2X00_LIB_LEDS ---help--- @@ -85,7 +84,7 @@ config RT2500PCI config RT2500PCI_RFKILL bool "Ralink rt2500 rfkill support" - depends on RT2500PCI && INPUT + depends on RT2500PCI select RT2X00_LIB_RFKILL ---help--- This adds support for integrated rt2500 hardware that features a @@ -94,7 +93,7 @@ config RT2500PCI_RFKILL config RT2500PCI_LEDS bool "Ralink rt2500 leds support" - depends on RT2500PCI && NEW_LEDS + depends on RT2500PCI select LEDS_CLASS select RT2X00_LIB_LEDS ---help--- @@ -115,7 +114,7 @@ config RT61PCI config RT61PCI_RFKILL bool "Ralink rt2501/rt61 rfkill support" - depends on RT61PCI && INPUT + depends on RT61PCI select RT2X00_LIB_RFKILL ---help--- This adds support for integrated rt61 hardware that features a @@ -124,7 +123,7 @@ config RT61PCI_RFKILL config RT61PCI_LEDS bool "Ralink rt2501/rt61 leds support" - depends on RT61PCI && NEW_LEDS + depends on RT61PCI select LEDS_CLASS select RT2X00_LIB_LEDS ---help--- @@ -142,7 +141,7 @@ config RT2500USB config RT2500USB_LEDS bool "Ralink rt2500 leds support" - depends on RT2500USB && NEW_LEDS + depends on RT2500USB select LEDS_CLASS select RT2X00_LIB_LEDS ---help--- @@ -162,7 +161,7 @@ config RT73USB config RT73USB_LEDS bool "Ralink rt2501/rt73 leds support" - depends on RT73USB && NEW_LEDS + depends on RT73USB select LEDS_CLASS select RT2X00_LIB_LEDS ---help--- diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c index bb3d83560d02..900140d3b304 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.c @@ -277,17 +277,6 @@ static int rt2400pci_blink_set(struct led_classdev *led_cdev, return 0; } - -static void rt2400pci_init_led(struct rt2x00_dev *rt2x00dev, - struct rt2x00_led *led, - enum led_type type) -{ - led->rt2x00dev = rt2x00dev; - led->type = type; - led->led_dev.brightness_set = rt2400pci_brightness_set; - led->led_dev.blink_set = rt2400pci_blink_set; - led->flags = LED_INITIALIZED; -} #endif /* CONFIG_RT2400PCI_LEDS */ /* @@ -792,32 +781,25 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2400pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; + u16 eeprom; + u8 reg_id; u8 value; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2400pci_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) - return 0; + goto continue_csr_init; + NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES; -} - -static int rt2400pci_init_bbp(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u16 eeprom; - u8 reg_id; - u8 value; - - if (unlikely(rt2400pci_wait_bbp_ready(rt2x00dev))) - return -EACCES; +continue_csr_init: rt2400pci_bbp_write(rt2x00dev, 1, 0x00); rt2400pci_bbp_write(rt2x00dev, 3, 0x27); rt2400pci_bbp_write(rt2x00dev, 4, 0x08); @@ -856,8 +838,7 @@ static void rt2400pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + state == STATE_RADIO_RX_OFF); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -894,10 +875,17 @@ static int rt2400pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (unlikely(rt2400pci_init_queues(rt2x00dev) || - rt2400pci_init_registers(rt2x00dev) || - rt2400pci_init_bbp(rt2x00dev))) + if (rt2400pci_init_queues(rt2x00dev) || + rt2400pci_init_registers(rt2x00dev) || + rt2400pci_init_bbp(rt2x00dev)) { + ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; + } + + /* + * Enable interrupts. + */ + rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); return 0; } @@ -919,6 +907,11 @@ static void rt2400pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + + /* + * Disable interrupts. + */ + rt2400pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); } static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -953,6 +946,10 @@ static int rt2400pci_set_state(struct rt2x00_dev *rt2x00dev, msleep(10); } + NOTICE(rt2x00dev, "Device failed to enter state %d, " + "current device state: bbp %d and rf %d.\n", + state, bbp_state, rf_state); + return -EBUSY; } @@ -970,13 +967,11 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt2400pci_toggle_rx(rt2x00dev, state); - break; - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - rt2400pci_toggle_irq(rt2x00dev, state); + rt2400pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -989,10 +984,6 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; } - if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); - return retval; } @@ -1016,8 +1007,8 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_desc_write(entry_priv->desc, 1, word); rt2x00_desc_read(txd, 2, &word); - rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skb->len); - rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skb->len); + rt2x00_set_field32(&word, TXD_W2_BUFFER_LENGTH, skbdesc->data_len); + rt2x00_set_field32(&word, TXD_W2_DATABYTE_COUNT, skbdesc->data_len); rt2x00_desc_write(txd, 2, word); rt2x00_desc_read(txd, 3, &word); @@ -1309,10 +1300,23 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2400PCI_LEDS value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); - rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); - if (value == LED_MODE_TXRX_ACTIVITY) - rt2400pci_init_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_ACTIVITY); + rt2x00dev->led_radio.rt2x00dev = rt2x00dev; + rt2x00dev->led_radio.type = LED_TYPE_RADIO; + rt2x00dev->led_radio.led_dev.brightness_set = + rt2400pci_brightness_set; + rt2x00dev->led_radio.led_dev.blink_set = + rt2400pci_blink_set; + rt2x00dev->led_radio.flags = LED_INITIALIZED; + + if (value == LED_MODE_TXRX_ACTIVITY) { + rt2x00dev->led_qual.rt2x00dev = rt2x00dev; + rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; + rt2x00dev->led_qual.led_dev.brightness_set = + rt2400pci_brightness_set; + rt2x00dev->led_qual.led_dev.blink_set = + rt2400pci_blink_set; + rt2x00dev->led_qual.flags = LED_INITIALIZED; + } #endif /* CONFIG_RT2400PCI_LEDS */ /* @@ -1507,6 +1511,9 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + skbdesc->data = skb->data; + skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2400pci.h b/trunk/drivers/net/wireless/rt2x00/rt2400pci.h index bc5564258228..e9aa326be9f6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2400pci.h @@ -37,6 +37,8 @@ * Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ +#define MAX_SIGNAL 100 +#define MAX_RX_SSI -1 #define DEFAULT_RSSI_OFFSET 100 /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c index 3c956b91c4e3..673350953b89 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.c @@ -277,17 +277,6 @@ static int rt2500pci_blink_set(struct led_classdev *led_cdev, return 0; } - -static void rt2500pci_init_led(struct rt2x00_dev *rt2x00dev, - struct rt2x00_led *led, - enum led_type type) -{ - led->rt2x00dev = rt2x00dev; - led->type = type; - led->led_dev.brightness_set = rt2500pci_brightness_set; - led->led_dev.blink_set = rt2500pci_blink_set; - led->flags = LED_INITIALIZED; -} #endif /* CONFIG_RT2500PCI_LEDS */ /* @@ -935,32 +924,25 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2500pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; + u16 eeprom; + u8 reg_id; u8 value; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2500pci_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) - return 0; + goto continue_csr_init; + NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES; -} - -static int rt2500pci_init_bbp(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u16 eeprom; - u8 reg_id; - u8 value; - - if (unlikely(rt2500pci_wait_bbp_ready(rt2x00dev))) - return -EACCES; +continue_csr_init: rt2500pci_bbp_write(rt2x00dev, 3, 0x02); rt2500pci_bbp_write(rt2x00dev, 4, 0x19); rt2500pci_bbp_write(rt2x00dev, 14, 0x1c); @@ -1015,8 +997,7 @@ static void rt2500pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, RXCSR0, ®); rt2x00_set_field32(®, RXCSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + state == STATE_RADIO_RX_OFF); rt2x00pci_register_write(rt2x00dev, RXCSR0, reg); } @@ -1053,10 +1034,17 @@ static int rt2500pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (unlikely(rt2500pci_init_queues(rt2x00dev) || - rt2500pci_init_registers(rt2x00dev) || - rt2500pci_init_bbp(rt2x00dev))) + if (rt2500pci_init_queues(rt2x00dev) || + rt2500pci_init_registers(rt2x00dev) || + rt2500pci_init_bbp(rt2x00dev)) { + ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; + } + + /* + * Enable interrupts. + */ + rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); return 0; } @@ -1078,6 +1066,11 @@ static void rt2500pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_read(rt2x00dev, TXCSR0, ®); rt2x00_set_field32(®, TXCSR0_ABORT, 1); rt2x00pci_register_write(rt2x00dev, TXCSR0, reg); + + /* + * Disable interrupts. + */ + rt2500pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); } static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, @@ -1112,6 +1105,10 @@ static int rt2500pci_set_state(struct rt2x00_dev *rt2x00dev, msleep(10); } + NOTICE(rt2x00dev, "Device failed to enter state %d, " + "current device state: bbp %d and rf %d.\n", + state, bbp_state, rf_state); + return -EBUSY; } @@ -1129,13 +1126,11 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt2500pci_toggle_rx(rt2x00dev, state); - break; - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - rt2500pci_toggle_irq(rt2x00dev, state); + rt2500pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -1148,10 +1143,6 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; } - if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); - return retval; } @@ -1487,10 +1478,23 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2500PCI_LEDS value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); - rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); - if (value == LED_MODE_TXRX_ACTIVITY) - rt2500pci_init_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_ACTIVITY); + rt2x00dev->led_radio.rt2x00dev = rt2x00dev; + rt2x00dev->led_radio.type = LED_TYPE_RADIO; + rt2x00dev->led_radio.led_dev.brightness_set = + rt2500pci_brightness_set; + rt2x00dev->led_radio.led_dev.blink_set = + rt2500pci_blink_set; + rt2x00dev->led_radio.flags = LED_INITIALIZED; + + if (value == LED_MODE_TXRX_ACTIVITY) { + rt2x00dev->led_qual.rt2x00dev = rt2x00dev; + rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; + rt2x00dev->led_qual.led_dev.brightness_set = + rt2500pci_brightness_set; + rt2x00dev->led_qual.led_dev.blink_set = + rt2500pci_blink_set; + rt2x00dev->led_qual.flags = LED_INITIALIZED; + } #endif /* CONFIG_RT2500PCI_LEDS */ /* @@ -1823,6 +1827,9 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + skbdesc->data = skb->data; + skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500pci.h b/trunk/drivers/net/wireless/rt2x00/rt2500pci.h index cb648c30a5b3..ea93b8f423a9 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2500pci.h @@ -48,6 +48,8 @@ * Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ +#define MAX_SIGNAL 100 +#define MAX_RX_SSI -1 #define DEFAULT_RSSI_OFFSET 121 /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c index 9851cefaabf3..cca1504550dc 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.c @@ -316,17 +316,6 @@ static int rt2500usb_blink_set(struct led_classdev *led_cdev, return 0; } - -static void rt2500usb_init_led(struct rt2x00_dev *rt2x00dev, - struct rt2x00_led *led, - enum led_type type) -{ - led->rt2x00dev = rt2x00dev; - led->type = type; - led->led_dev.brightness_set = rt2500usb_brightness_set; - led->led_dev.blink_set = rt2500usb_blink_set; - led->flags = LED_INITIALIZED; -} #endif /* CONFIG_RT2500USB_LEDS */ /* @@ -858,32 +847,25 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt2500usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; + u16 eeprom; u8 value; + u8 reg_id; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2500usb_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) - return 0; + goto continue_csr_init; + NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES; -} - -static int rt2500usb_init_bbp(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u16 eeprom; - u8 value; - u8 reg_id; - - if (unlikely(rt2500usb_wait_bbp_ready(rt2x00dev))) - return -EACCES; +continue_csr_init: rt2500usb_bbp_write(rt2x00dev, 3, 0x02); rt2500usb_bbp_write(rt2x00dev, 4, 0x19); rt2500usb_bbp_write(rt2x00dev, 14, 0x1c); @@ -939,8 +921,7 @@ static void rt2500usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); rt2x00_set_field16(®, TXRX_CSR2_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + state == STATE_RADIO_RX_OFF); rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); } @@ -949,9 +930,11 @@ static int rt2500usb_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (unlikely(rt2500usb_init_registers(rt2x00dev) || - rt2500usb_init_bbp(rt2x00dev))) + if (rt2500usb_init_registers(rt2x00dev) || + rt2500usb_init_bbp(rt2x00dev)) { + ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; + } return 0; } @@ -1004,6 +987,10 @@ static int rt2500usb_set_state(struct rt2x00_dev *rt2x00dev, msleep(30); } + NOTICE(rt2x00dev, "Device failed to enter state %d, " + "current device state: bbp %d and rf %d.\n", + state, bbp_state, rf_state); + return -EBUSY; } @@ -1021,13 +1008,11 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt2500usb_toggle_rx(rt2x00dev, state); - break; - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - /* No support, but no error either */ + rt2500usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -1040,10 +1025,6 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev, break; } - if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); - return retval; } @@ -1088,8 +1069,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_NEW_SEQ, test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, - skb->len - skbdesc->desc_len); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); rt2x00_set_field32(&word, TXD_W0_CIPHER, CIPHER_NONE); rt2x00_desc_write(txd, 0, word); } @@ -1117,10 +1097,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, { u16 reg; - if (queue != QID_BEACON) { - rt2x00usb_kick_tx_queue(rt2x00dev, queue); + if (queue != QID_BEACON) return; - } rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®); if (!rt2x00_get_field16(reg, TXRX_CSR19_BEACON_GEN)) { @@ -1156,10 +1134,14 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, u32 word1; /* - * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of - * frame data in rt2x00usb. + * Copy descriptor to the skb->cb array, this has 2 benefits: + * 1) Each descriptor word is 4 byte aligned. + * 2) Descriptor is safe from moving of frame data in rt2x00usb. */ - memcpy(skbdesc->desc, rxd, skbdesc->desc_len); + skbdesc->desc_len = + min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); + memcpy(entry->skb->cb, rxd, skbdesc->desc_len); + skbdesc->desc = entry->skb->cb; rxd = (__le32 *)skbdesc->desc; /* @@ -1193,6 +1175,8 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, * Adjust the skb memory window to the frame boundaries. */ skb_trim(entry->skb, rxdesc->size); + skbdesc->data = entry->skb->data; + skbdesc->data_len = rxdesc->size; } /* @@ -1393,10 +1377,23 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT2500USB_LEDS value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); - rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); - if (value == LED_MODE_TXRX_ACTIVITY) - rt2500usb_init_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_ACTIVITY); + rt2x00dev->led_radio.rt2x00dev = rt2x00dev; + rt2x00dev->led_radio.type = LED_TYPE_RADIO; + rt2x00dev->led_radio.led_dev.brightness_set = + rt2500usb_brightness_set; + rt2x00dev->led_radio.led_dev.blink_set = + rt2500usb_blink_set; + rt2x00dev->led_radio.flags = LED_INITIALIZED; + + if (value == LED_MODE_TXRX_ACTIVITY) { + rt2x00dev->led_qual.rt2x00dev = rt2x00dev; + rt2x00dev->led_qual.type = LED_TYPE_ACTIVITY; + rt2x00dev->led_qual.led_dev.brightness_set = + rt2500usb_brightness_set; + rt2x00dev->led_qual.led_dev.blink_set = + rt2500usb_blink_set; + rt2x00dev->led_qual.flags = LED_INITIALIZED; + } #endif /* CONFIG_RT2500USB_LEDS */ /* @@ -1706,6 +1703,9 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + skbdesc->data = skb->data + intf->beacon->queue->desc_size; + skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2500usb.h b/trunk/drivers/net/wireless/rt2x00/rt2500usb.h index 3e21fdf2b00f..7d50098f0cc5 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2500usb.h @@ -48,6 +48,8 @@ * Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ +#define MAX_SIGNAL 100 +#define MAX_RX_SSI -1 #define DEFAULT_RSSI_OFFSET 120 /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00.h b/trunk/drivers/net/wireless/rt2x00/rt2x00.h index 0da8f972a1b2..15ec797c5ec1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00.h @@ -44,7 +44,7 @@ /* * Module information. */ -#define DRV_VERSION "2.1.7" +#define DRV_VERSION "2.1.6" #define DRV_PROJECT "http://rt2x00.serialmonkey.com" /* @@ -546,7 +546,8 @@ struct rt2x00lib_ops { void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev, struct sk_buff *skb, struct txentry_desc *txdesc); - int (*write_tx_data) (struct queue_entry *entry); + int (*write_tx_data) (struct rt2x00_dev *rt2x00dev, + struct data_queue *queue, struct sk_buff *skb); int (*get_tx_data_len) (struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); void (*kick_tx_queue) (struct rt2x00_dev *rt2x00dev, @@ -826,7 +827,7 @@ struct rt2x00_dev { * The Beacon array also contains the Atim queue * if that is supported by the device. */ - unsigned int data_queues; + int data_queues; struct data_queue *rx; struct data_queue *tx; struct data_queue *bcn; @@ -929,12 +930,6 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) return ((size * 8 * 10) % rate); } -/** - * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. - * @queue: The queue for which the skb will be applicable. - */ -struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); - /** * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input * @entry: The entry which will be used to transfer the TX frame. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00debug.c b/trunk/drivers/net/wireless/rt2x00/rt2x00debug.c index 300cf061035f..bd92cb8e68e0 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00debug.c @@ -133,7 +133,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, return; } - skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + skb->len, + skbcopy = alloc_skb(sizeof(*dump_hdr) + desc->desc_len + desc->data_len, GFP_ATOMIC); if (!skbcopy) { DEBUG(rt2x00dev, "Failed to copy skb for dump.\n"); @@ -144,7 +144,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, dump_hdr->version = cpu_to_le32(DUMP_HEADER_VERSION); dump_hdr->header_length = cpu_to_le32(sizeof(*dump_hdr)); dump_hdr->desc_length = cpu_to_le32(desc->desc_len); - dump_hdr->data_length = cpu_to_le32(skb->len); + dump_hdr->data_length = cpu_to_le32(desc->data_len); dump_hdr->chip_rt = cpu_to_le16(rt2x00dev->chip.rt); dump_hdr->chip_rf = cpu_to_le16(rt2x00dev->chip.rf); dump_hdr->chip_rev = cpu_to_le32(rt2x00dev->chip.rev); @@ -155,7 +155,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, dump_hdr->timestamp_usec = cpu_to_le32(timestamp.tv_usec); memcpy(skb_put(skbcopy, desc->desc_len), desc->desc, desc->desc_len); - memcpy(skb_put(skbcopy, skb->len), skb->data, skb->len); + memcpy(skb_put(skbcopy, desc->data_len), desc->data, desc->data_len); skb_queue_tail(&intf->frame_dump_skbqueue, skbcopy); wake_up_interruptible(&intf->frame_dump_waitqueue); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index 9ea677320daa..dc5ab90a52c3 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -112,8 +112,6 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev) if (status) return status; - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_ON); - rt2x00leds_led_radio(rt2x00dev, true); rt2x00led_led_activity(rt2x00dev, true); @@ -159,7 +157,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) * Disable radio. */ rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_OFF); - rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_RADIO_IRQ_OFF); rt2x00led_led_activity(rt2x00dev, false); rt2x00leds_led_radio(rt2x00dev, false); } @@ -554,31 +551,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry, { struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; - unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb); struct ieee80211_supported_band *sband; struct ieee80211_hdr *hdr; const struct rt2x00_rate *rate; - unsigned int align; unsigned int i; int idx = -1; u16 fc; - /* - * The data behind the ieee80211 header must be - * aligned on a 4 byte boundary. - */ - align = ((unsigned long)(entry->skb->data + header_size)) & 3; - - if (align) { - skb_push(entry->skb, align); - /* Move entire frame in 1 command */ - memmove(entry->skb->data, entry->skb->data + align, - rxdesc->size); - } - - /* Update data pointers, trim buffer to correct size */ - skb_trim(entry->skb, rxdesc->size); - /* * Update RX statistics. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h b/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h index 558f45bf27e3..c4ce534e3cdb 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -101,7 +101,6 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, /* * Queue handlers. */ -int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index c90992f613fe..b02dbc8a666e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -34,6 +34,7 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, struct sk_buff *frag_skb) { struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(frag_skb); + struct skb_frame_desc *skbdesc; struct ieee80211_tx_info *rts_info; struct sk_buff *skb; int size; @@ -64,7 +65,6 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb)); rts_info = IEEE80211_SKB_CB(skb); rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; - rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS; rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT; rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS; @@ -82,7 +82,14 @@ static int rt2x00mac_tx_rts_cts(struct rt2x00_dev *rt2x00dev, frag_skb->data, size, tx_info, (struct ieee80211_rts *)(skb->data)); - if (rt2x00queue_write_tx_frame(queue, skb)) { + /* + * Initialize skb descriptor + */ + skbdesc = get_skb_frame_desc(skb); + memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + + if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n"); return NETDEV_TX_BUSY; } @@ -128,16 +135,18 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) } /* - * If CTS/RTS is required. create and queue that frame first. - * Make sure we have at least enough entries available to send - * this CTS/RTS frame as well as the data frame. + * If CTS/RTS is required. and this frame is not CTS or RTS, + * create and queue that frame first. But make sure we have + * at least enough entries available to send this CTS/RTS + * frame as well as the data frame. * Note that when the driver has set the set_rts_threshold() * callback function it doesn't need software generation of - * either RTS or CTS-to-self frame and handles everything + * neither RTS or CTS-to-self frames and handles everything * inside the hardware. */ frame_control = le16_to_cpu(ieee80211hdr->frame_control); - if ((tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS | + if (!is_rts_frame(frame_control) && !is_cts_frame(frame_control) && + (tx_info->flags & (IEEE80211_TX_CTL_USE_RTS_CTS | IEEE80211_TX_CTL_USE_CTS_PROTECT)) && !rt2x00dev->ops->hw->set_rts_threshold) { if (rt2x00queue_available(queue) <= 1) { @@ -151,14 +160,17 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) } } - if (rt2x00queue_write_tx_frame(queue, skb)) { + if (rt2x00dev->ops->lib->write_tx_data(rt2x00dev, queue, skb)) { ieee80211_stop_queue(rt2x00dev->hw, qid); return NETDEV_TX_BUSY; } - if (rt2x00queue_threshold(queue)) + if (rt2x00queue_full(queue)) ieee80211_stop_queue(rt2x00dev->hw, qid); + if (rt2x00dev->ops->lib->kick_tx_queue) + rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, qid); + return NETDEV_TX_OK; } EXPORT_SYMBOL_GPL(rt2x00mac_tx); diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c index 8d6ad18d3890..70a3d135f64e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -34,38 +34,52 @@ /* * TX data handlers. */ -int rt2x00pci_write_tx_data(struct queue_entry *entry) +int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue, struct sk_buff *skb) { + struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry_priv_pci *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc; + struct txentry_desc txdesc; u32 word; + if (rt2x00queue_full(queue)) + return -EINVAL; + rt2x00_desc_read(entry_priv->desc, 0, &word); - /* - * This should not happen, we already checked the entry - * was ours. When the hardware disagrees there has been - * a queue corruption! - */ - if (unlikely(rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || - rt2x00_get_field32(word, TXD_ENTRY_VALID))) { - ERROR(entry->queue->rt2x00dev, - "Corrupt queue %d, accessing entry which is not ours.\n" + if (rt2x00_get_field32(word, TXD_ENTRY_OWNER_NIC) || + rt2x00_get_field32(word, TXD_ENTRY_VALID)) { + ERROR(rt2x00dev, + "Arrived at non-free entry in the non-full queue %d.\n" "Please file bug report to %s.\n", entry->queue->qid, DRV_PROJECT); return -EINVAL; } + /* + * Copy all TX descriptor information into txdesc, + * after that we are free to use the skb->cb array + * for our information. + */ + entry->skb = skb; + rt2x00queue_create_tx_descriptor(entry, &txdesc); + /* * Fill in skb descriptor */ - skbdesc = get_skb_frame_desc(entry->skb); + skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->data = skb->data; + skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; - skbdesc->desc_len = entry->queue->desc_size; + skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; - memcpy(entry_priv->data, entry->skb->data, entry->skb->len); + memcpy(entry_priv->data, skb->data, skb->len); + + rt2x00queue_write_tx_descriptor(entry, &txdesc); + rt2x00queue_index_inc(queue, Q_INDEX); return 0; } @@ -79,8 +93,11 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) struct data_queue *queue = rt2x00dev->rx; struct queue_entry *entry; struct queue_entry_priv_pci *entry_priv; + struct ieee80211_hdr *hdr; struct skb_frame_desc *skbdesc; struct rxdone_entry_desc rxdesc; + int header_size; + int align; u32 word; while (1) { @@ -94,21 +111,35 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) memset(&rxdesc, 0, sizeof(rxdesc)); rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); + hdr = (struct ieee80211_hdr *)entry_priv->data; + header_size = + ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); + + /* + * The data behind the ieee80211 header must be + * aligned on a 4 byte boundary. + */ + align = header_size % 4; + /* - * Allocate the sk_buffer and copy all data into it. + * Allocate the sk_buffer, initialize it and copy + * all data into it. */ - entry->skb = rt2x00queue_alloc_rxskb(queue); + entry->skb = dev_alloc_skb(rxdesc.size + align); if (!entry->skb) return; - memcpy(entry->skb->data, entry_priv->data, rxdesc.size); - skb_trim(entry->skb, rxdesc.size); + skb_reserve(entry->skb, align); + memcpy(skb_put(entry->skb, rxdesc.size), + entry_priv->data, rxdesc.size); /* * Fill in skb descriptor */ skbdesc = get_skb_frame_desc(entry->skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->data = entry->skb->data; + skbdesc->data_len = entry->skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; @@ -147,15 +178,14 @@ void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); rt2x00_desc_write(entry_priv->desc, 0, word); - __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* - * If the data queue was below the threshold before the txdone - * handler we must make sure the packet queue in the mac80211 stack + * If the data queue was full before the txdone handler + * we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ - if (!rt2x00queue_threshold(entry->queue)) + if (!rt2x00queue_full(entry->queue)) ieee80211_wake_queue(rt2x00dev->hw, qid); } @@ -357,7 +387,8 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) if (pci_set_mwi(pci_dev)) ERROR_PROBE("MWI not available.\n"); - if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { + if (pci_set_dma_mask(pci_dev, DMA_64BIT_MASK) && + pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { ERROR_PROBE("PCI DMA not supported.\n"); retval = -EIO; goto exit_disable_device; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h index 87c4a0cd78db..37c851e442c1 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00pci.h @@ -87,14 +87,11 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, memcpy_toio(rt2x00dev->csr.base + offset, value, length); } -/** - * rt2x00pci_write_tx_data - Initialize data for TX operation - * @entry: The entry where the frame is located - * - * This function will initialize the DMA and skb descriptor - * to prepare the entry for the actual TX operation. +/* + * TX data handlers. */ -int rt2x00pci_write_tx_data(struct queue_entry *entry); +int rt2x00pci_write_tx_data(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue, struct sk_buff *skb); /** * struct queue_entry_priv_pci: Per entry PCI specific information diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c index 7b52039b01a6..e69ef4b19239 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.c @@ -29,45 +29,6 @@ #include "rt2x00.h" #include "rt2x00lib.h" -struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) -{ - struct sk_buff *skb; - unsigned int frame_size; - unsigned int reserved_size; - - /* - * The frame size includes descriptor size, because the - * hardware directly receive the frame into the skbuffer. - */ - frame_size = queue->data_size + queue->desc_size; - - /* - * For the allocation we should keep a few things in mind: - * 1) 4byte alignment of 802.11 payload - * - * For (1) we need at most 4 bytes to guarentee the correct - * alignment. We are going to optimize the fact that the chance - * that the 802.11 header_size % 4 == 2 is much bigger then - * anything else. However since we need to move the frame up - * to 3 bytes to the front, which means we need to preallocate - * 6 bytes. - */ - reserved_size = 6; - - /* - * Allocate skbuffer. - */ - skb = dev_alloc_skb(frame_size + reserved_size); - if (!skb) - return NULL; - - skb_reserve(skb, reserved_size); - skb_put(skb, frame_size); - - return skb; -} -EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); - void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { @@ -130,7 +91,7 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, /* * Check if more fragments are pending */ - if (ieee80211_has_morefrags(hdr->frame_control)) { + if (ieee80211_get_morefrag(hdr)) { __set_bit(ENTRY_TXD_BURST, &txdesc->flags); __set_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags); } @@ -202,8 +163,8 @@ EXPORT_SYMBOL_GPL(rt2x00queue_create_tx_descriptor); void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { - struct data_queue *queue = entry->queue; - struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; + struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; + struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); @@ -214,61 +175,19 @@ void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); /* - * Check if we need to kick the queue, there are however a few rules - * 1) Don't kick beacon queue - * 2) Don't kick unless this is the last in frame in a burst. - * When the burst flag is set, this frame is always followed - * by another frame which in some way are related to eachother. - * This is true for fragments, RTS or CTS-to-self frames. - * 3) Rule 2 can be broken when the available entries - * in the queue are less then a certain threshold. + * We are done writing the frame to the queue entry, + * also kick the queue in case the correct flags are set, + * note that this will automatically filter beacons and + * RTS/CTS frames since those frames don't have this flag + * set. */ - if (entry->queue->qid == QID_BEACON) - return; - - if (rt2x00queue_threshold(queue) || - !test_bit(ENTRY_TXD_BURST, &txdesc->flags)) - rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, queue->qid); + if (rt2x00dev->ops->lib->kick_tx_queue && + !(skbdesc->flags & FRAME_DESC_DRIVER_GENERATED)) + rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, + entry->queue->qid); } EXPORT_SYMBOL_GPL(rt2x00queue_write_tx_descriptor); -int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) -{ - struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); - struct txentry_desc txdesc; - - if (unlikely(rt2x00queue_full(queue))) - return -EINVAL; - - if (__test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { - ERROR(queue->rt2x00dev, - "Arrived at non-free entry in the non-full queue %d.\n" - "Please file bug report to %s.\n", - queue->qid, DRV_PROJECT); - return -EINVAL; - } - - /* - * Copy all TX descriptor information into txdesc, - * after that we are free to use the skb->cb array - * for our information. - */ - entry->skb = skb; - rt2x00queue_create_tx_descriptor(entry, &txdesc); - - if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { - __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); - return -EIO; - } - - __set_bit(ENTRY_DATA_PENDING, &entry->flags); - - rt2x00queue_index_inc(queue, Q_INDEX); - rt2x00queue_write_tx_descriptor(entry, &txdesc); - - return 0; -} - struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, const enum data_queue_qid queue) { @@ -393,7 +312,6 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, rt2x00queue_reset(queue); queue->limit = qdesc->entry_num; - queue->threshold = DIV_ROUND_UP(qdesc->entry_num, 10); queue->data_size = qdesc->data_size; queue->desc_size = qdesc->desc_size; @@ -521,8 +439,7 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) * TX: qid = QID_AC_BE + index * TX: cw_min: 2^5 = 32. * TX: cw_max: 2^10 = 1024. - * BCN: qid = QID_BEACON - * ATIM: qid = QID_ATIM + * BCN & Atim: qid = QID_MGMT */ rt2x00queue_init(rt2x00dev, rt2x00dev->rx, QID_RX); @@ -530,9 +447,9 @@ int rt2x00queue_allocate(struct rt2x00_dev *rt2x00dev) tx_queue_for_each(rt2x00dev, queue) rt2x00queue_init(rt2x00dev, queue, qid++); - rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_BEACON); + rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[0], QID_MGMT); if (req_atim) - rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_ATIM); + rt2x00queue_init(rt2x00dev, &rt2x00dev->bcn[1], QID_MGMT); return 0; } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h index fcf52520b016..4d00ced14cc7 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00queue.h @@ -82,10 +82,12 @@ enum data_queue_qid { /** * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc * + * @FRAME_DESC_DRIVER_GENERATED: Frame was generated inside driver + * and should not be reported back to mac80211 during txdone. */ -//enum skb_frame_desc_flags { -// TEMPORARILY EMPTY -//}; +enum skb_frame_desc_flags { + FRAME_DESC_DRIVER_GENERATED = 1 << 0, +}; /** * struct skb_frame_desc: Descriptor information for the skb buffer @@ -105,8 +107,11 @@ enum data_queue_qid { struct skb_frame_desc { unsigned int flags; + unsigned short data_len; + unsigned short desc_len; + + void *data; void *desc; - unsigned int desc_len; struct queue_entry *entry; }; @@ -255,14 +260,11 @@ struct txentry_desc { * @ENTRY_OWNER_DEVICE_CRYPTO: This entry is owned by the device for data * encryption or decryption. The entry should only be touched after * the device has signaled it is done with it. - * @ENTRY_DATA_PENDING: This entry contains a valid frame and is waiting - * for the signal to start sending. */ enum queue_entry_flags { ENTRY_BCN_ASSIGNED, ENTRY_OWNER_DEVICE_DATA, ENTRY_OWNER_DEVICE_CRYPTO, - ENTRY_DATA_PENDING, }; /** @@ -320,7 +322,6 @@ enum queue_index { * index corruption due to concurrency. * @count: Number of frames handled in the queue. * @limit: Maximum number of entries in the queue. - * @threshold: Minimum number of free entries before queue is kicked by force. * @length: Number of frames in queue. * @index: Index pointers to entry positions in the queue, * use &enum queue_index to get a specific index field. @@ -339,7 +340,6 @@ struct data_queue { spinlock_t lock; unsigned int count; unsigned short limit; - unsigned short threshold; unsigned short length; unsigned short index[Q_INDEX_MAX]; @@ -463,15 +463,6 @@ static inline int rt2x00queue_available(struct data_queue *queue) return queue->limit - queue->length; } -/** - * rt2x00queue_threshold - Check if the queue is below threshold - * @queue: Queue to check. - */ -static inline int rt2x00queue_threshold(struct data_queue *queue) -{ - return rt2x00queue_available(queue) < queue->threshold; -} - /** * rt2x00_desc_read - Read a word from the hardware descriptor. * @desc: Base descriptor address diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00reg.h b/trunk/drivers/net/wireless/rt2x00/rt2x00reg.h index 7e88ce5651b9..3f255df58b78 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00reg.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00reg.h @@ -130,107 +130,83 @@ struct rt2x00_field32 { /* * Power of two check, this will check - * if the mask that has been given contains and contiguous set of bits. - * Note that we cannot use the is_power_of_2() function since this - * check must be done at compile-time. + * if the mask that has been given contains + * and contiguous set of bits. */ #define is_power_of_two(x) ( !((x) & ((x)-1)) ) #define low_bit_mask(x) ( ((x)-1) & ~(x) ) #define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x)) -/* - * Macro's to find first set bit in a variable. - * These macro's behaves the same as the __ffs() function with - * the most important difference that this is done during - * compile-time rather then run-time. - */ -#define compile_ffs2(__x) \ - __builtin_choose_expr(((__x) & 0x1), 0, 1) - -#define compile_ffs4(__x) \ - __builtin_choose_expr(((__x) & 0x3), \ - (compile_ffs2((__x))), \ - (compile_ffs2((__x) >> 2) + 2)) - -#define compile_ffs8(__x) \ - __builtin_choose_expr(((__x) & 0xf), \ - (compile_ffs4((__x))), \ - (compile_ffs4((__x) >> 4) + 4)) - -#define compile_ffs16(__x) \ - __builtin_choose_expr(((__x) & 0xff), \ - (compile_ffs8((__x))), \ - (compile_ffs8((__x) >> 8) + 8)) - -#define compile_ffs32(__x) \ - __builtin_choose_expr(((__x) & 0xffff), \ - (compile_ffs16((__x))), \ - (compile_ffs16((__x) >> 16) + 16)) - -/* - * This macro will check the requirements for the FIELD{8,16,32} macros - * The mask should be a constant non-zero contiguous set of bits which - * does not exceed the given typelimit. - */ -#define FIELD_CHECK(__mask, __type) \ - BUILD_BUG_ON(!__builtin_constant_p(__mask) || \ - !(__mask) || \ - !is_valid_mask(__mask) || \ - (__mask) != (__type)(__mask)) \ - #define FIELD8(__mask) \ ({ \ - FIELD_CHECK(__mask, u8); \ + BUILD_BUG_ON(!(__mask) || \ + !is_valid_mask(__mask) || \ + (__mask) != (u8)(__mask)); \ (struct rt2x00_field8) { \ - compile_ffs8(__mask), (__mask) \ + __ffs(__mask), (__mask) \ }; \ }) #define FIELD16(__mask) \ ({ \ - FIELD_CHECK(__mask, u16); \ + BUILD_BUG_ON(!(__mask) || \ + !is_valid_mask(__mask) || \ + (__mask) != (u16)(__mask));\ (struct rt2x00_field16) { \ - compile_ffs16(__mask), (__mask) \ + __ffs(__mask), (__mask) \ }; \ }) #define FIELD32(__mask) \ ({ \ - FIELD_CHECK(__mask, u32); \ + BUILD_BUG_ON(!(__mask) || \ + !is_valid_mask(__mask) || \ + (__mask) != (u32)(__mask));\ (struct rt2x00_field32) { \ - compile_ffs32(__mask), (__mask) \ + __ffs(__mask), (__mask) \ }; \ }) -#define SET_FIELD(__reg, __type, __field, __value)\ -({ \ - typecheck(__type, __field); \ - *(__reg) &= ~((__field).bit_mask); \ - *(__reg) |= ((__value) << \ - ((__field).bit_offset)) & \ - ((__field).bit_mask); \ -}) - -#define GET_FIELD(__reg, __type, __field) \ -({ \ - typecheck(__type, __field); \ - ((__reg) & ((__field).bit_mask)) >> \ - ((__field).bit_offset); \ -}) - -#define rt2x00_set_field32(__reg, __field, __value) \ - SET_FIELD(__reg, struct rt2x00_field32, __field, __value) -#define rt2x00_get_field32(__reg, __field) \ - GET_FIELD(__reg, struct rt2x00_field32, __field) - -#define rt2x00_set_field16(__reg, __field, __value) \ - SET_FIELD(__reg, struct rt2x00_field16, __field, __value) -#define rt2x00_get_field16(__reg, __field) \ - GET_FIELD(__reg, struct rt2x00_field16, __field) - -#define rt2x00_set_field8(__reg, __field, __value) \ - SET_FIELD(__reg, struct rt2x00_field8, __field, __value) -#define rt2x00_get_field8(__reg, __field) \ - GET_FIELD(__reg, struct rt2x00_field8, __field) +static inline void rt2x00_set_field32(u32 *reg, + const struct rt2x00_field32 field, + const u32 value) +{ + *reg &= ~(field.bit_mask); + *reg |= (value << field.bit_offset) & field.bit_mask; +} + +static inline u32 rt2x00_get_field32(const u32 reg, + const struct rt2x00_field32 field) +{ + return (reg & field.bit_mask) >> field.bit_offset; +} + +static inline void rt2x00_set_field16(u16 *reg, + const struct rt2x00_field16 field, + const u16 value) +{ + *reg &= ~(field.bit_mask); + *reg |= (value << field.bit_offset) & field.bit_mask; +} + +static inline u16 rt2x00_get_field16(const u16 reg, + const struct rt2x00_field16 field) +{ + return (reg & field.bit_mask) >> field.bit_offset; +} + +static inline void rt2x00_set_field8(u8 *reg, + const struct rt2x00_field8 field, + const u8 value) +{ + *reg &= ~(field.bit_mask); + *reg |= (value << field.bit_offset) & field.bit_mask; +} + +static inline u8 rt2x00_get_field8(const u8 reg, + const struct rt2x00_field8 field) +{ + return (reg & field.bit_mask) >> field.bit_offset; +} #endif /* RT2X00REG_H */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c index 3080969ae5b3..52d12fdc0ccf 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.c @@ -130,12 +130,16 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) struct queue_entry *entry = (struct queue_entry *)urb->context; struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct txdone_entry_desc txdesc; + __le32 *txd = (__le32 *)entry->skb->data; enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); + u32 word; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) return; + rt2x00_desc_read(txd, 0, &word); + /* * Remove the descriptor data from the buffer. */ @@ -165,101 +169,124 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); /* - * If the data queue was below the threshold before the txdone - * handler we must make sure the packet queue in the mac80211 stack + * If the data queue was full before the txdone handler + * we must make sure the packet queue in the mac80211 stack * is reenabled when the txdone handler has finished. */ - if (!rt2x00queue_threshold(entry->queue)) + if (!rt2x00queue_full(entry->queue)) ieee80211_wake_queue(rt2x00dev->hw, qid); } -int rt2x00usb_write_tx_data(struct queue_entry *entry) +int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue, struct sk_buff *skb) { - struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); + struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); struct queue_entry_priv_usb *entry_priv = entry->priv_data; struct skb_frame_desc *skbdesc; + struct txentry_desc txdesc; u32 length; + if (rt2x00queue_full(queue)) + return -EINVAL; + + if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) { + ERROR(rt2x00dev, + "Arrived at non-free entry in the non-full queue %d.\n" + "Please file bug report to %s.\n", + entry->queue->qid, DRV_PROJECT); + return -EINVAL; + } + + /* + * Copy all TX descriptor information into txdesc, + * after that we are free to use the skb->cb array + * for our information. + */ + entry->skb = skb; + rt2x00queue_create_tx_descriptor(entry, &txdesc); + /* * Add the descriptor in front of the skb. */ - skb_push(entry->skb, entry->queue->desc_size); - memset(entry->skb->data, 0, entry->queue->desc_size); + skb_push(skb, queue->desc_size); + memset(skb->data, 0, queue->desc_size); /* * Fill in skb descriptor */ - skbdesc = get_skb_frame_desc(entry->skb); + skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); - skbdesc->desc = entry->skb->data; - skbdesc->desc_len = entry->queue->desc_size; + skbdesc->data = skb->data + queue->desc_size; + skbdesc->data_len = skb->len - queue->desc_size; + skbdesc->desc = skb->data; + skbdesc->desc_len = queue->desc_size; skbdesc->entry = entry; + rt2x00queue_write_tx_descriptor(entry, &txdesc); + /* * USB devices cannot blindly pass the skb->len as the * length of the data to usb_fill_bulk_urb. Pass the skb * to the driver to determine what the length should be. */ - length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, entry->skb); + length = rt2x00dev->ops->lib->get_tx_data_len(rt2x00dev, skb); - usb_fill_bulk_urb(entry_priv->urb, usb_dev, - usb_sndbulkpipe(usb_dev, 1), - entry->skb->data, length, - rt2x00usb_interrupt_txdone, entry); + /* + * Initialize URB and send the frame to the device. + */ + __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); + usb_fill_bulk_urb(entry_priv->urb, usb_dev, usb_sndbulkpipe(usb_dev, 1), + skb->data, length, rt2x00usb_interrupt_txdone, entry); + usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + + rt2x00queue_index_inc(queue, Q_INDEX); return 0; } EXPORT_SYMBOL_GPL(rt2x00usb_write_tx_data); -static inline void rt2x00usb_kick_tx_entry(struct queue_entry *entry) +/* + * RX data handlers. + */ +static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue) { - struct queue_entry_priv_usb *entry_priv = entry->priv_data; - - if (__test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags)) - usb_submit_urb(entry_priv->urb, GFP_ATOMIC); -} + struct sk_buff *skb; + unsigned int frame_size; + unsigned int reserved_size; -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid) -{ - struct data_queue *queue = rt2x00queue_get_queue(rt2x00dev, qid); - unsigned long irqflags; - unsigned int index; - unsigned int index_done; - unsigned int i; + /* + * The frame size includes descriptor size, because the + * hardware directly receive the frame into the skbuffer. + */ + frame_size = queue->data_size + queue->desc_size; /* - * Only protect the range we are going to loop over, - * if during our loop a extra entry is set to pending - * it should not be kicked during this run, since it - * is part of another TX operation. + * For the allocation we should keep a few things in mind: + * 1) 4byte alignment of 802.11 payload + * + * For (1) we need at most 4 bytes to guarentee the correct + * alignment. We are going to optimize the fact that the chance + * that the 802.11 header_size % 4 == 2 is much bigger then + * anything else. However since we need to move the frame up + * to 3 bytes to the front, which means we need to preallocate + * 6 bytes. */ - spin_lock_irqsave(&queue->lock, irqflags); - index = queue->index[Q_INDEX]; - index_done = queue->index[Q_INDEX_DONE]; - spin_unlock_irqrestore(&queue->lock, irqflags); + reserved_size = 6; /* - * Start from the TX done pointer, this guarentees that we will - * send out all frames in the correct order. + * Allocate skbuffer. */ - if (index_done < index) { - for (i = index_done; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } else { - for (i = index_done; i < queue->limit; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - - for (i = 0; i < index; i++) - rt2x00usb_kick_tx_entry(&queue->entries[i]); - } + skb = dev_alloc_skb(frame_size + reserved_size); + if (!skb) + return NULL; + + skb_reserve(skb, reserved_size); + skb_put(skb, frame_size); + + return skb; } -EXPORT_SYMBOL_GPL(rt2x00usb_kick_tx_queue); -/* - * RX data handlers. - */ static void rt2x00usb_interrupt_rxdone(struct urb *urb) { struct queue_entry *entry = (struct queue_entry *)urb->context; @@ -267,7 +294,8 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) struct sk_buff *skb; struct skb_frame_desc *skbdesc; struct rxdone_entry_desc rxdesc; - u8 rxd[32]; + unsigned int header_size; + unsigned int align; if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) @@ -287,18 +315,39 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) skbdesc = get_skb_frame_desc(entry->skb); memset(skbdesc, 0, sizeof(*skbdesc)); skbdesc->entry = entry; - skbdesc->desc = rxd; - skbdesc->desc_len = entry->queue->desc_size; memset(&rxdesc, 0, sizeof(rxdesc)); rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); + header_size = ieee80211_get_hdrlen_from_skb(entry->skb); + + /* + * The data behind the ieee80211 header must be + * aligned on a 4 byte boundary. We already reserved + * 2 bytes for header_size % 4 == 2 optimization. + * To determine the number of bytes which the data + * should be moved to the left, we must add these + * 2 bytes to the header_size. + */ + align = (header_size + 2) % 4; + + if (align) { + skb_push(entry->skb, align); + /* Move entire frame in 1 command */ + memmove(entry->skb->data, entry->skb->data + align, + rxdesc.size); + } + + /* Update data pointers, trim buffer to correct size */ + skbdesc->data = entry->skb->data; + skb_trim(entry->skb, rxdesc.size); + /* * Allocate a new sk buffer to replace the current one. * If allocation fails, we should drop the current frame * so we can recycle the existing sk buffer for the new frame. */ - skb = rt2x00queue_alloc_rxskb(entry->queue); + skb = rt2x00usb_alloc_rxskb(entry->queue); if (!skb) goto skip_entry; @@ -345,11 +394,8 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) } /* - * Kill guardian urb (if required by driver). + * Kill guardian urb. */ - if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) - return; - for (i = 0; i < rt2x00dev->bcn->limit; i++) { bcn_priv = rt2x00dev->bcn->entries[i].priv_data; if (bcn_priv->guardian_urb) @@ -473,7 +519,7 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) */ entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; for (i = 0; i < rt2x00dev->rx->limit; i++) { - skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx); + skb = rt2x00usb_alloc_rxskb(rt2x00dev->rx); if (!skb) goto exit; diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.h b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.h index b1187c812e7f..26f53f868af6 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00usb.h @@ -212,14 +212,11 @@ static inline int rt2x00usb_eeprom_read(struct rt2x00_dev *rt2x00dev, */ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev); -/** - * rt2x00usb_write_tx_data - Initialize URB for TX operation - * @entry: The entry where the frame is located - * - * This function will initialize the URB and skb descriptor - * to prepare the entry for the actual TX operation. +/* + * TX data handlers. */ -int rt2x00usb_write_tx_data(struct queue_entry *entry); +int rt2x00usb_write_tx_data(struct rt2x00_dev *rt2x00dev, + struct data_queue *queue, struct sk_buff *skb); /** * struct queue_entry_priv_usb: Per entry USB specific information @@ -248,17 +245,6 @@ struct queue_entry_priv_usb_bcn { struct urb *guardian_urb; }; -/** - * rt2x00usb_kick_tx_queue - Kick data queue - * @rt2x00dev: Pointer to &struct rt2x00_dev - * @qid: Data queue to kick - * - * This will walk through all entries of the queue and push all pending - * frames to the hardware as a single burst. - */ -void rt2x00usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, - const enum data_queue_qid qid); - /* * Device initialization handlers. */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.c b/trunk/drivers/net/wireless/rt2x00/rt61pci.c index 5b7267ece1b9..e13ed5ced26e 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.c +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.c @@ -330,17 +330,6 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev, return 0; } - -static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev, - struct rt2x00_led *led, - enum led_type type) -{ - led->rt2x00dev = rt2x00dev; - led->type = type; - led->led_dev.brightness_set = rt61pci_brightness_set; - led->led_dev.blink_set = rt61pci_blink_set; - led->flags = LED_INITIALIZED; -} #endif /* CONFIG_RT61PCI_LEDS */ /* @@ -1281,32 +1270,25 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; + u16 eeprom; + u8 reg_id; u8 value; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt61pci_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) - return 0; + goto continue_csr_init; + NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES; -} - -static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u16 eeprom; - u8 reg_id; - u8 value; - - if (unlikely(rt61pci_wait_bbp_ready(rt2x00dev))) - return -EACCES; +continue_csr_init: rt61pci_bbp_write(rt2x00dev, 3, 0x00); rt61pci_bbp_write(rt2x00dev, 15, 0x30); rt61pci_bbp_write(rt2x00dev, 21, 0xc8); @@ -1355,8 +1337,7 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + state == STATE_RADIO_RX_OFF); rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1408,10 +1389,17 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (unlikely(rt61pci_init_queues(rt2x00dev) || - rt61pci_init_registers(rt2x00dev) || - rt61pci_init_bbp(rt2x00dev))) + if (rt61pci_init_queues(rt2x00dev) || + rt61pci_init_registers(rt2x00dev) || + rt61pci_init_bbp(rt2x00dev)) { + ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; + } + + /* + * Enable interrupts. + */ + rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); /* * Enable RX. @@ -1443,6 +1431,11 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); + + /* + * Disable interrupts. + */ + rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); } static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) @@ -1450,6 +1443,7 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) u32 reg; unsigned int i; char put_to_sleep; + char current_state; put_to_sleep = (state != STATE_AWAKE); @@ -1465,12 +1459,16 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); - if (state == !put_to_sleep) + current_state = + rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); + if (current_state == !put_to_sleep) return 0; msleep(10); } + NOTICE(rt2x00dev, "Device failed to enter state %d, " + "current device state %d.\n", !put_to_sleep, current_state); + return -EBUSY; } @@ -1488,13 +1486,11 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt61pci_toggle_rx(rt2x00dev, state); - break; - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - rt61pci_toggle_irq(rt2x00dev, state); + rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -1507,10 +1503,6 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, break; } - if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); - return retval; } @@ -1562,7 +1554,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, if (skbdesc->desc_len > TXINFO_SIZE) { rt2x00_desc_read(txd, 11, &word); - rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); + rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); rt2x00_desc_write(txd, 11, word); } @@ -1581,7 +1573,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); rt2x00_set_field32(&word, TXD_W0_BURST, test_bit(ENTRY_TXD_BURST, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); @@ -2075,11 +2067,31 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); - rt61pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); - rt61pci_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); - if (value == LED_MODE_SIGNAL_STRENGTH) - rt61pci_init_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_QUALITY); + rt2x00dev->led_radio.rt2x00dev = rt2x00dev; + rt2x00dev->led_radio.type = LED_TYPE_RADIO; + rt2x00dev->led_radio.led_dev.brightness_set = + rt61pci_brightness_set; + rt2x00dev->led_radio.led_dev.blink_set = + rt61pci_blink_set; + rt2x00dev->led_radio.flags = LED_INITIALIZED; + + rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; + rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; + rt2x00dev->led_assoc.led_dev.brightness_set = + rt61pci_brightness_set; + rt2x00dev->led_assoc.led_dev.blink_set = + rt61pci_blink_set; + rt2x00dev->led_assoc.flags = LED_INITIALIZED; + + if (value == LED_MODE_SIGNAL_STRENGTH) { + rt2x00dev->led_qual.rt2x00dev = rt2x00dev; + rt2x00dev->led_qual.type = LED_TYPE_QUALITY; + rt2x00dev->led_qual.led_dev.brightness_set = + rt61pci_brightness_set; + rt2x00dev->led_qual.led_dev.blink_set = + rt61pci_blink_set; + rt2x00dev->led_qual.flags = LED_INITIALIZED; + } rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, @@ -2375,6 +2387,9 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + skbdesc->data = skb->data; + skbdesc->data_len = skb->len; skbdesc->desc = entry_priv->desc; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; @@ -2399,7 +2414,7 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) skbdesc->desc, skbdesc->desc_len); rt2x00pci_register_multiwrite(rt2x00dev, beacon_base + skbdesc->desc_len, - skb->data, skb->len); + skbdesc->data, skbdesc->data_len); rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); return 0; diff --git a/trunk/drivers/net/wireless/rt2x00/rt61pci.h b/trunk/drivers/net/wireless/rt2x00/rt61pci.h index 1004d5b899e6..c5a04b9329d2 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt61pci.h +++ b/trunk/drivers/net/wireless/rt2x00/rt61pci.h @@ -39,6 +39,8 @@ * Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ +#define MAX_SIGNAL 100 +#define MAX_RX_SSI -1 #define DEFAULT_RSSI_OFFSET 120 /* diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index fceefd730ab8..26c2e0a1a308 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -335,17 +335,6 @@ static int rt73usb_blink_set(struct led_classdev *led_cdev, return 0; } - -static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev, - struct rt2x00_led *led, - enum led_type type) -{ - led->rt2x00dev = rt2x00dev; - led->type = type; - led->led_dev.brightness_set = rt73usb_brightness_set; - led->led_dev.blink_set = rt73usb_blink_set; - led->flags = LED_INITIALIZED; -} #endif /* CONFIG_RT73USB_LEDS */ /* @@ -1095,32 +1084,25 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) return 0; } -static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) +static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) { unsigned int i; + u16 eeprom; + u8 reg_id; u8 value; for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt73usb_bbp_read(rt2x00dev, 0, &value); if ((value != 0xff) && (value != 0x00)) - return 0; + goto continue_csr_init; + NOTICE(rt2x00dev, "Waiting for BBP register.\n"); udelay(REGISTER_BUSY_DELAY); } ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); return -EACCES; -} - -static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u16 eeprom; - u8 reg_id; - u8 value; - - if (unlikely(rt73usb_wait_bbp_ready(rt2x00dev))) - return -EACCES; +continue_csr_init: rt73usb_bbp_write(rt2x00dev, 3, 0x80); rt73usb_bbp_write(rt2x00dev, 15, 0x30); rt73usb_bbp_write(rt2x00dev, 21, 0xc8); @@ -1170,8 +1152,7 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, - (state == STATE_RADIO_RX_OFF) || - (state == STATE_RADIO_RX_OFF_LINK)); + state == STATE_RADIO_RX_OFF); rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); } @@ -1180,9 +1161,11 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) /* * Initialize all registers. */ - if (unlikely(rt73usb_init_registers(rt2x00dev) || - rt73usb_init_bbp(rt2x00dev))) + if (rt73usb_init_registers(rt2x00dev) || + rt73usb_init_bbp(rt2x00dev)) { + ERROR(rt2x00dev, "Register initialization failed.\n"); return -EIO; + } return 0; } @@ -1204,6 +1187,7 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) u32 reg; unsigned int i; char put_to_sleep; + char current_state; put_to_sleep = (state != STATE_AWAKE); @@ -1219,12 +1203,16 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) */ for (i = 0; i < REGISTER_BUSY_COUNT; i++) { rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); - state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); - if (state == !put_to_sleep) + current_state = + rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); + if (current_state == !put_to_sleep) return 0; msleep(10); } + NOTICE(rt2x00dev, "Device failed to enter state %d, " + "current device state %d.\n", !put_to_sleep, current_state); + return -EBUSY; } @@ -1242,13 +1230,11 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, break; case STATE_RADIO_RX_ON: case STATE_RADIO_RX_ON_LINK: + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); + break; case STATE_RADIO_RX_OFF: case STATE_RADIO_RX_OFF_LINK: - rt73usb_toggle_rx(rt2x00dev, state); - break; - case STATE_RADIO_IRQ_ON: - case STATE_RADIO_IRQ_OFF: - /* No support, but no error either */ + rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); break; case STATE_DEEP_SLEEP: case STATE_SLEEP: @@ -1261,10 +1247,6 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, break; } - if (unlikely(retval)) - ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", - state, retval); - return retval; } @@ -1320,8 +1302,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); - rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, - skb->len - skbdesc->desc_len); + rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); rt2x00_set_field32(&word, TXD_W0_BURST2, test_bit(ENTRY_TXD_BURST, &txdesc->flags)); rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); @@ -1351,10 +1332,8 @@ static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, { u32 reg; - if (queue != QID_BEACON) { - rt2x00usb_kick_tx_queue(rt2x00dev, queue); + if (queue != QID_BEACON) return; - } /* * For Wi-Fi faily generated beacons between participating stations. @@ -1428,10 +1407,14 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, u32 word1; /* - * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of - * frame data in rt2x00usb. + * Copy descriptor to the skb->cb array, this has 2 benefits: + * 1) Each descriptor word is 4 byte aligned. + * 2) Descriptor is safe from moving of frame data in rt2x00usb. */ - memcpy(skbdesc->desc, rxd, skbdesc->desc_len); + skbdesc->desc_len = + min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb)); + memcpy(entry->skb->cb, rxd, skbdesc->desc_len); + skbdesc->desc = entry->skb->cb; rxd = (__le32 *)skbdesc->desc; /* @@ -1463,6 +1446,8 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, */ skb_pull(entry->skb, entry->queue->desc_size); skb_trim(entry->skb, rxdesc->size); + skbdesc->data = entry->skb->data; + skbdesc->data_len = rxdesc->size; } /* @@ -1635,11 +1620,31 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) #ifdef CONFIG_RT73USB_LEDS rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); - rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); - rt73usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); - if (value == LED_MODE_SIGNAL_STRENGTH) - rt73usb_init_led(rt2x00dev, &rt2x00dev->led_qual, - LED_TYPE_QUALITY); + rt2x00dev->led_radio.rt2x00dev = rt2x00dev; + rt2x00dev->led_radio.type = LED_TYPE_RADIO; + rt2x00dev->led_radio.led_dev.brightness_set = + rt73usb_brightness_set; + rt2x00dev->led_radio.led_dev.blink_set = + rt73usb_blink_set; + rt2x00dev->led_radio.flags = LED_INITIALIZED; + + rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; + rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; + rt2x00dev->led_assoc.led_dev.brightness_set = + rt73usb_brightness_set; + rt2x00dev->led_assoc.led_dev.blink_set = + rt73usb_blink_set; + rt2x00dev->led_assoc.flags = LED_INITIALIZED; + + if (value == LED_MODE_SIGNAL_STRENGTH) { + rt2x00dev->led_qual.rt2x00dev = rt2x00dev; + rt2x00dev->led_qual.type = LED_TYPE_QUALITY; + rt2x00dev->led_qual.led_dev.brightness_set = + rt73usb_brightness_set; + rt2x00dev->led_qual.led_dev.blink_set = + rt73usb_blink_set; + rt2x00dev->led_qual.flags = LED_INITIALIZED; + } rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, @@ -1975,6 +1980,9 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) */ skbdesc = get_skb_frame_desc(skb); memset(skbdesc, 0, sizeof(*skbdesc)); + skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; + skbdesc->data = skb->data + intf->beacon->queue->desc_size; + skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; skbdesc->desc = skb->data; skbdesc->desc_len = intf->beacon->queue->desc_size; skbdesc->entry = intf->beacon; @@ -2114,7 +2122,6 @@ static struct usb_device_id rt73usb_device_table[] = { /* D-Link */ { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, - { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, /* Gemtek */ { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.h b/trunk/drivers/net/wireless/rt2x00/rt73usb.h index 148493501011..25cdcc9bf7c4 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.h +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.h @@ -39,6 +39,8 @@ * Signal information. * Defaul offset is required for RSSI <-> dBm conversion. */ +#define MAX_SIGNAL 100 +#define MAX_RX_SSI -1 #define DEFAULT_RSSI_OFFSET 120 /* diff --git a/trunk/drivers/net/wireless/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl8187_dev.c index bec96d762c6c..0078c7e9918c 100644 --- a/trunk/drivers/net/wireless/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl8187_dev.c @@ -181,7 +181,7 @@ static int rtl8187_tx(struct ieee80211_hw *dev, struct sk_buff *skb) flags |= RTL8187_TX_FLAG_NO_ENCRYPT; flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; - if (ieee80211_has_morefrags(((struct ieee80211_hdr *)skb->data)->frame_control)) + if (ieee80211_get_morefrag((struct ieee80211_hdr *)skb->data)) flags |= RTL8187_TX_FLAG_MORE_FRAG; if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) { flags |= RTL8187_TX_FLAG_RTS; diff --git a/trunk/drivers/of/of_i2c.c b/trunk/drivers/of/of_i2c.c index b2ccdcbeb896..715a44471617 100644 --- a/trunk/drivers/of/of_i2c.c +++ b/trunk/drivers/of/of_i2c.c @@ -21,6 +21,7 @@ struct i2c_driver_device { }; static struct i2c_driver_device i2c_devices[] = { + { "dallas,ds1374", "rtc-ds1374" }, }; static int of_find_i2c_driver(struct device_node *node, diff --git a/trunk/drivers/pnp/pnpacpi/rsparser.c b/trunk/drivers/pnp/pnpacpi/rsparser.c index 46c791adb894..0201c8adfda7 100644 --- a/trunk/drivers/pnp/pnpacpi/rsparser.c +++ b/trunk/drivers/pnp/pnpacpi/rsparser.c @@ -50,17 +50,15 @@ static int irq_flags(int triggering, int polarity, int shareable) flags = IORESOURCE_IRQ_HIGHEDGE; } - if (shareable == ACPI_SHARED) + if (shareable) flags |= IORESOURCE_IRQ_SHAREABLE; return flags; } -static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, - int *polarity, int *shareable) +static void decode_irq_flags(int flag, int *triggering, int *polarity) { - switch (flags & (IORESOURCE_IRQ_LOWLEVEL | IORESOURCE_IRQ_HIGHLEVEL | - IORESOURCE_IRQ_LOWEDGE | IORESOURCE_IRQ_HIGHEDGE)) { + switch (flag) { case IORESOURCE_IRQ_LOWLEVEL: *triggering = ACPI_LEVEL_SENSITIVE; *polarity = ACPI_ACTIVE_LOW; @@ -77,18 +75,7 @@ static void decode_irq_flags(struct pnp_dev *dev, int flags, int *triggering, *triggering = ACPI_EDGE_SENSITIVE; *polarity = ACPI_ACTIVE_HIGH; break; - default: - dev_err(&dev->dev, "can't encode invalid IRQ mode %#x\n", - flags); - *triggering = ACPI_EDGE_SENSITIVE; - *polarity = ACPI_ACTIVE_HIGH; - break; } - - if (flags & IORESOURCE_IRQ_SHAREABLE) - *shareable = ACPI_SHARED; - else - *shareable = ACPI_EXCLUSIVE; } static void pnpacpi_parse_allocated_irqresource(struct pnp_dev *dev, @@ -755,9 +742,6 @@ static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) if (pnpacpi_supported_resource(res)) { (*resource)->type = res->type; (*resource)->length = sizeof(struct acpi_resource); - if (res->type == ACPI_RESOURCE_TYPE_IRQ) - (*resource)->data.irq.descriptor_length = - res->data.irq.descriptor_length; (*resource)++; } @@ -804,21 +788,22 @@ static void pnpacpi_encode_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_irq *irq = &resource->data.irq; - int triggering, polarity, shareable; + int triggering, polarity; - decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); irq->triggering = triggering; irq->polarity = polarity; - irq->sharable = shareable; + if (triggering == ACPI_EDGE_SENSITIVE) + irq->sharable = ACPI_EXCLUSIVE; + else + irq->sharable = ACPI_SHARED; irq->interrupt_count = 1; irq->interrupts[0] = p->start; - dev_dbg(&dev->dev, " encode irq %d %s %s %s (%d-byte descriptor)\n", - (int) p->start, + dev_dbg(&dev->dev, " encode irq %d %s %s %s\n", (int) p->start, triggering == ACPI_LEVEL_SENSITIVE ? "level" : "edge", polarity == ACPI_ACTIVE_LOW ? "low" : "high", - irq->sharable == ACPI_SHARED ? "shared" : "exclusive", - irq->descriptor_length); + irq->sharable == ACPI_SHARED ? "shared" : "exclusive"); } static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, @@ -826,13 +811,16 @@ static void pnpacpi_encode_ext_irq(struct pnp_dev *dev, struct resource *p) { struct acpi_resource_extended_irq *extended_irq = &resource->data.extended_irq; - int triggering, polarity, shareable; + int triggering, polarity; - decode_irq_flags(dev, p->flags, &triggering, &polarity, &shareable); + decode_irq_flags(p->flags & IORESOURCE_BITS, &triggering, &polarity); extended_irq->producer_consumer = ACPI_CONSUMER; extended_irq->triggering = triggering; extended_irq->polarity = polarity; - extended_irq->sharable = shareable; + if (triggering == ACPI_EDGE_SENSITIVE) + extended_irq->sharable = ACPI_EXCLUSIVE; + else + extended_irq->sharable = ACPI_SHARED; extended_irq->interrupt_count = 1; extended_irq->interrupts[0] = p->start; diff --git a/trunk/drivers/pnp/quirks.c b/trunk/drivers/pnp/quirks.c index 1ff3bb585ab2..e2b7de4cb05e 100644 --- a/trunk/drivers/pnp/quirks.c +++ b/trunk/drivers/pnp/quirks.c @@ -286,7 +286,7 @@ static void quirk_system_pci_resources(struct pnp_dev *dev) pci_name(pdev), i, (unsigned long long) pci_start, (unsigned long long) pci_end); - res->flags |= IORESOURCE_DISABLED; + res->flags = 0; } } } diff --git a/trunk/drivers/pnp/system.c b/trunk/drivers/pnp/system.c index cf4e07b01d48..9c2496dbeee4 100644 --- a/trunk/drivers/pnp/system.c +++ b/trunk/drivers/pnp/system.c @@ -81,7 +81,7 @@ static void reserve_resources_of_dev(struct pnp_dev *dev) } for (i = 0; (res = pnp_get_resource(dev, IORESOURCE_MEM, i)); i++) { - if (res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED)) + if (res->flags & IORESOURCE_UNSET) continue; reserve_range(dev, res->start, res->end, 0); diff --git a/trunk/drivers/power/power_supply_sysfs.c b/trunk/drivers/power/power_supply_sysfs.c index 49215da5249b..c444d6b10c58 100644 --- a/trunk/drivers/power/power_supply_sysfs.c +++ b/trunk/drivers/power/power_supply_sysfs.c @@ -201,7 +201,7 @@ int power_supply_uevent(struct device *dev, struct kobj_uevent_env *env) dev_dbg(dev, "uevent\n"); - if (!psy || !psy->dev) { + if (!psy) { dev_dbg(dev, "No power supply yet\n"); return ret; } diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index 4949dc4859be..6cc2c0330230 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -256,17 +256,6 @@ config RTC_DRV_S35390A This driver can also be built as a module. If so the module will be called rtc-s35390a. -config RTC_DRV_FM3130 - tristate "Ramtron FM3130" - help - If you say Y here you will get support for the - Ramtron FM3130 RTC chips. - Ramtron FM3130 is a chip with two separate devices inside, - RTC clock and FRAM. This driver provides only RTC functionality. - - This driver can also be built as a module. If so the module - will be called rtc-fm3130. - endif # I2C comment "SPI RTC drivers" @@ -545,12 +534,4 @@ config RTC_DRV_RS5C313 help If you say yes here you get support for the Ricoh RS5C313 RTC chips. -config RTC_DRV_PPC - tristate "PowerPC machine dependent RTC support" - depends on PPC_MERGE - help - The PowerPC kernel has machine-specific functions for accessing - the RTC. This exposes that functionality through the generic RTC - class. - endif # RTC_CLASS diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index b6e14d51670b..872f1218ff9f 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -31,7 +31,6 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o -obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o @@ -42,7 +41,6 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o -obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o diff --git a/trunk/drivers/rtc/rtc-at32ap700x.c b/trunk/drivers/rtc/rtc-at32ap700x.c index 2ef8cdfda4a7..42244f14b41c 100644 --- a/trunk/drivers/rtc/rtc-at32ap700x.c +++ b/trunk/drivers/rtc/rtc-at32ap700x.c @@ -94,11 +94,8 @@ static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); - spin_lock_irq(&rtc->lock); rtc_time_to_tm(rtc->alarm_time, &alrm->time); - alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; - alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0; - spin_unlock_irq(&rtc->lock); + alrm->pending = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; return 0; } @@ -122,7 +119,7 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) spin_lock_irq(&rtc->lock); rtc->alarm_time = alarm_unix_time; rtc_writel(rtc, TOP, rtc->alarm_time); - if (alrm->enabled) + if (alrm->pending) rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | RTC_BIT(CTRL_TOPEN)); else diff --git a/trunk/drivers/rtc/rtc-cmos.c b/trunk/drivers/rtc/rtc-cmos.c index d7bb9bac71df..d060a06ce05b 100644 --- a/trunk/drivers/rtc/rtc-cmos.c +++ b/trunk/drivers/rtc/rtc-cmos.c @@ -905,7 +905,19 @@ static struct pnp_driver cmos_pnp_driver = { .resume = cmos_pnp_resume, }; -#endif /* CONFIG_PNP */ +static int __init cmos_init(void) +{ + return pnp_register_driver(&cmos_pnp_driver); +} +module_init(cmos_init); + +static void __exit cmos_exit(void) +{ + pnp_unregister_driver(&cmos_pnp_driver); +} +module_exit(cmos_exit); + +#else /* no PNP */ /*----------------------------------------------------------------*/ @@ -946,33 +958,20 @@ static struct platform_driver cmos_platform_driver = { static int __init cmos_init(void) { -#ifdef CONFIG_PNP - if (pnp_platform_devices) - return pnp_register_driver(&cmos_pnp_driver); - else - return platform_driver_probe(&cmos_platform_driver, - cmos_platform_probe); -#else return platform_driver_probe(&cmos_platform_driver, cmos_platform_probe); -#endif /* CONFIG_PNP */ } module_init(cmos_init); static void __exit cmos_exit(void) { -#ifdef CONFIG_PNP - if (pnp_platform_devices) - pnp_unregister_driver(&cmos_pnp_driver); - else - platform_driver_unregister(&cmos_platform_driver); -#else platform_driver_unregister(&cmos_platform_driver); -#endif /* CONFIG_PNP */ } module_exit(cmos_exit); +#endif /* !PNP */ + MODULE_AUTHOR("David Brownell"); MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/rtc/rtc-ds1374.c b/trunk/drivers/rtc/rtc-ds1374.c index 640acd20fdde..fa2d2f8b3f4d 100644 --- a/trunk/drivers/rtc/rtc-ds1374.c +++ b/trunk/drivers/rtc/rtc-ds1374.c @@ -42,7 +42,7 @@ #define DS1374_REG_TCR 0x09 /* Trickle Charge */ static const struct i2c_device_id ds1374_id[] = { - { "ds1374", 0 }, + { "rtc-ds1374", 0 }, { } }; MODULE_DEVICE_TABLE(i2c, ds1374_id); diff --git a/trunk/drivers/rtc/rtc-fm3130.c b/trunk/drivers/rtc/rtc-fm3130.c deleted file mode 100644 index 11644c8fca82..000000000000 --- a/trunk/drivers/rtc/rtc-fm3130.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * rtc-fm3130.c - RTC driver for Ramtron FM3130 I2C chip. - * - * Copyright (C) 2008 Sergey Lapin - * Based on ds1307 driver by James Chapman and David Brownell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include - -#define FM3130_RTC_CONTROL (0x0) -#define FM3130_CAL_CONTROL (0x1) -#define FM3130_RTC_SECONDS (0x2) -#define FM3130_RTC_MINUTES (0x3) -#define FM3130_RTC_HOURS (0x4) -#define FM3130_RTC_DAY (0x5) -#define FM3130_RTC_DATE (0x6) -#define FM3130_RTC_MONTHS (0x7) -#define FM3130_RTC_YEARS (0x8) - -#define FM3130_ALARM_SECONDS (0x9) -#define FM3130_ALARM_MINUTES (0xa) -#define FM3130_ALARM_HOURS (0xb) -#define FM3130_ALARM_DATE (0xc) -#define FM3130_ALARM_MONTHS (0xd) -#define FM3130_ALARM_WP_CONTROL (0xe) - -#define FM3130_CAL_CONTROL_BIT_nOSCEN (1 << 7) /* Osciallator enabled */ -#define FM3130_RTC_CONTROL_BIT_LB (1 << 7) /* Low battery */ -#define FM3130_RTC_CONTROL_BIT_AF (1 << 6) /* Alarm flag */ -#define FM3130_RTC_CONTROL_BIT_CF (1 << 5) /* Century overflow */ -#define FM3130_RTC_CONTROL_BIT_POR (1 << 4) /* Power on reset */ -#define FM3130_RTC_CONTROL_BIT_AEN (1 << 3) /* Alarm enable */ -#define FM3130_RTC_CONTROL_BIT_CAL (1 << 2) /* Calibration mode */ -#define FM3130_RTC_CONTROL_BIT_WRITE (1 << 1) /* W=1 -> write mode W=0 normal */ -#define FM3130_RTC_CONTROL_BIT_READ (1 << 0) /* R=1 -> read mode R=0 normal */ - -#define FM3130_CLOCK_REGS 7 -#define FM3130_ALARM_REGS 5 - -struct fm3130 { - u8 reg_addr_time; - u8 reg_addr_alarm; - u8 regs[15]; - struct i2c_msg msg[4]; - struct i2c_client *client; - struct rtc_device *rtc; - int data_valid; - int alarm; -}; -static const struct i2c_device_id fm3130_id[] = { - { "fm3130-rtc", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, fm3130_id); - -#define FM3130_MODE_NORMAL 0 -#define FM3130_MODE_WRITE 1 -#define FM3130_MODE_READ 2 - -static void fm3130_rtc_mode(struct device *dev, int mode) -{ - struct fm3130 *fm3130 = dev_get_drvdata(dev); - - fm3130->regs[FM3130_RTC_CONTROL] = - i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); - switch (mode) { - case FM3130_MODE_NORMAL: - fm3130->regs[FM3130_RTC_CONTROL] &= - ~(FM3130_RTC_CONTROL_BIT_WRITE | - FM3130_RTC_CONTROL_BIT_READ); - break; - case FM3130_MODE_WRITE: - fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE; - break; - case FM3130_MODE_READ: - fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ; - break; - default: - dev_dbg(dev, "invalid mode %d\n", mode); - break; - } - /* Checking for alarm */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { - fm3130->alarm = 1; - fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; - } - i2c_smbus_write_byte_data(fm3130->client, - FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]); -} - -static int fm3130_get_time(struct device *dev, struct rtc_time *t) -{ - struct fm3130 *fm3130 = dev_get_drvdata(dev); - int tmp; - - if (!fm3130->data_valid) { - /* We have invalid data in RTC, probably due - to battery faults or other problems. Return EIO - for now, it will allow us to set data later insted - of error during probing which disables device */ - return -EIO; - } - fm3130_rtc_mode(dev, FM3130_MODE_READ); - - /* read the RTC date and time registers all at once */ - tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), - fm3130->msg, 2); - if (tmp != 2) { - dev_err(dev, "%s error %d\n", "read", tmp); - return -EIO; - } - - fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); - - dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" - "%02x %02x %02x %02x %02x %02x %02x\n", - "read", - fm3130->regs[0], fm3130->regs[1], - fm3130->regs[2], fm3130->regs[3], - fm3130->regs[4], fm3130->regs[5], - fm3130->regs[6], fm3130->regs[7], - fm3130->regs[8], fm3130->regs[9], - fm3130->regs[0xa], fm3130->regs[0xb], - fm3130->regs[0xc], fm3130->regs[0xd], - fm3130->regs[0xe]); - - t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); - t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); - tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; - t->tm_hour = BCD2BIN(tmp); - t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; - t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); - tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; - t->tm_mon = BCD2BIN(tmp) - 1; - - /* assume 20YY not 19YY, and ignore CF bit */ - t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "read", t->tm_sec, t->tm_min, - t->tm_hour, t->tm_mday, - t->tm_mon, t->tm_year, t->tm_wday); - - /* initial clock setting can be undefined */ - return rtc_valid_tm(t); -} - - -static int fm3130_set_time(struct device *dev, struct rtc_time *t) -{ - struct fm3130 *fm3130 = dev_get_drvdata(dev); - int tmp, i; - u8 *buf = fm3130->regs; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "write", t->tm_sec, t->tm_min, - t->tm_hour, t->tm_mday, - t->tm_mon, t->tm_year, t->tm_wday); - - /* first register addr */ - buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec); - buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min); - buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour); - buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1); - buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday); - buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1); - - /* assume 20YY not 19YY */ - tmp = t->tm_year - 100; - buf[FM3130_RTC_YEARS] = BIN2BCD(tmp); - - dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" - "%02x %02x %02x %02x %02x %02x %02x %02x\n", - "write", buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7], - buf[8], buf[9], buf[0xa], buf[0xb], - buf[0xc], buf[0xd], buf[0xe]); - - fm3130_rtc_mode(dev, FM3130_MODE_WRITE); - - /* Writing time registers, we don't support multibyte transfers */ - for (i = 0; i < FM3130_CLOCK_REGS; i++) { - i2c_smbus_write_byte_data(fm3130->client, - FM3130_RTC_SECONDS + i, - fm3130->regs[FM3130_RTC_SECONDS + i]); - } - - fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); - - /* We assume here that data are valid once written */ - if (!fm3130->data_valid) - fm3130->data_valid = 1; - return 0; -} - -static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct fm3130 *fm3130 = dev_get_drvdata(dev); - int tmp; - struct rtc_time *tm = &alrm->time; - /* read the RTC alarm registers all at once */ - tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), - &fm3130->msg[2], 2); - if (tmp != 2) { - dev_err(dev, "%s error %d\n", "read", tmp); - return -EIO; - } - dev_dbg(dev, "alarm read %02x %02x %02x %02x %02x\n", - fm3130->regs[FM3130_ALARM_SECONDS], - fm3130->regs[FM3130_ALARM_MINUTES], - fm3130->regs[FM3130_ALARM_HOURS], - fm3130->regs[FM3130_ALARM_DATE], - fm3130->regs[FM3130_ALARM_MONTHS]); - - - tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); - tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); - tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); - tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); - tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); - if (tm->tm_mon > 0) - tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "read alarm", tm->tm_sec, tm->tm_min, - tm->tm_hour, tm->tm_mday, - tm->tm_mon, tm->tm_year, tm->tm_wday); - - return 0; -} - -static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) -{ - struct fm3130 *fm3130 = dev_get_drvdata(dev); - struct rtc_time *tm = &alrm->time; - int i; - - dev_dbg(dev, "%s secs=%d, mins=%d, " - "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", - "write alarm", tm->tm_sec, tm->tm_min, - tm->tm_hour, tm->tm_mday, - tm->tm_mon, tm->tm_year, tm->tm_wday); - - if (tm->tm_sec != -1) - fm3130->regs[FM3130_ALARM_SECONDS] = - BIN2BCD(tm->tm_sec) | 0x80; - - if (tm->tm_min != -1) - fm3130->regs[FM3130_ALARM_MINUTES] = - BIN2BCD(tm->tm_min) | 0x80; - - if (tm->tm_hour != -1) - fm3130->regs[FM3130_ALARM_HOURS] = - BIN2BCD(tm->tm_hour) | 0x80; - - if (tm->tm_mday != -1) - fm3130->regs[FM3130_ALARM_DATE] = - BIN2BCD(tm->tm_mday) | 0x80; - - if (tm->tm_mon != -1) - fm3130->regs[FM3130_ALARM_MONTHS] = - BIN2BCD(tm->tm_mon + 1) | 0x80; - - dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", - fm3130->regs[FM3130_ALARM_SECONDS], - fm3130->regs[FM3130_ALARM_MINUTES], - fm3130->regs[FM3130_ALARM_HOURS], - fm3130->regs[FM3130_ALARM_DATE], - fm3130->regs[FM3130_ALARM_MONTHS]); - /* Writing time registers, we don't support multibyte transfers */ - for (i = 0; i < FM3130_ALARM_REGS; i++) { - i2c_smbus_write_byte_data(fm3130->client, - FM3130_ALARM_SECONDS + i, - fm3130->regs[FM3130_ALARM_SECONDS + i]); - } - fm3130->regs[FM3130_RTC_CONTROL] = - i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); - /* Checking for alarm */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { - fm3130->alarm = 1; - fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; - } - if (alrm->enabled) { - i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, - (fm3130->regs[FM3130_RTC_CONTROL] & - ~(FM3130_RTC_CONTROL_BIT_CAL)) | - FM3130_RTC_CONTROL_BIT_AEN); - } else { - i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, - fm3130->regs[FM3130_RTC_CONTROL] & - ~(FM3130_RTC_CONTROL_BIT_AEN)); - } - return 0; -} - -static const struct rtc_class_ops fm3130_rtc_ops = { - .read_time = fm3130_get_time, - .set_time = fm3130_set_time, - .read_alarm = fm3130_read_alarm, - .set_alarm = fm3130_set_alarm, -}; - -static struct i2c_driver fm3130_driver; - -static int __devinit fm3130_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - struct fm3130 *fm3130; - int err = -ENODEV; - int tmp; - struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); - - if (!i2c_check_functionality(adapter, - I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) - return -EIO; - - fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL); - - if (!fm3130) - return -ENOMEM; - - fm3130->client = client; - i2c_set_clientdata(client, fm3130); - fm3130->reg_addr_time = FM3130_RTC_SECONDS; - fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS; - - /* Messages to read time */ - fm3130->msg[0].addr = client->addr; - fm3130->msg[0].flags = 0; - fm3130->msg[0].len = 1; - fm3130->msg[0].buf = &fm3130->reg_addr_time; - - fm3130->msg[1].addr = client->addr; - fm3130->msg[1].flags = I2C_M_RD; - fm3130->msg[1].len = FM3130_CLOCK_REGS; - fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS]; - - /* Messages to read alarm */ - fm3130->msg[2].addr = client->addr; - fm3130->msg[2].flags = 0; - fm3130->msg[2].len = 1; - fm3130->msg[2].buf = &fm3130->reg_addr_alarm; - - fm3130->msg[3].addr = client->addr; - fm3130->msg[3].flags = I2C_M_RD; - fm3130->msg[3].len = FM3130_ALARM_REGS; - fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS]; - - fm3130->data_valid = 0; - - tmp = i2c_transfer(adapter, fm3130->msg, 4); - if (tmp != 4) { - pr_debug("read error %d\n", tmp); - err = -EIO; - goto exit_free; - } - - fm3130->regs[FM3130_RTC_CONTROL] = - i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL); - fm3130->regs[FM3130_CAL_CONTROL] = - i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL); - - /* Checking for alarm */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { - fm3130->alarm = 1; - fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; - } - - /* Disabling calibration mode */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) - i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, - fm3130->regs[FM3130_RTC_CONTROL] & - ~(FM3130_RTC_CONTROL_BIT_CAL)); - dev_warn(&client->dev, "Disabling calibration mode!\n"); - - /* Disabling read and write modes */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE || - fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) - i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, - fm3130->regs[FM3130_RTC_CONTROL] & - ~(FM3130_RTC_CONTROL_BIT_READ | - FM3130_RTC_CONTROL_BIT_WRITE)); - dev_warn(&client->dev, "Disabling READ or WRITE mode!\n"); - - /* oscillator off? turn it on, so clock can tick. */ - if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN) - i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL, - fm3130->regs[FM3130_CAL_CONTROL] & - ~(FM3130_CAL_CONTROL_BIT_nOSCEN)); - - /* oscillator fault? clear flag, and warn */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB) - dev_warn(&client->dev, "Low battery!\n"); - - /* oscillator fault? clear flag, and warn */ - if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) { - i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, - fm3130->regs[FM3130_RTC_CONTROL] & - ~FM3130_RTC_CONTROL_BIT_POR); - dev_warn(&client->dev, "SET TIME!\n"); - } - /* ACS is controlled by alarm */ - i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80); - - /* TODO */ - /* TODO need to sanity check alarm */ - tmp = fm3130->regs[FM3130_RTC_SECONDS]; - tmp = BCD2BIN(tmp & 0x7f); - if (tmp > 60) - goto exit_bad; - tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); - if (tmp > 60) - goto exit_bad; - - tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); - if (tmp == 0 || tmp > 31) - goto exit_bad; - - tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); - if (tmp == 0 || tmp > 12) - goto exit_bad; - - tmp = fm3130->regs[FM3130_RTC_HOURS]; - - fm3130->data_valid = 1; - -exit_bad: - if (!fm3130->data_valid) - dev_dbg(&client->dev, - "%s: %02x %02x %02x %02x %02x %02x %02x %02x" - "%02x %02x %02x %02x %02x %02x %02x\n", - "bogus registers", - fm3130->regs[0], fm3130->regs[1], - fm3130->regs[2], fm3130->regs[3], - fm3130->regs[4], fm3130->regs[5], - fm3130->regs[6], fm3130->regs[7], - fm3130->regs[8], fm3130->regs[9], - fm3130->regs[0xa], fm3130->regs[0xb], - fm3130->regs[0xc], fm3130->regs[0xd], - fm3130->regs[0xe]); - - /* We won't bail out here because we just got invalid data. - Time setting from u-boot doesn't work anyway */ - fm3130->rtc = rtc_device_register(client->name, &client->dev, - &fm3130_rtc_ops, THIS_MODULE); - if (IS_ERR(fm3130->rtc)) { - err = PTR_ERR(fm3130->rtc); - dev_err(&client->dev, - "unable to register the class device\n"); - goto exit_free; - } - return 0; -exit_free: - kfree(fm3130); - return err; -} - -static int __devexit fm3130_remove(struct i2c_client *client) -{ - struct fm3130 *fm3130 = i2c_get_clientdata(client); - - rtc_device_unregister(fm3130->rtc); - kfree(fm3130); - return 0; -} - -static struct i2c_driver fm3130_driver = { - .driver = { - .name = "rtc-fm3130", - .owner = THIS_MODULE, - }, - .probe = fm3130_probe, - .remove = __devexit_p(fm3130_remove), - .id_table = fm3130_id, -}; - -static int __init fm3130_init(void) -{ - return i2c_add_driver(&fm3130_driver); -} -module_init(fm3130_init); - -static void __exit fm3130_exit(void) -{ - i2c_del_driver(&fm3130_driver); -} -module_exit(fm3130_exit); - -MODULE_DESCRIPTION("RTC driver for FM3130"); -MODULE_AUTHOR("Sergey Lapin "); -MODULE_LICENSE("GPL"); - diff --git a/trunk/drivers/rtc/rtc-ppc.c b/trunk/drivers/rtc/rtc-ppc.c deleted file mode 100644 index c8e97e25ef7e..000000000000 --- a/trunk/drivers/rtc/rtc-ppc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * RTC driver for ppc_md RTC functions - * - * © 2007 Red Hat, Inc. - * - * Author: David Woodhouse - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - - -#include -#include -#include -#include -#include - -static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm) -{ - ppc_md.get_rtc_time(tm); - return 0; -} - -static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm) -{ - return ppc_md.set_rtc_time(tm); -} - -static const struct rtc_class_ops ppc_rtc_ops = { - .set_time = ppc_rtc_set_time, - .read_time = ppc_rtc_read_time, -}; - -static struct rtc_device *rtc; -static struct platform_device *ppc_rtc_pdev; - -static int __init ppc_rtc_init(void) -{ - if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time) - return -ENODEV; - - ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0); - if (IS_ERR(ppc_rtc_pdev)) - return PTR_ERR(ppc_rtc_pdev); - - rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev, - &ppc_rtc_ops, THIS_MODULE); - if (IS_ERR(rtc)) { - platform_device_unregister(ppc_rtc_pdev); - return PTR_ERR(rtc); - } - - return 0; -} - -static void __exit ppc_rtc_exit(void) -{ - rtc_device_unregister(rtc); - platform_device_unregister(ppc_rtc_pdev); -} - -module_init(ppc_rtc_init); -module_exit(ppc_rtc_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("David Woodhouse "); -MODULE_DESCRIPTION("Generic RTC class driver for PowerPC"); diff --git a/trunk/drivers/s390/char/sclp_vt220.c b/trunk/drivers/s390/char/sclp_vt220.c index 3e577f655b18..62576af36f47 100644 --- a/trunk/drivers/s390/char/sclp_vt220.c +++ b/trunk/drivers/s390/char/sclp_vt220.c @@ -773,7 +773,6 @@ sclp_vt220_con_init(void) { int rc; - INIT_LIST_HEAD(&sclp_vt220_register.list); if (!CONSOLE_IS_SCLP) return 0; rc = __sclp_vt220_init(); diff --git a/trunk/drivers/s390/char/tape_3590.c b/trunk/drivers/s390/char/tape_3590.c index 42ce7915fc5d..8246ef3ab095 100644 --- a/trunk/drivers/s390/char/tape_3590.c +++ b/trunk/drivers/s390/char/tape_3590.c @@ -1598,7 +1598,7 @@ tape_3590_setup_device(struct tape_device *device) rc = tape_3590_read_dev_chars(device, rdc_data); if (rc) { DBF_LH(3, "Read device characteristics failed!\n"); - goto fail_rdc_data; + goto fail_kmalloc; } rc = tape_std_assign(device); if (rc) diff --git a/trunk/drivers/s390/cio/blacklist.c b/trunk/drivers/s390/cio/blacklist.c index 0bfcbbe375c4..a4a5f2efea48 100644 --- a/trunk/drivers/s390/cio/blacklist.c +++ b/trunk/drivers/s390/cio/blacklist.c @@ -97,8 +97,8 @@ static int pure_hex(char **cp, unsigned int *val, int min_digit, return 0; } -static int parse_busid(char *str, unsigned int *cssid, unsigned int *ssid, - unsigned int *devno, int msgtrigger) +static int parse_busid(char *str, int *cssid, int *ssid, int *devno, + int msgtrigger) { char *str_work; int val, rc, ret; @@ -148,7 +148,7 @@ static int parse_busid(char *str, unsigned int *cssid, unsigned int *ssid, static int blacklist_parse_parameters(char *str, range_action action, int msgtrigger) { - unsigned int from_cssid, to_cssid, from_ssid, to_ssid, from, to; + int from_cssid, to_cssid, from_ssid, to_ssid, from, to; int rc, totalrc; char *parm; range_action ra; diff --git a/trunk/drivers/s390/cio/cio.c b/trunk/drivers/s390/cio/cio.c index b32d7eb3d81a..82c6a2d45128 100644 --- a/trunk/drivers/s390/cio/cio.c +++ b/trunk/drivers/s390/cio/cio.c @@ -576,14 +576,12 @@ cio_validate_subchannel (struct subchannel *sch, struct subchannel_id schid) err = -ENODEV; goto out; } - if (cio_is_console(sch->schid)) { + if (cio_is_console(sch->schid)) sch->opm = 0xff; - sch->isc = 1; - } else { + else sch->opm = chp_get_sch_opm(sch); - sch->isc = 3; - } sch->lpm = sch->schib.pmcw.pam & sch->opm; + sch->isc = 3; CIO_MSG_EVENT(6, "Detected device %04x on subchannel 0.%x.%04X " "- PIM = %02X, PAM = %02X, POM = %02X\n", @@ -706,9 +704,9 @@ void wait_cons_dev(void) if (!console_subchannel_in_use) return; - /* disable all but isc 1 (console device) */ + /* disable all but isc 7 (console device) */ __ctl_store (save_cr6, 6, 6); - cr6 = 0x40000000; + cr6 = 0x01000000; __ctl_load (cr6, 6, 6); do { @@ -790,11 +788,11 @@ cio_probe_console(void) } /* - * enable console I/O-interrupt subclass 1 + * enable console I/O-interrupt subclass 7 */ - ctl_set_bit(6, 30); - console_subchannel.isc = 1; - console_subchannel.schib.pmcw.isc = 1; + ctl_set_bit(6, 24); + console_subchannel.isc = 7; + console_subchannel.schib.pmcw.isc = 7; console_subchannel.schib.pmcw.intparm = (u32)(addr_t)&console_subchannel; ret = cio_modify(&console_subchannel); diff --git a/trunk/drivers/s390/net/qeth_core_main.c b/trunk/drivers/s390/net/qeth_core_main.c index 9a71dae223e8..436bf1f6d4a6 100644 --- a/trunk/drivers/s390/net/qeth_core_main.c +++ b/trunk/drivers/s390/net/qeth_core_main.c @@ -290,6 +290,9 @@ int qeth_set_large_send(struct qeth_card *card, card->dev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_HW_CSUM; } else { + PRINT_WARN("TSO not supported on %s. " + "large_send set to 'no'.\n", + card->dev->name); card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_HW_CSUM); card->options.large_send = QETH_LARGE_SEND_NO; @@ -1404,6 +1407,12 @@ static void qeth_init_func_level(struct qeth_card *card) } } +static inline __u16 qeth_raw_devno_from_bus_id(char *id) +{ + id += (strlen(id) - 4); + return (__u16) simple_strtoul(id, &id, 16); +} + static int qeth_idx_activate_get_answer(struct qeth_channel *channel, void (*idx_reply_cb)(struct qeth_channel *, struct qeth_cmd_buffer *)) @@ -1430,7 +1439,7 @@ static int qeth_idx_activate_get_answer(struct qeth_channel *channel, spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); if (rc) { - QETH_DBF_MESSAGE(2, "Error2 in activating channel rc=%d\n", rc); + PRINT_ERR("Error2 in activating channel rc=%d\n", rc); QETH_DBF_TEXT_(SETUP, 2, "2err%d", rc); atomic_set(&channel->irq_pending, 0); wake_up(&card->wait_q); @@ -1459,7 +1468,6 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, __u16 temp; __u8 tmp; int rc; - struct ccw_dev_id temp_devid; card = CARD_FROM_CDEV(channel->ccwdev); @@ -1486,8 +1494,8 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, &card->token.issuer_rm_w, QETH_MPC_TOKEN_LENGTH); memcpy(QETH_IDX_ACT_FUNC_LEVEL(iob->data), &card->info.func_level, sizeof(__u16)); - ccw_device_get_id(CARD_DDEV(card), &temp_devid); - memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp_devid.devno, 2); + temp = qeth_raw_devno_from_bus_id(CARD_DDEV_ID(card)); + memcpy(QETH_IDX_ACT_QDIO_DEV_CUA(iob->data), &temp, 2); temp = (card->info.cula << 8) + card->info.unit_addr2; memcpy(QETH_IDX_ACT_QDIO_DEV_REALADDR(iob->data), &temp, 2); @@ -1500,8 +1508,7 @@ static int qeth_idx_activate_channel(struct qeth_channel *channel, spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); if (rc) { - QETH_DBF_MESSAGE(2, "Error1 in activating channel. rc=%d\n", - rc); + PRINT_ERR("Error1 in activating channel. rc=%d\n", rc); QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); atomic_set(&channel->irq_pending, 0); wake_up(&card->wait_q); @@ -1651,6 +1658,7 @@ int qeth_send_control_data(struct qeth_card *card, int len, reply = qeth_alloc_reply(card); if (!reply) { + PRINT_WARN("Could not alloc qeth_reply!\n"); return -ENOMEM; } reply->callback = reply_cb; @@ -2604,9 +2612,15 @@ void qeth_queue_input_buffer(struct qeth_card *card, int index) if (newcount < count) { /* we are in memory shortage so we switch back to traditional skb allocation and drop packages */ + if (!atomic_read(&card->force_alloc_skb) && + net_ratelimit()) + PRINT_WARN("Switch to alloc skb\n"); atomic_set(&card->force_alloc_skb, 3); count = newcount; } else { + if ((atomic_read(&card->force_alloc_skb) == 1) && + net_ratelimit()) + PRINT_WARN("Switch to sg\n"); atomic_add_unless(&card->force_alloc_skb, -1, 0); } @@ -3020,7 +3034,7 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE) + skb->len) >> PAGE_SHIFT); if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { - QETH_DBF_MESSAGE(2, "Invalid size of IP packet " + PRINT_ERR("Invalid size of IP packet " "(Number=%d / Length=%d). Discarded.\n", (elements_needed+elems), skb->len); return 0; @@ -3233,6 +3247,8 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, * free buffers) to handle eddp context */ if (qeth_eddp_check_buffers_for_context(queue, ctx) < 0) { + if (net_ratelimit()) + PRINT_WARN("eddp tx_dropped 1\n"); rc = -EBUSY; goto out; } @@ -3244,6 +3260,7 @@ int qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue, tmp = qeth_eddp_fill_buffer(queue, ctx, queue->next_buf_to_fill); if (tmp < 0) { + PRINT_ERR("eddp tx_dropped 2\n"); rc = -EBUSY; goto out; } @@ -3585,6 +3602,8 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) if ((!qeth_adp_supported(card, IPA_SETADP_SET_SNMP_CONTROL)) && (!card->options.layer2)) { + PRINT_WARN("SNMP Query MIBS not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } /* skip 4 bytes (data_len struct member) to get req_len */ @@ -3615,7 +3634,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata) rc = qeth_send_ipa_snmp_cmd(card, iob, QETH_SETADP_BASE_LEN + req_len, qeth_snmp_command_cb, (void *)&qinfo); if (rc) - QETH_DBF_MESSAGE(2, "SNMP command failed on %s: (0x%x)\n", + PRINT_WARN("SNMP command failed on %s: (0x%x)\n", QETH_CARD_IFNAME(card), rc); else { if (copy_to_user(udata, qinfo.udata, qinfo.udata_len)) @@ -3788,8 +3807,8 @@ int qeth_core_hardsetup_card(struct qeth_card *card) if (mpno) mpno = min(mpno - 1, QETH_MAX_PORTNO); if (card->info.portno > mpno) { - QETH_DBF_MESSAGE(2, "Device %s does not offer port number %d" - "\n.", CARD_BUS_ID(card), card->info.portno); + PRINT_ERR("Device %s does not offer port number %d \n.", + CARD_BUS_ID(card), card->info.portno); rc = -ENODEV; goto out; } @@ -3966,6 +3985,8 @@ struct sk_buff *qeth_core_get_next_skb(struct qeth_card *card, return skb; no_mem: if (net_ratelimit()) { + PRINT_WARN("No memory for packet received on %s.\n", + QETH_CARD_IFNAME(card)); QETH_DBF_TEXT(TRACE, 2, "noskbmem"); QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_BUS_ID(card)); } @@ -3983,17 +4004,15 @@ static void qeth_unregister_dbf_views(void) } } -void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *fmt, ...) +void qeth_dbf_longtext(enum qeth_dbf_names dbf_nix, int level, char *text, ...) { char dbf_txt_buf[32]; - va_list args; if (level > (qeth_dbf[dbf_nix].id)->level) return; - va_start(args, fmt); - vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args); - va_end(args); + snprintf(dbf_txt_buf, sizeof(dbf_txt_buf), text); debug_text_event(qeth_dbf[dbf_nix].id, level, dbf_txt_buf); + } EXPORT_SYMBOL_GPL(qeth_dbf_longtext); diff --git a/trunk/drivers/s390/net/qeth_core_offl.c b/trunk/drivers/s390/net/qeth_core_offl.c index 452874e89740..822df8362856 100644 --- a/trunk/drivers/s390/net/qeth_core_offl.c +++ b/trunk/drivers/s390/net/qeth_core_offl.c @@ -122,8 +122,8 @@ int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, if (element == 0) return -EBUSY; else { - QETH_DBF_MESSAGE(2, "could only partially fill" - "eddp buffer!\n"); + PRINT_WARN("could only partially fill eddp " + "buffer!\n"); goto out; } } @@ -143,6 +143,8 @@ int qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue, if (must_refcnt) { must_refcnt = 0; if (qeth_eddp_buf_ref_context(buf, ctx)) { + PRINT_WARN("no memory to create eddp context " + "reference\n"); goto out_check; } } diff --git a/trunk/drivers/s390/net/qeth_core_sys.c b/trunk/drivers/s390/net/qeth_core_sys.c index c26e842ad905..08a50f057284 100644 --- a/trunk/drivers/s390/net/qeth_core_sys.c +++ b/trunk/drivers/s390/net/qeth_core_sys.c @@ -129,6 +129,7 @@ static ssize_t qeth_dev_portno_store(struct device *dev, portno = simple_strtoul(buf, &tmp, 16); if (portno > QETH_MAX_PORTNO) { + PRINT_WARN("portno 0x%X is out of range\n", portno); return -EINVAL; } @@ -222,6 +223,8 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, * if though we have to permit priority queueing */ if (card->qdio.no_out_queues == 1) { + PRINT_WARN("Priority queueing disabled due " + "to hardware limitations!\n"); card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; return -EPERM; } @@ -247,6 +250,7 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; } else { + PRINT_WARN("Unknown queueing type '%s'\n", tmp); return -EINVAL; } return count; @@ -287,6 +291,9 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, ((cnt > QETH_IN_BUF_COUNT_MAX) ? QETH_IN_BUF_COUNT_MAX : cnt); if (old_cnt != cnt) { rc = qeth_realloc_buffer_pool(card, cnt); + if (rc) + PRINT_WARN("Error (%d) while setting " + "buffer count.\n", rc); } return count; } @@ -348,6 +355,7 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, card->perf_stats.initial_rx_packets = card->stats.rx_packets; card->perf_stats.initial_tx_packets = card->stats.tx_packets; } else { + PRINT_WARN("performance_stats: write 0 or 1 to this file!\n"); return -EINVAL; } return count; @@ -391,6 +399,7 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, newdis = QETH_DISCIPLINE_LAYER2; break; default: + PRINT_WARN("layer2: write 0 or 1 to this file!\n"); return -EINVAL; } @@ -454,6 +463,7 @@ static ssize_t qeth_dev_large_send_store(struct device *dev, } else if (!strcmp(tmp, "TSO")) { type = QETH_LARGE_SEND_TSO; } else { + PRINT_WARN("large_send: invalid mode %s!\n", tmp); return -EINVAL; } if (card->options.large_send == type) @@ -493,6 +503,8 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card, if (i <= max_value) { *value = i; } else { + PRINT_WARN("blkt total time: write values between" + " 0 and %d to this file!\n", max_value); return -EINVAL; } return count; diff --git a/trunk/drivers/s390/net/qeth_l2_main.c b/trunk/drivers/s390/net/qeth_l2_main.c index f682f7b14480..86ec50ddae13 100644 --- a/trunk/drivers/s390/net/qeth_l2_main.c +++ b/trunk/drivers/s390/net/qeth_l2_main.c @@ -101,16 +101,19 @@ static struct net_device *qeth_l2_netdev_by_devno(unsigned char *read_dev_no) { struct qeth_card *card; struct net_device *ndev; - __u16 temp_dev_no; + unsigned char *readno; + __u16 temp_dev_no, card_dev_no; + char *endp; unsigned long flags; - struct ccw_dev_id read_devid; ndev = NULL; memcpy(&temp_dev_no, read_dev_no, 2); read_lock_irqsave(&qeth_core_card_list.rwlock, flags); list_for_each_entry(card, &qeth_core_card_list.list, list) { - ccw_device_get_id(CARD_RDEV(card), &read_devid); - if (read_devid.devno == temp_dev_no) { + readno = CARD_RDEV_ID(card); + readno += (strlen(readno) - 4); + card_dev_no = simple_strtoul(readno, &endp, 16); + if (card_dev_no == temp_dev_no) { ndev = card->dev; break; } @@ -131,14 +134,14 @@ static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card, mac = &cmd->data.setdelmac.mac[0]; /* MAC already registered, needed in couple/uncouple case */ if (cmd->hdr.return_code == 0x2005) { - QETH_DBF_MESSAGE(2, "Group MAC %02x:%02x:%02x:%02x:%02x:%02x " + PRINT_WARN("Group MAC %02x:%02x:%02x:%02x:%02x:%02x " \ "already existing on %s \n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], QETH_CARD_IFNAME(card)); cmd->hdr.return_code = 0; } if (cmd->hdr.return_code) - QETH_DBF_MESSAGE(2, "Could not set group MAC " + PRINT_ERR("Could not set group MAC " \ "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], QETH_CARD_IFNAME(card), cmd->hdr.return_code); @@ -163,7 +166,7 @@ static int qeth_l2_send_delgroupmac_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) data; mac = &cmd->data.setdelmac.mac[0]; if (cmd->hdr.return_code) - QETH_DBF_MESSAGE(2, "Could not delete group MAC " + PRINT_ERR("Could not delete group MAC " \ "%02x:%02x:%02x:%02x:%02x:%02x on %s: %x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], QETH_CARD_IFNAME(card), cmd->hdr.return_code); @@ -183,8 +186,10 @@ static void qeth_l2_add_mc(struct qeth_card *card, __u8 *mac) mc = kmalloc(sizeof(struct qeth_mc_mac), GFP_ATOMIC); - if (!mc) + if (!mc) { + PRINT_ERR("no mem vor mc mac address\n"); return; + } memcpy(mc->mc_addr, mac, OSA_ADDR_LEN); mc->mc_addrlen = OSA_ADDR_LEN; @@ -275,7 +280,7 @@ static int qeth_l2_send_setdelvlan_cb(struct qeth_card *card, QETH_DBF_TEXT(TRACE, 2, "L2sdvcb"); cmd = (struct qeth_ipa_cmd *) data; if (cmd->hdr.return_code) { - QETH_DBF_MESSAGE(2, "Error in processing VLAN %i on %s: 0x%x. " + PRINT_ERR("Error in processing VLAN %i on %s: 0x%x. " "Continuing\n", cmd->data.setdelvlan.vlan_id, QETH_CARD_IFNAME(card), cmd->hdr.return_code); QETH_DBF_TEXT_(TRACE, 2, "L2VL%4x", cmd->hdr.command); @@ -328,6 +333,8 @@ static void qeth_l2_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) spin_lock_bh(&card->vlanlock); list_add_tail(&id->list, &card->vid_list); spin_unlock_bh(&card->vlanlock); + } else { + PRINT_ERR("no memory for vid\n"); } } @@ -543,15 +550,16 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) rc = qeth_query_setadapterparms(card); if (rc) { - QETH_DBF_MESSAGE(2, "could not query adapter parameters on " - "device %s: x%x\n", CARD_BUS_ID(card), rc); + PRINT_WARN("could not query adapter parameters on device %s: " + "x%x\n", CARD_BUS_ID(card), rc); } if (card->info.guestlan) { rc = qeth_setadpparms_change_macaddr(card); if (rc) { - QETH_DBF_MESSAGE(2, "couldn't get MAC address on " - "device %s: x%x\n", CARD_BUS_ID(card), rc); + PRINT_WARN("couldn't get MAC address on " + "device %s: x%x\n", + CARD_BUS_ID(card), rc); QETH_DBF_TEXT_(SETUP, 2, "1err%d", rc); return rc; } @@ -577,6 +585,8 @@ static int qeth_l2_set_mac_address(struct net_device *dev, void *p) } if (card->info.type == QETH_CARD_TYPE_OSN) { + PRINT_WARN("Setting MAC address on %s is not supported.\n", + dev->name); QETH_DBF_TEXT(TRACE, 3, "setmcOSN"); return -EOPNOTSUPP; } @@ -656,7 +666,7 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ctx = qeth_eddp_create_context(card, new_skb, hdr, skb->sk->sk_protocol); if (ctx == NULL) { - QETH_DBF_MESSAGE(2, "could not create eddp context\n"); + PRINT_WARN("could not create eddp context\n"); goto tx_drop; } } else { @@ -721,7 +731,6 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if ((new_skb != skb) && new_skb) dev_kfree_skb_any(new_skb); dev_kfree_skb_any(skb); - netif_wake_queue(dev); return NETDEV_TX_OK; } @@ -1146,7 +1155,7 @@ static int qeth_osn_send_control_data(struct qeth_card *card, int len, (addr_t) iob, 0, 0); spin_unlock_irqrestore(get_ccwdev_lock(card->write.ccwdev), flags); if (rc) { - QETH_DBF_MESSAGE(2, "qeth_osn_send_control_data: " + PRINT_WARN("qeth_osn_send_control_data: " "ccw_device_start rc = %i\n", rc); QETH_DBF_TEXT_(TRACE, 2, " err%d", rc); qeth_release_buffer(iob->channel, iob); diff --git a/trunk/drivers/s390/net/qeth_l3_main.c b/trunk/drivers/s390/net/qeth_l3_main.c index 999552c83bbe..94a8ead64ed4 100644 --- a/trunk/drivers/s390/net/qeth_l3_main.c +++ b/trunk/drivers/s390/net/qeth_l3_main.c @@ -311,6 +311,7 @@ static struct qeth_ipaddr *qeth_l3_get_addr_buffer( addr = kzalloc(sizeof(struct qeth_ipaddr), GFP_ATOMIC); if (addr == NULL) { + PRINT_WARN("Not enough memory to add address\n"); return NULL; } addr->type = QETH_IP_TYPE_NORMAL; @@ -648,6 +649,15 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card, } } out_inval: + PRINT_WARN("Routing type '%s' not supported for interface %s.\n" + "Router status set to 'no router'.\n", + ((*type == PRIMARY_ROUTER)? "primary router" : + (*type == SECONDARY_ROUTER)? "secondary router" : + (*type == PRIMARY_CONNECTOR)? "primary connector" : + (*type == SECONDARY_CONNECTOR)? "secondary connector" : + (*type == MULTICAST_ROUTER)? "multicast router" : + "unknown"), + card->dev->name); *type = NO_ROUTER; } @@ -664,9 +674,9 @@ int qeth_l3_setrouting_v4(struct qeth_card *card) QETH_PROT_IPV4); if (rc) { card->options.route4.type = NO_ROUTER; - QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type" - " on %s. Type set to 'no router'.\n", rc, - QETH_CARD_IFNAME(card)); + PRINT_WARN("Error (0x%04x) while setting routing type on %s. " + "Type set to 'no router'.\n", + rc, QETH_CARD_IFNAME(card)); } return rc; } @@ -687,9 +697,9 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) QETH_PROT_IPV6); if (rc) { card->options.route6.type = NO_ROUTER; - QETH_DBF_MESSAGE(2, "Error (0x%04x) while setting routing type" - " on %s. Type set to 'no router'.\n", rc, - QETH_CARD_IFNAME(card)); + PRINT_WARN("Error (0x%04x) while setting routing type on %s. " + "Type set to 'no router'.\n", + rc, QETH_CARD_IFNAME(card)); } #endif return rc; @@ -727,6 +737,7 @@ int qeth_l3_add_ipato_entry(struct qeth_card *card, if (!memcmp(ipatoe->addr, new->addr, (ipatoe->proto == QETH_PROT_IPV4)? 4:16) && (ipatoe->mask_bits == new->mask_bits)) { + PRINT_WARN("ipato entry already exists!\n"); rc = -EEXIST; break; } @@ -791,6 +802,7 @@ int qeth_l3_add_vipa(struct qeth_card *card, enum qeth_prot_versions proto, rc = -EEXIST; spin_unlock_irqrestore(&card->ip_lock, flags); if (rc) { + PRINT_WARN("Cannot add VIPA. Address already exists!\n"); return rc; } if (!qeth_l3_add_ip(card, ipaddr)) @@ -855,6 +867,7 @@ int qeth_l3_add_rxip(struct qeth_card *card, enum qeth_prot_versions proto, rc = -EEXIST; spin_unlock_irqrestore(&card->ip_lock, flags); if (rc) { + PRINT_WARN("Cannot add RXIP. Address already exists!\n"); return rc; } if (!qeth_l3_add_ip(card, ipaddr)) @@ -1007,23 +1020,23 @@ static int qeth_l3_setadapter_hstr(struct qeth_card *card) IPA_SETADP_SET_BROADCAST_MODE, card->options.broadcast_mode); if (rc) - QETH_DBF_MESSAGE(2, "couldn't set broadcast mode on " + PRINT_WARN("couldn't set broadcast mode on " "device %s: x%x\n", CARD_BUS_ID(card), rc); rc = qeth_l3_send_setadp_mode(card, IPA_SETADP_ALTER_MAC_ADDRESS, card->options.macaddr_mode); if (rc) - QETH_DBF_MESSAGE(2, "couldn't set macaddr mode on " + PRINT_WARN("couldn't set macaddr mode on " "device %s: x%x\n", CARD_BUS_ID(card), rc); return rc; } if (card->options.broadcast_mode == QETH_TR_BROADCAST_LOCAL) - QETH_DBF_MESSAGE(2, "set adapter parameters not available " + PRINT_WARN("set adapter parameters not available " "to set broadcast mode, using ALLRINGS " "on device %s:\n", CARD_BUS_ID(card)); if (card->options.macaddr_mode == QETH_TR_MACADDR_CANONICAL) - QETH_DBF_MESSAGE(2, "set adapter parameters not available " + PRINT_WARN("set adapter parameters not available " "to set macaddr mode, using NONCANONICAL " "on device %s:\n", CARD_BUS_ID(card)); return 0; @@ -2057,7 +2070,7 @@ static struct qeth_card *qeth_l3_get_card_from_dev(struct net_device *dev) card = netdev_priv(dev); else if (rc == QETH_VLAN_CARD) card = netdev_priv(vlan_dev_info(dev)->real_dev); - if (card && card->options.layer2) + if (card->options.layer2) card = NULL; QETH_DBF_TEXT_(TRACE, 4, "%d", rc); return card ; @@ -2169,6 +2182,8 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) if (card->info.guestlan) return -EOPNOTSUPP; if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { + PRINT_WARN("ARP processing not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, @@ -2176,8 +2191,8 @@ static int qeth_l3_arp_set_no_entries(struct qeth_card *card, int no_entries) no_entries); if (rc) { tmp = rc; - QETH_DBF_MESSAGE(2, "Could not set number of ARP entries on " - "%s: %s (0x%x/%d)\n", QETH_CARD_IFNAME(card), + PRINT_WARN("Could not set number of ARP entries on %s: " + "%s (0x%x/%d)\n", QETH_CARD_IFNAME(card), qeth_l3_arp_get_error_cause(&rc), tmp, tmp); } return rc; @@ -2245,6 +2260,9 @@ static int qeth_l3_arp_query_cb(struct qeth_card *card, qdata->no_entries * uentry_size){ QETH_DBF_TEXT_(TRACE, 4, "qaer3%i", -ENOMEM); cmd->hdr.return_code = -ENOMEM; + PRINT_WARN("query ARP user space buffer is too small for " + "the returned number of ARP entries. " + "Aborting query!\n"); goto out_error; } QETH_DBF_TEXT_(TRACE, 4, "anore%i", @@ -2306,6 +2324,8 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/ IPA_ARP_PROCESSING)) { + PRINT_WARN("ARP processing not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } /* get size of userspace buffer and mask_bits -> 6 bytes */ @@ -2324,7 +2344,7 @@ static int qeth_l3_arp_query(struct qeth_card *card, char __user *udata) qeth_l3_arp_query_cb, (void *)&qinfo); if (rc) { tmp = rc; - QETH_DBF_MESSAGE(2, "Error while querying ARP cache on %s: %s " + PRINT_WARN("Error while querying ARP cache on %s: %s " "(0x%x/%d)\n", QETH_CARD_IFNAME(card), qeth_l3_arp_get_error_cause(&rc), tmp, tmp); if (copy_to_user(udata, qinfo.udata, 4)) @@ -2355,6 +2375,8 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, if (card->info.guestlan) return -EOPNOTSUPP; if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { + PRINT_WARN("ARP processing not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } @@ -2369,9 +2391,10 @@ static int qeth_l3_arp_add_entry(struct qeth_card *card, if (rc) { tmp = rc; qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); - QETH_DBF_MESSAGE(2, "Could not add ARP entry for address %s " - "on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card), - qeth_l3_arp_get_error_cause(&rc), tmp, tmp); + PRINT_WARN("Could not add ARP entry for address %s on %s: " + "%s (0x%x/%d)\n", + buf, QETH_CARD_IFNAME(card), + qeth_l3_arp_get_error_cause(&rc), tmp, tmp); } return rc; } @@ -2394,6 +2417,8 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, if (card->info.guestlan) return -EOPNOTSUPP; if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { + PRINT_WARN("ARP processing not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } memcpy(buf, entry, 12); @@ -2408,9 +2433,10 @@ static int qeth_l3_arp_remove_entry(struct qeth_card *card, tmp = rc; memset(buf, 0, 16); qeth_l3_ipaddr4_to_string((u8 *)entry->ipaddr, buf); - QETH_DBF_MESSAGE(2, "Could not delete ARP entry for address %s" - " on %s: %s (0x%x/%d)\n", buf, QETH_CARD_IFNAME(card), - qeth_l3_arp_get_error_cause(&rc), tmp, tmp); + PRINT_WARN("Could not delete ARP entry for address %s on %s: " + "%s (0x%x/%d)\n", + buf, QETH_CARD_IFNAME(card), + qeth_l3_arp_get_error_cause(&rc), tmp, tmp); } return rc; } @@ -2430,14 +2456,16 @@ static int qeth_l3_arp_flush_cache(struct qeth_card *card) if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD)) return -EOPNOTSUPP; if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { + PRINT_WARN("ARP processing not supported " + "on %s!\n", QETH_CARD_IFNAME(card)); return -EOPNOTSUPP; } rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, IPA_CMD_ASS_ARP_FLUSH_CACHE, 0); if (rc) { tmp = rc; - QETH_DBF_MESSAGE(2, "Could not flush ARP cache on %s: %s " - "(0x%x/%d)\n", QETH_CARD_IFNAME(card), + PRINT_WARN("Could not flush ARP cache on %s: %s (0x%x/%d)\n", + QETH_CARD_IFNAME(card), qeth_l3_arp_get_error_cause(&rc), tmp, tmp); } return rc; @@ -2696,7 +2724,7 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ctx = qeth_eddp_create_context(card, new_skb, hdr, skb->sk->sk_protocol); if (ctx == NULL) { - QETH_DBF_MESSAGE(2, "could not create eddp context\n"); + PRINT_WARN("could not create eddp context\n"); goto tx_drop; } } else { @@ -2764,7 +2792,6 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) if ((new_skb != skb) && new_skb) dev_kfree_skb_any(new_skb); dev_kfree_skb_any(skb); - netif_wake_queue(dev); return NETDEV_TX_OK; } diff --git a/trunk/drivers/s390/net/qeth_l3_sys.c b/trunk/drivers/s390/net/qeth_l3_sys.c index ac1993708ae9..08f51fd902c4 100644 --- a/trunk/drivers/s390/net/qeth_l3_sys.c +++ b/trunk/drivers/s390/net/qeth_l3_sys.c @@ -85,6 +85,7 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, } else if (!strcmp(tmp, "multicast_router")) { route->type = MULTICAST_ROUTER; } else { + PRINT_WARN("Invalid routing type '%s'.\n", tmp); return -EINVAL; } if (((card->state == CARD_STATE_SOFTSETUP) || @@ -136,6 +137,9 @@ static ssize_t qeth_l3_dev_route6_store(struct device *dev, return -EINVAL; if (!qeth_is_supported(card, IPA_IPV6)) { + PRINT_WARN("IPv6 not supported for interface %s.\n" + "Routing status no changed.\n", + QETH_CARD_IFNAME(card)); return -ENOTSUPP; } @@ -175,6 +179,7 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, if ((i == 0) || (i == 1)) card->options.fake_broadcast = i; else { + PRINT_WARN("fake_broadcast: write 0 or 1 to this file!\n"); return -EINVAL; } return count; @@ -215,6 +220,7 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { + PRINT_WARN("Device is not a tokenring device!\n"); return -EINVAL; } @@ -227,6 +233,8 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; return count; } else { + PRINT_WARN("broadcast_mode: invalid mode %s!\n", + tmp); return -EINVAL; } return count; @@ -267,6 +275,7 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { + PRINT_WARN("Device is not a tokenring device!\n"); return -EINVAL; } @@ -276,6 +285,7 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, QETH_TR_MACADDR_CANONICAL : QETH_TR_MACADDR_NONCANONICAL; else { + PRINT_WARN("canonical_macaddr: write 0 or 1 to this file!\n"); return -EINVAL; } return count; @@ -317,6 +327,7 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, else if (!strcmp(tmp, "no_checksumming")) card->options.checksum_type = NO_CHECKSUMMING; else { + PRINT_WARN("Unknown checksumming type '%s'\n", tmp); return -EINVAL; } return count; @@ -371,6 +382,8 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, } else if (!strcmp(tmp, "0")) { card->ipato.enabled = 0; } else { + PRINT_WARN("ipato_enable: write 0, 1 or 'toggle' to " + "this file\n"); return -EINVAL; } return count; @@ -409,6 +422,8 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, } else if (!strcmp(tmp, "0")) { card->ipato.invert4 = 0; } else { + PRINT_WARN("ipato_invert4: write 0, 1 or 'toggle' to " + "this file\n"); return -EINVAL; } return count; @@ -471,10 +486,13 @@ static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto, /* get address string */ end = strchr(start, '/'); if (!end || (end - start >= 40)) { + PRINT_WARN("Invalid format for ipato_addx/delx. " + "Use /\n"); return -EINVAL; } strncpy(buffer, start, end - start); if (qeth_l3_string_to_ipaddr(buffer, proto, addr)) { + PRINT_WARN("Invalid IP address format!\n"); return -EINVAL; } start = end + 1; @@ -482,6 +500,7 @@ static int qeth_l3_parse_ipatoe(const char *buf, enum qeth_prot_versions proto, if (!strlen(start) || (tmp == start) || (*mask_bits > ((proto == QETH_PROT_IPV4) ? 32 : 128))) { + PRINT_WARN("Invalid mask bits for ipato_addx/delx !\n"); return -EINVAL; } return 0; @@ -501,6 +520,7 @@ static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count, ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); if (!ipatoe) { + PRINT_WARN("No memory to allocate ipato entry\n"); return -ENOMEM; } ipatoe->proto = proto; @@ -589,6 +609,8 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, } else if (!strcmp(tmp, "0")) { card->ipato.invert6 = 0; } else { + PRINT_WARN("ipato_invert6: write 0, 1 or 'toggle' to " + "this file\n"); return -EINVAL; } return count; @@ -702,6 +724,7 @@ static int qeth_l3_parse_vipae(const char *buf, enum qeth_prot_versions proto, u8 *addr) { if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { + PRINT_WARN("Invalid IP address format!\n"); return -EINVAL; } return 0; @@ -868,6 +891,7 @@ static int qeth_l3_parse_rxipe(const char *buf, enum qeth_prot_versions proto, u8 *addr) { if (qeth_l3_string_to_ipaddr(buf, proto, addr)) { + PRINT_WARN("Invalid IP address format!\n"); return -EINVAL; } return 0; diff --git a/trunk/drivers/s390/s390mach.c b/trunk/drivers/s390/s390mach.c index 5bfbe7659830..5080f343ad74 100644 --- a/trunk/drivers/s390/s390mach.c +++ b/trunk/drivers/s390/s390mach.c @@ -207,7 +207,6 @@ s390_handle_mcck(void) do_exit(SIGSEGV); } } -EXPORT_SYMBOL_GPL(s390_handle_mcck); /* * returns 0 if all registers could be validated diff --git a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c index 5d23368a1bce..ccfd8aca3765 100644 --- a/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/trunk/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -1348,7 +1348,7 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, del_timer(&evt_struct->timer); - if ((crq->status != VIOSRP_OK && crq->status != VIOSRP_OK2) && evt_struct->cmnd) + if (crq->status != VIOSRP_OK && evt_struct->cmnd) evt_struct->cmnd->result = DID_ERROR << 16; if (evt_struct->done) evt_struct->done(evt_struct); diff --git a/trunk/drivers/scsi/ibmvscsi/viosrp.h b/trunk/drivers/scsi/ibmvscsi/viosrp.h index 204604501ad8..4c4aadb3e405 100644 --- a/trunk/drivers/scsi/ibmvscsi/viosrp.h +++ b/trunk/drivers/scsi/ibmvscsi/viosrp.h @@ -65,8 +65,7 @@ enum viosrp_crq_status { VIOSRP_VIOLATES_MAX_XFER = 0x2, VIOSRP_PARTNER_PANIC = 0x3, VIOSRP_DEVICE_BUSY = 0x8, - VIOSRP_ADAPTER_FAIL = 0x10, - VIOSRP_OK2 = 0x99, + VIOSRP_ADAPTER_FAIL = 0x10 }; struct viosrp_crq { diff --git a/trunk/drivers/scsi/qla2xxx/qla_attr.c b/trunk/drivers/scsi/qla2xxx/qla_attr.c index 8dd88fc1244a..287690853caf 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_attr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_attr.c @@ -70,9 +70,6 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, case 2: qla2x00_alloc_fw_dump(ha); break; - case 3: - qla2x00_system_error(ha); - break; } return (count); } @@ -889,13 +886,9 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) static void qla2x00_get_host_port_type(struct Scsi_Host *shost) { - scsi_qla_host_t *ha = shost_priv(shost); + scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost)); uint32_t port_type = FC_PORTTYPE_UNKNOWN; - if (ha->parent) { - fc_host_port_type(shost) = FC_PORTTYPE_NPIV; - return; - } switch (ha->current_topology) { case ISP_CFG_NL: port_type = FC_PORTTYPE_LPORT; @@ -1179,10 +1172,10 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) qla24xx_disable_vp(vha); qla24xx_deallocate_vp_id(vha); - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); ha->cur_vport_count--; clear_bit(vha->vp_idx, ha->vp_idx_map); - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); kfree(vha->node_name); kfree(vha->port_name); diff --git a/trunk/drivers/scsi/qla2xxx/qla_def.h b/trunk/drivers/scsi/qla2xxx/qla_def.h index 8dd600013bd1..299eccf6cabd 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_def.h +++ b/trunk/drivers/scsi/qla2xxx/qla_def.h @@ -2457,7 +2457,7 @@ typedef struct scsi_qla_host { #define MBX_INTR_WAIT 2 #define MBX_UPDATE_FLASH_ACTIVE 3 - struct mutex vport_lock; /* Virtual port synchronization */ + struct semaphore vport_sem; /* Virtual port synchronization */ struct completion mbx_cmd_comp; /* Serialize mbx access */ struct completion mbx_intr_comp; /* Used for completion notification */ diff --git a/trunk/drivers/scsi/qla2xxx/qla_gbl.h b/trunk/drivers/scsi/qla2xxx/qla_gbl.h index 9b4bebee6879..f8827068d30f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_gbl.h +++ b/trunk/drivers/scsi/qla2xxx/qla_gbl.h @@ -227,9 +227,6 @@ extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *); extern int qla24xx_abort_target(struct fc_port *, unsigned int); extern int qla24xx_lun_reset(struct fc_port *, unsigned int); -extern int -qla2x00_system_error(scsi_qla_host_t *); - extern int qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); diff --git a/trunk/drivers/scsi/qla2xxx/qla_inline.h b/trunk/drivers/scsi/qla2xxx/qla_inline.h index 92fafbdbbaab..e9bae27737d1 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_inline.h +++ b/trunk/drivers/scsi/qla2xxx/qla_inline.h @@ -34,11 +34,7 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr) static inline void qla2x00_poll(scsi_qla_host_t *ha) { - unsigned long flags; - - local_irq_save(flags); ha->isp_ops->intr_handler(0, ha); - local_irq_restore(flags); } static __inline__ scsi_qla_host_t * diff --git a/trunk/drivers/scsi/qla2xxx/qla_isr.c b/trunk/drivers/scsi/qla2xxx/qla_isr.c index ec63b79f900a..5d9a64a7879b 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_isr.c +++ b/trunk/drivers/scsi/qla2xxx/qla_isr.c @@ -272,6 +272,8 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) uint32_t rscn_entry, host_pid; uint8_t rscn_queue_index; unsigned long flags; + scsi_qla_host_t *vha; + int i; /* Setup to process RIO completion. */ handle_cnt = 0; @@ -542,10 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_PORT_UPDATE: /* Port database update */ - /* Only handle SCNs for our Vport index. */ - if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) - break; - + if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { + for_each_mapped_vp_idx(ha, i) { + list_for_each_entry(vha, &ha->vp_list, + vp_list) { + if ((mb[3] & 0xff) + == vha->vp_idx) { + ha = vha; + break; + } + } + } + } /* * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET * event etc. earlier indicating loop is down) then process @@ -580,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb) break; case MBA_RSCN_UPDATE: /* State Change Registration */ - /* Check if the Vport has issued a SCR */ - if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags)) - break; - /* Only handle SCNs for our Vport index. */ - if (ha->parent && ha->vp_idx != (mb[3] & 0xff)) - break; + if ((ha->flags.npiv_supported) && (ha->num_vhosts)) { + for_each_mapped_vp_idx(ha, i) { + list_for_each_entry(vha, &ha->vp_list, + vp_list) { + if ((mb[3] & 0xff) + == vha->vp_idx) { + ha = vha; + break; + } + } + } + } DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n", ha->host_no)); @@ -1116,6 +1132,25 @@ qla2x00_status_entry(scsi_qla_host_t *ha, void *pkt) break; qla2x00_handle_sense(sp, sense_data, sense_len); + + /* + * In case of a Underrun condition, set both the lscsi + * status and the completion status to appropriate + * values. + */ + if (resid && + ((unsigned)(scsi_bufflen(cp) - resid) < + cp->underflow)) { + DEBUG2(qla_printk(KERN_INFO, ha, + "scsi(%ld:%d:%d:%d): Mid-layer underflow " + "detected (%x of %x bytes)...returning " + "error status.\n", ha->host_no, + cp->device->channel, cp->device->id, + cp->device->lun, resid, + scsi_bufflen(cp))); + + cp->result = DID_ERROR << 16 | lscsi_status; + } } else { /* * If RISC reports underrun and target does not report @@ -1604,12 +1639,12 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) ha = dev_id; reg = &ha->iobase->isp24; - spin_lock_irq(&ha->hardware_lock); + spin_lock(&ha->hardware_lock); qla24xx_process_response_queue(ha); WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); - spin_unlock_irq(&ha->hardware_lock); + spin_unlock(&ha->hardware_lock); return IRQ_HANDLED; } @@ -1628,7 +1663,7 @@ qla24xx_msix_default(int irq, void *dev_id) reg = &ha->iobase->isp24; status = 0; - spin_lock_irq(&ha->hardware_lock); + spin_lock(&ha->hardware_lock); do { stat = RD_REG_DWORD(®->host_status); if (stat & HSRX_RISC_PAUSED) { @@ -1681,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id) } WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); } while (0); - spin_unlock_irq(&ha->hardware_lock); + spin_unlock(&ha->hardware_lock); if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && (status & MBX_INTERRUPT) && ha->flags.mbox_int) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_mbx.c b/trunk/drivers/scsi/qla2xxx/qla_mbx.c index 250d2f604397..210060420809 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mbx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mbx.c @@ -2303,6 +2303,8 @@ qla24xx_lun_reset(struct fc_port *fcport, unsigned int l) return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l); } +#if 0 + int qla2x00_system_error(scsi_qla_host_t *ha) { @@ -2310,7 +2312,7 @@ qla2x00_system_error(scsi_qla_host_t *ha) mbx_cmd_t mc; mbx_cmd_t *mcp = &mc; - if (!IS_QLA23XX(ha) && !IS_FWI2_CAPABLE(ha)) + if (!IS_FWI2_CAPABLE(ha)) return QLA_FUNCTION_FAILED; DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); @@ -2332,6 +2334,8 @@ qla2x00_system_error(scsi_qla_host_t *ha) return rval; } +#endif /* 0 */ + /** * qla2x00_set_serdes_params() - * @ha: HA context @@ -2504,7 +2508,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma, if (mb) memcpy(mb, mcp->mb, 8 * sizeof(*mb)); if (dwords) - *dwords = buffers; + *dwords = mcp->mb[6]; } return rval; @@ -2803,9 +2807,9 @@ qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) */ map = (vp_index - 1) / 8; pos = (vp_index - 1) & 7; - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); vce->vp_idx_map[map] |= 1 << pos; - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); rval = qla2x00_issue_iocb(ha, vce, vce_dma, 0); if (rval != QLA_SUCCESS) { diff --git a/trunk/drivers/scsi/qla2xxx/qla_mid.c b/trunk/drivers/scsi/qla2xxx/qla_mid.c index 62a3ad6e8ecb..f2b04979e5f0 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_mid.c +++ b/trunk/drivers/scsi/qla2xxx/qla_mid.c @@ -32,12 +32,12 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) scsi_qla_host_t *ha = vha->parent; /* Find an empty slot and assign an vp_id */ - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); vp_id = find_first_zero_bit(ha->vp_idx_map, ha->max_npiv_vports + 1); if (vp_id > ha->max_npiv_vports) { DEBUG15(printk ("vp_id %d is bigger than max-supported %d.\n", vp_id, ha->max_npiv_vports)); - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); return vp_id; } @@ -45,7 +45,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha) ha->num_vhosts++; vha->vp_idx = vp_id; list_add_tail(&vha->vp_list, &ha->vp_list); - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); return vp_id; } @@ -55,12 +55,12 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha) uint16_t vp_id; scsi_qla_host_t *ha = vha->parent; - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); vp_id = vha->vp_idx; ha->num_vhosts--; clear_bit(vp_id, ha->vp_idx_map); list_del(&vha->vp_list); - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); } static scsi_qla_host_t * @@ -145,9 +145,9 @@ qla24xx_enable_vp(scsi_qla_host_t *vha) } /* Initialize the new vport unless it is a persistent port */ - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); ret = qla24xx_modify_vp_config(vha); - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); if (ret != QLA_SUCCESS) { fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); @@ -406,7 +406,6 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) INIT_LIST_HEAD(&vha->list); INIT_LIST_HEAD(&vha->fcports); INIT_LIST_HEAD(&vha->vp_fcports); - INIT_LIST_HEAD(&vha->work_list); vha->dpc_flags = 0L; set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); @@ -438,10 +437,10 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) vha->flags.init_done = 1; num_hosts++; - mutex_lock(&ha->vport_lock); + down(&ha->vport_sem); set_bit(vha->vp_idx, ha->vp_idx_map); ha->cur_vport_count++; - mutex_unlock(&ha->vport_lock); + up(&ha->vport_sem); return vha; diff --git a/trunk/drivers/scsi/qla2xxx/qla_os.c b/trunk/drivers/scsi/qla2xxx/qla_os.c index 48eaa3bb5433..3223fd16bcfe 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_os.c +++ b/trunk/drivers/scsi/qla2xxx/qla_os.c @@ -10,7 +10,6 @@ #include #include #include -#include #include #include @@ -1632,7 +1631,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) /* load the F/W, read paramaters, and init the H/W */ ha->instance = num_hosts; - mutex_init(&ha->vport_lock); + init_MUTEX(&ha->vport_sem); init_completion(&ha->mbx_cmd_comp); complete(&ha->mbx_cmd_comp); init_completion(&ha->mbx_intr_comp); @@ -2157,14 +2156,13 @@ static int qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked) { unsigned long flags; - scsi_qla_host_t *pha = to_qla_parent(ha); if (!locked) - spin_lock_irqsave(&pha->hardware_lock, flags); + spin_lock_irqsave(&ha->hardware_lock, flags); list_add_tail(&e->list, &ha->work_list); qla2xxx_wake_dpc(ha); if (!locked) - spin_unlock_irqrestore(&pha->hardware_lock, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; } @@ -2204,13 +2202,12 @@ static void qla2x00_do_work(struct scsi_qla_host *ha) { struct qla_work_evt *e; - scsi_qla_host_t *pha = to_qla_parent(ha); - spin_lock_irq(&pha->hardware_lock); + spin_lock_irq(&ha->hardware_lock); while (!list_empty(&ha->work_list)) { e = list_entry(ha->work_list.next, struct qla_work_evt, list); list_del_init(&e->list); - spin_unlock_irq(&pha->hardware_lock); + spin_unlock_irq(&ha->hardware_lock); switch (e->type) { case QLA_EVT_AEN: @@ -2224,9 +2221,9 @@ qla2x00_do_work(struct scsi_qla_host *ha) } if (e->flags & QLA_EVT_FLAG_FREE) kfree(e); - spin_lock_irq(&pha->hardware_lock); + spin_lock_irq(&ha->hardware_lock); } - spin_unlock_irq(&pha->hardware_lock); + spin_unlock_irq(&ha->hardware_lock); } /************************************************************************** @@ -2637,7 +2634,7 @@ qla2x00_timer(scsi_qla_host_t *ha) #define FW_FILE_ISP24XX "ql2400_fw.bin" #define FW_FILE_ISP25XX "ql2500_fw.bin" -static DEFINE_MUTEX(qla_fw_lock); +static DECLARE_MUTEX(qla_fw_lock); static struct fw_blob qla_fw_blobs[FW_BLOBS] = { { .name = FW_FILE_ISP21XX, .segs = { 0x1000, 0 }, }, @@ -2668,7 +2665,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) blob = &qla_fw_blobs[FW_ISP25XX]; } - mutex_lock(&qla_fw_lock); + down(&qla_fw_lock); if (blob->fw) goto out; @@ -2681,7 +2678,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha) } out: - mutex_unlock(&qla_fw_lock); + up(&qla_fw_lock); return blob; } @@ -2690,11 +2687,11 @@ qla2x00_release_firmware(void) { int idx; - mutex_lock(&qla_fw_lock); + down(&qla_fw_lock); for (idx = 0; idx < FW_BLOBS; idx++) if (qla_fw_blobs[idx].fw) release_firmware(qla_fw_blobs[idx].fw); - mutex_unlock(&qla_fw_lock); + up(&qla_fw_lock); } static pci_ers_result_t @@ -2867,8 +2864,7 @@ qla2x00_module_init(void) return -ENODEV; } - printk(KERN_INFO "QLogic Fibre Channel HBA Driver: %s\n", - qla2x00_version_str); + printk(KERN_INFO "QLogic Fibre Channel HBA Driver\n"); ret = pci_register_driver(&qla2xxx_pci_driver); if (ret) { kmem_cache_destroy(srb_cachep); diff --git a/trunk/drivers/scsi/qla2xxx/qla_version.h b/trunk/drivers/scsi/qla2xxx/qla_version.h index d058c8862b35..afeae2bfe7eb 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_version.h +++ b/trunk/drivers/scsi/qla2xxx/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "8.02.01-k4" +#define QLA2XXX_VERSION "8.02.01-k2" #define QLA_DRIVER_MAJOR_VER 8 #define QLA_DRIVER_MINOR_VER 2 diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index 93d2b6714453..049103f1d16f 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -359,12 +359,7 @@ static int scsi_bus_match(struct device *dev, struct device_driver *gendrv) static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env) { - struct scsi_device *sdev; - - if (dev->type != &scsi_dev_type) - return 0; - - sdev = to_scsi_device(dev); + struct scsi_device *sdev = to_scsi_device(dev); add_uevent_var(env, "MODALIAS=" SCSI_DEVICE_MODALIAS_FMT, sdev->type); return 0; diff --git a/trunk/drivers/serial/atmel_serial.c b/trunk/drivers/serial/atmel_serial.c index 42be8b01a40f..c065a704a93a 100644 --- a/trunk/drivers/serial/atmel_serial.c +++ b/trunk/drivers/serial/atmel_serial.c @@ -1318,7 +1318,7 @@ static void __init atmel_console_get_options(struct uart_port *port, int *baud, * If the baud rate generator isn't running, the port wasn't * initialized by the boot loader. */ - quot = UART_GET_BRGR(port) & ATMEL_US_CD; + quot = UART_GET_BRGR(port); if (!quot) return; diff --git a/trunk/drivers/serial/bfin_5xx.c b/trunk/drivers/serial/bfin_5xx.c index f20952c43cb8..d6b4ead693b7 100644 --- a/trunk/drivers/serial/bfin_5xx.c +++ b/trunk/drivers/serial/bfin_5xx.c @@ -530,7 +530,11 @@ static unsigned int bfin_serial_get_mctrl(struct uart_port *port) if (uart->cts_pin < 0) return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - if (UART_GET_CTS(uart)) +# ifdef BF54x + if (UART_GET_MSR(uart) & CTS) +# else + if (gpio_get_value(uart->cts_pin)) +# endif return TIOCM_DSR | TIOCM_CAR; else #endif @@ -545,9 +549,17 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl) return; if (mctrl & TIOCM_RTS) - UART_CLEAR_RTS(uart); +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) & ~MRTS); +# else + gpio_set_value(uart->rts_pin, 0); +# endif else - UART_SET_RTS(uart); +# ifdef BF54x + UART_PUT_MCR(uart, UART_GET_MCR(uart) | MRTS); +# else + gpio_set_value(uart->rts_pin, 1); +# endif #endif } @@ -740,7 +752,11 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, /* Disable UART */ ier = UART_GET_IER(uart); - UART_DISABLE_INTS(uart); +#ifdef CONFIG_BF54x + UART_CLEAR_IER(uart, 0xF); +#else + UART_PUT_IER(uart, 0); +#endif /* Set DLAB in LCR to Access DLL and DLH */ UART_SET_DLAB(uart); @@ -755,7 +771,11 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, UART_PUT_LCR(uart, lcr); /* Enable UART */ - UART_ENABLE_INTS(uart, ier); +#ifdef CONFIG_BF54x + UART_SET_IER(uart, ier); +#else + UART_PUT_IER(uart, ier); +#endif val = UART_GET_GCTL(uart); val |= UCEN; @@ -813,15 +833,15 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser) * Enable the IrDA function if tty->ldisc.num is N_IRDA. * In other cases, disable IrDA function. */ -static void bfin_serial_set_ldisc(struct uart_port *port) +static void bfin_set_ldisc(struct tty_struct *tty) { - int line = port->line; + int line = tty->index; unsigned short val; - if (line >= port->info->tty->driver->num) + if (line >= tty->driver->num) return; - switch (port->info->tty->ldisc.num) { + switch (tty->ldisc.num) { case N_IRDA: val = UART_GET_GCTL(&bfin_serial_ports[line]); val |= (IREN | RPOLC); @@ -846,7 +866,6 @@ static struct uart_ops bfin_serial_pops = { .startup = bfin_serial_startup, .shutdown = bfin_serial_shutdown, .set_termios = bfin_serial_set_termios, - .set_ldisc = bfin_serial_set_ldisc, .type = bfin_serial_type, .release_port = bfin_serial_release_port, .request_port = bfin_serial_request_port, @@ -1187,6 +1206,7 @@ static int __init bfin_serial_init(void) ret = uart_register_driver(&bfin_serial_reg); if (ret == 0) { + bfin_serial_reg.tty_driver->set_ldisc = bfin_set_ldisc; ret = platform_driver_register(&bfin_serial_driver); if (ret) { pr_debug("uart register failed\n"); diff --git a/trunk/drivers/serial/sb1250-duart.c b/trunk/drivers/serial/sb1250-duart.c index f8e1447a022a..2d6c08b3dbcf 100644 --- a/trunk/drivers/serial/sb1250-duart.c +++ b/trunk/drivers/serial/sb1250-duart.c @@ -924,7 +924,7 @@ console_initcall(sbd_serial_console_init); static struct uart_driver sbd_reg = { .owner = THIS_MODULE, - .driver_name = "sb1250_duart", + .driver_name = "serial", .dev_name = "duart", .major = TTY_MAJOR, .minor = SB1250_DUART_MINOR_BASE, diff --git a/trunk/drivers/serial/serial_core.c b/trunk/drivers/serial/serial_core.c index c9b64e73c987..53b03c629aff 100644 --- a/trunk/drivers/serial/serial_core.c +++ b/trunk/drivers/serial/serial_core.c @@ -1165,15 +1165,6 @@ uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, return ret; } -static void uart_set_ldisc(struct tty_struct *tty) -{ - struct uart_state *state = tty->driver_data; - struct uart_port *port = state->port; - - if (port->ops->set_ldisc) - port->ops->set_ldisc(port); -} - static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { @@ -2297,7 +2288,6 @@ static const struct tty_operations uart_ops = { .unthrottle = uart_unthrottle, .send_xchar = uart_send_xchar, .set_termios = uart_set_termios, - .set_ldisc = uart_set_ldisc, .stop = uart_stop, .start = uart_start, .hangup = uart_hangup, diff --git a/trunk/drivers/serial/ucc_uart.c b/trunk/drivers/serial/ucc_uart.c index 566a8b42e05a..01917c433f17 100644 --- a/trunk/drivers/serial/ucc_uart.c +++ b/trunk/drivers/serial/ucc_uart.c @@ -195,7 +195,7 @@ struct uart_qe_port { static struct uart_driver ucc_uart_driver = { .owner = THIS_MODULE, - .driver_name = "ucc_uart", + .driver_name = "serial", .dev_name = "ttyQE", .major = SERIAL_QE_MAJOR, .minor = SERIAL_QE_MINOR, diff --git a/trunk/drivers/spi/spidev.c b/trunk/drivers/spi/spidev.c index 799337f7fde1..41620c0fb046 100644 --- a/trunk/drivers/spi/spidev.c +++ b/trunk/drivers/spi/spidev.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -68,12 +67,11 @@ static unsigned long minors[N_SPI_MINORS / BITS_PER_LONG]; | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) struct spidev_data { - dev_t devt; + struct device dev; spinlock_t spi_lock; struct spi_device *spi; struct list_head device_entry; - /* buffer is NULL unless this device is open (users > 0) */ struct mutex buf_lock; unsigned users; u8 *buffer; @@ -469,7 +467,7 @@ static int spidev_open(struct inode *inode, struct file *filp) mutex_lock(&device_list_lock); list_for_each_entry(spidev, &device_list, device_entry) { - if (spidev->devt == inode->i_rdev) { + if (spidev->dev.devt == inode->i_rdev) { status = 0; break; } @@ -502,22 +500,10 @@ static int spidev_release(struct inode *inode, struct file *filp) mutex_lock(&device_list_lock); spidev = filp->private_data; filp->private_data = NULL; - - /* last close? */ spidev->users--; if (!spidev->users) { - int dofree; - kfree(spidev->buffer); spidev->buffer = NULL; - - /* ... after we unbound from the underlying device? */ - spin_lock_irq(&spidev->spi_lock); - dofree = (spidev->spi == NULL); - spin_unlock_irq(&spidev->spi_lock); - - if (dofree) - kfree(spidev); } mutex_unlock(&device_list_lock); @@ -544,7 +530,19 @@ static struct file_operations spidev_fops = { * It also simplifies memory management. */ -static struct class *spidev_class; +static void spidev_classdev_release(struct device *dev) +{ + struct spidev_data *spidev; + + spidev = container_of(dev, struct spidev_data, dev); + kfree(spidev); +} + +static struct class spidev_class = { + .name = "spidev", + .owner = THIS_MODULE, + .dev_release = spidev_classdev_release, +}; /*-------------------------------------------------------------------------*/ @@ -572,20 +570,20 @@ static int spidev_probe(struct spi_device *spi) mutex_lock(&device_list_lock); minor = find_first_zero_bit(minors, N_SPI_MINORS); if (minor < N_SPI_MINORS) { - struct device *dev; - - spidev->devt = MKDEV(SPIDEV_MAJOR, minor); - dev = device_create(spidev_class, &spi->dev, spidev->devt, + spidev->dev.parent = &spi->dev; + spidev->dev.class = &spidev_class; + spidev->dev.devt = MKDEV(SPIDEV_MAJOR, minor); + snprintf(spidev->dev.bus_id, sizeof spidev->dev.bus_id, "spidev%d.%d", spi->master->bus_num, spi->chip_select); - status = IS_ERR(dev) ? PTR_ERR(dev) : 0; + status = device_register(&spidev->dev); } else { dev_dbg(&spi->dev, "no minor number available!\n"); status = -ENODEV; } if (status == 0) { set_bit(minor, minors); - spi_set_drvdata(spi, spidev); + dev_set_drvdata(&spi->dev, spidev); list_add(&spidev->device_entry, &device_list); } mutex_unlock(&device_list_lock); @@ -598,21 +596,19 @@ static int spidev_probe(struct spi_device *spi) static int spidev_remove(struct spi_device *spi) { - struct spidev_data *spidev = spi_get_drvdata(spi); + struct spidev_data *spidev = dev_get_drvdata(&spi->dev); /* make sure ops on existing fds can abort cleanly */ spin_lock_irq(&spidev->spi_lock); spidev->spi = NULL; - spi_set_drvdata(spi, NULL); spin_unlock_irq(&spidev->spi_lock); /* prevent new opens */ mutex_lock(&device_list_lock); list_del(&spidev->device_entry); - device_destroy(spidev_class, spidev->devt); - clear_bit(MINOR(spidev->devt), minors); - if (spidev->users == 0) - kfree(spidev); + dev_set_drvdata(&spi->dev, NULL); + clear_bit(MINOR(spidev->dev.devt), minors); + device_unregister(&spidev->dev); mutex_unlock(&device_list_lock); return 0; @@ -648,15 +644,15 @@ static int __init spidev_init(void) if (status < 0) return status; - spidev_class = class_create(THIS_MODULE, "spidev"); - if (IS_ERR(spidev_class)) { + status = class_register(&spidev_class); + if (status < 0) { unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); - return PTR_ERR(spidev_class); + return status; } status = spi_register_driver(&spidev_spi); if (status < 0) { - class_destroy(spidev_class); + class_unregister(&spidev_class); unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); } return status; @@ -666,7 +662,7 @@ module_init(spidev_init); static void __exit spidev_exit(void) { spi_unregister_driver(&spidev_spi); - class_destroy(spidev_class); + class_unregister(&spidev_class); unregister_chrdev(SPIDEV_MAJOR, spidev_spi.driver.name); } module_exit(spidev_exit); diff --git a/trunk/drivers/ssb/main.c b/trunk/drivers/ssb/main.c index d184f2aea78d..7cf8851286b5 100644 --- a/trunk/drivers/ssb/main.c +++ b/trunk/drivers/ssb/main.c @@ -1168,21 +1168,15 @@ EXPORT_SYMBOL(ssb_dma_translation); int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask) { struct device *dma_dev = ssb_dev->dma_dev; - int err = 0; #ifdef CONFIG_SSB_PCIHOST - if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) { - err = pci_set_dma_mask(ssb_dev->bus->host_pci, mask); - if (err) - return err; - err = pci_set_consistent_dma_mask(ssb_dev->bus->host_pci, mask); - return err; - } + if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI) + return dma_set_mask(dma_dev, mask); #endif dma_dev->coherent_dma_mask = mask; dma_dev->dma_mask = &dma_dev->coherent_dma_mask; - return err; + return 0; } EXPORT_SYMBOL(ssb_dma_set_mask); diff --git a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c b/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c index a9636f43bca2..5100fbbf6cb0 100644 --- a/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c +++ b/trunk/drivers/usb/c67x00/c67x00-ll-hpi.c @@ -120,7 +120,7 @@ static void hpi_write_word(struct c67x00_device *dev, u16 reg, u16 value) * Only data is little endian, addr has cpu endianess */ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, - __le16 *data, u16 count) + u16 *data, u16 count) { unsigned long flags; int i; @@ -129,7 +129,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, hpi_write_reg(dev, HPI_ADDR, addr); for (i = 0; i < count; i++) - hpi_write_reg(dev, HPI_DATA, le16_to_cpu(*data++)); + hpi_write_reg(dev, HPI_DATA, cpu_to_le16(*data++)); spin_unlock_irqrestore(&dev->hpi.lock, flags); } @@ -138,7 +138,7 @@ static void hpi_write_words_le16(struct c67x00_device *dev, u16 addr, * Only data is little endian, addr has cpu endianess */ static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, - __le16 *data, u16 count) + u16 *data, u16 count) { unsigned long flags; int i; @@ -146,7 +146,7 @@ static void hpi_read_words_le16(struct c67x00_device *dev, u16 addr, spin_lock_irqsave(&dev->hpi.lock, flags); hpi_write_reg(dev, HPI_ADDR, addr); for (i = 0; i < count; i++) - *data++ = cpu_to_le16(hpi_read_reg(dev, HPI_DATA)); + *data++ = le16_to_cpu(hpi_read_reg(dev, HPI_DATA)); spin_unlock_irqrestore(&dev->hpi.lock, flags); } @@ -425,7 +425,7 @@ void c67x00_ll_write_mem_le16(struct c67x00_device *dev, u16 addr, len--; } - hpi_write_words_le16(dev, addr, (__le16 *)buf, len / 2); + hpi_write_words_le16(dev, addr, (u16 *)buf, len / 2); buf += len & ~0x01; addr += len & ~0x01; len &= 0x01; @@ -456,7 +456,7 @@ void c67x00_ll_read_mem_le16(struct c67x00_device *dev, u16 addr, len--; } - hpi_read_words_le16(dev, addr, (__le16 *)buf, len / 2); + hpi_read_words_le16(dev, addr, (u16 *)buf, len / 2); buf += len & ~0x01; addr += len & ~0x01; len &= 0x01; diff --git a/trunk/drivers/usb/class/cdc-wdm.c b/trunk/drivers/usb/class/cdc-wdm.c index 731db051070a..107666d4e2ec 100644 --- a/trunk/drivers/usb/class/cdc-wdm.c +++ b/trunk/drivers/usb/class/cdc-wdm.c @@ -611,8 +611,8 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err; } - desc->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); - desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; + desc->wMaxPacketSize = ep->wMaxPacketSize; + desc->bMaxPacketSize0 = cpu_to_le16(udev->descriptor.bMaxPacketSize0); desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) diff --git a/trunk/drivers/usb/core/hub.c b/trunk/drivers/usb/core/hub.c index 94789be54ca3..8eb4da332f56 100644 --- a/trunk/drivers/usb/core/hub.c +++ b/trunk/drivers/usb/core/hub.c @@ -644,48 +644,6 @@ static void hub_stop(struct usb_hub *hub) #ifdef CONFIG_PM -/* Try to identify which devices need USB-PERSIST handling */ -static int persistent_device(struct usb_device *udev) -{ - int i; - int retval; - struct usb_host_config *actconfig; - - /* Explicitly not marked persistent? */ - if (!udev->persist_enabled) - return 0; - - /* No active config? */ - actconfig = udev->actconfig; - if (!actconfig) - return 0; - - /* FIXME! We should check whether it's open here or not! */ - - /* - * Check that all the interface drivers have a - * 'reset_resume' entrypoint - */ - retval = 0; - for (i = 0; i < actconfig->desc.bNumInterfaces; i++) { - struct usb_interface *intf; - struct usb_driver *driver; - - intf = actconfig->interface[i]; - if (!intf->dev.driver) - continue; - driver = to_usb_driver(intf->dev.driver); - if (!driver->reset_resume) - return 0; - /* - * We have at least one driver, and that one - * has a reset_resume method. - */ - retval = 1; - } - return retval; -} - static void hub_restart(struct usb_hub *hub, int type) { struct usb_device *hdev = hub->hdev; @@ -731,8 +689,8 @@ static void hub_restart(struct usb_hub *hub, int type) * turn off the various status changes to prevent * khubd from disconnecting it later. */ - if (status == 0 && !(portstatus & USB_PORT_STAT_ENABLE) && - persistent_device(udev)) { + if (udev->persist_enabled && status == 0 && + !(portstatus & USB_PORT_STAT_ENABLE)) { if (portchange & USB_PORT_STAT_C_ENABLE) clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_ENABLE); diff --git a/trunk/drivers/usb/host/Kconfig b/trunk/drivers/usb/host/Kconfig index 228797e54f9c..1ef6df395e0c 100644 --- a/trunk/drivers/usb/host/Kconfig +++ b/trunk/drivers/usb/host/Kconfig @@ -300,8 +300,8 @@ config USB_R8A66597_HCD module will be called r8a66597-hcd. config SUPERH_ON_CHIP_R8A66597 - boolean "Enable SuperH on-chip R8A66597 USB" - depends on USB_R8A66597_HCD && (CPU_SUBTYPE_SH7366 || CPU_SUBTYPE_SH7723) + boolean "Enable SuperH on-chip USB like the R8A66597" + depends on USB_R8A66597_HCD && CPU_SUBTYPE_SH7366 help - This driver enables support for the on-chip R8A66597 in the - SH7366 and SH7723 processors. + Renesas SuperH processor has USB like the R8A66597. + This driver supported processor is SH7366. diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c index 65aa5ecf569a..c9cec8738261 100644 --- a/trunk/drivers/usb/host/isp1760-hcd.c +++ b/trunk/drivers/usb/host/isp1760-hcd.c @@ -2207,14 +2207,14 @@ struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, goto err_put; } - hcd->irq = irq; - hcd->rsrc_start = res_start; - hcd->rsrc_len = res_len; - ret = usb_add_hcd(hcd, irq, irqflags); if (ret) goto err_unmap; + hcd->irq = irq; + hcd->rsrc_start = res_start; + hcd->rsrc_len = res_len; + return hcd; err_unmap: diff --git a/trunk/drivers/usb/host/isp1760-if.c b/trunk/drivers/usb/host/isp1760-if.c index c9db3fe98726..440bf94f0d4c 100644 --- a/trunk/drivers/usb/host/isp1760-if.c +++ b/trunk/drivers/usb/host/isp1760-if.c @@ -104,8 +104,8 @@ static u32 nxp_pci_io_base; static u32 iolength; static u32 pci_mem_phy0; static u32 length; -static u8 __iomem *chip_addr; -static u8 __iomem *iobase; +static u8 *chip_addr; +static u8 *iobase; static int __devinit isp1761_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) diff --git a/trunk/drivers/usb/misc/Kconfig b/trunk/drivers/usb/misc/Kconfig index 001789c9a11a..eb6c06979f3b 100644 --- a/trunk/drivers/usb/misc/Kconfig +++ b/trunk/drivers/usb/misc/Kconfig @@ -272,7 +272,6 @@ config USB_TEST config USB_ISIGHTFW tristate "iSight firmware loading support" depends on USB - select FW_LOADER help This driver loads firmware for USB Apple iSight cameras, allowing them to be driven by the USB video class driver available at diff --git a/trunk/drivers/usb/misc/isight_firmware.c b/trunk/drivers/usb/misc/isight_firmware.c index 9f30aa1f8a5d..390e04885536 100644 --- a/trunk/drivers/usb/misc/isight_firmware.c +++ b/trunk/drivers/usb/misc/isight_firmware.c @@ -39,12 +39,9 @@ static int isight_firmware_load(struct usb_interface *intf, struct usb_device *dev = interface_to_usbdev(intf); int llen, len, req, ret = 0; const struct firmware *firmware; - unsigned char *buf = kmalloc(50, GFP_KERNEL); + unsigned char *buf; unsigned char data[4]; - u8 *ptr; - - if (!buf) - return -ENOMEM; + char *ptr; if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { printk(KERN_ERR "Unable to load isight firmware\n"); @@ -62,7 +59,7 @@ static int isight_firmware_load(struct usb_interface *intf, goto out; } - while (ptr+4 <= firmware->data+firmware->size) { + while (1) { memcpy(data, ptr, 4); len = (data[0] << 8 | data[1]); req = (data[2] << 8 | data[3]); @@ -74,14 +71,10 @@ static int isight_firmware_load(struct usb_interface *intf, continue; for (; len > 0; req += 50) { - llen = min(len, 50); + llen = len > 50 ? 50 : len; len -= llen; - if (ptr+llen > firmware->data+firmware->size) { - printk(KERN_ERR - "Malformed isight firmware"); - ret = -ENODEV; - goto out; - } + + buf = kmalloc(llen, GFP_KERNEL); memcpy(buf, ptr, llen); ptr += llen; @@ -96,18 +89,16 @@ static int isight_firmware_load(struct usb_interface *intf, goto out; } + kfree(buf); } } - if (usb_control_msg (dev, usb_sndctrlpipe(dev, 0), 0xa0, 0x40, 0xe600, 0, "\0", 1, 300) != 1) { printk(KERN_ERR "isight firmware loading completion failed\n"); ret = -ENODEV; } - out: - kfree(buf); release_firmware(firmware); return ret; } diff --git a/trunk/drivers/video/cirrusfb.c b/trunk/drivers/video/cirrusfb.c index c14b2435d23e..35ac9d956b3d 100644 --- a/trunk/drivers/video/cirrusfb.c +++ b/trunk/drivers/video/cirrusfb.c @@ -2432,9 +2432,9 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, info->screen_size = board_size; cinfo->unmap = cirrusfb_pci_unmap; - printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " - "Logic chipset on PCI bus\n", - info->screen_size >> 10, board_addr); + printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ", + info->screen_size >> 10, board_addr); + printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n"); pci_set_drvdata(pdev, info); ret = cirrusfb_register(info); diff --git a/trunk/drivers/video/console/fbcon.c b/trunk/drivers/video/console/fbcon.c index 97aff8db10bf..5fa8b76673cb 100644 --- a/trunk/drivers/video/console/fbcon.c +++ b/trunk/drivers/video/console/fbcon.c @@ -2275,7 +2275,9 @@ static int fbcon_switch(struct vc_data *vc) * in fb_set_var() */ info->var.activate = var.activate; - var.vmode |= info->var.vmode & ~FB_VMODE_MASK; + var.yoffset = info->var.yoffset; + var.xoffset = info->var.xoffset; + var.vmode = info->var.vmode; fb_set_var(info, &var); ops->var = info->var; diff --git a/trunk/drivers/video/fsl-diu-fb.c b/trunk/drivers/video/fsl-diu-fb.c index 0a2785361ca3..b50bb03cb5ab 100644 --- a/trunk/drivers/video/fsl-diu-fb.c +++ b/trunk/drivers/video/fsl-diu-fb.c @@ -1320,7 +1320,7 @@ static void free_irq_local(int irq) * Power management hooks. Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */ -static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) +static int fsl_diu_suspend(struct of_device *dev, pm_message_t state) { struct fsl_diu_data *machine_data; @@ -1330,7 +1330,7 @@ static int fsl_diu_suspend(struct of_device *ofdev, pm_message_t state) return 0; } -static int fsl_diu_resume(struct of_device *ofdev) +static int fsl_diu_resume(struct of_device *dev) { struct fsl_diu_data *machine_data; diff --git a/trunk/drivers/video/hgafb.c b/trunk/drivers/video/hgafb.c index c18880d9db1f..fb9e67228543 100644 --- a/trunk/drivers/video/hgafb.c +++ b/trunk/drivers/video/hgafb.c @@ -279,7 +279,7 @@ static void hga_blank(int blank_mode) static int __init hga_card_detect(void) { - int count = 0; + int count=0; void __iomem *p, *q; unsigned short p_save, q_save; @@ -303,18 +303,20 @@ static int __init hga_card_detect(void) writew(0x55aa, p); if (readw(p) == 0x55aa) count++; writew(p_save, p); - if (count != 2) - goto error; + if (count != 2) { + return 0; + } /* Ok, there is definitely a card registering at the correct * memory location, so now we do an I/O port test. */ - if (!test_hga_b(0x66, 0x0f)) /* cursor low register */ - goto error; - - if (!test_hga_b(0x99, 0x0f)) /* cursor low register */ - goto error; + if (!test_hga_b(0x66, 0x0f)) { /* cursor low register */ + return 0; + } + if (!test_hga_b(0x99, 0x0f)) { /* cursor low register */ + return 0; + } /* See if the card is a Hercules, by checking whether the vsync * bit of the status register is changing. This test lasts for @@ -329,7 +331,7 @@ static int __init hga_card_detect(void) } if (p_save == q_save) - goto error; + return 0; switch (inb_p(HGA_STATUS_PORT) & 0x70) { case 0x10: @@ -346,12 +348,6 @@ static int __init hga_card_detect(void) break; } return 1; -error: - if (release_io_ports) - release_region(0x3b0, 12); - if (release_io_port) - release_region(0x3bf, 1); - return 0; } /** diff --git a/trunk/drivers/video/leo.c b/trunk/drivers/video/leo.c index 13fea61d6ae4..8bc46e930340 100644 --- a/trunk/drivers/video/leo.c +++ b/trunk/drivers/video/leo.c @@ -17,8 +17,8 @@ #include #include #include -#include +#include #include #include "sbuslib.h" @@ -33,6 +33,7 @@ static int leo_blank(int, struct fb_info *); static int leo_mmap(struct fb_info *, struct vm_area_struct *); static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); +static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *); /* * Frame buffer operations @@ -42,6 +43,7 @@ static struct fb_ops leo_ops = { .owner = THIS_MODULE, .fb_setcolreg = leo_setcolreg, .fb_blank = leo_blank, + .fb_pan_display = leo_pan_display, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, @@ -76,7 +78,7 @@ static struct fb_ops leo_ops = { #define LEO_CUR_TYPE_CMAP 0x00000050 struct leo_cursor { - u8 xxx0[16]; + u8 xxx0[16]; u32 cur_type; u32 cur_misc; u32 cur_cursxy; @@ -103,7 +105,7 @@ struct leo_lx_krn { struct leo_lc_ss0_krn { u32 misc; - u8 xxx0[0x800-4]; + u8 xxx0[0x800-4]; u32 rev; }; @@ -114,7 +116,7 @@ struct leo_lc_ss0_usr { u32 fontt; u32 extent; u32 src; - u32 dst; + u32 dst; u32 copy; u32 fill; }; @@ -127,8 +129,8 @@ struct leo_lc_ss1_usr { u8 unknown; }; -struct leo_ld_ss0 { - u8 xxx0[0xe00]; +struct leo_ld { + u8 xxx0[0xe00]; u32 csr; u32 wid; u32 wmask; @@ -142,13 +144,13 @@ struct leo_ld_ss0 { u32 src; /* Copy/Scroll (SS0 only) */ u32 dst; /* Copy/Scroll/Fill (SS0 only) */ u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ - u32 xxx1[3]; + u32 xxx1[3]; u32 setsem; /* SS1 only */ u32 clrsem; /* SS1 only */ u32 clrpick; /* SS1 only */ u32 clrdat; /* SS1 only */ u32 alpha; /* SS1 only */ - u8 xxx2[0x2c]; + u8 xxx2[0x2c]; u32 winbg; u32 planemask; u32 rop; @@ -197,12 +199,11 @@ struct leo_par { static void leo_wait(struct leo_lx_krn __iomem *lx_krn) { int i; - + for (i = 0; - (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && - i < 300000; + (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && i < 300000; i++) - udelay(1); /* Busy wait at most 0.3 sec */ + udelay (1); /* Busy wait at most 0.3 sec */ return; } @@ -220,7 +221,7 @@ static int leo_setcolreg(unsigned regno, unsigned transp, struct fb_info *info) { struct leo_par *par = (struct leo_par *) info->par; - struct leo_lx_krn __iomem *lx_krn = par->lx_krn; + struct leo_lx_krn __iomem *lx_krn = par->lx_krn; unsigned long flags; u32 val; int i; @@ -407,7 +408,7 @@ static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl) leo_wait(lx_krn); for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { - switch (wi->wi_type) { + switch(wi->wi_type) { case FB_WID_DBL_8: j = (wi->wi_index & 0xf) + 0x40; break; @@ -452,12 +453,13 @@ static void leo_init_wids(struct fb_info *info) wi.wi_index = 1; wi.wi_values [0] = 0x30; leo_wid_put(info, &wl); + } static void leo_switch_from_graph(struct fb_info *info) { struct leo_par *par = (struct leo_par *) info->par; - struct leo_ld_ss0 __iomem *ss = par->ld_ss0; + struct leo_ld __iomem *ss = (struct leo_ld __iomem *) par->ld_ss0; unsigned long flags; u32 val; @@ -483,15 +485,21 @@ static void leo_switch_from_graph(struct fb_info *info) val = sbus_readl(&par->lc_ss0_usr->csr); } while (val & 0x20000000); - /* setup screen buffer for cfb_* functions */ - sbus_writel(1, &ss->wid); - sbus_writel(0x00ffffff, &ss->planemask); - sbus_writel(0x310b90, &ss->rop); - sbus_writel(0, &par->lc_ss0_usr->addrspace); - spin_unlock_irqrestore(&par->lock, flags); } +static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + /* We just use this to catch switches out of + * graphics mode. + */ + leo_switch_from_graph(info); + + if (var->xoffset || var->yoffset || var->vmode) + return -EINVAL; + return 0; +} + static void leo_init_hw(struct fb_info *info) { struct leo_par *par = (struct leo_par *) info->par; @@ -534,8 +542,7 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info, of_iounmap(&op->resource[0], info->screen_base, 0x800000); } -static int __devinit leo_probe(struct of_device *op, - const struct of_device_id *match) +static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match) { struct device_node *dp = op->node; struct fb_info *info; @@ -587,9 +594,8 @@ static int __devinit leo_probe(struct of_device *op, !info->screen_base) goto out_unmap_regs; - info->flags = FBINFO_DEFAULT; + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; info->fbops = &leo_ops; - info->pseudo_palette = par->clut_data; leo_init_wids(info); leo_init_hw(info); @@ -643,7 +649,7 @@ static int __devexit leo_remove(struct of_device *op) static struct of_device_id leo_match[] = { { - .name = "SUNW,leo", + .name = "leo", }, {}, }; diff --git a/trunk/drivers/video/modedb.c b/trunk/drivers/video/modedb.c index d3c3af53a290..473562191586 100644 --- a/trunk/drivers/video/modedb.c +++ b/trunk/drivers/video/modedb.c @@ -28,7 +28,6 @@ #endif const char *fb_mode_option; -EXPORT_SYMBOL_GPL(fb_mode_option); /* * Standard video mode definitions (taken from XFree86) @@ -591,7 +590,6 @@ int fb_find_mode(struct fb_var_screeninfo *var, "", (margins) ? " with margins" : "", (interlace) ? " interlaced" : ""); - memset(&cvt_mode, 0, sizeof(cvt_mode)); cvt_mode.xres = xres; cvt_mode.yres = yres; cvt_mode.refresh = (refresh) ? refresh : 60; diff --git a/trunk/drivers/video/pxafb.c b/trunk/drivers/video/pxafb.c index 7dcda187d9ba..274bc93ab7d8 100644 --- a/trunk/drivers/video/pxafb.c +++ b/trunk/drivers/video/pxafb.c @@ -573,8 +573,8 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; } else { - pal_desc = &fbi->dma_buff->pal_desc[pal]; - pal_desc_off = offsetof(struct pxafb_dma_buff, pal_desc[pal]); + pal_desc = &fbi->dma_buff->pal_desc[dma]; + pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]); pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; pal_desc->fidr = 0; @@ -1276,8 +1276,6 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) fbi->dma_buff_phys = fbi->map_dma; fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; - pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); - #ifdef CONFIG_FB_PXA_SMARTPANEL fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; fbi->n_smart_cmds = 0; diff --git a/trunk/fs/Kconfig.binfmt b/trunk/fs/Kconfig.binfmt index 3263084eef9e..55e8ee1900a5 100644 --- a/trunk/fs/Kconfig.binfmt +++ b/trunk/fs/Kconfig.binfmt @@ -42,7 +42,7 @@ config BINFMT_ELF_FDPIC config BINFMT_FLAT bool "Kernel support for flat binaries" - depends on !MMU && (!FRV || BROKEN) + depends on !MMU help Support uClinux FLAT format binaries. diff --git a/trunk/fs/afs/callback.c b/trunk/fs/afs/callback.c index 587ef5123cd8..a78d5b236bb1 100644 --- a/trunk/fs/afs/callback.c +++ b/trunk/fs/afs/callback.c @@ -8,7 +8,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Authors: David Woodhouse + * Authors: David Woodhouse * David Howells * */ diff --git a/trunk/fs/afs/inode.c b/trunk/fs/afs/inode.c index bb47217f6a18..08db82e1343a 100644 --- a/trunk/fs/afs/inode.c +++ b/trunk/fs/afs/inode.c @@ -8,7 +8,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * Authors: David Woodhouse + * Authors: David Woodhouse * David Howells * */ diff --git a/trunk/fs/afs/super.c b/trunk/fs/afs/super.c index 7e3faeef6818..4b572b801d8d 100644 --- a/trunk/fs/afs/super.c +++ b/trunk/fs/afs/super.c @@ -10,7 +10,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Authors: David Howells - * David Woodhouse + * David Woodhouse * */ diff --git a/trunk/fs/aio.c b/trunk/fs/aio.c index 0fb3117ddd93..b5253e77eb2f 100644 --- a/trunk/fs/aio.c +++ b/trunk/fs/aio.c @@ -591,6 +591,10 @@ static void use_mm(struct mm_struct *mm) atomic_inc(&mm->mm_count); tsk->mm = mm; tsk->active_mm = mm; + /* + * Note that on UML this *requires* PF_BORROWED_MM to be set, otherwise + * it won't work. Update it accordingly if you change it here + */ switch_mm(active_mm, mm, tsk); task_unlock(tsk); diff --git a/trunk/fs/binfmt_elf_fdpic.c b/trunk/fs/binfmt_elf_fdpic.c index d051a32e6270..ddd35d873391 100644 --- a/trunk/fs/binfmt_elf_fdpic.c +++ b/trunk/fs/binfmt_elf_fdpic.c @@ -390,7 +390,7 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, } /* expand the stack mapping to use up the entire allocation granule */ - fullsize = kobjsize((char *) current->mm->start_brk); + fullsize = ksize((char *) current->mm->start_brk); if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size, fullsize, 0, 0))) stack_size = fullsize; diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 2cb1acda3a82..3b40d45a3a16 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -548,7 +548,7 @@ static int load_flat_file(struct linux_binprm * bprm, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, 0); /* Remap to use all availabe slack region space */ if (realdatastart && (realdatastart < (unsigned long)-4096)) { - reallen = kobjsize((void *)realdatastart); + reallen = ksize((void *)realdatastart); if (reallen > len) { realdatastart = do_mremap(realdatastart, len, reallen, MREMAP_FIXED, realdatastart); @@ -600,7 +600,7 @@ static int load_flat_file(struct linux_binprm * bprm, PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0); /* Remap to use all availabe slack region space */ if (textpos && (textpos < (unsigned long) -4096)) { - reallen = kobjsize((void *)textpos); + reallen = ksize((void *)textpos); if (reallen > len) { textpos = do_mremap(textpos, len, reallen, MREMAP_FIXED, textpos); @@ -683,7 +683,7 @@ static int load_flat_file(struct linux_binprm * bprm, */ current->mm->start_brk = datapos + data_len + bss_len; current->mm->brk = (current->mm->start_brk + 3) & ~3; - current->mm->context.end_brk = memp + kobjsize((void *) memp) - stack_len; + current->mm->context.end_brk = memp + ksize((void *) memp) - stack_len; } if (flags & FLAT_FLAG_KTRACE) @@ -790,7 +790,7 @@ static int load_flat_file(struct linux_binprm * bprm, /* zero the BSS, BRK and stack areas */ memset((void*)(datapos + data_len), 0, bss_len + - (memp + kobjsize((void *) memp) - stack_len - /* end brk */ + (memp + ksize((void *) memp) - stack_len - /* end brk */ libinfo->lib_list[id].start_brk) + /* start brk */ stack_len); diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index 470c10ceb0fb..7d822fae7765 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -929,14 +928,9 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part) { struct module *owner = NULL; struct gendisk *disk; - int ret; + int ret = -ENXIO; int part; - ret = devcgroup_inode_permission(bdev->bd_inode, file->f_mode); - if (ret != 0) - return ret; - - ret = -ENXIO; file->f_mapping = bdev->bd_inode->i_mapping; lock_kernel(); disk = get_gendisk(bdev->bd_dev, &part); diff --git a/trunk/fs/cifs/CHANGES b/trunk/fs/cifs/CHANGES index 1f3465201fdf..28e3d5c5fcac 100644 --- a/trunk/fs/cifs/CHANGES +++ b/trunk/fs/cifs/CHANGES @@ -2,11 +2,6 @@ Version 1.53 ------------ DFS support added (Microsoft Distributed File System client support needed for referrals which enable a hierarchical name space among servers). -Disable temporary caching of mode bits to servers which do not support -storing of mode (e.g. Windows servers, when client mounts without cifsacl -mount option) and add new "dynperm" mount option to enable temporary caching -of mode (enable old behavior). Fix hang on mount caused when server crashes -tcp session during negotiate protocol. Version 1.52 ------------ diff --git a/trunk/fs/cifs/asn1.c b/trunk/fs/cifs/asn1.c index f58e41d3ba48..cb52cbbe45ff 100644 --- a/trunk/fs/cifs/asn1.c +++ b/trunk/fs/cifs/asn1.c @@ -186,11 +186,6 @@ asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len) } } } - - /* don't trust len bigger than ctx buffer */ - if (*len > ctx->end - ctx->pointer) - return 0; - return 1; } @@ -208,10 +203,6 @@ asn1_header_decode(struct asn1_ctx *ctx, if (!asn1_length_decode(ctx, &def, &len)) return 0; - /* primitive shall be definite, indefinite shall be constructed */ - if (*con == ASN1_PRI && !def) - return 0; - if (def) *eoc = ctx->pointer + len; else @@ -398,11 +389,6 @@ asn1_oid_decode(struct asn1_ctx *ctx, unsigned long *optr; size = eoc - ctx->pointer + 1; - - /* first subid actually encodes first two subids */ - if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) - return 0; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) return 0; diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index 86b4d5f405ae..5df93fd6303f 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -97,6 +97,9 @@ cifs_read_super(struct super_block *sb, void *data, { struct inode *inode; struct cifs_sb_info *cifs_sb; +#ifdef CONFIG_CIFS_DFS_UPCALL + int len; +#endif int rc = 0; /* BB should we make this contingent on mount parm? */ @@ -114,17 +117,15 @@ cifs_read_super(struct super_block *sb, void *data, * complex operation (mount), and in case of fail * just exit instead of doing mount and attempting * undo it if this copy fails?*/ - if (data) { - int len = strlen(data); - cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); - if (cifs_sb->mountdata == NULL) { - kfree(sb->s_fs_info); - sb->s_fs_info = NULL; - return -ENOMEM; - } - strncpy(cifs_sb->mountdata, data, len + 1); - cifs_sb->mountdata[len] = '\0'; + len = strlen(data); + cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); + if (cifs_sb->mountdata == NULL) { + kfree(sb->s_fs_info); + sb->s_fs_info = NULL; + return -ENOMEM; } + strncpy(cifs_sb->mountdata, data, len + 1); + cifs_sb->mountdata[len] = '\0'; #endif rc = cifs_mount(sb, cifs_sb, data, devname); diff --git a/trunk/fs/cifs/cifsglob.h b/trunk/fs/cifs/cifsglob.h index 9cfcf326ead3..08914053242b 100644 --- a/trunk/fs/cifs/cifsglob.h +++ b/trunk/fs/cifs/cifsglob.h @@ -333,6 +333,7 @@ struct cifsFileInfo { bool messageMode:1; /* for pipes: message vs byte mode */ atomic_t wrtPending; /* handle in use - defer close */ struct semaphore fh_sem; /* prevents reopen race after dead ses*/ + char *search_resume_name; /* BB removeme BB */ struct cifs_search_info srch_inf; }; @@ -625,7 +626,7 @@ GLOBAL_EXTERN atomic_t tcpSesAllocCount; GLOBAL_EXTERN atomic_t tcpSesReconnectCount; GLOBAL_EXTERN atomic_t tconInfoReconnectCount; -/* Various Debug counters */ +/* Various Debug counters to remove someday (BB) */ GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */ #ifdef CONFIG_CIFS_STATS2 GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ diff --git a/trunk/fs/cifs/cifspdu.h b/trunk/fs/cifs/cifspdu.h index 0f327c224da3..65d58b4e6a61 100644 --- a/trunk/fs/cifs/cifspdu.h +++ b/trunk/fs/cifs/cifspdu.h @@ -79,19 +79,6 @@ #define TRANS2_GET_DFS_REFERRAL 0x10 #define TRANS2_REPORT_DFS_INCOSISTENCY 0x11 -/* SMB Transact (Named Pipe) subcommand codes */ -#define TRANS_SET_NMPIPE_STATE 0x0001 -#define TRANS_RAW_READ_NMPIPE 0x0011 -#define TRANS_QUERY_NMPIPE_STATE 0x0021 -#define TRANS_QUERY_NMPIPE_INFO 0x0022 -#define TRANS_PEEK_NMPIPE 0x0023 -#define TRANS_TRANSACT_NMPIPE 0x0026 -#define TRANS_RAW_WRITE_NMPIPE 0x0031 -#define TRANS_READ_NMPIPE 0x0036 -#define TRANS_WRITE_NMPIPE 0x0037 -#define TRANS_WAIT_NMPIPE 0x0053 -#define TRANS_CALL_NMPIPE 0x0054 - /* NT Transact subcommand codes */ #define NT_TRANSACT_CREATE 0x01 #define NT_TRANSACT_IOCTL 0x02 @@ -341,13 +328,12 @@ #define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */ #define CREATE_NO_EA_KNOWLEDGE 0x00000200 #define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete - "open for recovery" flag - should - be zero in any case */ -#define CREATE_OPEN_FOR_RECOVERY 0x00000400 + open for recovery flag - should + be zero */ #define CREATE_RANDOM_ACCESS 0x00000800 #define CREATE_DELETE_ON_CLOSE 0x00001000 #define CREATE_OPEN_BY_ID 0x00002000 -#define CREATE_OPEN_BACKUP_INTENT 0x00004000 +#define CREATE_OPEN_BACKUP_INTN 0x00004000 #define CREATE_NO_COMPRESSION 0x00008000 #define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */ #define OPEN_REPARSE_POINT 0x00200000 @@ -736,6 +722,7 @@ typedef struct smb_com_tconx_rsp_ext { #define SMB_CSC_CACHE_AUTO_REINT 0x0004 #define SMB_CSC_CACHE_VDO 0x0008 #define SMB_CSC_NO_CACHING 0x000C + #define SMB_UNIQUE_FILE_NAME 0x0010 #define SMB_EXTENDED_SIGNATURES 0x0020 @@ -819,7 +806,7 @@ typedef struct smb_com_findclose_req { #define ICOUNT_MASK 0x00FF #define PIPE_READ_MODE 0x0100 #define NAMED_PIPE_TYPE 0x0400 -#define PIPE_END_POINT 0x4000 +#define PIPE_END_POINT 0x0800 #define BLOCKING_NAMED_PIPE 0x8000 typedef struct smb_com_open_req { /* also handles create */ diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 4511b708f0f3..9b8b4cfdf993 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -1728,7 +1728,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, { int rc = 0; LOCK_REQ *pSMB = NULL; -/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */ + LOCK_RSP *pSMBr = NULL; int bytes_returned; int timeout = 0; __u16 count; @@ -1739,6 +1739,8 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, if (rc) return rc; + pSMBr = (LOCK_RSP *)pSMB; /* BB removeme BB */ + if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) { timeout = CIFS_ASYNC_OP; /* no response expected */ pSMB->Timeout = 0; @@ -1772,7 +1774,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, if (waitFlag) { rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMB, &bytes_returned); + (struct smb_hdr *) pSMBr, &bytes_returned); cifs_small_buf_release(pSMB); } else { rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *)pSMB, @@ -3925,9 +3927,9 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, } ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals); - if (ref->VersionNumber != cpu_to_le16(3)) { + if (ref->VersionNumber != 3) { cERROR(1, ("Referrals of V%d version are not supported," - "should be V3", le16_to_cpu(ref->VersionNumber))); + "should be V3", ref->VersionNumber)); rc = -EINVAL; goto parse_DFS_referrals_exit; } @@ -3975,7 +3977,7 @@ parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr, if (rc) goto parse_DFS_referrals_exit; - ref += le16_to_cpu(ref->Size); + ref += ref->Size; } parse_DFS_referrals_exit: diff --git a/trunk/fs/cifs/connect.c b/trunk/fs/cifs/connect.c index e8fa46c7cff2..023434f72c15 100644 --- a/trunk/fs/cifs/connect.c +++ b/trunk/fs/cifs/connect.c @@ -653,7 +653,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) spin_lock(&GlobalMid_Lock); server->tcpStatus = CifsExiting; spin_unlock(&GlobalMid_Lock); - wake_up_all(&server->response_q); /* don't exit until kthread_stop is called */ set_current_state(TASK_UNINTERRUPTIBLE); @@ -2121,10 +2120,6 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; } - if ((volume_info.cifs_acl) && (volume_info.dynperm)) - cERROR(1, ("mount option dynperm ignored if cifsacl " - "mount option supported")); - tcon = find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, volume_info.username); diff --git a/trunk/fs/cifs/dir.c b/trunk/fs/cifs/dir.c index fb69c1fa85c9..f0b5b5f3dd2e 100644 --- a/trunk/fs/cifs/dir.c +++ b/trunk/fs/cifs/dir.c @@ -260,9 +260,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, buf, inode->i_sb, xid, &fileHandle); if (newinode) { - if (cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_DYNPERM) - newinode->i_mode = mode; + newinode->i_mode = mode; if ((oplock & CIFS_CREATE_ACTION) && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { diff --git a/trunk/fs/cifs/file.c b/trunk/fs/cifs/file.c index 0aac824371a5..8636cec2642c 100644 --- a/trunk/fs/cifs/file.c +++ b/trunk/fs/cifs/file.c @@ -546,6 +546,7 @@ int cifs_close(struct inode *inode, struct file *file) msleep(timeout); timeout *= 8; } + kfree(pSMBFile->search_resume_name); kfree(file->private_data); file->private_data = NULL; } else @@ -604,6 +605,12 @@ int cifs_closedir(struct inode *inode, struct file *file) else cifs_buf_release(ptmp); } + ptmp = pCFileStruct->search_resume_name; + if (ptmp) { + cFYI(1, ("closedir free resume name")); + pCFileStruct->search_resume_name = NULL; + kfree(ptmp); + } kfree(file->private_data); file->private_data = NULL; } diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 722be543ceec..129dbfe4dca7 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -418,7 +418,6 @@ int cifs_get_inode_info(struct inode **pinode, char *buf = NULL; bool adjustTZ = false; bool is_dfs_referral = false; - umode_t default_mode; pTcon = cifs_sb->tcon; cFYI(1, ("Getting info on %s", full_path)); @@ -531,42 +530,47 @@ int cifs_get_inode_info(struct inode **pinode, inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj; } - /* get default inode mode */ - if (attr & ATTR_DIRECTORY) - default_mode = cifs_sb->mnt_dir_mode; - else - default_mode = cifs_sb->mnt_file_mode; - - /* set permission bits */ - if (atomic_read(&cifsInfo->inUse) == 0 || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) - inode->i_mode = default_mode; - else { - /* just reenable write bits if !ATTR_READONLY */ - if ((inode->i_mode & S_IWUGO) == 0 && - (attr & ATTR_READONLY) == 0) - inode->i_mode |= (S_IWUGO & default_mode); - inode->i_mode &= ~S_IFMT; - } - /* clear write bits if ATTR_READONLY is set */ - if (attr & ATTR_READONLY) - inode->i_mode &= ~S_IWUGO; - - /* set inode type */ - if ((attr & ATTR_SYSTEM) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { - /* no need to fix endianness on 0 */ - if (pfindData->EndOfFile == 0) - inode->i_mode |= S_IFIFO; - else if (decode_sfu_inode(inode, - le64_to_cpu(pfindData->EndOfFile), - full_path, cifs_sb, xid)) - cFYI(1, ("unknown SFU file type\n")); + /* set default mode. will override for dirs below */ + if (atomic_read(&cifsInfo->inUse) == 0) + /* new inode, can safely set these fields */ + inode->i_mode = cifs_sb->mnt_file_mode; + else /* since we set the inode type below we need to mask off + to avoid strange results if type changes and both + get orred in */ + inode->i_mode &= ~S_IFMT; +/* if (attr & ATTR_REPARSE) */ + /* We no longer handle these as symlinks because we could not + follow them due to the absolute path with drive letter */ + if (attr & ATTR_DIRECTORY) { + /* override default perms since we do not do byte range locking + on dirs */ + inode->i_mode = cifs_sb->mnt_dir_mode; + inode->i_mode |= S_IFDIR; + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (cifsInfo->cifsAttrs & ATTR_SYSTEM) && + /* No need to le64 convert size of zero */ + (pfindData->EndOfFile == 0)) { + inode->i_mode = cifs_sb->mnt_file_mode; + inode->i_mode |= S_IFIFO; +/* BB Finish for SFU style symlinks and devices */ + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (cifsInfo->cifsAttrs & ATTR_SYSTEM)) { + if (decode_sfu_inode(inode, le64_to_cpu(pfindData->EndOfFile), + full_path, cifs_sb, xid)) + cFYI(1, ("Unrecognized sfu inode type")); + + cFYI(1, ("sfu mode 0%o", inode->i_mode)); } else { - if (attr & ATTR_DIRECTORY) - inode->i_mode |= S_IFDIR; - else - inode->i_mode |= S_IFREG; + inode->i_mode |= S_IFREG; + /* treat dos attribute of read-only as read-only mode eg 555 */ + if (cifsInfo->cifsAttrs & ATTR_READONLY) + inode->i_mode &= ~(S_IWUGO); + else if ((inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been */ + /* changed on server -- set any w bits */ + /* allowed by mnt_file_mode */ + inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); + /* BB add code to validate if device or weird share or device type? */ } spin_lock(&inode->i_lock); @@ -1015,11 +1019,8 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) CIFS_MOUNT_MAP_SPECIAL_CHR); } if (direntry->d_inode) { - if (cifs_sb->mnt_cifs_flags & - CIFS_MOUNT_DYNPERM) - direntry->d_inode->i_mode = - (mode | S_IFDIR); - + direntry->d_inode->i_mode = mode; + direntry->d_inode->i_mode |= S_IFDIR; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { direntry->d_inode->i_uid = @@ -1546,26 +1547,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) } else goto cifs_setattr_exit; } - - /* - * Without unix extensions we can't send ownership changes to the - * server, so silently ignore them. This is consistent with how - * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With - * CIFSACL support + proper Windows to Unix idmapping, we may be - * able to support this in the future. - */ - if (!pTcon->unix_ext && - !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { - attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); - } else { - if (attrs->ia_valid & ATTR_UID) { - cFYI(1, ("UID changed to %d", attrs->ia_uid)); - uid = attrs->ia_uid; - } - if (attrs->ia_valid & ATTR_GID) { - cFYI(1, ("GID changed to %d", attrs->ia_gid)); - gid = attrs->ia_gid; - } + if (attrs->ia_valid & ATTR_UID) { + cFYI(1, ("UID changed to %d", attrs->ia_uid)); + uid = attrs->ia_uid; + } + if (attrs->ia_valid & ATTR_GID) { + cFYI(1, ("GID changed to %d", attrs->ia_gid)); + gid = attrs->ia_gid; } time_buf.Attributes = 0; @@ -1575,7 +1563,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) attrs->ia_valid &= ~ATTR_MODE; if (attrs->ia_valid & ATTR_MODE) { - cFYI(1, ("Mode changed to 0%o", attrs->ia_mode)); + cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode)); mode = attrs->ia_mode; } @@ -1590,18 +1578,18 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) #ifdef CONFIG_CIFS_EXPERIMENTAL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) rc = mode_to_acl(inode, full_path, mode); - else + else if ((mode & S_IWUGO) == 0) { +#else + if ((mode & S_IWUGO) == 0) { #endif - if (((mode & S_IWUGO) == 0) && - (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { - set_dosattr = true; - time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs | - ATTR_READONLY); - /* fix up mode if we're not using dynperm */ - if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) - attrs->ia_mode = inode->i_mode & ~S_IWUGO; - } else if ((mode & S_IWUGO) && - (cifsInode->cifsAttrs & ATTR_READONLY)) { + /* not writeable */ + if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { + set_dosattr = true; + time_buf.Attributes = + cpu_to_le32(cifsInode->cifsAttrs | + ATTR_READONLY); + } + } else if (cifsInode->cifsAttrs & ATTR_READONLY) { /* If file is readonly on server, we would not be able to write to it - so if any write bit is enabled for user or group or other we @@ -1612,20 +1600,6 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) /* Windows ignores set to zero */ if (time_buf.Attributes == 0) time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); - - /* reset local inode permissions to normal */ - if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { - attrs->ia_mode &= ~(S_IALLUGO); - if (S_ISDIR(inode->i_mode)) - attrs->ia_mode |= - cifs_sb->mnt_dir_mode; - else - attrs->ia_mode |= - cifs_sb->mnt_file_mode; - } - } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { - /* ignore mode change - ATTR_READONLY hasn't changed */ - attrs->ia_valid &= ~ATTR_MODE; } } diff --git a/trunk/fs/cifs/misc.c b/trunk/fs/cifs/misc.c index 4b17f8fe3157..1d69b8014e0b 100644 --- a/trunk/fs/cifs/misc.c +++ b/trunk/fs/cifs/misc.c @@ -519,7 +519,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) pnotify = (struct file_notify_information *) ((char *)&pSMBr->hdr.Protocol + data_offset); cFYI(1, ("dnotify on %s Action: 0x%x", - pnotify->FileName, pnotify->Action)); + pnotify->FileName, + pnotify->Action)); /* BB removeme BB */ /* cifs_dump_mem("Rcvd notify Data: ",buf, sizeof(struct smb_hdr)+60); */ return true; diff --git a/trunk/fs/cifs/readdir.c b/trunk/fs/cifs/readdir.c index 83f306954883..713c25110197 100644 --- a/trunk/fs/cifs/readdir.c +++ b/trunk/fs/cifs/readdir.c @@ -132,7 +132,6 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, __u32 attr; __u64 allocation_size; __u64 end_of_file; - umode_t default_mode; /* save mtime and size */ local_mtime = tmp_inode->i_mtime; @@ -188,54 +187,48 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, if (atomic_read(&cifsInfo->inUse) == 0) { tmp_inode->i_uid = cifs_sb->mnt_uid; tmp_inode->i_gid = cifs_sb->mnt_gid; - } - - if (attr & ATTR_DIRECTORY) - default_mode = cifs_sb->mnt_dir_mode; - else - default_mode = cifs_sb->mnt_file_mode; - - /* set initial permissions */ - if ((atomic_read(&cifsInfo->inUse) == 0) || - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) - tmp_inode->i_mode = default_mode; - else { - /* just reenable write bits if !ATTR_READONLY */ - if ((tmp_inode->i_mode & S_IWUGO) == 0 && - (attr & ATTR_READONLY) == 0) - tmp_inode->i_mode |= (S_IWUGO & default_mode); - + /* set default mode. will override for dirs below */ + tmp_inode->i_mode = cifs_sb->mnt_file_mode; + } else { + /* mask off the type bits since it gets set + below and we do not want to get two type + bits set */ tmp_inode->i_mode &= ~S_IFMT; } - /* clear write bits if ATTR_READONLY is set */ - if (attr & ATTR_READONLY) - tmp_inode->i_mode &= ~S_IWUGO; - - /* set inode type */ - if ((attr & ATTR_SYSTEM) && - (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) { + if (attr & ATTR_DIRECTORY) { + *pobject_type = DT_DIR; + /* override default perms since we do not lock dirs */ + if (atomic_read(&cifsInfo->inUse) == 0) + tmp_inode->i_mode = cifs_sb->mnt_dir_mode; + tmp_inode->i_mode |= S_IFDIR; + } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) && + (attr & ATTR_SYSTEM)) { if (end_of_file == 0) { - tmp_inode->i_mode |= S_IFIFO; *pobject_type = DT_FIFO; + tmp_inode->i_mode |= S_IFIFO; } else { - /* - * trying to get the type can be slow, so just call - * this a regular file for now, and mark for reval - */ - tmp_inode->i_mode |= S_IFREG; + /* rather than get the type here, we mark the + inode as needing revalidate and get the real type + (blk vs chr vs. symlink) later ie in lookup */ *pobject_type = DT_REG; + tmp_inode->i_mode |= S_IFREG; cifsInfo->time = 0; } +/* we no longer mark these because we could not follow them */ +/* } else if (attr & ATTR_REPARSE) { + *pobject_type = DT_LNK; + tmp_inode->i_mode |= S_IFLNK; */ } else { - if (attr & ATTR_DIRECTORY) { - tmp_inode->i_mode |= S_IFDIR; - *pobject_type = DT_DIR; - } else { - tmp_inode->i_mode |= S_IFREG; - *pobject_type = DT_REG; - } - } + *pobject_type = DT_REG; + tmp_inode->i_mode |= S_IFREG; + if (attr & ATTR_READONLY) + tmp_inode->i_mode &= ~(S_IWUGO); + else if ((tmp_inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been changed on */ + /* server -- set any w bits allowed by mnt_file_mode */ + tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); + } /* could add code here - to validate if device or weird share type? */ /* can not fill in nlink here as in qpathinfo version and Unx search */ if (atomic_read(&cifsInfo->inUse) == 0) @@ -682,6 +675,8 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, cifsFile->invalidHandle = true; CIFSFindClose(xid, pTcon, cifsFile->netfid); } + kfree(cifsFile->search_resume_name); + cifsFile->search_resume_name = NULL; if (cifsFile->srch_inf.ntwrk_buf_start) { cFYI(1, ("freeing SMB ff cache buf on search rewind")); if (cifsFile->srch_inf.smallBuf) @@ -1048,7 +1043,9 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) } /* else { cifsFile->invalidHandle = true; CIFSFindClose(xid, pTcon, cifsFile->netfid); - } */ + } + kfree(cifsFile->search_resume_name); + cifsFile->search_resume_name = NULL; */ rc = find_cifs_entry(xid, pTcon, file, ¤t_entry, &num_to_fill); diff --git a/trunk/fs/ecryptfs/ecryptfs_kernel.h b/trunk/fs/ecryptfs/ecryptfs_kernel.h index c15c25745e05..951ee33a022d 100644 --- a/trunk/fs/ecryptfs/ecryptfs_kernel.h +++ b/trunk/fs/ecryptfs/ecryptfs_kernel.h @@ -660,6 +660,8 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, struct ecryptfs_auth_tok **auth_tok, char *sig); +int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, + int num_zeros); int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, loff_t offset, size_t size); int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, diff --git a/trunk/fs/ecryptfs/read_write.c b/trunk/fs/ecryptfs/read_write.c index 75c2ea9fee35..ebf55150be56 100644 --- a/trunk/fs/ecryptfs/read_write.c +++ b/trunk/fs/ecryptfs/read_write.c @@ -157,6 +157,20 @@ int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset, ecryptfs_page_idx, rc); goto out; } + if (start_offset_in_page) { + /* Read in the page from the lower + * into the eCryptfs inode page cache, + * decrypting */ + rc = ecryptfs_decrypt_page(ecryptfs_page); + if (rc) { + printk(KERN_ERR "%s: Error decrypting " + "page; rc = [%d]\n", + __func__, rc); + ClearPageUptodate(ecryptfs_page); + page_cache_release(ecryptfs_page); + goto out; + } + } ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); /* @@ -335,6 +349,14 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, ecryptfs_page_idx, rc); goto out; } + rc = ecryptfs_decrypt_page(ecryptfs_page); + if (rc) { + printk(KERN_ERR "%s: Error decrypting " + "page; rc = [%d]\n", __func__, rc); + ClearPageUptodate(ecryptfs_page); + page_cache_release(ecryptfs_page); + goto out; + } ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0); memcpy((data + data_offset), ((char *)ecryptfs_page_virt + start_offset_in_page), diff --git a/trunk/fs/ext3/resize.c b/trunk/fs/ext3/resize.c index 77278e947e94..28cfd0b40527 100644 --- a/trunk/fs/ext3/resize.c +++ b/trunk/fs/ext3/resize.c @@ -580,8 +580,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, } blk = EXT3_SB(sb)->s_sbh->b_blocknr + 1 + EXT3_SB(sb)->s_gdb_count; - data = (__le32 *)dind->b_data + (EXT3_SB(sb)->s_gdb_count % - EXT3_ADDR_PER_BLOCK(sb)); + data = (__le32 *)dind->b_data + EXT3_SB(sb)->s_gdb_count; end = (__le32 *)dind->b_data + EXT3_ADDR_PER_BLOCK(sb); /* Get each reserved primary GDT block and verify it holds backups */ diff --git a/trunk/fs/ext4/balloc.c b/trunk/fs/ext4/balloc.c index 9cc80b9cc8d8..30494c5da843 100644 --- a/trunk/fs/ext4/balloc.c +++ b/trunk/fs/ext4/balloc.c @@ -43,46 +43,6 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr, } -static int ext4_block_in_group(struct super_block *sb, ext4_fsblk_t block, - ext4_group_t block_group) -{ - ext4_group_t actual_group; - ext4_get_group_no_and_offset(sb, block, &actual_group, 0); - if (actual_group == block_group) - return 1; - return 0; -} - -static int ext4_group_used_meta_blocks(struct super_block *sb, - ext4_group_t block_group) -{ - ext4_fsblk_t tmp; - struct ext4_sb_info *sbi = EXT4_SB(sb); - /* block bitmap, inode bitmap, and inode table blocks */ - int used_blocks = sbi->s_itb_per_group + 2; - - if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { - struct ext4_group_desc *gdp; - struct buffer_head *bh; - - gdp = ext4_get_group_desc(sb, block_group, &bh); - if (!ext4_block_in_group(sb, ext4_block_bitmap(sb, gdp), - block_group)) - used_blocks--; - - if (!ext4_block_in_group(sb, ext4_inode_bitmap(sb, gdp), - block_group)) - used_blocks--; - - tmp = ext4_inode_table(sb, gdp); - for (; tmp < ext4_inode_table(sb, gdp) + - sbi->s_itb_per_group; tmp++) { - if (!ext4_block_in_group(sb, tmp, block_group)) - used_blocks -= 1; - } - } - return used_blocks; -} /* Initializes an uninitialized block bitmap if given, and returns the * number of blocks free in the group. */ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, @@ -145,34 +105,20 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, free_blocks = group_blocks - bit_max; if (bh) { - ext4_fsblk_t start, tmp; - int flex_bg = 0; + ext4_fsblk_t start; for (bit = 0; bit < bit_max; bit++) ext4_set_bit(bit, bh->b_data); start = ext4_group_first_block_no(sb, block_group); - if (EXT4_HAS_INCOMPAT_FEATURE(sb, - EXT4_FEATURE_INCOMPAT_FLEX_BG)) - flex_bg = 1; - /* Set bits for block and inode bitmaps, and inode table */ - tmp = ext4_block_bitmap(sb, gdp); - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) - ext4_set_bit(tmp - start, bh->b_data); - - tmp = ext4_inode_bitmap(sb, gdp); - if (!flex_bg || ext4_block_in_group(sb, tmp, block_group)) - ext4_set_bit(tmp - start, bh->b_data); - - tmp = ext4_inode_table(sb, gdp); - for (; tmp < ext4_inode_table(sb, gdp) + - sbi->s_itb_per_group; tmp++) { - if (!flex_bg || - ext4_block_in_group(sb, tmp, block_group)) - ext4_set_bit(tmp - start, bh->b_data); - } + ext4_set_bit(ext4_block_bitmap(sb, gdp) - start, bh->b_data); + ext4_set_bit(ext4_inode_bitmap(sb, gdp) - start, bh->b_data); + for (bit = (ext4_inode_table(sb, gdp) - start), + bit_max = bit + sbi->s_itb_per_group; bit < bit_max; bit++) + ext4_set_bit(bit, bh->b_data); + /* * Also if the number of blocks within the group is * less than the blocksize * 8 ( which is the size @@ -180,7 +126,8 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh, */ mark_bitmap_end(group_blocks, sb->s_blocksize * 8, bh->b_data); } - return free_blocks - ext4_group_used_meta_blocks(sb, block_group); + + return free_blocks - sbi->s_itb_per_group - 2; } diff --git a/trunk/fs/ext4/mballoc.c b/trunk/fs/ext4/mballoc.c index c9900aade150..873ad9b3418c 100644 --- a/trunk/fs/ext4/mballoc.c +++ b/trunk/fs/ext4/mballoc.c @@ -2745,6 +2745,8 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, sbi = EXT4_SB(sb); es = sbi->s_es; + ext4_debug("using block group %lu(%d)\n", ac->ac_b_ex.fe_group, + gdp->bg_free_blocks_count); err = -EIO; bitmap_bh = read_block_bitmap(sb, ac->ac_b_ex.fe_group); @@ -2760,9 +2762,6 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, if (!gdp) goto out_err; - ext4_debug("using block group %lu(%d)\n", ac->ac_b_ex.fe_group, - gdp->bg_free_blocks_count); - err = ext4_journal_get_write_access(handle, gdp_bh); if (err) goto out_err; @@ -3095,7 +3094,8 @@ static void ext4_mb_use_inode_pa(struct ext4_allocation_context *ac, static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac, struct ext4_prealloc_space *pa) { - unsigned int len = ac->ac_o_ex.fe_len; + unsigned len = ac->ac_o_ex.fe_len; + ext4_get_group_no_and_offset(ac->ac_sb, pa->pa_pstart, &ac->ac_b_ex.fe_group, &ac->ac_b_ex.fe_start); diff --git a/trunk/fs/ext4/resize.c b/trunk/fs/ext4/resize.c index 9ecb92f68543..9f086a6a472b 100644 --- a/trunk/fs/ext4/resize.c +++ b/trunk/fs/ext4/resize.c @@ -563,8 +563,7 @@ static int reserve_backup_gdb(handle_t *handle, struct inode *inode, } blk = EXT4_SB(sb)->s_sbh->b_blocknr + 1 + EXT4_SB(sb)->s_gdb_count; - data = (__le32 *)dind->b_data + (EXT4_SB(sb)->s_gdb_count % - EXT4_ADDR_PER_BLOCK(sb)); + data = (__le32 *)dind->b_data + EXT4_SB(sb)->s_gdb_count; end = (__le32 *)dind->b_data + EXT4_ADDR_PER_BLOCK(sb); /* Get each reserved primary GDT block and verify it holds backups */ diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index cb96f127c366..09d9359c8055 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -671,7 +671,6 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) unsigned long def_mount_opts; struct super_block *sb = vfs->mnt_sb; struct ext4_sb_info *sbi = EXT4_SB(sb); - journal_t *journal = sbi->s_journal; struct ext4_super_block *es = sbi->s_es; def_mount_opts = le32_to_cpu(es->s_default_mount_opts); @@ -730,15 +729,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) seq_printf(seq, ",commit=%u", (unsigned) (sbi->s_commit_interval / HZ)); } - /* - * We're changing the default of barrier mount option, so - * let's always display its mount state so it's clear what its - * status is. - */ - seq_puts(seq, ",barrier="); - seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); - if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) - seq_puts(seq, ",journal_async_commit"); + if (test_opt(sb, BARRIER)) + seq_puts(seq, ",barrier=1"); if (test_opt(sb, NOBH)) seq_puts(seq, ",nobh"); if (!test_opt(sb, EXTENTS)) @@ -1915,7 +1907,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) sbi->s_resgid = le16_to_cpu(es->s_def_resgid); set_opt(sbi->s_mount_opt, RESERVATION); - set_opt(sbi->s_mount_opt, BARRIER); /* * turn on extents feature by default in ext4 filesystem @@ -2198,29 +2189,6 @@ static int ext4_fill_super (struct super_block *sb, void *data, int silent) EXT4_HAS_COMPAT_FEATURE(sb, EXT4_FEATURE_COMPAT_HAS_JOURNAL)) { if (ext4_load_journal(sb, es, journal_devnum)) goto failed_mount3; - if (!(sb->s_flags & MS_RDONLY) && - EXT4_SB(sb)->s_journal->j_failed_commit) { - printk(KERN_CRIT "EXT4-fs error (device %s): " - "ext4_fill_super: Journal transaction " - "%u is corrupt\n", sb->s_id, - EXT4_SB(sb)->s_journal->j_failed_commit); - if (test_opt (sb, ERRORS_RO)) { - printk (KERN_CRIT - "Mounting filesystem read-only\n"); - sb->s_flags |= MS_RDONLY; - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - } - if (test_opt(sb, ERRORS_PANIC)) { - EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; - es->s_state |= cpu_to_le16(EXT4_ERROR_FS); - ext4_commit_super(sb, es, 1); - printk(KERN_CRIT - "EXT4-fs (device %s): mount failed\n", - sb->s_id); - goto failed_mount4; - } - } } else if (journal_inum) { if (ext4_create_journal(sb, es, journal_inum)) goto failed_mount3; diff --git a/trunk/fs/fat/file.c b/trunk/fs/fat/file.c index 771326b8047e..27cc1164ec36 100644 --- a/trunk/fs/fat/file.c +++ b/trunk/fs/fat/file.c @@ -257,34 +257,26 @@ int fat_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) } EXPORT_SYMBOL_GPL(fat_getattr); -static int fat_sanitize_mode(const struct msdos_sb_info *sbi, - struct inode *inode, umode_t *mode_ptr) +static int fat_check_mode(const struct msdos_sb_info *sbi, struct inode *inode, + mode_t mode) { - mode_t mask, perm; + mode_t mask, req = mode & ~S_IFMT; - /* - * Note, the basic check is already done by a caller of - * (attr->ia_mode & ~MSDOS_VALID_MODE) - */ - - if (S_ISREG(inode->i_mode)) + if (S_ISREG(mode)) mask = sbi->options.fs_fmask; else mask = sbi->options.fs_dmask; - perm = *mode_ptr & ~(S_IFMT | mask); - /* * Of the r and x bits, all (subject to umask) must be present. Of the * w bits, either all (subject to umask) or none must be present. */ - if ((perm & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) + req &= ~mask; + if ((req & (S_IRUGO | S_IXUGO)) != (inode->i_mode & (S_IRUGO|S_IXUGO))) return -EPERM; - if ((perm & S_IWUGO) && ((perm & S_IWUGO) != (S_IWUGO & ~mask))) + if ((req & S_IWUGO) && ((req & S_IWUGO) != (S_IWUGO & ~mask))) return -EPERM; - *mode_ptr &= S_IFMT | perm; - return 0; } @@ -307,7 +299,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) { struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); struct inode *inode = dentry->d_inode; - int error = 0; + int mask, error = 0; unsigned int ia_valid; lock_kernel(); @@ -340,13 +332,12 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) error = 0; goto out; } - if (((attr->ia_valid & ATTR_UID) && (attr->ia_uid != sbi->options.fs_uid)) || ((attr->ia_valid & ATTR_GID) && (attr->ia_gid != sbi->options.fs_gid)) || ((attr->ia_valid & ATTR_MODE) && - (attr->ia_mode & ~MSDOS_VALID_MODE))) + fat_check_mode(sbi, inode, attr->ia_mode) < 0)) error = -EPERM; if (error) { @@ -355,16 +346,15 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr) goto out; } - /* - * We don't return -EPERM here. Yes, strange, but this is too - * old behavior. - */ - if (attr->ia_valid & ATTR_MODE) { - if (fat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0) - attr->ia_valid &= ~ATTR_MODE; - } - error = inode_setattr(inode, attr); + if (error) + goto out; + + if (S_ISDIR(inode->i_mode)) + mask = sbi->options.fs_dmask; + else + mask = sbi->options.fs_fmask; + inode->i_mode &= S_IFMT | (S_IRWXUGO & ~mask); out: unlock_kernel(); return error; diff --git a/trunk/fs/jbd2/commit.c b/trunk/fs/jbd2/commit.c index a2ed72f7ceee..4d99685fdce4 100644 --- a/trunk/fs/jbd2/commit.c +++ b/trunk/fs/jbd2/commit.c @@ -168,7 +168,6 @@ static int journal_submit_commit_record(journal_t *journal, spin_unlock(&journal->j_state_lock); /* And try again, without the barrier */ - lock_buffer(bh); set_buffer_uptodate(bh); set_buffer_dirty(bh); ret = submit_bh(WRITE, bh); diff --git a/trunk/fs/jbd2/recovery.c b/trunk/fs/jbd2/recovery.c index 058f50f65b76..5d0405a9e7ca 100644 --- a/trunk/fs/jbd2/recovery.c +++ b/trunk/fs/jbd2/recovery.c @@ -344,7 +344,6 @@ static int calc_chksums(journal_t *journal, struct buffer_head *bh, *crc32_sum = crc32_be(*crc32_sum, (void *)obh->b_data, obh->b_size); } - put_bh(obh); } return 0; } @@ -611,8 +610,9 @@ static int do_one_pass(journal_t *journal, chksum_err = chksum_seen = 0; if (info->end_transaction) { - journal->j_failed_commit = - info->end_transaction; + printk(KERN_ERR "JBD: Transaction %u " + "found to be corrupt.\n", + next_commit_ID - 1); brelse(bh); break; } @@ -643,8 +643,10 @@ static int do_one_pass(journal_t *journal, if (!JBD2_HAS_INCOMPAT_FEATURE(journal, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT)){ - journal->j_failed_commit = - next_commit_ID; + printk(KERN_ERR + "JBD: Transaction %u " + "found to be corrupt.\n", + next_commit_ID); brelse(bh); break; } diff --git a/trunk/fs/libfs.c b/trunk/fs/libfs.c index 892d41cb3382..b004dfadd891 100644 --- a/trunk/fs/libfs.c +++ b/trunk/fs/libfs.c @@ -528,23 +528,6 @@ ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, return count; } -ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, - const void *from, size_t available) -{ - loff_t pos = *ppos; - - if (pos < 0) - return -EINVAL; - if (pos >= available) - return 0; - if (count > available - pos) - count = available - pos; - memcpy(to, from + pos, count); - *ppos = pos + count; - - return count; -} - /* * Transaction based IO. * The file expects a single write which triggers the transaction, and then @@ -817,7 +800,6 @@ EXPORT_SYMBOL(simple_statfs); EXPORT_SYMBOL(simple_sync_file); EXPORT_SYMBOL(simple_unlink); EXPORT_SYMBOL(simple_read_from_buffer); -EXPORT_SYMBOL(memory_read_from_buffer); EXPORT_SYMBOL(simple_transaction_get); EXPORT_SYMBOL(simple_transaction_read); EXPORT_SYMBOL(simple_transaction_release); diff --git a/trunk/fs/proc/array.c b/trunk/fs/proc/array.c index 797d775e0354..9e3b8c33c24b 100644 --- a/trunk/fs/proc/array.c +++ b/trunk/fs/proc/array.c @@ -288,7 +288,7 @@ static void render_cap_t(struct seq_file *m, const char *header, seq_printf(m, "%s", header); CAP_FOR_EACH_U32(__capi) { seq_printf(m, "%08x", - a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]); + a->cap[(_LINUX_CAPABILITY_U32S-1) - __capi]); } seq_printf(m, "\n"); } diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 3b455371e7ff..c447e0743a3c 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -127,25 +127,6 @@ struct pid_entry { NULL, &proc_single_file_operations, \ { .proc_show = &proc_##OTYPE } ) -/* - * Count the number of hardlinks for the pid_entry table, excluding the . - * and .. links. - */ -static unsigned int pid_entry_count_dirs(const struct pid_entry *entries, - unsigned int n) -{ - unsigned int i; - unsigned int count; - - count = 0; - for (i = 0; i < n; ++i) { - if (S_ISDIR(entries[i].mode)) - ++count; - } - - return count; -} - int maps_protect; EXPORT_SYMBOL(maps_protect); @@ -2604,9 +2585,10 @@ static struct dentry *proc_pid_instantiate(struct inode *dir, inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; inode->i_flags|=S_IMMUTABLE; - - inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff, - ARRAY_SIZE(tgid_base_stuff)); + inode->i_nlink = 5; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; +#endif dentry->d_op = &pid_dentry_operations; @@ -2834,9 +2816,10 @@ static struct dentry *proc_task_instantiate(struct inode *dir, inode->i_op = &proc_tid_base_inode_operations; inode->i_fop = &proc_tid_base_operations; inode->i_flags|=S_IMMUTABLE; - - inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff, - ARRAY_SIZE(tid_base_stuff)); + inode->i_nlink = 4; +#ifdef CONFIG_SECURITY + inode->i_nlink += 1; +#endif dentry->d_op = &pid_dentry_operations; diff --git a/trunk/fs/proc/proc_misc.c b/trunk/fs/proc/proc_misc.c index 7e277f2ad466..32dc14cd8900 100644 --- a/trunk/fs/proc/proc_misc.c +++ b/trunk/fs/proc/proc_misc.c @@ -716,7 +716,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, pfn = src / KPMSIZE; count = min_t(size_t, count, (max_pfn * KPMSIZE) - src); if (src & KPMMASK || count & KPMMASK) - return -EINVAL; + return -EIO; while (count > 0) { ppage = NULL; @@ -726,7 +726,7 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf, if (!ppage) pcount = 0; else - pcount = page_mapcount(ppage); + pcount = atomic_read(&ppage->_count); if (put_user(pcount, out++)) { ret = -EFAULT; @@ -782,7 +782,7 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf, pfn = src / KPMSIZE; count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src); if (src & KPMMASK || count & KPMMASK) - return -EINVAL; + return -EIO; while (count > 0) { ppage = NULL; diff --git a/trunk/fs/proc/task_mmu.c b/trunk/fs/proc/task_mmu.c index ab8ccc9d14ff..88717c0f941b 100644 --- a/trunk/fs/proc/task_mmu.c +++ b/trunk/fs/proc/task_mmu.c @@ -315,9 +315,9 @@ struct mem_size_stats { }; static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, - struct mm_walk *walk) + void *private) { - struct mem_size_stats *mss = walk->private; + struct mem_size_stats *mss = private; struct vm_area_struct *vma = mss->vma; pte_t *pte, ptent; spinlock_t *ptl; @@ -365,21 +365,19 @@ static int smaps_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, return 0; } +static struct mm_walk smaps_walk = { .pmd_entry = smaps_pte_range }; + static int show_smap(struct seq_file *m, void *v) { struct vm_area_struct *vma = v; struct mem_size_stats mss; int ret; - struct mm_walk smaps_walk = { - .pmd_entry = smaps_pte_range, - .mm = vma->vm_mm, - .private = &mss, - }; memset(&mss, 0, sizeof mss); mss.vma = vma; if (vma->vm_mm && !is_vm_hugetlb_page(vma)) - walk_page_range(vma->vm_start, vma->vm_end, &smaps_walk); + walk_page_range(vma->vm_mm, vma->vm_start, vma->vm_end, + &smaps_walk, &mss); ret = show_map(m, v); if (ret) @@ -428,9 +426,9 @@ const struct file_operations proc_smaps_operations = { }; static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, - unsigned long end, struct mm_walk *walk) + unsigned long end, void *private) { - struct vm_area_struct *vma = walk->private; + struct vm_area_struct *vma = private; pte_t *pte, ptent; spinlock_t *ptl; struct page *page; @@ -454,6 +452,8 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, return 0; } +static struct mm_walk clear_refs_walk = { .pmd_entry = clear_refs_pte_range }; + static ssize_t clear_refs_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { @@ -476,17 +476,11 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, return -ESRCH; mm = get_task_mm(task); if (mm) { - static struct mm_walk clear_refs_walk; - memset(&clear_refs_walk, 0, sizeof(clear_refs_walk)); - clear_refs_walk.pmd_entry = clear_refs_pte_range; - clear_refs_walk.mm = mm; down_read(&mm->mmap_sem); - for (vma = mm->mmap; vma; vma = vma->vm_next) { - clear_refs_walk.private = vma; + for (vma = mm->mmap; vma; vma = vma->vm_next) if (!is_vm_hugetlb_page(vma)) - walk_page_range(vma->vm_start, vma->vm_end, - &clear_refs_walk); - } + walk_page_range(mm, vma->vm_start, vma->vm_end, + &clear_refs_walk, vma); flush_tlb_mm(mm); up_read(&mm->mmap_sem); mmput(mm); @@ -502,7 +496,7 @@ const struct file_operations proc_clear_refs_operations = { }; struct pagemapread { - u64 __user *out, *end; + char __user *out, *end; }; #define PM_ENTRY_BYTES sizeof(u64) @@ -525,18 +519,28 @@ struct pagemapread { static int add_to_pagemap(unsigned long addr, u64 pfn, struct pagemapread *pm) { + /* + * Make sure there's room in the buffer for an + * entire entry. Otherwise, only copy part of + * the pfn. + */ + if (pm->out + PM_ENTRY_BYTES >= pm->end) { + if (copy_to_user(pm->out, &pfn, pm->end - pm->out)) + return -EFAULT; + pm->out = pm->end; + return PM_END_OF_BUFFER; + } + if (put_user(pfn, pm->out)) return -EFAULT; - pm->out++; - if (pm->out >= pm->end) - return PM_END_OF_BUFFER; + pm->out += PM_ENTRY_BYTES; return 0; } static int pagemap_pte_hole(unsigned long start, unsigned long end, - struct mm_walk *walk) + void *private) { - struct pagemapread *pm = walk->private; + struct pagemapread *pm = private; unsigned long addr; int err = 0; for (addr = start; addr < end; addr += PAGE_SIZE) { @@ -553,45 +557,24 @@ static u64 swap_pte_to_pagemap_entry(pte_t pte) return swp_type(e) | (swp_offset(e) << MAX_SWAPFILES_SHIFT); } -static unsigned long pte_to_pagemap_entry(pte_t pte) -{ - unsigned long pme = 0; - if (is_swap_pte(pte)) - pme = PM_PFRAME(swap_pte_to_pagemap_entry(pte)) - | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; - else if (pte_present(pte)) - pme = PM_PFRAME(pte_pfn(pte)) - | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; - return pme; -} - static int pagemap_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, - struct mm_walk *walk) + void *private) { - struct vm_area_struct *vma; - struct pagemapread *pm = walk->private; + struct pagemapread *pm = private; pte_t *pte; int err = 0; - /* find the first VMA at or above 'addr' */ - vma = find_vma(walk->mm, addr); for (; addr != end; addr += PAGE_SIZE) { u64 pfn = PM_NOT_PRESENT; - - /* check to see if we've left 'vma' behind - * and need a new, higher one */ - if (vma && (addr >= vma->vm_end)) - vma = find_vma(walk->mm, addr); - - /* check that 'vma' actually covers this address, - * and that it isn't a huge page vma */ - if (vma && (vma->vm_start <= addr) && - !is_vm_hugetlb_page(vma)) { - pte = pte_offset_map(pmd, addr); - pfn = pte_to_pagemap_entry(*pte); - /* unmap before userspace copy */ - pte_unmap(pte); - } + pte = pte_offset_map(pmd, addr); + if (is_swap_pte(*pte)) + pfn = PM_PFRAME(swap_pte_to_pagemap_entry(*pte)) + | PM_PSHIFT(PAGE_SHIFT) | PM_SWAP; + else if (pte_present(*pte)) + pfn = PM_PFRAME(pte_pfn(*pte)) + | PM_PSHIFT(PAGE_SHIFT) | PM_PRESENT; + /* unmap so we're not in atomic when we copy to userspace */ + pte_unmap(pte); err = add_to_pagemap(addr, pfn, pm); if (err) return err; @@ -651,7 +634,7 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, ret = -EINVAL; /* file position must be aligned */ - if ((*ppos % PM_ENTRY_BYTES) || (count % PM_ENTRY_BYTES)) + if (*ppos % PM_ENTRY_BYTES) goto out_task; ret = 0; @@ -681,8 +664,8 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, goto out_pages; } - pm.out = (u64 *)buf; - pm.end = (u64 *)(buf + count); + pm.out = buf; + pm.end = buf + count; if (!ptrace_may_attach(task)) { ret = -EIO; @@ -702,14 +685,14 @@ static ssize_t pagemap_read(struct file *file, char __user *buf, * user buffer is tracked in "pm", and the walk * will stop when we hit the end of the buffer. */ - ret = walk_page_range(start_vaddr, end_vaddr, - &pagemap_walk); + ret = walk_page_range(mm, start_vaddr, end_vaddr, + &pagemap_walk, &pm); if (ret == PM_END_OF_BUFFER) ret = 0; /* don't need mmap_sem for these, but this looks cleaner */ - *ppos += (char *)pm.out - buf; + *ppos += pm.out - buf; if (!ret) - ret = (char *)pm.out - buf; + ret = pm.out - buf; } out_pages: diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 06ebb6ef72aa..06480bcabfdc 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -319,7 +319,6 @@ static inline int acpi_processor_ppc_has_changed(struct acpi_processor *pr) #endif /* CONFIG_CPU_FREQ */ /* in processor_throttling.c */ -int acpi_processor_tstate_has_changed(struct acpi_processor *pr); int acpi_processor_get_throttling_info(struct acpi_processor *pr); extern int acpi_processor_set_throttling(struct acpi_processor *pr, int state); extern struct file_operations acpi_processor_throttling_fops; diff --git a/trunk/include/asm-arm/arch-at91/io.h b/trunk/include/asm-arm/arch-at91/io.h index f8beaa228467..80073fd36b8e 100644 --- a/trunk/include/asm-arm/arch-at91/io.h +++ b/trunk/include/asm-arm/arch-at91/io.h @@ -21,6 +21,8 @@ #ifndef __ASM_ARCH_IO_H #define __ASM_ARCH_IO_H +#include + #define IO_SPACE_LIMIT 0xFFFFFFFF #define __io(a) ((void __iomem *)(a)) diff --git a/trunk/include/asm-arm/arch-pxa/mfp-pxa27x.h b/trunk/include/asm-arm/arch-pxa/mfp-pxa27x.h index bc73ab84167c..eb6eaa174f8d 100644 --- a/trunk/include/asm-arm/arch-pxa/mfp-pxa27x.h +++ b/trunk/include/asm-arm/arch-pxa/mfp-pxa27x.h @@ -112,7 +112,6 @@ #define GPIO57_nIOIS16 MFP_CFG_IN(GPIO57, AF1) #define GPIO56_nPWAIT MFP_CFG_IN(GPIO56, AF1) #define GPIO79_PSKTSEL MFP_CFG_OUT(GPIO79, AF1, DRIVE_HIGH) -#define GPIO104_PSKTSEL MFP_CFG_OUT(GPIO104, AF1, DRIVE_HIGH) /* I2C */ #define GPIO117_I2C_SCL MFP_CFG_IN(GPIO117, AF1) diff --git a/trunk/include/asm-arm/arch-pxa/pxa2xx-gpio.h b/trunk/include/asm-arm/arch-pxa/pxa2xx-gpio.h index b81cd63cb2eb..763313c5e6be 100644 --- a/trunk/include/asm-arm/arch-pxa/pxa2xx-gpio.h +++ b/trunk/include/asm-arm/arch-pxa/pxa2xx-gpio.h @@ -134,11 +134,7 @@ #define GPIO93_CIF_DD_6 93 /* Camera data pin 6 */ #define GPIO94_CIF_DD_5 94 /* Camera data pin 5 */ #define GPIO95_CIF_DD_4 95 /* Camera data pin 4 */ -#define GPIO96_FFRXD 96 /* FFUART recieve */ -#define GPIO98_FFRTS 98 /* FFUART request to send */ #define GPIO98_CIF_DD_0 98 /* Camera data pin 0 */ -#define GPIO99_FFTXD 99 /* FFUART transmit data */ -#define GPIO100_FFCTS 100 /* FFUART Clear to send */ #define GPIO102_nPCE_1 102 /* PCMCIA (PXA27x) */ #define GPIO103_CIF_DD_3 103 /* Camera data pin 3 */ #define GPIO104_CIF_DD_2 104 /* Camera data pin 2 */ @@ -320,8 +316,6 @@ #define GPIO85_nPCE_1_MD (85 | GPIO_ALT_FN_1_OUT) #define GPIO85_CIF_LV_MD (85 | GPIO_ALT_FN_3_IN) #define GPIO86_nPCE_1_MD (86 | GPIO_ALT_FN_1_OUT) -#define GPIO88_USBH1_PWR_MD (88 | GPIO_ALT_FN_1_IN) -#define GPIO89_USBH1_PEN_MD (89 | GPIO_ALT_FN_2_OUT) #define GPIO90_CIF_DD_4_MD (90 | GPIO_ALT_FN_3_IN) #define GPIO91_CIF_DD_5_MD (91 | GPIO_ALT_FN_3_IN) #define GPIO92_MMCDAT0_MD (92 | GPIO_ALT_FN_1_OUT) @@ -330,11 +324,8 @@ #define GPIO95_CIF_DD_4_MD (95 | GPIO_ALT_FN_2_IN) #define GPIO95_KP_MKIN6_MD (95 | GPIO_ALT_FN_3_IN) #define GPIO96_KP_DKIN3_MD (96 | GPIO_ALT_FN_1_IN) -#define GPIO96_FFRXD_MD (96 | GPIO_ALT_FN_3_IN) #define GPIO97_KP_MKIN3_MD (97 | GPIO_ALT_FN_3_IN) #define GPIO98_CIF_DD_0_MD (98 | GPIO_ALT_FN_2_IN) -#define GPIO98_FFRTS_MD (98 | GPIO_ALT_FN_3_OUT) -#define GPIO99_FFTXD_MD (99 | GPIO_ALT_FN_3_OUT) #define GPIO100_KP_MKIN0_MD (100 | GPIO_ALT_FN_1_IN) #define GPIO101_KP_MKIN1_MD (101 | GPIO_ALT_FN_1_IN) #define GPIO102_nPCE_1_MD (102 | GPIO_ALT_FN_1_OUT) diff --git a/trunk/include/asm-arm/arch-pxa/regs-lcd.h b/trunk/include/asm-arm/arch-pxa/regs-lcd.h index 3ba464c913a5..f762493f5141 100644 --- a/trunk/include/asm-arm/arch-pxa/regs-lcd.h +++ b/trunk/include/asm-arm/arch-pxa/regs-lcd.h @@ -1,8 +1,5 @@ #ifndef __ASM_ARCH_REGS_LCD_H #define __ASM_ARCH_REGS_LCD_H - -#include - /* * LCD Controller Registers and Bits Definitions */ @@ -72,7 +69,7 @@ #define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */ #define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */ #define LCCR0_PDD_S 12 -#define LCCR0_BM (1 << 20) /* Branch mask */ +#define LCCR0_BM (1 << 20) /* Branch mask */ #define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */ #define LCCR0_LCDT (1 << 22) /* LCD panel type */ #define LCCR0_RDSTM (1 << 23) /* Read status interrupt mask */ diff --git a/trunk/include/asm-arm/pgtable-nommu.h b/trunk/include/asm-arm/pgtable-nommu.h index 386fcc10a973..2e5868bbe03b 100644 --- a/trunk/include/asm-arm/pgtable-nommu.h +++ b/trunk/include/asm-arm/pgtable-nommu.h @@ -16,6 +16,7 @@ #include #include #include +#include /* * Trivial page table functions. diff --git a/trunk/include/asm-arm/spinlock.h b/trunk/include/asm-arm/spinlock.h index 2b41ebbfa7ff..800ba5254daf 100644 --- a/trunk/include/asm-arm/spinlock.h +++ b/trunk/include/asm-arm/spinlock.h @@ -142,7 +142,7 @@ static inline void __raw_write_unlock(raw_rwlock_t *rw) } /* write_can_lock - would write_trylock() succeed? */ -#define __raw_write_can_lock(x) ((x)->lock == 0) +#define __raw_write_can_lock(x) ((x)->lock == 0x80000000) /* * Read locks are a bit more hairy: diff --git a/trunk/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h b/trunk/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h index 96bd09e31e36..26e3c8076b4e 100644 --- a/trunk/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h +++ b/trunk/include/asm-blackfin/mach-bf527/bfin_serial_5xx.h @@ -53,12 +53,6 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) -#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) -#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) - #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/trunk/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h b/trunk/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h index e924569ad1d8..d016603b6615 100644 --- a/trunk/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h +++ b/trunk/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h @@ -53,12 +53,6 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) -#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) -#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) - #ifdef CONFIG_BFIN_UART0_CTSRTS # define CONFIG_SERIAL_BFIN_CTSRTS # ifndef CONFIG_UART0_CTS_PIN diff --git a/trunk/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h b/trunk/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h index 41d7b6490bb1..f79d1a0e9129 100644 --- a/trunk/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h +++ b/trunk/include/asm-blackfin/mach-bf537/bfin_serial_5xx.h @@ -53,12 +53,6 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) -#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) -#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) - #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/trunk/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h b/trunk/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h index 59b4ad4e5b4a..5eb46a77d919 100644 --- a/trunk/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h +++ b/trunk/include/asm-blackfin/mach-bf548/bfin_serial_5xx.h @@ -57,12 +57,6 @@ #define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */ #define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */ -#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS) -#define UART_SET_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS)) -#define UART_CLEAR_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) & ~MRTS)) -#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v) -#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF) - #if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) # define CONFIG_SERIAL_BFIN_CTSRTS diff --git a/trunk/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h b/trunk/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h index 30d90b580f18..7a9628769296 100644 --- a/trunk/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h +++ b/trunk/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h @@ -53,12 +53,6 @@ #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0) #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0) -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin) -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1) -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0) -#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v) -#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0) - #ifdef CONFIG_BFIN_UART0_CTSRTS # define CONFIG_SERIAL_BFIN_CTSRTS # ifndef CONFIG_UART0_CTS_PIN diff --git a/trunk/include/asm-frv/checksum.h b/trunk/include/asm-frv/checksum.h index 269da09ff637..9b1689850187 100644 --- a/trunk/include/asm-frv/checksum.h +++ b/trunk/include/asm-frv/checksum.h @@ -75,7 +75,7 @@ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (inc), "=&r"(tmp) : "0" (sum), "1" (iph), "2" (ihl), "3" (4), "m"(*(volatile struct { int _[100]; } *)iph) - : "icc0", "icc1", "memory" + : "icc0", "icc1" ); return (__force __sum16)~sum; diff --git a/trunk/include/asm-h8300/cacheflush.h b/trunk/include/asm-h8300/cacheflush.h index 5ffdca217b95..71210d141b64 100644 --- a/trunk/include/asm-h8300/cacheflush.h +++ b/trunk/include/asm-h8300/cacheflush.h @@ -3,7 +3,7 @@ */ #ifndef _ASM_H8300_CACHEFLUSH_H -#define _ASM_H8300_CACHEFLUSH_H +#define _AMS_H8300_CACHEFLUSH_H /* * Cache handling functions diff --git a/trunk/include/asm-m32r/uaccess.h b/trunk/include/asm-m32r/uaccess.h index 1c7047bea200..bd8c83765a5c 100644 --- a/trunk/include/asm-m32r/uaccess.h +++ b/trunk/include/asm-m32r/uaccess.h @@ -14,7 +14,6 @@ #include #include #include -#include #define VERIFY_READ 0 #define VERIFY_WRITE 1 @@ -107,6 +106,7 @@ static inline void set_fs(mm_segment_t s) #else static inline int access_ok(int type, const void *addr, unsigned long size) { + extern unsigned long memory_start, memory_end; unsigned long val = (unsigned long)addr; return ((val >= memory_start) && ((val + size) < memory_end)); diff --git a/trunk/include/asm-m68k/bitops.h b/trunk/include/asm-m68k/bitops.h index 3e8106442d5a..83d1f286230b 100644 --- a/trunk/include/asm-m68k/bitops.h +++ b/trunk/include/asm-m68k/bitops.h @@ -410,49 +410,8 @@ static inline int ext2_find_next_zero_bit(const void *vaddr, unsigned size, res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); return (p - addr) * 32 + res; } - -static inline int ext2_find_first_bit(const void *vaddr, unsigned size) -{ - const unsigned long *p = vaddr, *addr = vaddr; - int res; - - if (!size) - return 0; - - size = (size >> 5) + ((size & 31) > 0); - while (*p++ == 0UL) { - if (--size == 0) - return (p - addr) << 5; - } - - --p; - for (res = 0; res < 32; res++) - if (ext2_test_bit(res, p)) - break; - return (p - addr) * 32 + res; -} - -static inline int ext2_find_next_bit(const void *vaddr, unsigned size, - unsigned offset) -{ - const unsigned long *addr = vaddr; - const unsigned long *p = addr + (offset >> 5); - int bit = offset & 31UL, res; - - if (offset >= size) - return size; - - if (bit) { - /* Look for one in first longword */ - for (res = bit; res < 32; res++) - if (ext2_test_bit(res, p)) - return (p - addr) * 32 + res; - p++; - } - /* No set bit yet, search remaining full bytes for a set bit */ - res = ext2_find_first_bit(p, size - 32 * (p - addr)); - return (p - addr) * 32 + res; -} +#define ext2_find_next_bit(addr, size, off) \ + generic_find_next_le_bit((unsigned long *)(addr), (size), (off)) #endif /* __KERNEL__ */ diff --git a/trunk/include/asm-mips/mach-au1x00/au1xxx_dbdma.h b/trunk/include/asm-mips/mach-au1x00/au1xxx_dbdma.h index 44a67bf05dc1..ad17d7ce516a 100644 --- a/trunk/include/asm-mips/mach-au1x00/au1xxx_dbdma.h +++ b/trunk/include/asm-mips/mach-au1x00/au1xxx_dbdma.h @@ -355,7 +355,6 @@ void au1xxx_dbdma_dump(u32 chanid); u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr); u32 au1xxx_ddma_add_device(dbdev_tab_t *dev); -extern void au1xxx_ddma_del_device(u32 devid); void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp); /* diff --git a/trunk/include/asm-mips/mipsregs.h b/trunk/include/asm-mips/mipsregs.h index a46f8e258e6b..aa17f658f73c 100644 --- a/trunk/include/asm-mips/mipsregs.h +++ b/trunk/include/asm-mips/mipsregs.h @@ -765,9 +765,6 @@ do { \ #define read_c0_index() __read_32bit_c0_register($0, 0) #define write_c0_index(val) __write_32bit_c0_register($0, 0, val) -#define read_c0_random() __read_32bit_c0_register($1, 0) -#define write_c0_random(val) __write_32bit_c0_register($1, 0, val) - #define read_c0_entrylo0() __read_ulong_c0_register($2, 0) #define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) diff --git a/trunk/include/asm-mips/pgtable.h b/trunk/include/asm-mips/pgtable.h index 6a0edf72ffbc..2f597eea4448 100644 --- a/trunk/include/asm-mips/pgtable.h +++ b/trunk/include/asm-mips/pgtable.h @@ -239,10 +239,9 @@ static inline pte_t pte_mkdirty(pte_t pte) static inline pte_t pte_mkyoung(pte_t pte) { pte.pte_low |= _PAGE_ACCESSED; - if (pte.pte_low & _PAGE_READ) { + if (pte.pte_low & _PAGE_READ) pte.pte_low |= _PAGE_SILENT_READ; pte.pte_high |= _PAGE_SILENT_READ; - } return pte; } #else diff --git a/trunk/include/asm-mips/rtlx.h b/trunk/include/asm-mips/rtlx.h index 4ca3063ed2ce..20b666022dcb 100644 --- a/trunk/include/asm-mips/rtlx.h +++ b/trunk/include/asm-mips/rtlx.h @@ -3,7 +3,7 @@ * */ -#ifndef __ASM_RTLX_H_ +#ifndef __ASM_RTLX_H #define __ASM_RTLX_H_ #include diff --git a/trunk/include/asm-parisc/checksum.h b/trunk/include/asm-parisc/checksum.h index e9639ccc3fce..cc3ec1bd8919 100644 --- a/trunk/include/asm-parisc/checksum.h +++ b/trunk/include/asm-parisc/checksum.h @@ -65,7 +65,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) "2:\n" : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl) - : "r19", "r20", "r21", "memory"); + : "r19", "r20", "r21" ); return (__force __sum16)sum; } diff --git a/trunk/include/asm-powerpc/kvm_ppc.h b/trunk/include/asm-powerpc/kvm_ppc.h index 5a21115228af..b35a7e3ef978 100644 --- a/trunk/include/asm-powerpc/kvm_ppc.h +++ b/trunk/include/asm-powerpc/kvm_ppc.h @@ -57,7 +57,6 @@ extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu, extern int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu); -extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu); extern void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 gvaddr, gfn_t gfn, u64 asid, u32 flags); diff --git a/trunk/include/asm-s390/system.h b/trunk/include/asm-s390/system.h index 819e7d99ca0c..e0d4500d5f95 100644 --- a/trunk/include/asm-s390/system.h +++ b/trunk/include/asm-s390/system.h @@ -315,14 +315,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) asm volatile( \ " lctlg %1,%2,0(%0)\n" \ : : "a" (&array), "i" (low), "i" (high), \ - "m" (*(addrtype *)(&array))); \ + "m" (*(addrtype *)(array))); \ }) #define __ctl_store(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ asm volatile( \ " stctg %2,%3,0(%1)\n" \ - : "=m" (*(addrtype *)(&array)) \ + : "=m" (*(addrtype *)(array)) \ : "a" (&array), "i" (low), "i" (high)); \ }) @@ -333,14 +333,14 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) asm volatile( \ " lctl %1,%2,0(%0)\n" \ : : "a" (&array), "i" (low), "i" (high), \ - "m" (*(addrtype *)(&array))); \ + "m" (*(addrtype *)(array))); \ }) #define __ctl_store(array, low, high) ({ \ typedef struct { char _[sizeof(array)]; } addrtype; \ asm volatile( \ " stctl %2,%3,0(%1)\n" \ - : "=m" (*(addrtype *)(&array)) \ + : "=m" (*(addrtype *)(array)) \ : "a" (&array), "i" (low), "i" (high)); \ }) diff --git a/trunk/include/asm-sh/checksum_32.h b/trunk/include/asm-sh/checksum_32.h index 14b7ac2f0a07..4bc8357e8892 100644 --- a/trunk/include/asm-sh/checksum_32.h +++ b/trunk/include/asm-sh/checksum_32.h @@ -109,7 +109,7 @@ static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) will assume they contain their original values. */ : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (__dummy0), "=&z" (__dummy1) : "1" (iph), "2" (ihl) - : "t", "memory"); + : "t"); return csum_fold(sum); } diff --git a/trunk/include/asm-sparc64/io.h b/trunk/include/asm-sparc64/io.h index 3158960f3eb5..c299b853b5ba 100644 --- a/trunk/include/asm-sparc64/io.h +++ b/trunk/include/asm-sparc64/io.h @@ -24,8 +24,7 @@ static inline u8 _inb(unsigned long addr) __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -36,8 +35,7 @@ static inline u16 _inw(unsigned long addr) __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -48,8 +46,7 @@ static inline u32 _inl(unsigned long addr) __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -58,24 +55,21 @@ static inline void _outb(u8 b, unsigned long addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } static inline void _outw(u16 w, unsigned long addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } static inline void _outl(u32 l, unsigned long addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } #define inb(__addr) (_inb((unsigned long)(__addr))) @@ -134,8 +128,7 @@ static inline u8 _readb(const volatile void __iomem *addr) __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -144,8 +137,7 @@ static inline u16 _readw(const volatile void __iomem *addr) __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -155,8 +147,7 @@ static inline u32 _readl(const volatile void __iomem *addr) __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -166,8 +157,7 @@ static inline u64 _readq(const volatile void __iomem *addr) __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); return ret; } @@ -176,32 +166,28 @@ static inline void _writeb(u8 b, volatile void __iomem *addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } static inline void _writew(u16 w, volatile void __iomem *addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } static inline void _writel(u32 l, volatile void __iomem *addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } static inline void _writeq(u64 q, volatile void __iomem *addr) { __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */" : /* no outputs */ - : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L) - : "memory"); + : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); } #define readb(__addr) _readb(__addr) @@ -313,8 +299,7 @@ static inline u8 _sbus_readb(const volatile void __iomem *addr) __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } @@ -325,8 +310,7 @@ static inline u16 _sbus_readw(const volatile void __iomem *addr) __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } @@ -337,8 +321,7 @@ static inline u32 _sbus_readl(const volatile void __iomem *addr) __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } @@ -349,8 +332,7 @@ static inline u64 _sbus_readq(const volatile void __iomem *addr) __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */" : "=r" (ret) - : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); return ret; } @@ -359,32 +341,28 @@ static inline void _sbus_writeb(u8 b, volatile void __iomem *addr) { __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */" : /* no outputs */ - : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } static inline void _sbus_writew(u16 w, volatile void __iomem *addr) { __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */" : /* no outputs */ - : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } static inline void _sbus_writel(u32 l, volatile void __iomem *addr) { __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */" : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } static inline void _sbus_writeq(u64 l, volatile void __iomem *addr) { __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */" : /* no outputs */ - : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E) - : "memory"); + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); } #define sbus_readb(__addr) _sbus_readb(__addr) diff --git a/trunk/include/asm-um/mmu_context.h b/trunk/include/asm-um/mmu_context.h index 54f42e8b0105..6686fc524ca1 100644 --- a/trunk/include/asm-um/mmu_context.h +++ b/trunk/include/asm-um/mmu_context.h @@ -22,10 +22,16 @@ extern void force_flush_all(void); static inline void activate_mm(struct mm_struct *old, struct mm_struct *new) { /* - * This is called by fs/exec.c and sys_unshare() - * when the new ->mm is used for the first time. + * This is called by fs/exec.c and fs/aio.c. In the first case, for an + * exec, we don't need to do anything as we're called from userspace + * and thus going to use a new host PID. In the second, we're called + * from a kernel thread, and thus need to go doing the mmap's on the + * host. Since they're very expensive, we want to avoid that as far as + * possible. */ - __switch_mm(&new->context.id); + if (old != new && (current->flags & PF_BORROWED_MM)) + __switch_mm(&new->context.id); + arch_dup_mmap(old, new); } diff --git a/trunk/include/asm-v850/clinkage.h b/trunk/include/asm-v850/clinkage.h index c389691d6f86..2b622adccae5 100644 --- a/trunk/include/asm-v850/clinkage.h +++ b/trunk/include/asm-v850/clinkage.h @@ -11,7 +11,7 @@ * Written by Miles Bader */ -#ifndef __V850_CLINKAGE_H__ +#ifndef __CLINKAGE_H__ #define __V850_CLINKAGE_H__ #include diff --git a/trunk/include/asm-x86/i387.h b/trunk/include/asm-x86/i387.h index 37672f79dcc8..6b722d315936 100644 --- a/trunk/include/asm-x86/i387.h +++ b/trunk/include/asm-x86/i387.h @@ -193,8 +193,6 @@ static inline int restore_i387(struct _fpstate __user *buf) #else /* CONFIG_X86_32 */ -extern void finit(void); - static inline void tolerant_fwait(void) { asm volatile("fnclex ; fwait"); diff --git a/trunk/include/linux/bitrev.h b/trunk/include/linux/bitrev.h index 7ffe03f4693d..05e540d6963a 100644 --- a/trunk/include/linux/bitrev.h +++ b/trunk/include/linux/bitrev.h @@ -10,7 +10,6 @@ static inline u8 bitrev8(u8 byte) return byte_rev_table[byte]; } -extern u16 bitrev16(u16 in); extern u32 bitrev32(u32 in); #endif /* _LINUX_BITREV_H */ diff --git a/trunk/include/linux/capability.h b/trunk/include/linux/capability.h index fa830f8de032..f4ea0dd9a618 100644 --- a/trunk/include/linux/capability.h +++ b/trunk/include/linux/capability.h @@ -31,11 +31,11 @@ struct task_struct; #define _LINUX_CAPABILITY_VERSION_1 0x19980330 #define _LINUX_CAPABILITY_U32S_1 1 -#define _LINUX_CAPABILITY_VERSION_2 0x20071026 /* deprecated - use v3 */ +#define _LINUX_CAPABILITY_VERSION_2 0x20071026 #define _LINUX_CAPABILITY_U32S_2 2 -#define _LINUX_CAPABILITY_VERSION_3 0x20080522 -#define _LINUX_CAPABILITY_U32S_3 2 +#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_2 +#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_2 typedef struct __user_cap_header_struct { __u32 version; @@ -77,23 +77,10 @@ struct vfs_cap_data { } data[VFS_CAP_U32]; }; -#ifndef __KERNEL__ - -/* - * Backwardly compatible definition for source code - trapped in a - * 32-bit world. If you find you need this, please consider using - * libcap to untrap yourself... - */ -#define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 -#define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 - -#else - -#define _KERNEL_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 -#define _KERNEL_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 +#ifdef __KERNEL__ typedef struct kernel_cap_struct { - __u32 cap[_KERNEL_CAPABILITY_U32S]; + __u32 cap[_LINUX_CAPABILITY_U32S]; } kernel_cap_t; #define _USER_CAP_HEADER_SIZE (sizeof(struct __user_cap_header_struct)) @@ -364,7 +351,7 @@ typedef struct kernel_cap_struct { */ #define CAP_FOR_EACH_U32(__capi) \ - for (__capi = 0; __capi < _KERNEL_CAPABILITY_U32S; ++__capi) + for (__capi = 0; __capi < _LINUX_CAPABILITY_U32S; ++__capi) # define CAP_FS_MASK_B0 (CAP_TO_MASK(CAP_CHOWN) \ | CAP_TO_MASK(CAP_DAC_OVERRIDE) \ @@ -374,7 +361,7 @@ typedef struct kernel_cap_struct { # define CAP_FS_MASK_B1 (CAP_TO_MASK(CAP_MAC_OVERRIDE)) -#if _KERNEL_CAPABILITY_U32S != 2 +#if _LINUX_CAPABILITY_U32S != 2 # error Fix up hand-coded capability macro initializers #else /* HAND-CODED capability initializers */ @@ -385,7 +372,7 @@ typedef struct kernel_cap_struct { # define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ CAP_FS_MASK_B1 } }) -#endif /* _KERNEL_CAPABILITY_U32S != 2 */ +#endif /* _LINUX_CAPABILITY_U32S != 2 */ #define CAP_INIT_INH_SET CAP_EMPTY_SET diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index dcf77fa826b5..51e6b1e520e6 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -82,7 +82,6 @@ struct cpuidle_state_kobj { }; struct cpuidle_device { - unsigned int registered:1; unsigned int enabled:1; unsigned int cpu; diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index d490779f18d9..f413085f748e 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -2000,10 +2000,7 @@ extern int simple_fill_super(struct super_block *, int, struct tree_descr *); extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count); extern void simple_release_fs(struct vfsmount **mount, int *count); -extern ssize_t simple_read_from_buffer(void __user *to, size_t count, - loff_t *ppos, const void *from, size_t available); -extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, - const void *from, size_t available); +extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t); #ifdef CONFIG_MIGRATION extern int buffer_migrate_page(struct address_space *, diff --git a/trunk/include/linux/ide.h b/trunk/include/linux/ide.h index 9918772bf274..f8f195c20da2 100644 --- a/trunk/include/linux/ide.h +++ b/trunk/include/linux/ide.h @@ -153,7 +153,7 @@ enum { ide_unknown, ide_generic, ide_pci, ide_qd65xx, ide_umc8672, ide_ht6560b, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, - ide_pmac, ide_acorn, + ide_pmac, ide_etrax100, ide_acorn, ide_au1xxx, ide_palm3710 }; diff --git a/trunk/include/linux/ieee80211.h b/trunk/include/linux/ieee80211.h index 2998e3b5f166..9300f37cd7e8 100644 --- a/trunk/include/linux/ieee80211.h +++ b/trunk/include/linux/ieee80211.h @@ -98,7 +98,6 @@ #define IEEE80211_MAX_SSID_LEN 32 #define IEEE80211_MAX_MESH_ID_LEN 32 -#define IEEE80211_QOS_CTL_LEN 2 struct ieee80211_hdr { __le16 frame_control; @@ -110,355 +109,6 @@ struct ieee80211_hdr { u8 addr4[6]; } __attribute__ ((packed)); -/** - * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_tods(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0; -} - -/** - * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_fromds(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0; -} - -/** - * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_a4(__le16 fc) -{ - __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); - return (fc & tmp) == tmp; -} - -/** - * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_morefrags(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0; -} - -/** - * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_retry(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0; -} - -/** - * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_pm(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0; -} - -/** - * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_moredata(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0; -} - -/** - * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_protected(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0; -} - -/** - * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_has_order(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0; -} - -/** - * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_mgmt(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT); -} - -/** - * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_ctl(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL); -} - -/** - * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_data(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == - cpu_to_le16(IEEE80211_FTYPE_DATA); -} - -/** - * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_data_qos(__le16 fc) -{ - /* - * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need - * to check the one bit - */ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); -} - -/** - * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_data_present(__le16 fc) -{ - /* - * mask with 0x40 and test that that bit is clear to only return true - * for the data-containing substypes. - */ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) == - cpu_to_le16(IEEE80211_FTYPE_DATA); -} - -/** - * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_assoc_req(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); -} - -/** - * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_assoc_resp(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP); -} - -/** - * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_reassoc_req(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); -} - -/** - * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_reassoc_resp(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP); -} - -/** - * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_probe_req(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); -} - -/** - * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_probe_resp(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); -} - -/** - * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_beacon(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); -} - -/** - * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_atim(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM); -} - -/** - * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_disassoc(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); -} - -/** - * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_auth(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); -} - -/** - * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_deauth(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); -} - -/** - * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_action(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); -} - -/** - * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_back_req(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ); -} - -/** - * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_back(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK); -} - -/** - * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_pspoll(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); -} - -/** - * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_rts(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); -} - -/** - * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_cts(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); -} - -/** - * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_ack(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK); -} - -/** - * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_cfend(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND); -} - -/** - * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_cfendack(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK); -} - -/** - * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC - * @fc: frame control bytes in little-endian byteorder - */ -static inline int ieee80211_is_nullfunc(__le16 fc) -{ - return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == - cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC); -} struct ieee80211s_hdr { u8 flags; @@ -670,7 +320,6 @@ struct ieee80211_ht_addt_info { #define IEEE80211_HT_CAP_MCS_TX_UEQM 0x10 /* 802.11n HT IE masks */ #define IEEE80211_HT_IE_CHA_SEC_OFFSET 0x03 -#define IEEE80211_HT_IE_CHA_SEC_NONE 0x00 #define IEEE80211_HT_IE_CHA_SEC_ABOVE 0x01 #define IEEE80211_HT_IE_CHA_SEC_BELOW 0x03 #define IEEE80211_HT_IE_CHA_WIDTH 0x04 @@ -902,58 +551,66 @@ enum ieee80211_back_parties { #define WLAN_MAX_KEY_LEN 32 -/** - * ieee80211_get_qos_ctl - get pointer to qos control bytes - * @hdr: the frame - * - * The qos ctrl bytes come after the frame_control, duration, seq_num - * and 3 or 4 addresses of length ETH_ALEN. - * 3 addr: 2 + 2 + 2 + 3*6 = 24 - * 4 addr: 2 + 2 + 2 + 4*6 = 30 - */ -static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) -{ - if (ieee80211_has_a4(hdr->frame_control)) - return (u8 *)hdr + 30; - else - return (u8 *)hdr + 24; -} - /** * ieee80211_get_SA - get pointer to SA - * @hdr: the frame * * Given an 802.11 frame, this function returns the offset * to the source address (SA). It does not verify that the * header is long enough to contain the address, and the * header must be long enough to contain the frame control * field. + * + * @hdr: the frame */ static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) { - if (ieee80211_has_a4(hdr->frame_control)) - return hdr->addr4; - if (ieee80211_has_fromds(hdr->frame_control)) + __le16 fc = hdr->frame_control; + fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); + + switch (fc) { + case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): return hdr->addr3; - return hdr->addr2; + case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS): + return hdr->addr4; + default: + return hdr->addr2; + } } /** * ieee80211_get_DA - get pointer to DA - * @hdr: the frame * * Given an 802.11 frame, this function returns the offset * to the destination address (DA). It does not verify that * the header is long enough to contain the address, and the * header must be long enough to contain the frame control * field. + * + * @hdr: the frame */ static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) { - if (ieee80211_has_tods(hdr->frame_control)) + __le16 fc = hdr->frame_control; + fc &= cpu_to_le16(IEEE80211_FCTL_TODS); + + if (fc) return hdr->addr3; else return hdr->addr1; } +/** + * ieee80211_get_morefrag - determine whether the MOREFRAGS bit is set + * + * This function determines whether the "more fragments" bit is set + * in the frame. + * + * @hdr: the frame + */ +static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) +{ + __le16 fc = hdr->frame_control; + return !!(fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)); +} + #endif /* IEEE80211_H */ diff --git a/trunk/include/linux/if_tunnel.h b/trunk/include/linux/if_tunnel.h index d4efe4014705..f1fbe9c930d7 100644 --- a/trunk/include/linux/if_tunnel.h +++ b/trunk/include/linux/if_tunnel.h @@ -41,7 +41,7 @@ struct ip_tunnel_prl { __u16 __reserved; __u32 datalen; __u32 __reserved2; - /* data follows */ + void __user *data; }; /* PRL flags */ diff --git a/trunk/include/linux/ioport.h b/trunk/include/linux/ioport.h index c6801bffe76d..d5d40a9f7929 100644 --- a/trunk/include/linux/ioport.h +++ b/trunk/include/linux/ioport.h @@ -53,14 +53,14 @@ struct resource_list { #define IORESOURCE_AUTO 0x40000000 #define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ -/* PnP IRQ specific bits (IORESOURCE_BITS) */ +/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */ #define IORESOURCE_IRQ_HIGHEDGE (1<<0) #define IORESOURCE_IRQ_LOWEDGE (1<<1) #define IORESOURCE_IRQ_HIGHLEVEL (1<<2) #define IORESOURCE_IRQ_LOWLEVEL (1<<3) #define IORESOURCE_IRQ_SHAREABLE (1<<4) -/* PnP DMA specific bits (IORESOURCE_BITS) */ +/* ISA PnP DMA specific bits (IORESOURCE_BITS) */ #define IORESOURCE_DMA_TYPE_MASK (3<<0) #define IORESOURCE_DMA_8BIT (0<<0) #define IORESOURCE_DMA_8AND16BIT (1<<0) @@ -76,7 +76,7 @@ struct resource_list { #define IORESOURCE_DMA_TYPEB (2<<6) #define IORESOURCE_DMA_TYPEF (3<<6) -/* PnP memory I/O specific bits (IORESOURCE_BITS) */ +/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */ #define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ #define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ #define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ diff --git a/trunk/include/linux/ipv6.h b/trunk/include/linux/ipv6.h index cde056e08181..10b666b61add 100644 --- a/trunk/include/linux/ipv6.h +++ b/trunk/include/linux/ipv6.h @@ -396,10 +396,8 @@ static inline struct request_sock *inet6_reqsk_alloc(struct request_sock_ops *op { struct request_sock *req = reqsk_alloc(ops); - if (req != NULL) { + if (req != NULL) inet_rsk(req)->inet6_rsk_offset = inet6_rsk_offset(req); - inet6_rsk(req)->pktopts = NULL; - } return req; } diff --git a/trunk/include/linux/jbd2.h b/trunk/include/linux/jbd2.h index d147f0f90360..05e2b307161a 100644 --- a/trunk/include/linux/jbd2.h +++ b/trunk/include/linux/jbd2.h @@ -919,9 +919,6 @@ struct journal_s struct proc_dir_entry *j_proc_entry; struct transaction_stats_s j_stats; - /* Failed journal commit ID */ - unsigned int j_failed_commit; - /* * An opaque pointer to fs-private information. ext3 puts its * superblock pointer here diff --git a/trunk/include/linux/kvm_host.h b/trunk/include/linux/kvm_host.h index 092b1b25291d..398978972b7a 100644 --- a/trunk/include/linux/kvm_host.h +++ b/trunk/include/linux/kvm_host.h @@ -297,7 +297,7 @@ static inline gpa_t gfn_to_gpa(gfn_t gfn) return (gpa_t)gfn << PAGE_SHIFT; } -static inline void kvm_migrate_timers(struct kvm_vcpu *vcpu) +static inline void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) { set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests); } diff --git a/trunk/include/linux/libata.h b/trunk/include/linux/libata.h index e57e5d08312d..4a92fbafce9d 100644 --- a/trunk/include/linux/libata.h +++ b/trunk/include/linux/libata.h @@ -111,10 +111,13 @@ enum { /* various global constants */ LIBATA_MAX_PRD = ATA_MAX_PRD / 2, LIBATA_DUMB_MAX_PRD = ATA_MAX_PRD / 4, /* Worst case */ + ATA_MAX_PORTS = 8, ATA_DEF_QUEUE = 1, /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ ATA_MAX_QUEUE = 32, ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, + ATA_MAX_BUS = 2, + ATA_DEF_BUSY_WAIT = 10000, ATA_SHORT_PAUSE = (HZ >> 6) + 1, ATAPI_MAX_DRAIN = 16 << 10, @@ -1432,8 +1435,7 @@ extern void ata_sff_qc_prep(struct ata_queued_cmd *qc); extern void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc); extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device); extern u8 ata_sff_check_status(struct ata_port *ap); -extern void ata_sff_pause(struct ata_port *ap); -extern void ata_sff_dma_pause(struct ata_port *ap); +extern u8 ata_sff_altstatus(struct ata_port *ap); extern int ata_sff_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, unsigned long timeout); extern int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline); @@ -1493,6 +1495,19 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev, struct scsi_host_template *sht, void *host_priv); #endif /* CONFIG_PCI */ +/** + * ata_sff_pause - Flush writes and pause 400 nanoseconds. + * @ap: Port to wait for. + * + * LOCKING: + * Inherited from caller. + */ +static inline void ata_sff_pause(struct ata_port *ap) +{ + ata_sff_altstatus(ap); + ndelay(400); +} + /** * ata_sff_busy_wait - Wait for a port status register * @ap: Port to wait for. diff --git a/trunk/include/linux/math64.h b/trunk/include/linux/math64.h index c87f1528703a..c1a5f81501ff 100644 --- a/trunk/include/linux/math64.h +++ b/trunk/include/linux/math64.h @@ -81,25 +81,4 @@ static inline s64 div_s64(s64 dividend, s32 divisor) } #endif -u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder); - -static __always_inline u32 -__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) -{ - u32 ret = 0; - - while (dividend >= divisor) { - /* The following asm() prevents the compiler from - optimising this loop into a modulo operation. */ - asm("" : "+rm"(dividend)); - - dividend -= divisor; - ret++; - } - - *remainder = dividend; - - return ret; -} - #endif /* _LINUX_MATH64_H */ diff --git a/trunk/include/linux/memory_hotplug.h b/trunk/include/linux/memory_hotplug.h index ea9f5ad9ec8e..73e358612eaf 100644 --- a/trunk/include/linux/memory_hotplug.h +++ b/trunk/include/linux/memory_hotplug.h @@ -77,6 +77,14 @@ extern int __add_pages(struct zone *zone, unsigned long start_pfn, extern int __remove_pages(struct zone *zone, unsigned long start_pfn, unsigned long nr_pages); +/* + * Walk through all memory which is registered as resource. + * arg is (start_pfn, nr_pages, private_arg_pointer) + */ +extern int walk_memory_resource(unsigned long start_pfn, + unsigned long nr_pages, void *arg, + int (*func)(unsigned long, unsigned long, void *)); + #ifdef CONFIG_NUMA extern int memory_add_physaddr_to_nid(u64 start); #else @@ -191,14 +199,6 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat) #endif /* ! CONFIG_MEMORY_HOTPLUG */ -/* - * Walk through all memory which is registered as resource. - * arg is (start_pfn, nr_pages, private_arg_pointer) - */ -extern int walk_memory_resource(unsigned long start_pfn, - unsigned long nr_pages, void *arg, - int (*func)(unsigned long, unsigned long, void *)); - extern int add_memory(int nid, u64 start, u64 size); extern int arch_add_memory(int nid, u64 start, u64 size); extern int remove_memory(u64 start, u64 size); diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index 586a943cab01..c31a9cd2a30e 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -760,17 +760,16 @@ unsigned long unmap_vmas(struct mmu_gather **tlb, * (see walk_page_range for more details) */ struct mm_walk { - int (*pgd_entry)(pgd_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pud_entry)(pud_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pte_entry)(pte_t *, unsigned long, unsigned long, struct mm_walk *); - int (*pte_hole)(unsigned long, unsigned long, struct mm_walk *); - struct mm_struct *mm; - void *private; + int (*pgd_entry)(pgd_t *, unsigned long, unsigned long, void *); + int (*pud_entry)(pud_t *, unsigned long, unsigned long, void *); + int (*pmd_entry)(pmd_t *, unsigned long, unsigned long, void *); + int (*pte_entry)(pte_t *, unsigned long, unsigned long, void *); + int (*pte_hole)(unsigned long, unsigned long, void *); }; -int walk_page_range(unsigned long addr, unsigned long end, - struct mm_walk *walk); +int walk_page_range(const struct mm_struct *, unsigned long addr, + unsigned long end, const struct mm_walk *walk, + void *private); void free_pgd_range(struct mmu_gather **tlb, unsigned long addr, unsigned long end, unsigned long floor, unsigned long ceiling); void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma, diff --git a/trunk/include/linux/msdos_fs.h b/trunk/include/linux/msdos_fs.h index 81cd36b735b0..b03b27457413 100644 --- a/trunk/include/linux/msdos_fs.h +++ b/trunk/include/linux/msdos_fs.h @@ -57,6 +57,12 @@ #define MSDOS_DOT ". " /* ".", padded to MSDOS_NAME chars */ #define MSDOS_DOTDOT ".. " /* "..", padded to MSDOS_NAME chars */ +/* media of boot sector */ +static inline int fat_valid_media(u8 media) +{ + return 0xf8 <= media || media == 0xf0; +} + #define FAT_FIRST_ENT(s, x) ((MSDOS_SB(s)->fat_bits == 32 ? 0x0FFFFF00 : \ MSDOS_SB(s)->fat_bits == 16 ? 0xFF00 : 0xF00) | (x)) @@ -328,12 +334,6 @@ static inline void fatwchar_to16(__u8 *dst, const wchar_t *src, size_t len) #endif } -/* media of boot sector */ -static inline int fat_valid_media(u8 media) -{ - return 0xf8 <= media || media == 0xf0; -} - /* fat/cache.c */ extern void fat_cache_inval_inode(struct inode *inode); extern int fat_get_cluster(struct inode *inode, int cluster, diff --git a/trunk/include/linux/msg.h b/trunk/include/linux/msg.h index 56abf1558fdd..6f3b8e79a991 100644 --- a/trunk/include/linux/msg.h +++ b/trunk/include/linux/msg.h @@ -64,11 +64,11 @@ struct msginfo { #define MSGMNB 16384 /* <= INT_MAX */ /* default max size of a message queue */ /* unused */ -#define MSGPOOL (MSGMNI * MSGMNB / 1024) /* size in kbytes of message pool */ +#define MSGPOOL (MSGMNI * MSGMNB) /* size in bytes of message pool */ #define MSGTQL MSGMNB /* number of system message headers */ #define MSGMAP MSGMNB /* number of entries in message map */ #define MSGSSZ 16 /* message segment size */ -#define __MSGSEG ((MSGPOOL * 1024) / MSGSSZ) /* max no. of segments */ +#define __MSGSEG (MSGPOOL / MSGSSZ) /* max no. of segments */ #define MSGSEG (__MSGSEG <= 0xffff ? __MSGSEG : 0xffff) #ifdef __KERNEL__ diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index 53ea3dc8b0e8..c42bc7f533a5 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -1,7 +1,7 @@ /* * linux/include/linux/mtd/nand.h * - * Copyright (c) 2000 David Woodhouse + * Copyright (c) 2000 David Woodhouse * Steven J. Hill * Thomas Gleixner * diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index 06d8ea5992df..f27fd2009334 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -595,8 +595,8 @@ struct net_device int uc_promisc; struct dev_addr_list *mc_list; /* Multicast mac addresses */ int mc_count; /* Number of installed mcasts */ - unsigned int promiscuity; - unsigned int allmulti; + int promiscuity; + int allmulti; /* Protocol specific pointers */ diff --git a/trunk/include/linux/nl80211.h b/trunk/include/linux/nl80211.h index aa8411e2a160..ea6517e58b04 100644 --- a/trunk/include/linux/nl80211.h +++ b/trunk/include/linux/nl80211.h @@ -122,13 +122,13 @@ enum nl80211_commands { NL80211_CMD_NEW_STATION, NL80211_CMD_DEL_STATION, + /* add commands here */ + NL80211_CMD_GET_MPATH, NL80211_CMD_SET_MPATH, NL80211_CMD_NEW_MPATH, NL80211_CMD_DEL_MPATH, - /* add commands here */ - /* used to define NL80211_CMD_MAX below */ __NL80211_CMD_AFTER_LAST, NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 @@ -230,13 +230,13 @@ enum nl80211_attrs { NL80211_ATTR_MNTR_FLAGS, + /* add attributes here, update the policy in nl80211.c */ + NL80211_ATTR_MESH_ID, NL80211_ATTR_STA_PLINK_ACTION, NL80211_ATTR_MPATH_NEXT_HOP, NL80211_ATTR_MPATH_INFO, - /* add attributes here, update the policy in nl80211.c */ - __NL80211_ATTR_AFTER_LAST, NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 }; diff --git a/trunk/include/linux/page-flags.h b/trunk/include/linux/page-flags.h index f31debfac926..590cff32415d 100644 --- a/trunk/include/linux/page-flags.h +++ b/trunk/include/linux/page-flags.h @@ -306,29 +306,5 @@ static inline void __ClearPageTail(struct page *page) } #endif /* !PAGEFLAGS_EXTENDED */ - -#define PAGE_FLAGS (1 << PG_lru | 1 << PG_private | 1 << PG_locked | \ - 1 << PG_buddy | 1 << PG_writeback | \ - 1 << PG_slab | 1 << PG_swapcache | 1 << PG_active) - -/* - * Flags checked in bad_page(). Pages on the free list should not have - * these flags set. It they are, there is a problem. - */ -#define PAGE_FLAGS_CLEAR_WHEN_BAD (PAGE_FLAGS | 1 << PG_reclaim | 1 << PG_dirty) - -/* - * Flags checked when a page is freed. Pages being freed should not have - * these flags set. It they are, there is a problem. - */ -#define PAGE_FLAGS_CHECK_AT_FREE (PAGE_FLAGS | 1 << PG_reserved) - -/* - * Flags checked when a page is prepped for return by the page allocator. - * Pages being prepped should not have these flags set. It they are, there - * is a problem. - */ -#define PAGE_FLAGS_CHECK_AT_PREP (PAGE_FLAGS | 1 << PG_reserved | 1 << PG_dirty) - #endif /* !__GENERATING_BOUNDS_H */ #endif /* PAGE_FLAGS_H */ diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index caa000596b25..1bbb346066dd 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -716,7 +716,6 @@ #define PCI_DEVICE_ID_HP_CISSA 0x3220 #define PCI_DEVICE_ID_HP_CISSC 0x3230 #define PCI_DEVICE_ID_HP_CISSD 0x3238 -#define PCI_DEVICE_ID_HP_CISSE 0x323a #define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 #define PCI_VENDOR_ID_PCTECH 0x1042 diff --git a/trunk/include/linux/proc_fs.h b/trunk/include/linux/proc_fs.h index fff1d27ddb4c..9883bc942262 100644 --- a/trunk/include/linux/proc_fs.h +++ b/trunk/include/linux/proc_fs.h @@ -9,8 +9,6 @@ struct net; struct completion; -struct mm_struct; - /* * The proc filesystem constants/structures */ @@ -103,6 +101,8 @@ extern spinlock_t proc_subdir_lock; extern void proc_root_init(void); extern void proc_misc_init(void); +struct mm_struct; + void proc_flush_task(struct task_struct *task); struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *); int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir); diff --git a/trunk/include/linux/rtnetlink.h b/trunk/include/linux/rtnetlink.h index b358c704d102..a2aec2c0cfb5 100644 --- a/trunk/include/linux/rtnetlink.h +++ b/trunk/include/linux/rtnetlink.h @@ -246,7 +246,6 @@ enum rt_class_t { RT_TABLE_UNSPEC=0, /* User defined values */ - RT_TABLE_COMPAT=252, RT_TABLE_DEFAULT=253, RT_TABLE_MAIN=254, RT_TABLE_LOCAL=255, diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index c5d3f847ca8d..ae0be3c62375 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -2026,19 +2026,6 @@ static inline int fatal_signal_pending(struct task_struct *p) return signal_pending(p) && __fatal_signal_pending(p); } -static inline int signal_pending_state(long state, struct task_struct *p) -{ - if (!(state & (TASK_INTERRUPTIBLE | TASK_WAKEKILL))) - return 0; - if (!signal_pending(p)) - return 0; - - if (state & (__TASK_STOPPED | __TASK_TRACED)) - return 0; - - return (state & TASK_INTERRUPTIBLE) || __fatal_signal_pending(p); -} - static inline int need_resched(void) { return unlikely(test_thread_flag(TIF_NEED_RESCHED)); diff --git a/trunk/include/linux/serial_core.h b/trunk/include/linux/serial_core.h index d8f31de632c5..d32123ae08ad 100644 --- a/trunk/include/linux/serial_core.h +++ b/trunk/include/linux/serial_core.h @@ -192,7 +192,6 @@ struct uart_ops { void (*shutdown)(struct uart_port *); void (*set_termios)(struct uart_port *, struct ktermios *new, struct ktermios *old); - void (*set_ldisc)(struct uart_port *); void (*pm)(struct uart_port *, unsigned int state, unsigned int oldstate); int (*set_wake)(struct uart_port *, unsigned int state); diff --git a/trunk/include/linux/slab.h b/trunk/include/linux/slab.h index c2ad35016599..805ed4b92f9a 100644 --- a/trunk/include/linux/slab.h +++ b/trunk/include/linux/slab.h @@ -276,17 +276,6 @@ static inline void *kzalloc(size_t size, gfp_t flags) return kmalloc(size, flags | __GFP_ZERO); } -/** - * kzalloc_node - allocate zeroed memory from a particular memory node. - * @size: how many bytes of memory are required. - * @flags: the type of memory to allocate (see kmalloc). - * @node: memory node from which to allocate - */ -static inline void *kzalloc_node(size_t size, gfp_t flags, int node) -{ - return kmalloc_node(size, flags | __GFP_ZERO, node); -} - #ifdef CONFIG_SLABINFO extern const struct seq_operations slabinfo_op; ssize_t slabinfo_write(struct file *, const char __user *, size_t, loff_t *); diff --git a/trunk/include/linux/smc911x.h b/trunk/include/linux/smc911x.h deleted file mode 100644 index b58f54c24183..000000000000 --- a/trunk/include/linux/smc911x.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __SMC911X_H__ -#define __SMC911X_H__ - -#define SMC911X_USE_16BIT (1 << 0) -#define SMC911X_USE_32BIT (1 << 1) - -struct smc911x_platdata { - unsigned long flags; - unsigned long irq_flags; /* IRQF_... */ -}; - -#endif /* __SMC911X_H__ */ diff --git a/trunk/include/linux/sonet.h b/trunk/include/linux/sonet.h index 67ad11fcf88b..753680296e17 100644 --- a/trunk/include/linux/sonet.h +++ b/trunk/include/linux/sonet.h @@ -34,7 +34,7 @@ struct sonet_stats { /* clear error insertion */ #define SONET_GETDIAG _IOR('a',ATMIOC_PHYTYP+4,int) /* query error insertion */ -#define SONET_SETFRAMING _IOW('a',ATMIOC_PHYTYP+5,int) +#define SONET_SETFRAMING _IO('a',ATMIOC_PHYTYP+5) /* set framing mode (SONET/SDH) */ #define SONET_GETFRAMING _IOR('a',ATMIOC_PHYTYP+6,int) /* get framing mode */ diff --git a/trunk/include/linux/tcp.h b/trunk/include/linux/tcp.h index 07e79bdb9cdf..9881295f3857 100644 --- a/trunk/include/linux/tcp.h +++ b/trunk/include/linux/tcp.h @@ -239,6 +239,11 @@ static inline struct tcp_request_sock *tcp_rsk(const struct request_sock *req) return (struct tcp_request_sock *)req; } +struct tcp_deferred_accept_info { + struct sock *listen_sk; + struct request_sock *request; +}; + struct tcp_sock { /* inet_connection_sock has to be the first member of tcp_sock */ struct inet_connection_sock inet_conn; @@ -374,6 +379,8 @@ struct tcp_sock { unsigned int keepalive_time; /* time before keep alive takes place */ unsigned int keepalive_intvl; /* time interval between keep alive probes */ + struct tcp_deferred_accept_info defer_tcp_accept; + unsigned long last_synq_overflow; /* Receiver side RTT estimation */ diff --git a/trunk/include/linux/time.h b/trunk/include/linux/time.h index e15206a7e82e..d32ef0ad4c0a 100644 --- a/trunk/include/linux/time.h +++ b/trunk/include/linux/time.h @@ -6,7 +6,6 @@ #ifdef __KERNEL__ # include # include -# include #endif #ifndef _STRUCT_TIMESPEC @@ -170,13 +169,18 @@ extern struct timeval ns_to_timeval(const s64 nsec); * timespec_add_ns - Adds nanoseconds to a timespec * @a: pointer to timespec to be incremented * @ns: unsigned nanoseconds value to be added - * - * This must always be inlined because its used from the x86-64 vdso, - * which cannot call other kernel functions. */ -static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) +static inline void timespec_add_ns(struct timespec *a, u64 ns) { - a->tv_sec += __iter_div_u64_rem(a->tv_nsec + ns, NSEC_PER_SEC, &ns); + ns += a->tv_nsec; + while(unlikely(ns >= NSEC_PER_SEC)) { + /* The following asm() prevents the compiler from + * optimising this loop into a modulo operation. */ + asm("" : "+r"(ns)); + + ns -= NSEC_PER_SEC; + a->tv_sec++; + } a->tv_nsec = ns; } #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/tty.h b/trunk/include/linux/tty.h index 324a3b231d40..7f7121f9c968 100644 --- a/trunk/include/linux/tty.h +++ b/trunk/include/linux/tty.h @@ -36,7 +36,7 @@ #define N_6PACK 7 #define N_MASC 8 /* Reserved for Mobitex module */ #define N_R3964 9 /* Reserved for Simatic R3964 module */ -#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ +#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ #define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data */ /* cards about SMS messages */ diff --git a/trunk/include/linux/udp.h b/trunk/include/linux/udp.h index 0cf5c4c0ec81..581ca2c14c52 100644 --- a/trunk/include/linux/udp.h +++ b/trunk/include/linux/udp.h @@ -38,7 +38,6 @@ struct udphdr { #ifdef __KERNEL__ #include #include -#include static inline struct udphdr *udp_hdr(const struct sk_buff *skb) { @@ -47,11 +46,6 @@ static inline struct udphdr *udp_hdr(const struct sk_buff *skb) #define UDP_HTABLE_SIZE 128 -static inline int udp_hashfn(struct net *net, const unsigned num) -{ - return (num + net_hash_mix(net)) & (UDP_HTABLE_SIZE - 1); -} - struct udp_sock { /* inet_sock has to be the first member */ struct inet_sock inet; diff --git a/trunk/include/linux/videodev2.h b/trunk/include/linux/videodev2.h index 4a535ea1e123..c1411189ba6c 100644 --- a/trunk/include/linux/videodev2.h +++ b/trunk/include/linux/videodev2.h @@ -865,9 +865,9 @@ struct v4l2_querymenu #define V4L2_CID_HFLIP (V4L2_CID_BASE+20) #define V4L2_CID_VFLIP (V4L2_CID_BASE+21) -/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ -#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) -#define V4L2_CID_VCENTER (V4L2_CID_BASE+23) +/* Deprecated, use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */ +#define V4L2_CID_HCENTER_DEPRECATED (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER_DEPRECATED (V4L2_CID_BASE+23) #define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24) enum v4l2_power_line_frequency { diff --git a/trunk/include/linux/virtio_net.h b/trunk/include/linux/virtio_net.h index 38c0571820fb..9405aa6cdf26 100644 --- a/trunk/include/linux/virtio_net.h +++ b/trunk/include/linux/virtio_net.h @@ -38,7 +38,7 @@ struct virtio_net_hdr #define VIRTIO_NET_HDR_GSO_ECN 0x80 // TCP has ECN set __u8 gso_type; __u16 hdr_len; /* Ethernet + IP + tcp/udp hdrs */ - __u16 gso_size; /* Bytes to append to hdr_len per frame */ + __u16 gso_size; /* Bytes to append to gso_hdr_len per frame */ __u16 csum_start; /* Position to start checksumming from */ __u16 csum_offset; /* Offset after that to place checksum */ }; diff --git a/trunk/include/media/v4l2-dev.h b/trunk/include/media/v4l2-dev.h index 33f01ae08f76..a807d2f86ee8 100644 --- a/trunk/include/media/v4l2-dev.h +++ b/trunk/include/media/v4l2-dev.h @@ -40,6 +40,7 @@ #define VFL_TYPE_VTX 3 /* Video standard functions */ +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); extern char *v4l2_norm_to_name(v4l2_std_id id); extern int v4l2_video_std_construct(struct v4l2_standard *vs, int id, char *name); diff --git a/trunk/include/net/addrconf.h b/trunk/include/net/addrconf.h index 06b28142b3ab..bbd3d583c6e6 100644 --- a/trunk/include/net/addrconf.h +++ b/trunk/include/net/addrconf.h @@ -121,8 +121,7 @@ static inline int addrconf_finite_timeout(unsigned long timeout) */ extern int ipv6_addr_label_init(void); extern void ipv6_addr_label_rtnl_register(void); -extern u32 ipv6_addr_label(struct net *net, - const struct in6_addr *addr, +extern u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex); /* diff --git a/trunk/include/net/if_inet6.h b/trunk/include/net/if_inet6.h index db66c7927743..b2cfc4927257 100644 --- a/trunk/include/net/if_inet6.h +++ b/trunk/include/net/if_inet6.h @@ -148,6 +148,7 @@ struct ifacaddr6 #define IFA_HOST IPV6_ADDR_LOOPBACK #define IFA_LINK IPV6_ADDR_LINKLOCAL #define IFA_SITE IPV6_ADDR_SITELOCAL +#define IFA_GLOBAL 0x0000U struct ipv6_devstat { struct proc_dir_entry *proc_dir_entry; diff --git a/trunk/include/net/inet6_hashtables.h b/trunk/include/net/inet6_hashtables.h index e48989f04c24..62a5b691858e 100644 --- a/trunk/include/net/inet6_hashtables.h +++ b/trunk/include/net/inet6_hashtables.h @@ -24,20 +24,18 @@ #include #include -#include struct inet_hashinfo; /* I have no idea if this is a good hash for v6 or not. -DaveM */ -static inline unsigned int inet6_ehashfn(struct net *net, - const struct in6_addr *laddr, const u16 lport, +static inline unsigned int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport, const struct in6_addr *faddr, const __be16 fport) { u32 ports = (lport ^ (__force u16)fport); return jhash_3words((__force u32)laddr->s6_addr32[3], (__force u32)faddr->s6_addr32[3], - ports, inet_ehash_secret + net_hash_mix(net)); + ports, inet_ehash_secret); } static inline int inet6_sk_ehashfn(const struct sock *sk) @@ -48,9 +46,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) const struct in6_addr *faddr = &np->daddr; const __u16 lport = inet->num; const __be16 fport = inet->dport; - struct net *net = sock_net(sk); - - return inet6_ehashfn(net, laddr, lport, faddr, fport); + return inet6_ehashfn(laddr, lport, faddr, fport); } extern void __inet6_hash(struct sock *sk); diff --git a/trunk/include/net/inet_hashtables.h b/trunk/include/net/inet_hashtables.h index bb619d80f2e2..735b926a3497 100644 --- a/trunk/include/net/inet_hashtables.h +++ b/trunk/include/net/inet_hashtables.h @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -202,24 +201,23 @@ extern struct inet_bind_bucket * extern void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb); -static inline int inet_bhashfn(struct net *net, - const __u16 lport, const int bhash_size) +static inline int inet_bhashfn(const __u16 lport, const int bhash_size) { - return (lport + net_hash_mix(net)) & (bhash_size - 1); + return lport & (bhash_size - 1); } extern void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, const unsigned short snum); /* These can have wildcards, don't try too hard. */ -static inline int inet_lhashfn(struct net *net, const unsigned short num) +static inline int inet_lhashfn(const unsigned short num) { - return (num + net_hash_mix(net)) & (INET_LHTABLE_SIZE - 1); + return num & (INET_LHTABLE_SIZE - 1); } static inline int inet_sk_listen_hashfn(const struct sock *sk) { - return inet_lhashfn(sock_net(sk), inet_sk(sk)->num); + return inet_lhashfn(inet_sk(sk)->num); } /* Caller must disable local BH processing. */ diff --git a/trunk/include/net/inet_sock.h b/trunk/include/net/inet_sock.h index 643e26be058e..a42cd63d241a 100644 --- a/trunk/include/net/inet_sock.h +++ b/trunk/include/net/inet_sock.h @@ -25,7 +25,6 @@ #include #include #include -#include /** struct ip_options - IP Options * @@ -172,14 +171,13 @@ extern int inet_sk_rebuild_header(struct sock *sk); extern u32 inet_ehash_secret; extern void build_ehash_secret(void); -static inline unsigned int inet_ehashfn(struct net *net, - const __be32 laddr, const __u16 lport, +static inline unsigned int inet_ehashfn(const __be32 laddr, const __u16 lport, const __be32 faddr, const __be16 fport) { return jhash_3words((__force __u32) laddr, (__force __u32) faddr, ((__u32) lport) << 16 | (__force __u32)fport, - inet_ehash_secret + net_hash_mix(net)); + inet_ehash_secret); } static inline int inet_sk_ehashfn(const struct sock *sk) @@ -189,9 +187,8 @@ static inline int inet_sk_ehashfn(const struct sock *sk) const __u16 lport = inet->num; const __be32 faddr = inet->daddr; const __be16 fport = inet->dport; - struct net *net = sock_net(sk); - return inet_ehashfn(net, laddr, lport, faddr, fport); + return inet_ehashfn(laddr, lport, faddr, fport); } @@ -200,14 +197,4 @@ static inline int inet_iif(const struct sk_buff *skb) return skb->rtable->rt_iif; } -static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops) -{ - struct request_sock *req = reqsk_alloc(ops); - - if (req != NULL) - inet_rsk(req)->opt = NULL; - - return req; -} - #endif /* _INET_SOCK_H */ diff --git a/trunk/include/net/mac80211.h b/trunk/include/net/mac80211.h index 7ab4ff6159a2..1196de85f8db 100644 --- a/trunk/include/net/mac80211.h +++ b/trunk/include/net/mac80211.h @@ -1535,7 +1535,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif); * * @skb: the frame */ -unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); +int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); /** * ieee80211_get_hdrlen - get header length from frame control @@ -1547,12 +1547,6 @@ unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); */ int ieee80211_get_hdrlen(u16 fc); -/** - * ieee80211_hdrlen - get header length in bytes from frame control - * @fc: frame control field in little-endian format - */ -unsigned int ieee80211_hdrlen(__le16 fc); - /** * ieee80211_get_tkip_key - get a TKIP rc4 for skb * diff --git a/trunk/include/net/netns/hash.h b/trunk/include/net/netns/hash.h deleted file mode 100644 index 548d78f2cc47..000000000000 --- a/trunk/include/net/netns/hash.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __NET_NS_HASH_H__ -#define __NET_NS_HASH_H__ - -#include - -struct net; - -static inline unsigned net_hash_mix(struct net *net) -{ -#ifdef CONFIG_NET_NS - /* - * shift this right to eliminate bits, that are - * always zeroed - */ - - return (unsigned)(((unsigned long)net) >> L1_CACHE_SHIFT); -#else - return 0; -#endif -} -#endif diff --git a/trunk/include/net/request_sock.h b/trunk/include/net/request_sock.h index 0c96e7bed5db..b220b5f624de 100644 --- a/trunk/include/net/request_sock.h +++ b/trunk/include/net/request_sock.h @@ -115,8 +115,8 @@ struct request_sock_queue { struct request_sock *rskq_accept_head; struct request_sock *rskq_accept_tail; rwlock_t syn_wait_lock; - u8 rskq_defer_accept; - /* 3 bytes hole, try to pack */ + u16 rskq_defer_accept; + /* 2 bytes hole, try to pack */ struct listen_sock *listen_opt; }; diff --git a/trunk/include/net/rose.h b/trunk/include/net/rose.h index cbd5364b2c8a..e5bb084d8754 100644 --- a/trunk/include/net/rose.h +++ b/trunk/include/net/rose.h @@ -201,7 +201,7 @@ extern void rose_link_device_down(struct net_device *); extern struct net_device *rose_dev_first(void); extern struct net_device *rose_dev_get(rose_address *); extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *); -extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *, int); +extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *); extern int rose_rt_ioctl(unsigned int, void __user *); extern void rose_link_failed(ax25_cb *, int); extern int rose_route_frame(struct sk_buff *, ax25_cb *); diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index 17b932b8a55a..5672d489e924 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -220,6 +220,8 @@ extern struct kmem_cache *sctp_bucket_cachep __read_mostly; #define sctp_release_sock(sk) release_sock(sk) #define sctp_bh_lock_sock(sk) bh_lock_sock(sk) #define sctp_bh_unlock_sock(sk) bh_unlock_sock(sk) +#define SCTP_SOCK_SLEEP_PRE(sk) SOCK_SLEEP_PRE(sk) +#define SCTP_SOCK_SLEEP_POST(sk) SOCK_SLEEP_POST(sk) /* SCTP SNMP MIB stats handlers */ DECLARE_SNMP_STAT(struct sctp_mib, sctp_statistics); diff --git a/trunk/include/net/sock.h b/trunk/include/net/sock.h index a7c30412de66..dc42b44c2aa1 100644 --- a/trunk/include/net/sock.h +++ b/trunk/include/net/sock.h @@ -166,7 +166,7 @@ struct sock_common { * @sk_err: last error * @sk_err_soft: errors that don't cause failure but are the cause of a * persistent failure not just 'timed out' - * @sk_drops: raw/udp drops counter + * @sk_drops: raw drops counter * @sk_ack_backlog: current listen backlog * @sk_max_ack_backlog: listen backlog set in listen() * @sk_priority: %SO_PRIORITY setting @@ -524,7 +524,7 @@ struct proto { int (*ioctl)(struct sock *sk, int cmd, unsigned long arg); int (*init)(struct sock *sk); - void (*destroy)(struct sock *sk); + int (*destroy)(struct sock *sk); void (*shutdown)(struct sock *sk, int how); int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, @@ -1331,6 +1331,30 @@ extern int net_msg_warn; #define LIMIT_NETDEBUG(fmt, args...) \ do { if (net_msg_warn && net_ratelimit()) printk(fmt,##args); } while(0) +/* + * Macros for sleeping on a socket. Use them like this: + * + * SOCK_SLEEP_PRE(sk) + * if (condition) + * schedule(); + * SOCK_SLEEP_POST(sk) + * + * N.B. These are now obsolete and were, afaik, only ever used in DECnet + * and when the last use of them in DECnet has gone, I'm intending to + * remove them. + */ + +#define SOCK_SLEEP_PRE(sk) { struct task_struct *tsk = current; \ + DECLARE_WAITQUEUE(wait, tsk); \ + tsk->state = TASK_INTERRUPTIBLE; \ + add_wait_queue((sk)->sk_sleep, &wait); \ + release_sock(sk); + +#define SOCK_SLEEP_POST(sk) tsk->state = TASK_RUNNING; \ + remove_wait_queue((sk)->sk_sleep, &wait); \ + lock_sock(sk); \ + } + extern __u32 sysctl_wmem_max; extern __u32 sysctl_rmem_max; diff --git a/trunk/include/net/tcp.h b/trunk/include/net/tcp.h index 6b827cc6c52f..633147cb6bbc 100644 --- a/trunk/include/net/tcp.h +++ b/trunk/include/net/tcp.h @@ -139,6 +139,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define MAX_TCP_KEEPINTVL 32767 #define MAX_TCP_KEEPCNT 127 #define MAX_TCP_SYNCNT 127 +#define MAX_TCP_ACCEPT_DEFERRED 65535 #define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ @@ -398,8 +399,6 @@ extern void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx, int estab); -extern u8 *tcp_parse_md5sig_option(struct tcphdr *th); - /* * TCP v4 functions exported for the inet6 API */ @@ -434,6 +433,7 @@ extern struct sk_buff * tcp_make_synack(struct sock *sk, extern int tcp_disconnect(struct sock *sk, int flags); +extern void tcp_unhash(struct sock *sk); /* From syncookies.c */ extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; @@ -1115,19 +1115,13 @@ struct tcp_md5sig_pool { #define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */ /* - functions */ -extern int tcp_calc_md5_hash(char *md5_hash, - struct tcp_md5sig_key *key, - int bplen, - struct tcphdr *th, - unsigned int tcplen, - struct tcp_md5sig_pool *hp); - extern int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, struct sock *sk, struct dst_entry *dst, struct request_sock *req, struct tcphdr *th, + int protocol, unsigned int tcplen); extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, struct sock *addr_sk); @@ -1140,16 +1134,6 @@ extern int tcp_v4_md5_do_add(struct sock *sk, extern int tcp_v4_md5_do_del(struct sock *sk, __be32 addr); -#ifdef CONFIG_TCP_MD5SIG -#define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_keylen ? \ - &(struct tcp_md5sig_key) { \ - .key = (twsk)->tw_md5_key, \ - .keylen = (twsk)->tw_md5_keylen, \ - } : NULL) -#else -#define tcp_twsk_md5_key(twsk) NULL -#endif - extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void); extern void tcp_free_md5sig_pool(void); @@ -1366,7 +1350,7 @@ extern void tcp_proc_unregister(struct net *net, struct tcp_seq_afinfo *afinfo); extern struct request_sock_ops tcp_request_sock_ops; extern struct request_sock_ops tcp6_request_sock_ops; -extern void tcp_v4_destroy_sock(struct sock *sk); +extern int tcp_v4_destroy_sock(struct sock *sk); extern int tcp_v4_gso_send_check(struct sk_buff *skb); extern struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features); @@ -1387,6 +1371,7 @@ struct tcp_sock_af_ops { struct dst_entry *dst, struct request_sock *req, struct tcphdr *th, + int protocol, unsigned int len); int (*md5_add) (struct sock *sk, struct sock *addr_sk, diff --git a/trunk/include/net/transp_v6.h b/trunk/include/net/transp_v6.h index 876b6f2bb4fd..112934a3288d 100644 --- a/trunk/include/net/transp_v6.h +++ b/trunk/include/net/transp_v6.h @@ -53,7 +53,7 @@ extern int datagram_send_ctl(struct net *net, */ extern struct inet_connection_sock_af_ops ipv4_specific; -extern void inet6_destroy_sock(struct sock *sk); +extern int inet6_destroy_sock(struct sock *sk); #endif diff --git a/trunk/include/net/udp.h b/trunk/include/net/udp.h index 7a8684855245..ccce83707046 100644 --- a/trunk/include/net/udp.h +++ b/trunk/include/net/udp.h @@ -196,8 +196,8 @@ struct udp_seq_afinfo { struct udp_iter_state { struct seq_net_private p; sa_family_t family; - int bucket; struct hlist_head *hashtable; + int bucket; }; #ifdef CONFIG_PROC_FS diff --git a/trunk/include/rdma/ib_verbs.h b/trunk/include/rdma/ib_verbs.h index 31d30b1852e8..911a661b7278 100644 --- a/trunk/include/rdma/ib_verbs.h +++ b/trunk/include/rdma/ib_verbs.h @@ -105,6 +105,7 @@ enum ib_device_cap_flags { */ IB_DEVICE_UD_IP_CSUM = (1<<18), IB_DEVICE_UD_TSO = (1<<19), + IB_DEVICE_SEND_W_INV = (1<<21), }; enum ib_atomic_cap { diff --git a/trunk/include/sound/ac97_codec.h b/trunk/include/sound/ac97_codec.h index 9c309daf492b..049edc5e6461 100644 --- a/trunk/include/sound/ac97_codec.h +++ b/trunk/include/sound/ac97_codec.h @@ -505,7 +505,6 @@ struct snd_ac97 { unsigned short pcmreg[3]; // PCM registers unsigned short codec_cfg[3]; // CODEC_CFG bits unsigned char swap_mic_linein; // AD1986/AD1986A only - unsigned char lo_as_master; /* LO as master */ } ad18xx; unsigned int dev_flags; /* device specific */ } spec; diff --git a/trunk/ipc/msg.c b/trunk/ipc/msg.c index b4eee1c6101d..32494e8cc7a5 100644 --- a/trunk/ipc/msg.c +++ b/trunk/ipc/msg.c @@ -98,15 +98,20 @@ void recompute_msgmni(struct ipc_namespace *ns) if (allowed < MSGMNI) { ns->msg_ctlmni = MSGMNI; - return; + goto out_callback; } if (allowed > IPCMNI / nb_ns) { ns->msg_ctlmni = IPCMNI / nb_ns; - return; + goto out_callback; } ns->msg_ctlmni = allowed; + +out_callback: + + printk(KERN_INFO "msgmni has been set to %d for ipc namespace %p\n", + ns->msg_ctlmni, ns); } void msg_init_ns(struct ipc_namespace *ns) @@ -131,10 +136,6 @@ void msg_exit_ns(struct ipc_namespace *ns) void __init msg_init(void) { msg_init_ns(&init_ipc_ns); - - printk(KERN_INFO "msgmni has been set to %d\n", - init_ipc_ns.msg_ctlmni); - ipc_init_proc_interface("sysvipc/msg", " key msqid perms cbytes qnum lspid lrpid uid gid cuid cgid stime rtime ctime\n", IPC_MSG_IDS, sysvipc_msg_proc_show); diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 790240cd067f..554429ade079 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -894,6 +894,8 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr) if (!sfd) goto out_put_dentry; + err = -ENOMEM; + file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); if (!file) goto out_free; @@ -1058,16 +1060,16 @@ asmlinkage long sys_shmdt(char __user *shmaddr) static int sysvipc_shm_proc_show(struct seq_file *s, void *it) { struct shmid_kernel *shp = it; + char *format; -#if BITS_PER_LONG <= 32 -#define SIZE_SPEC "%10lu" -#else -#define SIZE_SPEC "%21lu" -#endif +#define SMALL_STRING "%10d %10d %4o %10u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" +#define BIG_STRING "%10d %10d %4o %21u %5u %5u %5d %5u %5u %5u %5u %10lu %10lu %10lu\n" - return seq_printf(s, - "%10d %10d %4o " SIZE_SPEC " %5u %5u " - "%5lu %5u %5u %5u %5u %10lu %10lu %10lu\n", + if (sizeof(size_t) <= sizeof(int)) + format = SMALL_STRING; + else + format = BIG_STRING; + return seq_printf(s, format, shp->shm_perm.key, shp->shm_perm.id, shp->shm_perm.mode, diff --git a/trunk/kernel/capability.c b/trunk/kernel/capability.c index cfbe44299488..39e8193b41ea 100644 --- a/trunk/kernel/capability.c +++ b/trunk/kernel/capability.c @@ -52,69 +52,6 @@ static void warn_legacy_capability_use(void) } } -/* - * Version 2 capabilities worked fine, but the linux/capability.h file - * that accompanied their introduction encouraged their use without - * the necessary user-space source code changes. As such, we have - * created a version 3 with equivalent functionality to version 2, but - * with a header change to protect legacy source code from using - * version 2 when it wanted to use version 1. If your system has code - * that trips the following warning, it is using version 2 specific - * capabilities and may be doing so insecurely. - * - * The remedy is to either upgrade your version of libcap (to 2.10+, - * if the application is linked against it), or recompile your - * application with modern kernel headers and this warning will go - * away. - */ - -static void warn_deprecated_v2(void) -{ - static int warned; - - if (!warned) { - char name[sizeof(current->comm)]; - - printk(KERN_INFO "warning: `%s' uses deprecated v2" - " capabilities in a way that may be insecure.\n", - get_task_comm(name, current)); - warned = 1; - } -} - -/* - * Version check. Return the number of u32s in each capability flag - * array, or a negative value on error. - */ -static int cap_validate_magic(cap_user_header_t header, unsigned *tocopy) -{ - __u32 version; - - if (get_user(version, &header->version)) - return -EFAULT; - - switch (version) { - case _LINUX_CAPABILITY_VERSION_1: - warn_legacy_capability_use(); - *tocopy = _LINUX_CAPABILITY_U32S_1; - break; - case _LINUX_CAPABILITY_VERSION_2: - warn_deprecated_v2(); - /* - * fall through - v3 is otherwise equivalent to v2. - */ - case _LINUX_CAPABILITY_VERSION_3: - *tocopy = _LINUX_CAPABILITY_U32S_3; - break; - default: - if (put_user((u32)_KERNEL_CAPABILITY_VERSION, &header->version)) - return -EFAULT; - return -EINVAL; - } - - return 0; -} - /* * For sys_getproccap() and sys_setproccap(), any of the three * capability set pointers may be NULL -- indicating that that set is @@ -134,13 +71,27 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) { int ret = 0; pid_t pid; + __u32 version; struct task_struct *target; unsigned tocopy; kernel_cap_t pE, pI, pP; - ret = cap_validate_magic(header, &tocopy); - if (ret != 0) - return ret; + if (get_user(version, &header->version)) + return -EFAULT; + + switch (version) { + case _LINUX_CAPABILITY_VERSION_1: + warn_legacy_capability_use(); + tocopy = _LINUX_CAPABILITY_U32S_1; + break; + case _LINUX_CAPABILITY_VERSION_2: + tocopy = _LINUX_CAPABILITY_U32S_2; + break; + default: + if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) + return -EFAULT; + return -EINVAL; + } if (get_user(pid, &header->pid)) return -EFAULT; @@ -167,7 +118,7 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) spin_unlock(&task_capability_lock); if (!ret) { - struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; + struct __user_cap_data_struct kdata[_LINUX_CAPABILITY_U32S]; unsigned i; for (i = 0; i < tocopy; i++) { @@ -177,7 +128,7 @@ asmlinkage long sys_capget(cap_user_header_t header, cap_user_data_t dataptr) } /* - * Note, in the case, tocopy < _KERNEL_CAPABILITY_U32S, + * Note, in the case, tocopy < _LINUX_CAPABILITY_U32S, * we silently drop the upper capabilities here. This * has the effect of making older libcap * implementations implicitly drop upper capability @@ -289,16 +240,30 @@ static inline int cap_set_all(kernel_cap_t *effective, */ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) { - struct __user_cap_data_struct kdata[_KERNEL_CAPABILITY_U32S]; + struct __user_cap_data_struct kdata[_LINUX_CAPABILITY_U32S]; unsigned i, tocopy; kernel_cap_t inheritable, permitted, effective; + __u32 version; struct task_struct *target; int ret; pid_t pid; - ret = cap_validate_magic(header, &tocopy); - if (ret != 0) - return ret; + if (get_user(version, &header->version)) + return -EFAULT; + + switch (version) { + case _LINUX_CAPABILITY_VERSION_1: + warn_legacy_capability_use(); + tocopy = _LINUX_CAPABILITY_U32S_1; + break; + case _LINUX_CAPABILITY_VERSION_2: + tocopy = _LINUX_CAPABILITY_U32S_2; + break; + default: + if (put_user(_LINUX_CAPABILITY_VERSION, &header->version)) + return -EFAULT; + return -EINVAL; + } if (get_user(pid, &header->pid)) return -EFAULT; @@ -316,7 +281,7 @@ asmlinkage long sys_capset(cap_user_header_t header, const cap_user_data_t data) permitted.cap[i] = kdata[i].permitted; inheritable.cap[i] = kdata[i].inheritable; } - while (i < _KERNEL_CAPABILITY_U32S) { + while (i < _LINUX_CAPABILITY_U32S) { effective.cap[i] = 0; permitted.cap[i] = 0; inheritable.cap[i] = 0; diff --git a/trunk/kernel/cpuset.c b/trunk/kernel/cpuset.c index 039baa4cd90c..86ea9e34e326 100644 --- a/trunk/kernel/cpuset.c +++ b/trunk/kernel/cpuset.c @@ -797,10 +797,8 @@ static int update_cpumask(struct cpuset *cs, char *buf) retval = cpulist_parse(buf, trialcs.cpus_allowed); if (retval < 0) return retval; - - if (!cpus_subset(trialcs.cpus_allowed, cpu_online_map)) - return -EINVAL; } + cpus_and(trialcs.cpus_allowed, trialcs.cpus_allowed, cpu_online_map); retval = validate_change(cs, &trialcs); if (retval < 0) return retval; @@ -934,11 +932,9 @@ static int update_nodemask(struct cpuset *cs, char *buf) retval = nodelist_parse(buf, trialcs.mems_allowed); if (retval < 0) goto done; - - if (!nodes_subset(trialcs.mems_allowed, - node_states[N_HIGH_MEMORY])) - return -EINVAL; } + nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, + node_states[N_HIGH_MEMORY]); oldmem = cs->mems_allowed; if (nodes_equal(oldmem, trialcs.mems_allowed)) { retval = 0; /* Too easy - nothing to do */ diff --git a/trunk/kernel/kgdb.c b/trunk/kernel/kgdb.c index 79e3c90113c2..14787de568b3 100644 --- a/trunk/kernel/kgdb.c +++ b/trunk/kernel/kgdb.c @@ -52,7 +52,6 @@ #include #include #include -#include static int kgdb_break_asap; @@ -228,6 +227,8 @@ void __weak kgdb_disable_hw_debug(struct pt_regs *regs) * GDB remote protocol parser: */ +static const char hexchars[] = "0123456789abcdef"; + static int hex(char ch) { if ((ch >= 'a') && (ch <= 'f')) @@ -315,8 +316,8 @@ static void put_packet(char *buffer) } kgdb_io_ops->write_char('#'); - kgdb_io_ops->write_char(hex_asc_hi(checksum)); - kgdb_io_ops->write_char(hex_asc_lo(checksum)); + kgdb_io_ops->write_char(hexchars[checksum >> 4]); + kgdb_io_ops->write_char(hexchars[checksum & 0xf]); if (kgdb_io_ops->flush) kgdb_io_ops->flush(); @@ -477,8 +478,8 @@ static void error_packet(char *pkt, int error) { error = -error; pkt[0] = 'E'; - pkt[1] = hex_asc[(error / 10)]; - pkt[2] = hex_asc[(error % 10)]; + pkt[1] = hexchars[(error / 10)]; + pkt[2] = hexchars[(error % 10)]; pkt[3] = '\0'; } @@ -509,7 +510,10 @@ static void int_to_threadref(unsigned char *id, int value) scan = (unsigned char *)id; while (i--) *scan++ = 0; - put_unaligned_be32(value, scan); + *scan++ = (value >> 24) & 0xff; + *scan++ = (value >> 16) & 0xff; + *scan++ = (value >> 8) & 0xff; + *scan++ = (value & 0xff); } static struct task_struct *getthread(struct pt_regs *regs, int tid) diff --git a/trunk/kernel/kprobes.c b/trunk/kernel/kprobes.c index d4998f81e229..1e0250cb9486 100644 --- a/trunk/kernel/kprobes.c +++ b/trunk/kernel/kprobes.c @@ -699,9 +699,8 @@ static int __register_kprobes(struct kprobe **kps, int num, return -EINVAL; for (i = 0; i < num; i++) { ret = __register_kprobe(kps[i], called_from); - if (ret < 0) { - if (i > 0) - unregister_kprobes(kps, i); + if (ret < 0 && i > 0) { + unregister_kprobes(kps, i); break; } } @@ -777,9 +776,8 @@ static int __register_jprobes(struct jprobe **jps, int num, jp->kp.break_handler = longjmp_break_handler; ret = __register_kprobe(&jp->kp, called_from); } - if (ret < 0) { - if (i > 0) - unregister_jprobes(jps, i); + if (ret < 0 && i > 0) { + unregister_jprobes(jps, i); break; } } @@ -922,9 +920,8 @@ static int __register_kretprobes(struct kretprobe **rps, int num, return -EINVAL; for (i = 0; i < num; i++) { ret = __register_kretprobe(rps[i], called_from); - if (ret < 0) { - if (i > 0) - unregister_kretprobes(rps, i); + if (ret < 0 && i > 0) { + unregister_kretprobes(rps, i); break; } } diff --git a/trunk/kernel/sched.c b/trunk/kernel/sched.c index eaf6751e7612..bfb8ad8ed171 100644 --- a/trunk/kernel/sched.c +++ b/trunk/kernel/sched.c @@ -312,15 +312,12 @@ static DEFINE_SPINLOCK(task_group_lock); #endif /* - * A weight of 0 or 1 can cause arithmetics problems. - * A weight of a cfs_rq is the sum of weights of which entities - * are queued on this cfs_rq, so a weight of a entity should not be - * too large, so as the shares value of a task group. + * A weight of 0, 1 or ULONG_MAX can cause arithmetics problems. * (The default weight is 1024 - so there's no practical * limitation from this.) */ #define MIN_SHARES 2 -#define MAX_SHARES (1UL << 18) +#define MAX_SHARES (ULONG_MAX - 1) static int init_task_group_load = INIT_TASK_GROUP_LOAD; #endif @@ -1340,13 +1337,8 @@ calc_delta_mine(unsigned long delta_exec, unsigned long weight, { u64 tmp; - if (!lw->inv_weight) { - if (BITS_PER_LONG > 32 && unlikely(lw->weight >= WMULT_CONST)) - lw->inv_weight = 1; - else - lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2) - / (lw->weight+1); - } + if (!lw->inv_weight) + lw->inv_weight = 1 + (WMULT_CONST-lw->weight/2)/(lw->weight+1); tmp = (u64)delta_exec * weight; /* @@ -4167,10 +4159,12 @@ asmlinkage void __sched schedule(void) clear_tsk_need_resched(prev); if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { - if (unlikely(signal_pending_state(prev->state, prev))) + if (unlikely((prev->state & TASK_INTERRUPTIBLE) && + signal_pending(prev))) { prev->state = TASK_RUNNING; - else + } else { deactivate_task(rq, prev, 1); + } switch_count = &prev->nvcsw; } diff --git a/trunk/lib/bitrev.c b/trunk/lib/bitrev.c index 3956203456d4..989aff73f881 100644 --- a/trunk/lib/bitrev.c +++ b/trunk/lib/bitrev.c @@ -42,11 +42,10 @@ const u8 byte_rev_table[256] = { }; EXPORT_SYMBOL_GPL(byte_rev_table); -u16 bitrev16(u16 x) +static __always_inline u16 bitrev16(u16 x) { return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8); } -EXPORT_SYMBOL(bitrev16); /** * bitrev32 - reverse the order of bits in a u32 value diff --git a/trunk/lib/div64.c b/trunk/lib/div64.c index a111eb8de9cf..bb5bd0c0f030 100644 --- a/trunk/lib/div64.c +++ b/trunk/lib/div64.c @@ -98,13 +98,3 @@ EXPORT_SYMBOL(div64_u64); #endif #endif /* BITS_PER_LONG == 32 */ - -/* - * Iterative div/mod for use when dividend is not expected to be much - * bigger than divisor. - */ -u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder) -{ - return __iter_div_u64_rem(dividend, divisor, remainder); -} -EXPORT_SYMBOL(iter_div_u64_rem); diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index 169a2f8dabcc..bd521716ab1a 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -88,57 +88,6 @@ static inline gfp_t root_gfp_mask(struct radix_tree_root *root) return root->gfp_mask & __GFP_BITS_MASK; } -static inline void tag_set(struct radix_tree_node *node, unsigned int tag, - int offset) -{ - __set_bit(offset, node->tags[tag]); -} - -static inline void tag_clear(struct radix_tree_node *node, unsigned int tag, - int offset) -{ - __clear_bit(offset, node->tags[tag]); -} - -static inline int tag_get(struct radix_tree_node *node, unsigned int tag, - int offset) -{ - return test_bit(offset, node->tags[tag]); -} - -static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag) -{ - root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT)); -} - -static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag) -{ - root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT)); -} - -static inline void root_tag_clear_all(struct radix_tree_root *root) -{ - root->gfp_mask &= __GFP_BITS_MASK; -} - -static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag) -{ - return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); -} - -/* - * Returns 1 if any slot in the node has this tag set. - * Otherwise returns 0. - */ -static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag) -{ - int idx; - for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { - if (node->tags[tag][idx]) - return 1; - } - return 0; -} /* * This assumes that the caller has performed appropriate preallocation, and * that the caller has pinned this thread of control to the current CPU. @@ -175,17 +124,6 @@ static void radix_tree_node_rcu_free(struct rcu_head *head) { struct radix_tree_node *node = container_of(head, struct radix_tree_node, rcu_head); - - /* - * must only free zeroed nodes into the slab. radix_tree_shrink - * can leave us with a non-NULL entry in the first slot, so clear - * that here to make sure. - */ - tag_clear(node, 0, 0); - tag_clear(node, 1, 0); - node->slots[0] = NULL; - node->count = 0; - kmem_cache_free(radix_tree_node_cachep, node); } @@ -227,6 +165,59 @@ int radix_tree_preload(gfp_t gfp_mask) } EXPORT_SYMBOL(radix_tree_preload); +static inline void tag_set(struct radix_tree_node *node, unsigned int tag, + int offset) +{ + __set_bit(offset, node->tags[tag]); +} + +static inline void tag_clear(struct radix_tree_node *node, unsigned int tag, + int offset) +{ + __clear_bit(offset, node->tags[tag]); +} + +static inline int tag_get(struct radix_tree_node *node, unsigned int tag, + int offset) +{ + return test_bit(offset, node->tags[tag]); +} + +static inline void root_tag_set(struct radix_tree_root *root, unsigned int tag) +{ + root->gfp_mask |= (__force gfp_t)(1 << (tag + __GFP_BITS_SHIFT)); +} + + +static inline void root_tag_clear(struct radix_tree_root *root, unsigned int tag) +{ + root->gfp_mask &= (__force gfp_t)~(1 << (tag + __GFP_BITS_SHIFT)); +} + +static inline void root_tag_clear_all(struct radix_tree_root *root) +{ + root->gfp_mask &= __GFP_BITS_MASK; +} + +static inline int root_tag_get(struct radix_tree_root *root, unsigned int tag) +{ + return (__force unsigned)root->gfp_mask & (1 << (tag + __GFP_BITS_SHIFT)); +} + +/* + * Returns 1 if any slot in the node has this tag set. + * Otherwise returns 0. + */ +static inline int any_tag_set(struct radix_tree_node *node, unsigned int tag) +{ + int idx; + for (idx = 0; idx < RADIX_TREE_TAG_LONGS; idx++) { + if (node->tags[tag][idx]) + return 1; + } + return 0; +} + /* * Return the maximum key which can be store into a * radix tree with height HEIGHT. @@ -939,6 +930,11 @@ static inline void radix_tree_shrink(struct radix_tree_root *root) newptr = radix_tree_ptr_to_indirect(newptr); root->rnode = newptr; root->height--; + /* must only free zeroed nodes into the slab */ + tag_clear(to_free, 0, 0); + tag_clear(to_free, 1, 0); + to_free->slots[0] = NULL; + to_free->count = 0; radix_tree_node_free(to_free); } } diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index ab171274ef21..bbf953eeb58b 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -785,7 +785,7 @@ int copy_hugetlb_page_range(struct mm_struct *dst, struct mm_struct *src, continue; spin_lock(&dst->page_table_lock); - spin_lock_nested(&src->page_table_lock, SINGLE_DEPTH_NESTING); + spin_lock(&src->page_table_lock); if (!huge_pte_none(huge_ptep_get(src_pte))) { if (cow) huge_ptep_set_wrprotect(src, addr, src_pte); diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 3354fdd83d4b..669499e7c2f5 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -245,16 +245,10 @@ asmlinkage unsigned long sys_brk(unsigned long brk) unsigned long rlim, retval; unsigned long newbrk, oldbrk; struct mm_struct *mm = current->mm; - unsigned long min_brk; down_write(&mm->mmap_sem); -#ifdef CONFIG_COMPAT_BRK - min_brk = mm->end_code; -#else - min_brk = mm->start_brk; -#endif - if (brk < min_brk) + if (brk < mm->start_brk) goto out; /* diff --git a/trunk/mm/nommu.c b/trunk/mm/nommu.c index 4462b6a3fcb9..dca93fcb8b7a 100644 --- a/trunk/mm/nommu.c +++ b/trunk/mm/nommu.c @@ -109,23 +109,16 @@ unsigned int kobjsize(const void *objp) * If the object we have should not have ksize performed on it, * return size of 0 */ - if (!objp || !virt_addr_valid(objp)) + if (!objp || (unsigned long)objp >= memory_end || !((page = virt_to_page(objp)))) return 0; - page = virt_to_head_page(objp); - - /* - * If the allocator sets PageSlab, we know the pointer came from - * kmalloc(). - */ if (PageSlab(page)) return ksize(objp); - /* - * The ksize() function is only guaranteed to work for pointers - * returned by kmalloc(). So handle arbitrary pointers here. - */ - return PAGE_SIZE << compound_order(page); + BUG_ON(page->index < 0); + BUG_ON(page->index >= MAX_ORDER); + + return (PAGE_SIZE << page->index); } /* diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 2f552955a02f..8e83f02cd2d3 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -237,7 +237,16 @@ static void bad_page(struct page *page) printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n" KERN_EMERG "Backtrace:\n"); dump_stack(); - page->flags &= ~PAGE_FLAGS_CLEAR_WHEN_BAD; + page->flags &= ~(1 << PG_lru | + 1 << PG_private | + 1 << PG_locked | + 1 << PG_active | + 1 << PG_dirty | + 1 << PG_reclaim | + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | + 1 << PG_buddy ); set_page_count(page, 0); reset_page_mapcount(page); page->mapping = NULL; @@ -454,7 +463,16 @@ static inline int free_pages_check(struct page *page) (page->mapping != NULL) | (page_get_page_cgroup(page) != NULL) | (page_count(page) != 0) | - (page->flags & PAGE_FLAGS_CHECK_AT_FREE))) + (page->flags & ( + 1 << PG_lru | + 1 << PG_private | + 1 << PG_locked | + 1 << PG_active | + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | + 1 << PG_reserved | + 1 << PG_buddy )))) bad_page(page); if (PageDirty(page)) __ClearPageDirty(page); @@ -598,7 +616,17 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags) (page->mapping != NULL) | (page_get_page_cgroup(page) != NULL) | (page_count(page) != 0) | - (page->flags & PAGE_FLAGS_CHECK_AT_PREP))) + (page->flags & ( + 1 << PG_lru | + 1 << PG_private | + 1 << PG_locked | + 1 << PG_active | + 1 << PG_dirty | + 1 << PG_slab | + 1 << PG_swapcache | + 1 << PG_writeback | + 1 << PG_reserved | + 1 << PG_buddy )))) bad_page(page); /* diff --git a/trunk/mm/pagewalk.c b/trunk/mm/pagewalk.c index d5878bed7841..0afd2387e507 100644 --- a/trunk/mm/pagewalk.c +++ b/trunk/mm/pagewalk.c @@ -3,14 +3,14 @@ #include static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, - struct mm_walk *walk) + const struct mm_walk *walk, void *private) { pte_t *pte; int err = 0; pte = pte_offset_map(pmd, addr); for (;;) { - err = walk->pte_entry(pte, addr, addr + PAGE_SIZE, walk); + err = walk->pte_entry(pte, addr, addr + PAGE_SIZE, private); if (err) break; addr += PAGE_SIZE; @@ -24,7 +24,7 @@ static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, } static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, - struct mm_walk *walk) + const struct mm_walk *walk, void *private) { pmd_t *pmd; unsigned long next; @@ -35,15 +35,15 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, next = pmd_addr_end(addr, end); if (pmd_none_or_clear_bad(pmd)) { if (walk->pte_hole) - err = walk->pte_hole(addr, next, walk); + err = walk->pte_hole(addr, next, private); if (err) break; continue; } if (walk->pmd_entry) - err = walk->pmd_entry(pmd, addr, next, walk); + err = walk->pmd_entry(pmd, addr, next, private); if (!err && walk->pte_entry) - err = walk_pte_range(pmd, addr, next, walk); + err = walk_pte_range(pmd, addr, next, walk, private); if (err) break; } while (pmd++, addr = next, addr != end); @@ -52,7 +52,7 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end, } static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, - struct mm_walk *walk) + const struct mm_walk *walk, void *private) { pud_t *pud; unsigned long next; @@ -63,15 +63,15 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, next = pud_addr_end(addr, end); if (pud_none_or_clear_bad(pud)) { if (walk->pte_hole) - err = walk->pte_hole(addr, next, walk); + err = walk->pte_hole(addr, next, private); if (err) break; continue; } if (walk->pud_entry) - err = walk->pud_entry(pud, addr, next, walk); + err = walk->pud_entry(pud, addr, next, private); if (!err && (walk->pmd_entry || walk->pte_entry)) - err = walk_pmd_range(pud, addr, next, walk); + err = walk_pmd_range(pud, addr, next, walk, private); if (err) break; } while (pud++, addr = next, addr != end); @@ -85,15 +85,15 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, * @addr: starting address * @end: ending address * @walk: set of callbacks to invoke for each level of the tree + * @private: private data passed to the callback function * * Recursively walk the page table for the memory area in a VMA, * calling supplied callbacks. Callbacks are called in-order (first * PGD, first PUD, first PMD, first PTE, second PTE... second PMD, * etc.). If lower-level callbacks are omitted, walking depth is reduced. * - * Each callback receives an entry pointer and the start and end of the - * associated range, and a copy of the original mm_walk for access to - * the ->private or ->mm fields. + * Each callback receives an entry pointer, the start and end of the + * associated range, and a caller-supplied private data pointer. * * No locks are taken, but the bottom level iterator will map PTE * directories from highmem if necessary. @@ -101,8 +101,9 @@ static int walk_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end, * If any callback returns a non-zero value, the walk is aborted and * the return value is propagated back to the caller. Otherwise 0 is returned. */ -int walk_page_range(unsigned long addr, unsigned long end, - struct mm_walk *walk) +int walk_page_range(const struct mm_struct *mm, + unsigned long addr, unsigned long end, + const struct mm_walk *walk, void *private) { pgd_t *pgd; unsigned long next; @@ -111,24 +112,21 @@ int walk_page_range(unsigned long addr, unsigned long end, if (addr >= end) return err; - if (!walk->mm) - return -EINVAL; - - pgd = pgd_offset(walk->mm, addr); + pgd = pgd_offset(mm, addr); do { next = pgd_addr_end(addr, end); if (pgd_none_or_clear_bad(pgd)) { if (walk->pte_hole) - err = walk->pte_hole(addr, next, walk); + err = walk->pte_hole(addr, next, private); if (err) break; continue; } if (walk->pgd_entry) - err = walk->pgd_entry(pgd, addr, next, walk); + err = walk->pgd_entry(pgd, addr, next, private); if (!err && (walk->pud_entry || walk->pmd_entry || walk->pte_entry)) - err = walk_pud_range(pgd, addr, next, walk); + err = walk_pud_range(pgd, addr, next, walk, private); if (err) break; } while (pgd++, addr = next, addr != end); diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index 967d30ccd92b..9a29901ad3b3 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -1307,7 +1307,7 @@ static unsigned long do_try_to_free_pages(struct zonelist *zonelist, struct scan_control *sc) { int priority; - unsigned long ret = 0; + int ret = 0; unsigned long total_scanned = 0; unsigned long nr_reclaimed = 0; struct reclaim_state *reclaim_state = current->reclaim_state; diff --git a/trunk/net/atm/addr.c b/trunk/net/atm/addr.c index 82e85abc303d..6afa77d63bb5 100644 --- a/trunk/net/atm/addr.c +++ b/trunk/net/atm/addr.c @@ -9,7 +9,7 @@ #include "signaling.h" #include "addr.h" -static int check_addr(const struct sockaddr_atmsvc *addr) +static int check_addr(struct sockaddr_atmsvc *addr) { int i; @@ -23,7 +23,7 @@ static int check_addr(const struct sockaddr_atmsvc *addr) return -EINVAL; } -static int identical(const struct sockaddr_atmsvc *a, const struct sockaddr_atmsvc *b) +static int identical(struct sockaddr_atmsvc *a, struct sockaddr_atmsvc *b) { if (*a->sas_addr.prv) if (memcmp(a->sas_addr.prv, b->sas_addr.prv, ATM_ESA_LEN)) @@ -35,7 +35,7 @@ static int identical(const struct sockaddr_atmsvc *a, const struct sockaddr_atms return !strcmp(a->sas_addr.pub, b->sas_addr.pub); } -static void notify_sigd(const struct atm_dev *dev) +static void notify_sigd(struct atm_dev *dev) { struct sockaddr_atmpvc pvc; @@ -63,7 +63,7 @@ void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype) notify_sigd(dev); } -int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, +int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr, enum atm_addr_type_t atype) { unsigned long flags; @@ -98,7 +98,7 @@ int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, return 0; } -int atm_del_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, +int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr, enum atm_addr_type_t atype) { unsigned long flags; diff --git a/trunk/net/atm/addr.h b/trunk/net/atm/addr.h index 6837e9e7eb13..f39433ad45da 100644 --- a/trunk/net/atm/addr.h +++ b/trunk/net/atm/addr.h @@ -10,9 +10,9 @@ #include void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t type); -int atm_add_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, +int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr, enum atm_addr_type_t type); -int atm_del_addr(struct atm_dev *dev, const struct sockaddr_atmsvc *addr, +int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr, enum atm_addr_type_t type); int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user *buf, size_t size, enum atm_addr_type_t type); diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index 8d9a6f158880..9d52ebfc1962 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -52,12 +52,12 @@ static void skb_debug(const struct sk_buff *skb) #define ETHERTYPE_IPV6 0x86, 0xdd #define PAD_BRIDGED 0x00, 0x00 -static const unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 }; -static const unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 }; -static const unsigned char llc_oui_pid_pad[] = +static unsigned char ethertype_ipv4[] = { ETHERTYPE_IPV4 }; +static unsigned char ethertype_ipv6[] = { ETHERTYPE_IPV6 }; +static unsigned char llc_oui_pid_pad[] = { LLC, SNAP_BRIDGED, PID_ETHERNET, PAD_BRIDGED }; -static const unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 }; -static const unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 }; +static unsigned char llc_oui_ipv4[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV4 }; +static unsigned char llc_oui_ipv6[] = { LLC, SNAP_ROUTED, ETHERTYPE_IPV6 }; enum br2684_encaps { e_vc = BR2684_ENCAPS_VC, @@ -188,13 +188,10 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, return 0; } } - } else { /* e_vc */ - if (brdev->payload == p_bridged) { - skb_push(skb, 2); + } else { + skb_push(skb, 2); + if (brdev->payload == p_bridged) memset(skb->data, 0, 2); - } else { /* p_routed */ - skb_pull(skb, ETH_HLEN); - } } skb_debug(skb); @@ -217,8 +214,8 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct br2684_dev *brdev, return 1; } -static inline struct br2684_vcc *pick_outgoing_vcc(const struct sk_buff *skb, - const struct br2684_dev *brdev) +static inline struct br2684_vcc *pick_outgoing_vcc(struct sk_buff *skb, + struct br2684_dev *brdev) { return list_empty(&brdev->brvccs) ? NULL : list_entry_brvcc(brdev->brvccs.next); /* 1 vcc/dev right now */ } @@ -380,8 +377,11 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) (skb->data + 6, ethertype_ipv4, sizeof(ethertype_ipv4)) == 0) skb->protocol = __constant_htons(ETH_P_IP); - else - goto error; + else { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; + } skb_pull(skb, sizeof(llc_oui_ipv4)); skb_reset_network_header(skb); skb->pkt_type = PACKET_HOST; @@ -394,56 +394,44 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) (memcmp(skb->data, llc_oui_pid_pad, 7) == 0)) { skb_pull(skb, sizeof(llc_oui_pid_pad)); skb->protocol = eth_type_trans(skb, net_dev); - } else - goto error; - - } else { /* e_vc */ - if (brdev->payload == p_routed) { - struct iphdr *iph; + } else { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; + } - skb_reset_network_header(skb); - iph = ip_hdr(skb); - if (iph->version == 4) - skb->protocol = __constant_htons(ETH_P_IP); - else if (iph->version == 6) - skb->protocol = __constant_htons(ETH_P_IPV6); - else - goto error; - skb->pkt_type = PACKET_HOST; - } else { /* p_bridged */ - /* first 2 chars should be 0 */ - if (*((u16 *) (skb->data)) != 0) - goto error; - skb_pull(skb, BR2684_PAD_LEN); - skb->protocol = eth_type_trans(skb, net_dev); + } else { + /* first 2 chars should be 0 */ + if (*((u16 *) (skb->data)) != 0) { + brdev->stats.rx_errors++; + dev_kfree_skb(skb); + return; } + skb_pull(skb, BR2684_PAD_LEN + ETH_HLEN); /* pad, dstmac, srcmac, ethtype */ + skb->protocol = eth_type_trans(skb, net_dev); } #ifdef CONFIG_ATM_BR2684_IPFILTER - if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) - goto dropped; + if (unlikely(packet_fails_filter(skb->protocol, brvcc, skb))) { + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } #endif /* CONFIG_ATM_BR2684_IPFILTER */ skb->dev = net_dev; ATM_SKB(skb)->vcc = atmvcc; /* needed ? */ pr_debug("received packet's protocol: %x\n", ntohs(skb->protocol)); skb_debug(skb); - /* sigh, interface is down? */ - if (unlikely(!(net_dev->flags & IFF_UP))) - goto dropped; + if (unlikely(!(net_dev->flags & IFF_UP))) { + /* sigh, interface is down */ + brdev->stats.rx_dropped++; + dev_kfree_skb(skb); + return; + } brdev->stats.rx_packets++; brdev->stats.rx_bytes += skb->len; memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); netif_rx(skb); - return; - -dropped: - brdev->stats.rx_dropped++; - goto free_skb; -error: - brdev->stats.rx_errors++; -free_skb: - dev_kfree_skb(skb); - return; } /* @@ -530,9 +518,9 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) struct sk_buff *next = skb->next; skb->next = skb->prev = NULL; - br2684_push(atmvcc, skb); BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; BRPRIV(skb->dev)->stats.rx_packets--; + br2684_push(atmvcc, skb); skb = next; } diff --git a/trunk/net/atm/common.c b/trunk/net/atm/common.c index d34edbe754c8..c865517ba449 100644 --- a/trunk/net/atm/common.c +++ b/trunk/net/atm/common.c @@ -262,7 +262,7 @@ static int adjust_tp(struct atm_trafprm *tp,unsigned char aal) } -static int check_ci(const struct atm_vcc *vcc, short vpi, int vci) +static int check_ci(struct atm_vcc *vcc, short vpi, int vci) { struct hlist_head *head = &vcc_hash[vci & (VCC_HTABLE_SIZE - 1)]; @@ -290,7 +290,7 @@ static int check_ci(const struct atm_vcc *vcc, short vpi, int vci) } -static int find_ci(const struct atm_vcc *vcc, short *vpi, int *vci) +static int find_ci(struct atm_vcc *vcc, short *vpi, int *vci) { static short p; /* poor man's per-device cache */ static int c; @@ -646,7 +646,7 @@ static int atm_change_qos(struct atm_vcc *vcc,struct atm_qos *qos) } -static int check_tp(const struct atm_trafprm *tp) +static int check_tp(struct atm_trafprm *tp) { /* @@@ Should be merged with adjust_tp */ if (!tp->traffic_class || tp->traffic_class == ATM_ANYCLASS) return 0; @@ -663,7 +663,7 @@ static int check_tp(const struct atm_trafprm *tp) } -static int check_qos(const struct atm_qos *qos) +static int check_qos(struct atm_qos *qos) { int error; diff --git a/trunk/net/atm/lec.c b/trunk/net/atm/lec.c index 5799fb52365a..653aca3573ac 100644 --- a/trunk/net/atm/lec.c +++ b/trunk/net/atm/lec.c @@ -65,36 +65,36 @@ static int lec_close(struct net_device *dev); static struct net_device_stats *lec_get_stats(struct net_device *dev); static void lec_init(struct net_device *dev); static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, - const unsigned char *mac_addr); + unsigned char *mac_addr); static int lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove); /* LANE2 functions */ -static void lane2_associate_ind(struct net_device *dev, const u8 *mac_address, - const u8 *tlvs, u32 sizeoftlvs); -static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force, +static void lane2_associate_ind(struct net_device *dev, u8 *mac_address, + u8 *tlvs, u32 sizeoftlvs); +static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, u8 **tlvs, u32 *sizeoftlvs); -static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, - const u8 *tlvs, u32 sizeoftlvs); +static int lane2_associate_req(struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs); -static int lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr, +static int lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, unsigned long permanent); static void lec_arp_check_empties(struct lec_priv *priv, struct atm_vcc *vcc, struct sk_buff *skb); static void lec_arp_destroy(struct lec_priv *priv); static void lec_arp_init(struct lec_priv *priv); static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, - const unsigned char *mac_to_find, + unsigned char *mac_to_find, int is_rdesc, struct lec_arp_table **ret_entry); -static void lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, - const unsigned char *atm_addr, unsigned long remoteflag, +static void lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, + unsigned char *atm_addr, unsigned long remoteflag, unsigned int targetless_le_arp); static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id); static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc); static void lec_set_flush_tran_id(struct lec_priv *priv, - const unsigned char *atm_addr, + unsigned char *atm_addr, unsigned long tran_id); -static void lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data, +static void lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, struct atm_vcc *vcc, void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)); @@ -634,7 +634,7 @@ static struct atm_dev lecatm_dev = { */ static int send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, - const unsigned char *mac_addr, const unsigned char *atm_addr, + unsigned char *mac_addr, unsigned char *atm_addr, struct sk_buff *data) { struct sock *sk; @@ -705,9 +705,10 @@ static void lec_init(struct net_device *dev) dev->set_multicast_list = lec_set_multicast_list; dev->do_ioctl = NULL; printk("%s: Initialized!\n", dev->name); + return; } -static const unsigned char lec_ctrl_magic[] = { +static unsigned char lec_ctrl_magic[] = { 0xff, 0x00, 0x01, @@ -1275,7 +1276,7 @@ module_exit(lane_module_cleanup); * lec will be used. * If dst_mac == NULL, targetless LE_ARP will be sent */ -static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force, +static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force, u8 **tlvs, u32 *sizeoftlvs) { unsigned long flags; @@ -1321,8 +1322,8 @@ static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force, * Returns 1 for success, 0 for failure (out of memory) * */ -static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, - const u8 *tlvs, u32 sizeoftlvs) +static int lane2_associate_req(struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs) { int retval; struct sk_buff *skb; @@ -1357,8 +1358,8 @@ static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, * LANE2: 3.1.5, LE_ASSOCIATE.indication * */ -static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr, - const u8 *tlvs, u32 sizeoftlvs) +static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, + u8 *tlvs, u32 sizeoftlvs) { #if 0 int i = 0; @@ -1743,7 +1744,7 @@ static void lec_arp_destroy(struct lec_priv *priv) * Find entry by mac_address */ static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, - const unsigned char *mac_addr) + unsigned char *mac_addr) { struct hlist_node *node; struct hlist_head *head; @@ -1763,7 +1764,7 @@ static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, } static struct lec_arp_table *make_entry(struct lec_priv *priv, - const unsigned char *mac_addr) + unsigned char *mac_addr) { struct lec_arp_table *to_return; @@ -1920,7 +1921,7 @@ static void lec_arp_check_expire(struct work_struct *work) * */ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, - const unsigned char *mac_to_find, int is_rdesc, + unsigned char *mac_to_find, int is_rdesc, struct lec_arp_table **ret_entry) { unsigned long flags; @@ -2016,7 +2017,7 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, } static int -lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr, +lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, unsigned long permanent) { unsigned long flags; @@ -2046,8 +2047,8 @@ lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr, * Notifies: Response to arp_request (atm_addr != NULL) */ static void -lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, - const unsigned char *atm_addr, unsigned long remoteflag, +lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, + unsigned char *atm_addr, unsigned long remoteflag, unsigned int targetless_le_arp) { unsigned long flags; @@ -2147,7 +2148,7 @@ lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, * Notifies: Vcc setup ready */ static void -lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data, +lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, struct atm_vcc *vcc, void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)) { @@ -2335,7 +2336,7 @@ static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) static void lec_set_flush_tran_id(struct lec_priv *priv, - const unsigned char *atm_addr, unsigned long tran_id) + unsigned char *atm_addr, unsigned long tran_id) { unsigned long flags; struct hlist_node *node; diff --git a/trunk/net/atm/lec.h b/trunk/net/atm/lec.h index 0d376682c1a3..b41cda7ea1e1 100644 --- a/trunk/net/atm/lec.h +++ b/trunk/net/atm/lec.h @@ -42,12 +42,12 @@ struct lecdatahdr_8025 { * */ struct lane2_ops { - int (*resolve) (struct net_device *dev, const u8 *dst_mac, int force, + int (*resolve) (struct net_device *dev, u8 *dst_mac, int force, u8 **tlvs, u32 *sizeoftlvs); - int (*associate_req) (struct net_device *dev, const u8 *lan_dst, - const u8 *tlvs, u32 sizeoftlvs); - void (*associate_indicator) (struct net_device *dev, const u8 *mac_addr, - const u8 *tlvs, u32 sizeoftlvs); + int (*associate_req) (struct net_device *dev, u8 *lan_dst, + u8 *tlvs, u32 sizeoftlvs); + void (*associate_indicator) (struct net_device *dev, u8 *mac_addr, + u8 *tlvs, u32 sizeoftlvs); }; /* diff --git a/trunk/net/ax25/af_ax25.c b/trunk/net/ax25/af_ax25.c index 97eaa23ad9ea..2712544cf0ca 100644 --- a/trunk/net/ax25/af_ax25.c +++ b/trunk/net/ax25/af_ax25.c @@ -893,11 +893,13 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) sk->sk_destruct = ax25_free_sock; sk->sk_type = osk->sk_type; + sk->sk_socket = osk->sk_socket; sk->sk_priority = osk->sk_priority; sk->sk_protocol = osk->sk_protocol; sk->sk_rcvbuf = osk->sk_rcvbuf; sk->sk_sndbuf = osk->sk_sndbuf; sk->sk_state = TCP_ESTABLISHED; + sk->sk_sleep = osk->sk_sleep; sock_copy_flags(sk, osk); oax25 = ax25_sk(osk); @@ -1359,11 +1361,13 @@ static int ax25_accept(struct socket *sock, struct socket *newsock, int flags) goto out; newsk = skb->sk; - sock_graft(newsk, newsock); + newsk->sk_socket = newsock; + newsk->sk_sleep = &newsock->wait; /* Now attach up the new socket */ kfree_skb(skb); sk->sk_ack_backlog--; + newsock->sk = newsk; newsock->state = SS_CONNECTED; out: diff --git a/trunk/net/ax25/ax25_std_timer.c b/trunk/net/ax25/ax25_std_timer.c index cdc7e751ef36..96e4b9273250 100644 --- a/trunk/net/ax25/ax25_std_timer.c +++ b/trunk/net/ax25/ax25_std_timer.c @@ -39,9 +39,11 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25) switch (ax25->state) { case AX25_STATE_0: - if (!sk || - sock_flag(sk, SOCK_DESTROY) || - sock_flag(sk, SOCK_DEAD)) { + /* Magic here: If we listen() and a new link dies before it + is accepted() it isn't 'dead' so doesn't get removed. */ + if (!sk || sock_flag(sk, SOCK_DESTROY) || + (sk->sk_state == TCP_LISTEN && + sock_flag(sk, SOCK_DEAD))) { if (sk) { sock_hold(sk); ax25_destroy_socket(ax25); diff --git a/trunk/net/bridge/br_device.c b/trunk/net/bridge/br_device.c index d9449df7cad5..a6ffc6c2a69f 100644 --- a/trunk/net/bridge/br_device.c +++ b/trunk/net/bridge/br_device.c @@ -87,7 +87,6 @@ static int br_set_mac_address(struct net_device *dev, void *p) spin_lock_bh(&br->lock); memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); br_stp_change_bridge_id(br, addr->sa_data); - br->flags |= BR_SET_MAC_ADDR; spin_unlock_bh(&br->lock); return 0; diff --git a/trunk/net/bridge/br_input.c b/trunk/net/bridge/br_input.c index 30b88777c3df..0145e9416714 100644 --- a/trunk/net/bridge/br_input.c +++ b/trunk/net/bridge/br_input.c @@ -134,11 +134,14 @@ struct sk_buff *br_handle_frame(struct net_bridge_port *p, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_PAUSE)) goto drop; - if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, - NULL, br_handle_local_finish)) - return NULL; /* frame consumed by filter */ - else - return skb; /* continue processing */ + /* Process STP BPDU's through normal netif_receive_skb() path */ + if (p->br->stp_enabled != BR_NO_STP) { + if (NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, + NULL, br_handle_local_finish)) + return NULL; + else + return skb; + } } switch (p->state) { diff --git a/trunk/net/bridge/br_private.h b/trunk/net/bridge/br_private.h index 8593c9f6a302..83ff5861c2d2 100644 --- a/trunk/net/bridge/br_private.h +++ b/trunk/net/bridge/br_private.h @@ -92,8 +92,6 @@ struct net_bridge struct hlist_head hash[BR_HASH_SIZE]; struct list_head age_list; unsigned long feature_mask; - unsigned long flags; -#define BR_SET_MAC_ADDR 0x00000001 /* STP */ bridge_id designated_root; diff --git a/trunk/net/bridge/br_stp_if.c b/trunk/net/bridge/br_stp_if.c index 9a52ac5b4525..1a4e5c37a0cf 100644 --- a/trunk/net/bridge/br_stp_if.c +++ b/trunk/net/bridge/br_stp_if.c @@ -214,10 +214,6 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br) const unsigned char *addr = br_mac_zero; struct net_bridge_port *p; - /* user has chosen a value so keep it */ - if (br->flags & BR_SET_MAC_ADDR) - return; - list_for_each_entry(p, &br->port_list, list) { if (addr == br_mac_zero || memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) diff --git a/trunk/net/bridge/netfilter/Kconfig b/trunk/net/bridge/netfilter/Kconfig index 540df4106bec..fb684c2ff8b6 100644 --- a/trunk/net/bridge/netfilter/Kconfig +++ b/trunk/net/bridge/netfilter/Kconfig @@ -85,7 +85,7 @@ config BRIDGE_EBT_IP config BRIDGE_EBT_IP6 tristate "ebt: IP6 filter support" - depends on BRIDGE_NF_EBTABLES && IPV6 + depends on BRIDGE_NF_EBTABLES help This option adds the IP6 match, which allows basic IPV6 header field filtering. diff --git a/trunk/net/bridge/netfilter/Makefile b/trunk/net/bridge/netfilter/Makefile index 0718699540b0..dd960645b413 100644 --- a/trunk/net/bridge/netfilter/Makefile +++ b/trunk/net/bridge/netfilter/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o obj-$(CONFIG_BRIDGE_EBT_ARP) += ebt_arp.o obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip.o -obj-$(CONFIG_BRIDGE_EBT_IP6) += ebt_ip6.o +obj-$(CONFIG_BRIDGE_EBT_IP) += ebt_ip6.o obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o obj-$(CONFIG_BRIDGE_EBT_MARK) += ebt_mark_m.o obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o diff --git a/trunk/net/bridge/netfilter/ebt_log.c b/trunk/net/bridge/netfilter/ebt_log.c index 2f430d4ae911..c883ec8a28b4 100644 --- a/trunk/net/bridge/netfilter/ebt_log.c +++ b/trunk/net/bridge/netfilter/ebt_log.c @@ -123,7 +123,6 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum, goto out; } -#if defined(CONFIG_BRIDGE_EBT_IP6) || defined(CONFIG_BRIDGE_EBT_IP6_MODULE) if ((bitmask & EBT_LOG_IP6) && eth_hdr(skb)->h_proto == htons(ETH_P_IPV6)) { const struct ipv6hdr *ih; @@ -147,7 +146,6 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum, print_ports(skb, nexthdr, offset_ph); goto out; } -#endif if ((bitmask & EBT_LOG_ARP) && ((eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) || diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 68d8df0992ab..582963077877 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -119,7 +119,6 @@ #include #include #include -#include #include "net-sysfs.h" @@ -1363,29 +1362,6 @@ void netif_device_attach(struct net_device *dev) } EXPORT_SYMBOL(netif_device_attach); -static bool can_checksum_protocol(unsigned long features, __be16 protocol) -{ - return ((features & NETIF_F_GEN_CSUM) || - ((features & NETIF_F_IP_CSUM) && - protocol == htons(ETH_P_IP)) || - ((features & NETIF_F_IPV6_CSUM) && - protocol == htons(ETH_P_IPV6))); -} - -static bool dev_can_checksum(struct net_device *dev, struct sk_buff *skb) -{ - if (can_checksum_protocol(dev->features, skb->protocol)) - return true; - - if (skb->protocol == htons(ETH_P_8021Q)) { - struct vlan_ethhdr *veh = (struct vlan_ethhdr *)skb->data; - if (can_checksum_protocol(dev->features & dev->vlan_features, - veh->h_vlan_encapsulated_proto)) - return true; - } - - return false; -} /* * Invalidate hardware checksum when packet is to be mangled, and @@ -1664,8 +1640,14 @@ int dev_queue_xmit(struct sk_buff *skb) if (skb->ip_summed == CHECKSUM_PARTIAL) { skb_set_transport_header(skb, skb->csum_start - skb_headroom(skb)); - if (!dev_can_checksum(dev, skb) && skb_checksum_help(skb)) - goto out_kfree_skb; + + if (!(dev->features & NETIF_F_GEN_CSUM) && + !((dev->features & NETIF_F_IP_CSUM) && + skb->protocol == htons(ETH_P_IP)) && + !((dev->features & NETIF_F_IPV6_CSUM) && + skb->protocol == htons(ETH_P_IPV6))) + if (skb_checksum_help(skb)) + goto out_kfree_skb; } gso: diff --git a/trunk/net/dccp/ackvec.c b/trunk/net/dccp/ackvec.c index 1e8be246ad15..6de4bd195d28 100644 --- a/trunk/net/dccp/ackvec.c +++ b/trunk/net/dccp/ackvec.c @@ -290,12 +290,12 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, while (1) { const u8 len = dccp_ackvec_len(av, index); - const u8 av_state = dccp_ackvec_state(av, index); + const u8 state = dccp_ackvec_state(av, index); /* * valid packets not yet in av_buf have a reserved * entry, with a len equal to 0. */ - if (av_state == DCCP_ACKVEC_STATE_NOT_RECEIVED && + if (state == DCCP_ACKVEC_STATE_NOT_RECEIVED && len == 0 && delta == 0) { /* Found our reserved seat! */ dccp_pr_debug("Found %llu reserved seat!\n", @@ -325,6 +325,31 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk, return -EILSEQ; } +#ifdef CONFIG_IP_DCCP_DEBUG +void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len) +{ + dccp_pr_debug_cat("ACK vector len=%d, ackno=%llu |", len, + (unsigned long long)ackno); + + while (len--) { + const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6; + const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; + + dccp_pr_debug_cat("%d,%d|", state, rl); + ++vector; + } + + dccp_pr_debug_cat("\n"); +} + +void dccp_ackvec_print(const struct dccp_ackvec *av) +{ + dccp_ackvector_print(av->av_buf_ackno, + av->av_buf + av->av_buf_head, + av->av_vec_len); +} +#endif + static void dccp_ackvec_throw_record(struct dccp_ackvec *av, struct dccp_ackvec_record *avr) { diff --git a/trunk/net/dccp/ccids/ccid3.c b/trunk/net/dccp/ccids/ccid3.c index a1929f33d703..f813077234b7 100644 --- a/trunk/net/dccp/ccids/ccid3.c +++ b/trunk/net/dccp/ccids/ccid3.c @@ -159,8 +159,8 @@ static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp) } else if (ktime_us_delta(now, hctx->ccid3hctx_t_ld) - (s64)hctx->ccid3hctx_rtt >= 0) { - hctx->ccid3hctx_x = min(2 * hctx->ccid3hctx_x, min_rate); - hctx->ccid3hctx_x = max(hctx->ccid3hctx_x, + hctx->ccid3hctx_x = + max(min(2 * hctx->ccid3hctx_x, min_rate), scaled_div(((__u64)hctx->ccid3hctx_s) << 6, hctx->ccid3hctx_rtt)); hctx->ccid3hctx_t_ld = now; @@ -329,14 +329,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb) hctx->ccid3hctx_x = rfc3390_initial_rate(sk); hctx->ccid3hctx_t_ld = now; } else { - /* - * Sender does not have RTT sample: - * - set fallback RTT (RFC 4340, 3.4) since a RTT value - * is needed in several parts (e.g. window counter); - * - set sending rate X_pps = 1pps as per RFC 3448, 4.2. - */ - hctx->ccid3hctx_rtt = DCCP_FALLBACK_RTT; - hctx->ccid3hctx_x = hctx->ccid3hctx_s; + /* Sender does not have RTT sample: X_pps = 1 pkt/sec */ + hctx->ccid3hctx_x = hctx->ccid3hctx_s; hctx->ccid3hctx_x <<= 6; } ccid3_update_send_interval(hctx); diff --git a/trunk/net/dccp/ccids/lib/tfrc.c b/trunk/net/dccp/ccids/lib/tfrc.c index 97ecec0a8e76..d1dfbb8de64c 100644 --- a/trunk/net/dccp/ccids/lib/tfrc.c +++ b/trunk/net/dccp/ccids/lib/tfrc.c @@ -14,6 +14,14 @@ module_param(tfrc_debug, bool, 0444); MODULE_PARM_DESC(tfrc_debug, "Enable debug messages"); #endif +extern int tfrc_tx_packet_history_init(void); +extern void tfrc_tx_packet_history_exit(void); +extern int tfrc_rx_packet_history_init(void); +extern void tfrc_rx_packet_history_exit(void); + +extern int tfrc_li_init(void); +extern void tfrc_li_exit(void); + static int __init tfrc_module_init(void) { int rc = tfrc_li_init(); diff --git a/trunk/net/dccp/ccids/lib/tfrc.h b/trunk/net/dccp/ccids/lib/tfrc.h index ed9857527acf..1fb1187bbf1c 100644 --- a/trunk/net/dccp/ccids/lib/tfrc.h +++ b/trunk/net/dccp/ccids/lib/tfrc.h @@ -15,7 +15,7 @@ * (at your option) any later version. */ #include -#include +#include #include "../../dccp.h" /* internal includes that this module exports: */ #include "loss_interval.h" @@ -29,19 +29,21 @@ extern int tfrc_debug; #endif /* integer-arithmetic divisions of type (a * 1000000)/b */ -static inline u64 scaled_div(u64 a, u64 b) +static inline u64 scaled_div(u64 a, u32 b) { BUG_ON(b==0); - return div64_u64(a * 1000000, b); + a *= 1000000; + do_div(a, b); + return a; } -static inline u32 scaled_div32(u64 a, u64 b) +static inline u32 scaled_div32(u64 a, u32 b) { u64 result = scaled_div(a, b); if (result > UINT_MAX) { - DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX", - (unsigned long long)a, (unsigned long long)b); + DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U", + (unsigned long long)a, b); return UINT_MAX; } return result; @@ -56,14 +58,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight) return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval; } -extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); -extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); +extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); +extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); -extern int tfrc_tx_packet_history_init(void); -extern void tfrc_tx_packet_history_exit(void); -extern int tfrc_rx_packet_history_init(void); -extern void tfrc_rx_packet_history_exit(void); - -extern int tfrc_li_init(void); -extern void tfrc_li_exit(void); #endif /* _TFRC_H_ */ diff --git a/trunk/net/dccp/ccids/lib/tfrc_equation.c b/trunk/net/dccp/ccids/lib/tfrc_equation.c index 2f20a29cffe4..e4e64b76c10c 100644 --- a/trunk/net/dccp/ccids/lib/tfrc_equation.c +++ b/trunk/net/dccp/ccids/lib/tfrc_equation.c @@ -661,7 +661,7 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p) EXPORT_SYMBOL_GPL(tfrc_calc_x); -/** +/* * tfrc_calc_x_reverse_lookup - try to find p given f(p) * * @fvalue: function value to match, scaled by 1000000 @@ -676,11 +676,11 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue) /* Error cases. */ if (fvalue < tfrc_calc_x_lookup[0][1]) { - DCCP_WARN("fvalue %u smaller than resolution\n", fvalue); - return TFRC_SMALLEST_P; + DCCP_WARN("fvalue %d smaller than resolution\n", fvalue); + return tfrc_calc_x_lookup[0][1]; } if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) { - DCCP_WARN("fvalue %u exceeds bounds!\n", fvalue); + DCCP_WARN("fvalue %d exceeds bounds!\n", fvalue); return 1000000; } diff --git a/trunk/net/dccp/dccp.h b/trunk/net/dccp/dccp.h index 1b2cea244e12..f44d492d3b74 100644 --- a/trunk/net/dccp/dccp.h +++ b/trunk/net/dccp/dccp.h @@ -262,7 +262,7 @@ extern int dccp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct dccp_hdr *dh, const unsigned len); extern int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized); -extern void dccp_destroy_sock(struct sock *sk); +extern int dccp_destroy_sock(struct sock *sk); extern void dccp_close(struct sock *sk, long timeout); extern struct sk_buff *dccp_make_response(struct sock *sk, diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 37d27bcb361f..c22a3780c14e 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -589,7 +589,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) goto drop; - req = inet_reqsk_alloc(&dccp_request_sock_ops); + req = reqsk_alloc(&dccp_request_sock_ops); if (req == NULL) goto drop; @@ -605,6 +605,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb) ireq = inet_rsk(req); ireq->loc_addr = ip_hdr(skb)->daddr; ireq->rmt_addr = ip_hdr(skb)->saddr; + ireq->opt = NULL; /* * Step 3: Process LISTEN state diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index eec3c4717890..9b1129bb7ece 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -421,6 +421,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) ireq6 = inet6_rsk(req); ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); + ireq6->pktopts = NULL; if (ipv6_opt_accepted(sk, skb) || np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || @@ -1091,10 +1092,10 @@ static int dccp_v6_init_sock(struct sock *sk) return err; } -static void dccp_v6_destroy_sock(struct sock *sk) +static int dccp_v6_destroy_sock(struct sock *sk) { dccp_destroy_sock(sk); - inet6_destroy_sock(sk); + return inet6_destroy_sock(sk); } static struct timewait_sock_ops dccp6_timewait_sock_ops = { diff --git a/trunk/net/dccp/minisocks.c b/trunk/net/dccp/minisocks.c index 66dca5bba858..33ad48321b08 100644 --- a/trunk/net/dccp/minisocks.c +++ b/trunk/net/dccp/minisocks.c @@ -165,12 +165,12 @@ struct sock *dccp_create_openreq_child(struct sock *sk, /* See dccp_v4_conn_request */ newdmsk->dccpms_sequence_window = req->rcv_wnd; - newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss; - dccp_update_gss(newsk, dreq->dreq_iss); - - newdp->dccps_isr = dreq->dreq_isr; + newdp->dccps_gar = newdp->dccps_isr = dreq->dreq_isr; dccp_update_gsr(newsk, dreq->dreq_isr); + newdp->dccps_iss = dreq->dreq_iss; + dccp_update_gss(newsk, dreq->dreq_iss); + /* * SWL and AWL are initially adjusted so that they are not less than * the initial Sequence Numbers received and sent, respectively: diff --git a/trunk/net/dccp/options.c b/trunk/net/dccp/options.c index 43bc24e761d0..d2a84a2fecee 100644 --- a/trunk/net/dccp/options.c +++ b/trunk/net/dccp/options.c @@ -107,11 +107,9 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq, * * CCID-specific options are ignored during connection setup, as * negotiation may still be in progress (see RFC 4340, 10.3). - * The same applies to Ack Vectors, as these depend on the CCID. * */ - if (dreq != NULL && (opt >= 128 || - opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1)) + if (dreq != NULL && opt >= 128) goto ignore_option; switch (opt) { diff --git a/trunk/net/dccp/output.c b/trunk/net/dccp/output.c index fe20068c5d8e..1f8a9b64c083 100644 --- a/trunk/net/dccp/output.c +++ b/trunk/net/dccp/output.c @@ -508,7 +508,6 @@ void dccp_send_ack(struct sock *sk) EXPORT_SYMBOL_GPL(dccp_send_ack); -#if 0 /* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */ void dccp_send_delayed_ack(struct sock *sk) { @@ -539,7 +538,6 @@ void dccp_send_delayed_ack(struct sock *sk) icsk->icsk_ack.timeout = timeout; sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout); } -#endif void dccp_send_sync(struct sock *sk, const u64 ackno, const enum dccp_pkt_type pkt_type) diff --git a/trunk/net/dccp/probe.c b/trunk/net/dccp/probe.c index 81368a7f5379..0bcdc9250279 100644 --- a/trunk/net/dccp/probe.c +++ b/trunk/net/dccp/probe.c @@ -42,7 +42,7 @@ static int bufsize = 64 * 1024; static const char procname[] = "dccpprobe"; -static struct { +struct { struct kfifo *fifo; spinlock_t lock; wait_queue_head_t wait; diff --git a/trunk/net/dccp/proto.c b/trunk/net/dccp/proto.c index a0b56009611f..9dfe2470962c 100644 --- a/trunk/net/dccp/proto.c +++ b/trunk/net/dccp/proto.c @@ -237,7 +237,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized) EXPORT_SYMBOL_GPL(dccp_init_sock); -void dccp_destroy_sock(struct sock *sk) +int dccp_destroy_sock(struct sock *sk) { struct dccp_sock *dp = dccp_sk(sk); struct dccp_minisock *dmsk = dccp_msk(sk); @@ -268,6 +268,8 @@ void dccp_destroy_sock(struct sock *sk) /* clean up feature negotiation state */ dccp_feat_clean(dmsk); + + return 0; } EXPORT_SYMBOL_GPL(dccp_destroy_sock); diff --git a/trunk/net/decnet/af_decnet.c b/trunk/net/decnet/af_decnet.c index 931bdf9cb756..fc2efe899e91 100644 --- a/trunk/net/decnet/af_decnet.c +++ b/trunk/net/decnet/af_decnet.c @@ -1719,8 +1719,6 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, * See if there is data ready to read, sleep if there isn't */ for(;;) { - DEFINE_WAIT(wait); - if (sk->sk_err) goto out; @@ -1750,11 +1748,14 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock, goto out; } - prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - sk_wait_event(sk, &timeo, dn_data_ready(sk, queue, flags, target)); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - finish_wait(sk->sk_sleep, &wait); + set_bit(SOCK_ASYNC_WAITDATA, &sock->flags); + SOCK_SLEEP_PRE(sk) + + if (!dn_data_ready(sk, queue, flags, target)) + schedule(); + + SOCK_SLEEP_POST(sk) + clear_bit(SOCK_ASYNC_WAITDATA, &sock->flags); } for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) { @@ -2001,19 +2002,18 @@ static int dn_sendmsg(struct kiocb *iocb, struct socket *sock, * size. */ if (dn_queue_too_long(scp, queue, flags)) { - DEFINE_WAIT(wait); - if (flags & MSG_DONTWAIT) { err = -EWOULDBLOCK; goto out; } - prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE); - set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - sk_wait_event(sk, &timeo, - !dn_queue_too_long(scp, queue, flags)); - clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); - finish_wait(sk->sk_sleep, &wait); + SOCK_SLEEP_PRE(sk) + + if (dn_queue_too_long(scp, queue, flags)) + schedule(); + + SOCK_SLEEP_POST(sk) + continue; } diff --git a/trunk/net/econet/af_econet.c b/trunk/net/econet/af_econet.c index d35127bb84e1..7c9bb13b1539 100644 --- a/trunk/net/econet/af_econet.c +++ b/trunk/net/econet/af_econet.c @@ -573,7 +573,9 @@ static int econet_release(struct socket *sock) sk->sk_state_change(sk); /* It is useless. Just for sanity. */ - sock_orphan(sk); + sock->sk = NULL; + sk->sk_socket = NULL; + sock_set_flag(sk, SOCK_DEAD); /* Purge queues */ diff --git a/trunk/net/ipv4/fib_semantics.c b/trunk/net/ipv4/fib_semantics.c index ded2ae34eab1..9335eba683c3 100644 --- a/trunk/net/ipv4/fib_semantics.c +++ b/trunk/net/ipv4/fib_semantics.c @@ -958,10 +958,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, rtm->rtm_dst_len = dst_len; rtm->rtm_src_len = 0; rtm->rtm_tos = tos; - if (tb_id < 256) - rtm->rtm_table = tb_id; - else - rtm->rtm_table = RT_TABLE_COMPAT; + rtm->rtm_table = tb_id; NLA_PUT_U32(skb, RTA_TABLE, tb_id); rtm->rtm_type = type; rtm->rtm_flags = fi->fib_flags; diff --git a/trunk/net/ipv4/inet_connection_sock.c b/trunk/net/ipv4/inet_connection_sock.c index 5bbf00051512..828ea211ff21 100644 --- a/trunk/net/ipv4/inet_connection_sock.c +++ b/trunk/net/ipv4/inet_connection_sock.c @@ -103,8 +103,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) rover = net_random() % remaining + low; do { - head = &hashinfo->bhash[inet_bhashfn(net, rover, - hashinfo->bhash_size)]; + head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)]; spin_lock(&head->lock); inet_bind_bucket_for_each(tb, node, &head->chain) if (tb->ib_net == net && tb->port == rover) @@ -131,8 +130,7 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum) */ snum = rover; } else { - head = &hashinfo->bhash[inet_bhashfn(net, snum, - hashinfo->bhash_size)]; + head = &hashinfo->bhash[inet_bhashfn(snum, hashinfo->bhash_size)]; spin_lock(&head->lock); inet_bind_bucket_for_each(tb, node, &head->chain) if (tb->ib_net == net && tb->port == snum) @@ -421,8 +419,7 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, struct inet_connection_sock *icsk = inet_csk(parent); struct request_sock_queue *queue = &icsk->icsk_accept_queue; struct listen_sock *lopt = queue->listen_opt; - int max_retries = icsk->icsk_syn_retries ? : sysctl_tcp_synack_retries; - int thresh = max_retries; + int thresh = icsk->icsk_syn_retries ? : sysctl_tcp_synack_retries; unsigned long now = jiffies; struct request_sock **reqp, *req; int i, budget; @@ -458,9 +455,6 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, } } - if (queue->rskq_defer_accept) - max_retries = queue->rskq_defer_accept; - budget = 2 * (lopt->nr_table_entries / (timeout / interval)); i = lopt->clock_hand; @@ -468,9 +462,8 @@ void inet_csk_reqsk_queue_prune(struct sock *parent, reqp=&lopt->syn_table[i]; while ((req = *reqp) != NULL) { if (time_after_eq(now, req->expires)) { - if ((req->retrans < thresh || - (inet_rsk(req)->acked && req->retrans < max_retries)) - && !req->rsk_ops->rtx_syn_ack(parent, req)) { + if (req->retrans < thresh && + !req->rsk_ops->rtx_syn_ack(parent, req)) { unsigned long timeo; if (req->retrans++ == 0) diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index eca5899729e3..2023d37b2708 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -70,8 +70,7 @@ void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, static void __inet_put_port(struct sock *sk) { struct inet_hashinfo *hashinfo = sk->sk_prot->h.hashinfo; - const int bhash = inet_bhashfn(sock_net(sk), inet_sk(sk)->num, - hashinfo->bhash_size); + const int bhash = inet_bhashfn(inet_sk(sk)->num, hashinfo->bhash_size); struct inet_bind_hashbucket *head = &hashinfo->bhash[bhash]; struct inet_bind_bucket *tb; @@ -96,8 +95,7 @@ EXPORT_SYMBOL(inet_put_port); void __inet_inherit_port(struct sock *sk, struct sock *child) { struct inet_hashinfo *table = sk->sk_prot->h.hashinfo; - const int bhash = inet_bhashfn(sock_net(sk), inet_sk(child)->num, - table->bhash_size); + const int bhash = inet_bhashfn(inet_sk(child)->num, table->bhash_size); struct inet_bind_hashbucket *head = &table->bhash[bhash]; struct inet_bind_bucket *tb; @@ -194,7 +192,7 @@ struct sock *__inet_lookup_listener(struct net *net, const struct hlist_head *head; read_lock(&hashinfo->lhash_lock); - head = &hashinfo->listening_hash[inet_lhashfn(net, hnum)]; + head = &hashinfo->listening_hash[inet_lhashfn(hnum)]; if (!hlist_empty(head)) { const struct inet_sock *inet = inet_sk((sk = __sk_head(head))); @@ -227,7 +225,7 @@ struct sock * __inet_lookup_established(struct net *net, /* Optimize here for direct hit, only listening connections can * have wildcards anyways. */ - unsigned int hash = inet_ehashfn(net, daddr, hnum, saddr, sport); + unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); @@ -267,13 +265,13 @@ static int __inet_check_established(struct inet_timewait_death_row *death_row, int dif = sk->sk_bound_dev_if; INET_ADDR_COOKIE(acookie, saddr, daddr) const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); - struct net *net = sock_net(sk); - unsigned int hash = inet_ehashfn(net, daddr, lport, saddr, inet->dport); + unsigned int hash = inet_ehashfn(daddr, lport, saddr, inet->dport); struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); rwlock_t *lock = inet_ehash_lockp(hinfo, hash); struct sock *sk2; const struct hlist_node *node; struct inet_timewait_sock *tw; + struct net *net = sock_net(sk); prefetch(head->chain.first); write_lock(lock); @@ -440,8 +438,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, local_bh_disable(); for (i = 1; i <= remaining; i++) { port = low + (i + offset) % remaining; - head = &hinfo->bhash[inet_bhashfn(net, port, - hinfo->bhash_size)]; + head = &hinfo->bhash[inet_bhashfn(port, hinfo->bhash_size)]; spin_lock(&head->lock); /* Does not bother with rcv_saddr checks, @@ -496,7 +493,7 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row, goto out; } - head = &hinfo->bhash[inet_bhashfn(net, snum, hinfo->bhash_size)]; + head = &hinfo->bhash[inet_bhashfn(snum, hinfo->bhash_size)]; tb = inet_csk(sk)->icsk_bind_hash; spin_lock_bh(&head->lock); if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { diff --git a/trunk/net/ipv4/inet_timewait_sock.c b/trunk/net/ipv4/inet_timewait_sock.c index 06006a5ac8b9..ce16e9ac24c1 100644 --- a/trunk/net/ipv4/inet_timewait_sock.c +++ b/trunk/net/ipv4/inet_timewait_sock.c @@ -32,8 +32,7 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw, write_unlock(lock); /* Disassociate with bind bucket. */ - bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), tw->tw_num, - hashinfo->bhash_size)]; + bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_num, hashinfo->bhash_size)]; spin_lock(&bhead->lock); tb = tw->tw_tb; __hlist_del(&tw->tw_bind_node); @@ -82,8 +81,7 @@ void __inet_twsk_hashdance(struct inet_timewait_sock *tw, struct sock *sk, Note, that any socket with inet->num != 0 MUST be bound in binding cache, even if it is closed. */ - bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->num, - hashinfo->bhash_size)]; + bhead = &hashinfo->bhash[inet_bhashfn(inet->num, hashinfo->bhash_size)]; spin_lock(&bhead->lock); tw->tw_tb = icsk->icsk_bind_hash; BUG_TRAP(icsk->icsk_bind_hash); diff --git a/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c b/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c index 7750c97fde7b..5daefad3d193 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/trunk/net/ipv4/netfilter/nf_nat_snmp_basic.c @@ -232,11 +232,6 @@ static unsigned char asn1_length_decode(struct asn1_ctx *ctx, } } } - - /* don't trust len bigger than ctx buffer */ - if (*len > ctx->end - ctx->pointer) - return 0; - return 1; } @@ -255,10 +250,6 @@ static unsigned char asn1_header_decode(struct asn1_ctx *ctx, if (!asn1_length_decode(ctx, &def, &len)) return 0; - /* primitive shall be definite, indefinite shall be constructed */ - if (*con == ASN1_PRI && !def) - return 0; - if (def) *eoc = ctx->pointer + len; else @@ -443,11 +434,6 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx, unsigned long *optr; size = eoc - ctx->pointer + 1; - - /* first subid actually encodes first two subids */ - if (size < 2 || size > ULONG_MAX/sizeof(unsigned long)) - return 0; - *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); if (*oid == NULL) { if (net_ratelimit()) diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 925fdf18cf92..1d0c97c8712d 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -606,11 +606,12 @@ static void raw_close(struct sock *sk, long timeout) sk_common_release(sk); } -static void raw_destroy(struct sock *sk) +static int raw_destroy(struct sock *sk) { lock_sock(sk); ip_flush_pending_frames(sk); release_sock(sk); + return 0; } /* This gets rid of all the nasties in af_inet. -DaveM */ @@ -931,7 +932,7 @@ static void raw_sock_seq_show(struct seq_file *seq, struct sock *sp, int i) srcp = inet->num; seq_printf(seq, "%4d: %08X:%04X %08X:%04X" - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d", i, src, srcp, dest, destp, sp->sk_state, atomic_read(&sp->sk_wmem_alloc), atomic_read(&sp->sk_rmem_alloc), @@ -944,7 +945,7 @@ static int raw_seq_show(struct seq_file *seq, void *v) if (v == SEQ_START_TOKEN) seq_printf(seq, " sl local_address rem_address st tx_queue " "rx_queue tr tm->when retrnsmt uid timeout " - "inode ref pointer drops\n"); + "inode drops\n"); else raw_sock_seq_show(seq, v, raw_seq_private(seq)->bucket); return 0; diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index fdde2ae07e24..6317d3c8dc0d 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -283,7 +283,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, cookie_check_timestamp(&tcp_opt); ret = NULL; - req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ + req = reqsk_alloc(&tcp_request_sock_ops); /* for safety */ if (!req) goto out; @@ -299,6 +299,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, ireq->rmt_port = th->source; ireq->loc_addr = ip_hdr(skb)->daddr; ireq->rmt_addr = ip_hdr(skb)->saddr; + ireq->opt = NULL; ireq->snd_wscale = tcp_opt.snd_wscale; ireq->rcv_wscale = tcp_opt.rcv_wscale; ireq->sack_ok = tcp_opt.sack_ok; diff --git a/trunk/net/ipv4/tcp.c b/trunk/net/ipv4/tcp.c index cf0850c068f5..ad66b09e0bcd 100644 --- a/trunk/net/ipv4/tcp.c +++ b/trunk/net/ipv4/tcp.c @@ -2110,15 +2110,12 @@ static int do_tcp_setsockopt(struct sock *sk, int level, break; case TCP_DEFER_ACCEPT: - icsk->icsk_accept_queue.rskq_defer_accept = 0; - if (val > 0) { - /* Translate value in seconds to number of - * retransmits */ - while (icsk->icsk_accept_queue.rskq_defer_accept < 32 && - val > ((TCP_TIMEOUT_INIT / HZ) << - icsk->icsk_accept_queue.rskq_defer_accept)) - icsk->icsk_accept_queue.rskq_defer_accept++; - icsk->icsk_accept_queue.rskq_defer_accept++; + if (val < 0) { + err = -EINVAL; + } else { + if (val > MAX_TCP_ACCEPT_DEFERRED) + val = MAX_TCP_ACCEPT_DEFERRED; + icsk->icsk_accept_queue.rskq_defer_accept = val; } break; @@ -2300,8 +2297,7 @@ static int do_tcp_getsockopt(struct sock *sk, int level, val = (val ? : sysctl_tcp_fin_timeout) / HZ; break; case TCP_DEFER_ACCEPT: - val = !icsk->icsk_accept_queue.rskq_defer_accept ? 0 : - ((TCP_TIMEOUT_INIT / HZ) << (icsk->icsk_accept_queue.rskq_defer_accept - 1)); + val = icsk->icsk_accept_queue.rskq_defer_accept; break; case TCP_WINDOW_CLAMP: val = tp->window_clamp; @@ -2461,76 +2457,6 @@ static unsigned long tcp_md5sig_users; static struct tcp_md5sig_pool **tcp_md5sig_pool; static DEFINE_SPINLOCK(tcp_md5sig_pool_lock); -int tcp_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, - int bplen, - struct tcphdr *th, unsigned int tcplen, - struct tcp_md5sig_pool *hp) -{ - struct scatterlist sg[4]; - __u16 data_len; - int block = 0; - __sum16 cksum; - struct hash_desc *desc = &hp->md5_desc; - int err; - unsigned int nbytes = 0; - - sg_init_table(sg, 4); - - /* 1. The TCP pseudo-header */ - sg_set_buf(&sg[block++], &hp->md5_blk, bplen); - nbytes += bplen; - - /* 2. The TCP header, excluding options, and assuming a - * checksum of zero - */ - cksum = th->check; - th->check = 0; - sg_set_buf(&sg[block++], th, sizeof(*th)); - nbytes += sizeof(*th); - - /* 3. The TCP segment data (if any) */ - data_len = tcplen - (th->doff << 2); - if (data_len > 0) { - u8 *data = (u8 *)th + (th->doff << 2); - sg_set_buf(&sg[block++], data, data_len); - nbytes += data_len; - } - - /* 4. an independently-specified key or password, known to both - * TCPs and presumably connection-specific - */ - sg_set_buf(&sg[block++], key->key, key->keylen); - nbytes += key->keylen; - - sg_mark_end(&sg[block - 1]); - - /* Now store the hash into the packet */ - err = crypto_hash_init(desc); - if (err) { - if (net_ratelimit()) - printk(KERN_WARNING "%s(): hash_init failed\n", __func__); - return -1; - } - err = crypto_hash_update(desc, sg, nbytes); - if (err) { - if (net_ratelimit()) - printk(KERN_WARNING "%s(): hash_update failed\n", __func__); - return -1; - } - err = crypto_hash_final(desc, md5_hash); - if (err) { - if (net_ratelimit()) - printk(KERN_WARNING "%s(): hash_final failed\n", __func__); - return -1; - } - - /* Reset header */ - th->check = cksum; - - return 0; -} -EXPORT_SYMBOL(tcp_calc_md5_hash); - static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool) { int cpu; diff --git a/trunk/net/ipv4/tcp_input.c b/trunk/net/ipv4/tcp_input.c index de30e70ff256..b68c3c7d906b 100644 --- a/trunk/net/ipv4/tcp_input.c +++ b/trunk/net/ipv4/tcp_input.c @@ -3448,43 +3448,6 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th, return 1; } -#ifdef CONFIG_TCP_MD5SIG -/* - * Parse MD5 Signature option - */ -u8 *tcp_parse_md5sig_option(struct tcphdr *th) -{ - int length = (th->doff << 2) - sizeof (*th); - u8 *ptr = (u8*)(th + 1); - - /* If the TCP option is too short, we can short cut */ - if (length < TCPOLEN_MD5SIG) - return NULL; - - while (length > 0) { - int opcode = *ptr++; - int opsize; - - switch(opcode) { - case TCPOPT_EOL: - return NULL; - case TCPOPT_NOP: - length--; - continue; - default: - opsize = *ptr++; - if (opsize < 2 || opsize > length) - return NULL; - if (opcode == TCPOPT_MD5SIG) - return ptr; - } - ptr += opsize - 2; - length -= opsize; - } - return NULL; -} -#endif - static inline void tcp_store_ts_recent(struct tcp_sock *tp) { tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; @@ -4576,6 +4539,49 @@ static void tcp_urg(struct sock *sk, struct sk_buff *skb, struct tcphdr *th) } } +static int tcp_defer_accept_check(struct sock *sk) +{ + struct tcp_sock *tp = tcp_sk(sk); + + if (tp->defer_tcp_accept.request) { + int queued_data = tp->rcv_nxt - tp->copied_seq; + int hasfin = !skb_queue_empty(&sk->sk_receive_queue) ? + tcp_hdr((struct sk_buff *) + sk->sk_receive_queue.prev)->fin : 0; + + if (queued_data && hasfin) + queued_data--; + + if (queued_data && + tp->defer_tcp_accept.listen_sk->sk_state == TCP_LISTEN) { + if (sock_flag(sk, SOCK_KEEPOPEN)) { + inet_csk_reset_keepalive_timer(sk, + keepalive_time_when(tp)); + } else { + inet_csk_delete_keepalive_timer(sk); + } + + inet_csk_reqsk_queue_add( + tp->defer_tcp_accept.listen_sk, + tp->defer_tcp_accept.request, + sk); + + tp->defer_tcp_accept.listen_sk->sk_data_ready( + tp->defer_tcp_accept.listen_sk, 0); + + sock_put(tp->defer_tcp_accept.listen_sk); + sock_put(sk); + tp->defer_tcp_accept.listen_sk = NULL; + tp->defer_tcp_accept.request = NULL; + } else if (hasfin || + tp->defer_tcp_accept.listen_sk->sk_state != TCP_LISTEN) { + tcp_reset(sk); + return -1; + } + } + return 0; +} + static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen) { struct tcp_sock *tp = tcp_sk(sk); @@ -4936,6 +4942,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, tcp_data_snd_check(sk); tcp_ack_snd_check(sk); + + tcp_defer_accept_check(sk); return 0; csum_error: @@ -5457,9 +5465,6 @@ EXPORT_SYMBOL(sysctl_tcp_ecn); EXPORT_SYMBOL(sysctl_tcp_reordering); EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); EXPORT_SYMBOL(tcp_parse_options); -#ifdef CONFIG_TCP_MD5SIG -EXPORT_SYMBOL(tcp_parse_md5sig_option); -#endif EXPORT_SYMBOL(tcp_rcv_established); EXPORT_SYMBOL(tcp_rcv_state_process); EXPORT_SYMBOL(tcp_initialize_rcv_mss); diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 0db9b75c1fa2..f2926ae1de57 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -83,19 +83,18 @@ int sysctl_tcp_tw_reuse __read_mostly; int sysctl_tcp_low_latency __read_mostly; +/* Check TCP sequence numbers in ICMP packets. */ +#define ICMP_MIN_LENGTH 8 + +void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb); #ifdef CONFIG_TCP_MD5SIG static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr); static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, __be32 saddr, __be32 daddr, - struct tcphdr *th, unsigned int tcplen); -#else -static inline -struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr) -{ - return NULL; -} + struct tcphdr *th, int protocol, + unsigned int tcplen); #endif struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { @@ -585,7 +584,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) key, ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, - &rep.th, arg.iov[0].iov_len); + &rep.th, IPPROTO_TCP, + arg.iov[0].iov_len); } #endif arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, @@ -604,9 +604,9 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) outside socket context is ugly, certainly. What can I do? */ -static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, - u32 win, u32 ts, int oif, - struct tcp_md5sig_key *key) +static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk, + struct sk_buff *skb, u32 seq, u32 ack, + u32 win, u32 ts) { struct tcphdr *th = tcp_hdr(skb); struct { @@ -618,6 +618,10 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, ]; } rep; struct ip_reply_arg arg; +#ifdef CONFIG_TCP_MD5SIG + struct tcp_md5sig_key *key; + struct tcp_md5sig_key tw_key; +#endif memset(&rep.th, 0, sizeof(struct tcphdr)); memset(&arg, 0, sizeof(arg)); @@ -643,6 +647,23 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, rep.th.window = htons(win); #ifdef CONFIG_TCP_MD5SIG + /* + * The SKB holds an imcoming packet, but may not have a valid ->sk + * pointer. This is especially the case when we're dealing with a + * TIME_WAIT ack, because the sk structure is long gone, and only + * the tcp_timewait_sock remains. So the md5 key is stashed in that + * structure, and we use it in preference. I believe that (twsk || + * skb->sk) holds true, but we program defensively. + */ + if (!twsk && skb->sk) { + key = tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr); + } else if (twsk && twsk->tw_md5_keylen) { + tw_key.key = twsk->tw_md5_key; + tw_key.keylen = twsk->tw_md5_keylen; + key = &tw_key; + } else + key = NULL; + if (key) { int offset = (ts) ? 3 : 0; @@ -657,15 +678,16 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, key, ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, - &rep.th, arg.iov[0].iov_len); + &rep.th, IPPROTO_TCP, + arg.iov[0].iov_len); } #endif arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, ip_hdr(skb)->saddr, /* XXX */ arg.iov[0].iov_len, IPPROTO_TCP, 0); arg.csumoffset = offsetof(struct tcphdr, check) / 2; - if (oif) - arg.bound_dev_if = oif; + if (twsk) + arg.bound_dev_if = twsk->tw_sk.tw_bound_dev_if; ip_send_reply(dev_net(skb->dev)->ipv4.tcp_sock, skb, &arg, arg.iov[0].iov_len); @@ -678,12 +700,9 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); - tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, + tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcptw->tw_ts_recent, - tw->tw_bound_dev_if, - tcp_twsk_md5_key(tcptw) - ); + tcptw->tw_ts_recent); inet_twsk_put(tw); } @@ -691,11 +710,9 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) { - tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, + tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, - req->ts_recent, - 0, - tcp_v4_md5_do_lookup(skb->sk, ip_hdr(skb)->daddr)); + req->ts_recent); } /* @@ -987,12 +1004,18 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval, static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, __be32 saddr, __be32 daddr, - struct tcphdr *th, + struct tcphdr *th, int protocol, unsigned int tcplen) { + struct scatterlist sg[4]; + __u16 data_len; + int block = 0; + __sum16 old_checksum; struct tcp_md5sig_pool *hp; struct tcp4_pseudohdr *bp; + struct hash_desc *desc; int err; + unsigned int nbytes = 0; /* * Okay, so RFC2385 is turned on for this connection, @@ -1004,25 +1027,63 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, goto clear_hash_noput; bp = &hp->md5_blk.ip4; + desc = &hp->md5_desc; /* - * The TCP pseudo-header (in the order: source IP address, + * 1. the TCP pseudo-header (in the order: source IP address, * destination IP address, zero-padded protocol number, and * segment length) */ bp->saddr = saddr; bp->daddr = daddr; bp->pad = 0; - bp->protocol = IPPROTO_TCP; + bp->protocol = protocol; bp->len = htons(tcplen); - err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp), - th, tcplen, hp); + sg_init_table(sg, 4); + + sg_set_buf(&sg[block++], bp, sizeof(*bp)); + nbytes += sizeof(*bp); + + /* 2. the TCP header, excluding options, and assuming a + * checksum of zero/ + */ + old_checksum = th->check; + th->check = 0; + sg_set_buf(&sg[block++], th, sizeof(struct tcphdr)); + nbytes += sizeof(struct tcphdr); + + /* 3. the TCP segment data (if any) */ + data_len = tcplen - (th->doff << 2); + if (data_len > 0) { + unsigned char *data = (unsigned char *)th + (th->doff << 2); + sg_set_buf(&sg[block++], data, data_len); + nbytes += data_len; + } + + /* 4. an independently-specified key or password, known to both + * TCPs and presumably connection-specific + */ + sg_set_buf(&sg[block++], key->key, key->keylen); + nbytes += key->keylen; + + sg_mark_end(&sg[block - 1]); + + /* Now store the Hash into the packet */ + err = crypto_hash_init(desc); + if (err) + goto clear_hash; + err = crypto_hash_update(desc, sg, nbytes); + if (err) + goto clear_hash; + err = crypto_hash_final(desc, md5_hash); if (err) goto clear_hash; - /* Free up the crypto pool */ + /* Reset header, and free up the crypto */ tcp_put_md5sig_pool(); + th->check = old_checksum; + out: return 0; clear_hash: @@ -1036,7 +1097,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct tcphdr *th, + struct tcphdr *th, int protocol, unsigned int tcplen) { __be32 saddr, daddr; @@ -1052,7 +1113,7 @@ int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, } return tcp_v4_do_calc_md5_hash(md5_hash, key, saddr, daddr, - th, tcplen); + th, protocol, tcplen); } EXPORT_SYMBOL(tcp_v4_calc_md5_hash); @@ -1071,12 +1132,52 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) struct tcp_md5sig_key *hash_expected; const struct iphdr *iph = ip_hdr(skb); struct tcphdr *th = tcp_hdr(skb); + int length = (th->doff << 2) - sizeof(struct tcphdr); int genhash; + unsigned char *ptr; unsigned char newhash[16]; hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr); - hash_location = tcp_parse_md5sig_option(th); + /* + * If the TCP option length is less than the TCP_MD5SIG + * option length, then we can shortcut + */ + if (length < TCPOLEN_MD5SIG) { + if (hash_expected) + return 1; + else + return 0; + } + + /* Okay, we can't shortcut - we have to grub through the options */ + ptr = (unsigned char *)(th + 1); + while (length > 0) { + int opcode = *ptr++; + int opsize; + + switch (opcode) { + case TCPOPT_EOL: + goto done_opts; + case TCPOPT_NOP: + length--; + continue; + default: + opsize = *ptr++; + if (opsize < 2) + goto done_opts; + if (opsize > length) + goto done_opts; + + if (opcode == TCPOPT_MD5SIG) { + hash_location = ptr; + goto done_opts; + } + } + ptr += opsize-2; + length -= opsize; + } +done_opts: /* We've parsed the options - do we have a hash? */ if (!hash_expected && !hash_location) return 0; @@ -1103,7 +1204,8 @@ static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb) genhash = tcp_v4_do_calc_md5_hash(newhash, hash_expected, iph->saddr, iph->daddr, - th, skb->len); + th, sk->sk_protocol, + skb->len); if (genhash || memcmp(hash_location, newhash, 16) != 0) { if (net_ratelimit()) { @@ -1181,7 +1283,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) goto drop; - req = inet_reqsk_alloc(&tcp_request_sock_ops); + req = reqsk_alloc(&tcp_request_sock_ops); if (!req) goto drop; @@ -1771,7 +1873,7 @@ static int tcp_v4_init_sock(struct sock *sk) return 0; } -void tcp_v4_destroy_sock(struct sock *sk) +int tcp_v4_destroy_sock(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); @@ -1814,7 +1916,17 @@ void tcp_v4_destroy_sock(struct sock *sk) sk->sk_sndmsg_page = NULL; } + if (tp->defer_tcp_accept.request) { + reqsk_free(tp->defer_tcp_accept.request); + sock_put(tp->defer_tcp_accept.listen_sk); + sock_put(sk); + tp->defer_tcp_accept.listen_sk = NULL; + tp->defer_tcp_accept.request = NULL; + } + atomic_dec(&tcp_sockets_allocated); + + return 0; } EXPORT_SYMBOL(tcp_v4_destroy_sock); diff --git a/trunk/net/ipv4/tcp_minisocks.c b/trunk/net/ipv4/tcp_minisocks.c index ea68a478fad6..1276cab85e3e 100644 --- a/trunk/net/ipv4/tcp_minisocks.c +++ b/trunk/net/ipv4/tcp_minisocks.c @@ -569,10 +569,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, does sequence test, SYN is truncated, and thus we consider it a bare ACK. - If icsk->icsk_accept_queue.rskq_defer_accept, we silently drop this - bare ACK. Otherwise, we create an established connection. Both - ends (listening sockets) accept the new incoming connection and try - to talk to each other. 8-) + Both ends (listening sockets) accept the new incoming + connection and try to talk to each other. 8-) Note: This case is both harmless, and rare. Possibility is about the same as us discovering intelligent life on another plant tomorrow. @@ -640,13 +638,6 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, if (!(flg & TCP_FLAG_ACK)) return NULL; - /* If TCP_DEFER_ACCEPT is set, drop bare ACK. */ - if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && - TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { - inet_rsk(req)->acked = 1; - return NULL; - } - /* OK, ACK is valid, create big socket and * feed this segment to it. It will repeat all * the tests. THIS SEGMENT MUST MOVE SOCKET TO @@ -685,7 +676,24 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb, inet_csk_reqsk_queue_unlink(sk, req, prev); inet_csk_reqsk_queue_removed(sk, req); - inet_csk_reqsk_queue_add(sk, req, child); + if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept && + TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) { + + /* the accept queue handling is done is est recv slow + * path so lets make sure to start there + */ + tcp_sk(child)->pred_flags = 0; + sock_hold(sk); + sock_hold(child); + tcp_sk(child)->defer_tcp_accept.listen_sk = sk; + tcp_sk(child)->defer_tcp_accept.request = req; + + inet_csk_reset_keepalive_timer(child, + inet_csk(sk)->icsk_accept_queue.rskq_defer_accept * HZ); + } else { + inet_csk_reqsk_queue_add(sk, req, child); + } + return child; listen_overflow: diff --git a/trunk/net/ipv4/tcp_output.c b/trunk/net/ipv4/tcp_output.c index 8f83ab432705..b171ac65ccab 100644 --- a/trunk/net/ipv4/tcp_output.c +++ b/trunk/net/ipv4/tcp_output.c @@ -605,6 +605,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, md5, sk, NULL, NULL, tcp_hdr(skb), + sk->sk_protocol, skb->len); } #endif @@ -2263,7 +2264,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, tp->af_specific->calc_md5_hash(md5_hash_location, md5, NULL, dst, req, - tcp_hdr(skb), + tcp_hdr(skb), sk->sk_protocol, skb->len); } #endif diff --git a/trunk/net/ipv4/tcp_timer.c b/trunk/net/ipv4/tcp_timer.c index 3e358cbb1247..e77e7ae0bf2c 100644 --- a/trunk/net/ipv4/tcp_timer.c +++ b/trunk/net/ipv4/tcp_timer.c @@ -487,6 +487,11 @@ static void tcp_keepalive_timer (unsigned long data) goto death; } + if (tp->defer_tcp_accept.request && sk->sk_state == TCP_ESTABLISHED) { + tcp_send_active_reset(sk, GFP_ATOMIC); + goto death; + } + if (!sock_flag(sk, SOCK_KEEPOPEN) || sk->sk_state == TCP_CLOSE) goto out; diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 3bbf6fb6e4f5..355e6d62d483 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -134,7 +134,7 @@ static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, struct sock *sk; struct hlist_node *node; - sk_for_each(sk, node, &udptable[udp_hashfn(net, num)]) + sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)]) if (net_eq(sock_net(sk), net) && sk->sk_hash == num) return 1; return 0; @@ -174,7 +174,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, for (i = 0; i < UDP_HTABLE_SIZE; i++) { int size = 0; - head = &udptable[udp_hashfn(net, rover)]; + head = &udptable[rover & (UDP_HTABLE_SIZE - 1)]; if (hlist_empty(head)) goto gotit; @@ -211,7 +211,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, gotit: snum = rover; } else { - head = &udptable[udp_hashfn(net, snum)]; + head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; sk_for_each(sk2, node, head) if (sk2->sk_hash == snum && @@ -227,7 +227,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum, inet_sk(sk)->num = snum; sk->sk_hash = snum; if (sk_unhashed(sk)) { - head = &udptable[udp_hashfn(net, snum)]; + head = &udptable[snum & (UDP_HTABLE_SIZE - 1)]; sk_add_node(sk, head); sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); } @@ -264,7 +264,7 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, int badness = -1; read_lock(&udp_hash_lock); - sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { + sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_sock *inet = inet_sk(sk); if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && @@ -1040,10 +1040,8 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { /* Note that an ENOMEM error is charged twice */ - if (rc == -ENOMEM) { + if (rc == -ENOMEM) UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); - atomic_inc(&sk->sk_drops); - } goto drop; } @@ -1061,7 +1059,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) * Note: called only from the BH handler context, * so we don't need to lock the hashes. */ -static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, +static int __udp4_lib_mcast_deliver(struct sk_buff *skb, struct udphdr *uh, __be32 saddr, __be32 daddr, struct hlist_head udptable[]) @@ -1070,7 +1068,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb, int dif; read_lock(&udp_hash_lock); - sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); + sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); dif = skb->dev->ifindex; sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); if (sk) { @@ -1158,7 +1156,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], struct rtable *rt = (struct rtable*)skb->dst; __be32 saddr = ip_hdr(skb)->saddr; __be32 daddr = ip_hdr(skb)->daddr; - struct net *net; /* * Validate the packet. @@ -1180,12 +1177,10 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], if (udp4_csum_init(skb, uh, proto)) goto csum_error; - net = dev_net(skb->dev); if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) - return __udp4_lib_mcast_deliver(net, skb, uh, - saddr, daddr, udptable); + return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable); - sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, + sk = __udp4_lib_lookup(dev_net(skb->dev), saddr, uh->source, daddr, uh->dest, inet_iif(skb), udptable); if (sk != NULL) { @@ -1258,11 +1253,12 @@ int udp_rcv(struct sk_buff *skb) return __udp4_lib_rcv(skb, udp_hash, IPPROTO_UDP); } -void udp_destroy_sock(struct sock *sk) +int udp_destroy_sock(struct sock *sk) { lock_sock(sk); udp_flush_pending_frames(sk); release_sock(sk); + return 0; } /* @@ -1631,13 +1627,12 @@ static void udp4_format_sock(struct sock *sp, struct seq_file *f, __u16 srcp = ntohs(inet->sport); seq_printf(f, "%4d: %08X:%04X %08X:%04X" - " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d%n", + " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p%n", bucket, src, srcp, dest, destp, sp->sk_state, atomic_read(&sp->sk_wmem_alloc), atomic_read(&sp->sk_rmem_alloc), 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), - atomic_read(&sp->sk_refcnt), sp, - atomic_read(&sp->sk_drops), len); + atomic_read(&sp->sk_refcnt), sp, len); } int udp4_seq_show(struct seq_file *seq, void *v) @@ -1646,7 +1641,7 @@ int udp4_seq_show(struct seq_file *seq, void *v) seq_printf(seq, "%-127s\n", " sl local_address rem_address st tx_queue " "rx_queue tr tm->when retrnsmt uid timeout " - "inode ref pointer drops"); + "inode"); else { struct udp_iter_state *state = seq->private; int len; diff --git a/trunk/net/ipv4/udp_impl.h b/trunk/net/ipv4/udp_impl.h index 2e9bad2fa1bc..7288bf7977fb 100644 --- a/trunk/net/ipv4/udp_impl.h +++ b/trunk/net/ipv4/udp_impl.h @@ -26,7 +26,7 @@ extern int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, extern int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags); extern int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); -extern void udp_destroy_sock(struct sock *sk); +extern int udp_destroy_sock(struct sock *sk); #ifdef CONFIG_PROC_FS extern int udp4_seq_show(struct seq_file *seq, void *v); diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index 9be6be3a7ff3..deb38bf03376 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -229,12 +229,6 @@ static inline int addrconf_qdisc_ok(struct net_device *dev) return (dev->qdisc != &noop_qdisc); } -/* Check if a route is valid prefix route */ -static inline int addrconf_is_prefix_route(const struct rt6_info *rt) -{ - return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); -} - static void addrconf_del_timer(struct inet6_ifaddr *ifp) { if (del_timer(&ifp->timer)) @@ -781,7 +775,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); - if (rt && addrconf_is_prefix_route(rt)) { + if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { if (onlink == 0) { ip6_del_rt(rt); rt = NULL; @@ -962,8 +956,7 @@ static inline int ipv6_saddr_preferred(int type) return 0; } -static int ipv6_get_saddr_eval(struct net *net, - struct ipv6_saddr_score *score, +static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, struct ipv6_saddr_dst *dst, int i) { @@ -1042,8 +1035,7 @@ static int ipv6_get_saddr_eval(struct net *net, break; case IPV6_SADDR_RULE_LABEL: /* Rule 6: Prefer matching label */ - ret = ipv6_addr_label(net, - &score->ifa->addr, score->addr_type, + ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, score->ifa->idev->dev->ifindex) == dst->label; break; #ifdef CONFIG_IPV6_PRIVACY @@ -1097,7 +1089,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev, dst.addr = daddr; dst.ifindex = dst_dev ? dst_dev->ifindex : 0; dst.scope = __ipv6_addr_src_scope(dst_type); - dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex); + dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); dst.prefs = prefs; hiscore->rule = -1; @@ -1165,8 +1157,8 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev, for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { int minihiscore, miniscore; - minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i); - miniscore = ipv6_get_saddr_eval(net, score, &dst, i); + minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); + miniscore = ipv6_get_saddr_eval(score, &dst, i); if (minihiscore > miniscore) { if (i == IPV6_SADDR_RULE_SCOPE && @@ -1794,7 +1786,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, dev->ifindex, 1); - if (rt && addrconf_is_prefix_route(rt)) { + if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { /* Autoconf prefix route */ if (valid_lft == 0) { ip6_del_rt(rt); diff --git a/trunk/net/ipv6/addrlabel.c b/trunk/net/ipv6/addrlabel.c index 08909039d87b..9bfa8846f262 100644 --- a/trunk/net/ipv6/addrlabel.c +++ b/trunk/net/ipv6/addrlabel.c @@ -29,9 +29,6 @@ */ struct ip6addrlbl_entry { -#ifdef CONFIG_NET_NS - struct net *lbl_net; -#endif struct in6_addr prefix; int prefixlen; int ifindex; @@ -49,16 +46,6 @@ static struct ip6addrlbl_table u32 seq; } ip6addrlbl_table; -static inline -struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl) -{ -#ifdef CONFIG_NET_NS - return lbl->lbl_net; -#else - return &init_net; -#endif -} - /* * Default policy table (RFC3484 + extensions) * @@ -78,7 +65,7 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl) #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL -static const __net_initdata struct ip6addrlbl_init_table +static const __initdata struct ip6addrlbl_init_table { const struct in6_addr *prefix; int prefixlen; @@ -121,9 +108,6 @@ static const __net_initdata struct ip6addrlbl_init_table /* Object management */ static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) { -#ifdef CONFIG_NET_NS - release_net(p->lbl_net); -#endif kfree(p); } @@ -144,13 +128,10 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p) } /* Find label */ -static int __ip6addrlbl_match(struct net *net, - struct ip6addrlbl_entry *p, +static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, const struct in6_addr *addr, int addrtype, int ifindex) { - if (!net_eq(ip6addrlbl_net(p), net)) - return 0; if (p->ifindex && p->ifindex != ifindex) return 0; if (p->addrtype && p->addrtype != addrtype) @@ -160,21 +141,19 @@ static int __ip6addrlbl_match(struct net *net, return 1; } -static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net, - const struct in6_addr *addr, +static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) { struct hlist_node *pos; struct ip6addrlbl_entry *p; hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { - if (__ip6addrlbl_match(net, p, addr, type, ifindex)) + if (__ip6addrlbl_match(p, addr, type, ifindex)) return p; } return NULL; } -u32 ipv6_addr_label(struct net *net, - const struct in6_addr *addr, int type, int ifindex) +u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) { u32 label; struct ip6addrlbl_entry *p; @@ -182,7 +161,7 @@ u32 ipv6_addr_label(struct net *net, type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; rcu_read_lock(); - p = __ipv6_addr_label(net, addr, type, ifindex); + p = __ipv6_addr_label(addr, type, ifindex); label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; rcu_read_unlock(); @@ -195,8 +174,7 @@ u32 ipv6_addr_label(struct net *net, } /* allocate one entry */ -static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net, - const struct in6_addr *prefix, +static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, int prefixlen, int ifindex, u32 label) { @@ -238,9 +216,6 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net, newp->addrtype = addrtype; newp->label = label; INIT_HLIST_NODE(&newp->list); -#ifdef CONFIG_NET_NS - newp->lbl_net = hold_net(net); -#endif atomic_set(&newp->refcnt, 1); return newp; } @@ -262,7 +237,6 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace) hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { if (p->prefixlen == newp->prefixlen && - net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) && p->ifindex == newp->ifindex && ipv6_addr_equal(&p->prefix, &newp->prefix)) { if (!replace) { @@ -287,8 +261,7 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace) } /* add a label */ -static int ip6addrlbl_add(struct net *net, - const struct in6_addr *prefix, int prefixlen, +static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, int ifindex, u32 label, int replace) { struct ip6addrlbl_entry *newp; @@ -301,7 +274,7 @@ static int ip6addrlbl_add(struct net *net, (unsigned int)label, replace); - newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label); + newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); if (IS_ERR(newp)) return PTR_ERR(newp); spin_lock(&ip6addrlbl_table.lock); @@ -313,8 +286,7 @@ static int ip6addrlbl_add(struct net *net, } /* remove a label */ -static int __ip6addrlbl_del(struct net *net, - const struct in6_addr *prefix, int prefixlen, +static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, int ifindex) { struct ip6addrlbl_entry *p = NULL; @@ -328,7 +300,6 @@ static int __ip6addrlbl_del(struct net *net, hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { if (p->prefixlen == prefixlen && - net_eq(ip6addrlbl_net(p), net) && p->ifindex == ifindex && ipv6_addr_equal(&p->prefix, prefix)) { hlist_del_rcu(&p->list); @@ -340,8 +311,7 @@ static int __ip6addrlbl_del(struct net *net, return ret; } -static int ip6addrlbl_del(struct net *net, - const struct in6_addr *prefix, int prefixlen, +static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, int ifindex) { struct in6_addr prefix_buf; @@ -354,13 +324,13 @@ static int ip6addrlbl_del(struct net *net, ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); spin_lock(&ip6addrlbl_table.lock); - ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex); + ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); spin_unlock(&ip6addrlbl_table.lock); return ret; } /* add default label */ -static int __net_init ip6addrlbl_net_init(struct net *net) +static __init int ip6addrlbl_init(void) { int err = 0; int i; @@ -368,8 +338,7 @@ static int __net_init ip6addrlbl_net_init(struct net *net) ADDRLABEL(KERN_DEBUG "%s()\n", __func__); for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { - int ret = ip6addrlbl_add(net, - ip6addrlbl_init_table[i].prefix, + int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, ip6addrlbl_init_table[i].prefixlen, 0, ip6addrlbl_init_table[i].label, 0); @@ -380,32 +349,11 @@ static int __net_init ip6addrlbl_net_init(struct net *net) return err; } -static void __net_exit ip6addrlbl_net_exit(struct net *net) -{ - struct ip6addrlbl_entry *p = NULL; - struct hlist_node *pos, *n; - - /* Remove all labels belonging to the exiting net */ - spin_lock(&ip6addrlbl_table.lock); - hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { - if (net_eq(ip6addrlbl_net(p), net)) { - hlist_del_rcu(&p->list); - ip6addrlbl_put(p); - } - } - spin_unlock(&ip6addrlbl_table.lock); -} - -static struct pernet_operations ipv6_addr_label_ops = { - .init = ip6addrlbl_net_init, - .exit = ip6addrlbl_net_exit, -}; - int __init ipv6_addr_label_init(void) { spin_lock_init(&ip6addrlbl_table.lock); - return register_pernet_subsys(&ipv6_addr_label_ops); + return ip6addrlbl_init(); } static const struct nla_policy ifal_policy[IFAL_MAX+1] = { @@ -423,6 +371,9 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, u32 label; int err = 0; + if (net != &init_net) + return 0; + err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); if (err < 0) return err; @@ -434,7 +385,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, return -EINVAL; if (ifal->ifal_index && - !__dev_get_by_index(net, ifal->ifal_index)) + !__dev_get_by_index(&init_net, ifal->ifal_index)) return -EINVAL; if (!tb[IFAL_ADDRESS]) @@ -452,12 +403,12 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh, switch(nlh->nlmsg_type) { case RTM_NEWADDRLABEL: - err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen, + err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, ifal->ifal_index, label, nlh->nlmsg_flags & NLM_F_REPLACE); break; case RTM_DELADDRLABEL: - err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen, + err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, ifal->ifal_index); break; default: @@ -507,10 +458,12 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb) int idx = 0, s_idx = cb->args[0]; int err; + if (net != &init_net) + return 0; + rcu_read_lock(); hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { - if (idx >= s_idx && - net_eq(ip6addrlbl_net(p), net)) { + if (idx >= s_idx) { if ((err = ip6addrlbl_fill(skb, p, ip6addrlbl_table.seq, NETLINK_CB(cb->skb).pid, @@ -546,6 +499,9 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, struct ip6addrlbl_entry *p; struct sk_buff *skb; + if (net != &init_net) + return 0; + err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); if (err < 0) return err; @@ -557,7 +513,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, return -EINVAL; if (ifal->ifal_index && - !__dev_get_by_index(net, ifal->ifal_index)) + !__dev_get_by_index(&init_net, ifal->ifal_index)) return -EINVAL; if (!tb[IFAL_ADDRESS]) @@ -568,7 +524,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, return -EINVAL; rcu_read_lock(); - p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index); + p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); if (p && ip6addrlbl_hold(p)) p = NULL; lseq = ip6addrlbl_table.seq; @@ -596,7 +552,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh, goto out; } - err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); + err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); out: return err; } diff --git a/trunk/net/ipv6/af_inet6.c b/trunk/net/ipv6/af_inet6.c index 3ce8d2f318c6..350457c761e6 100644 --- a/trunk/net/ipv6/af_inet6.c +++ b/trunk/net/ipv6/af_inet6.c @@ -371,7 +371,7 @@ int inet6_release(struct socket *sock) EXPORT_SYMBOL(inet6_release); -void inet6_destroy_sock(struct sock *sk) +int inet6_destroy_sock(struct sock *sk) { struct ipv6_pinfo *np = inet6_sk(sk); struct sk_buff *skb; @@ -389,6 +389,8 @@ void inet6_destroy_sock(struct sock *sk) if ((opt = xchg(&np->opt, NULL)) != NULL) sock_kfree_s(sk, opt, opt->tot_len); + + return 0; } EXPORT_SYMBOL_GPL(inet6_destroy_sock); diff --git a/trunk/net/ipv6/datagram.c b/trunk/net/ipv6/datagram.c index f7b535dec860..8cdb6b65ee96 100644 --- a/trunk/net/ipv6/datagram.c +++ b/trunk/net/ipv6/datagram.c @@ -703,11 +703,6 @@ int datagram_send_ctl(struct net *net, } *hlimit = *(int *)CMSG_DATA(cmsg); - if (*hlimit < -1 || *hlimit > 0xff) { - err = -EINVAL; - goto exit_f; - } - break; case IPV6_TCLASS: diff --git a/trunk/net/ipv6/inet6_hashtables.c b/trunk/net/ipv6/inet6_hashtables.c index a9cc8ab33a49..580014aea4d6 100644 --- a/trunk/net/ipv6/inet6_hashtables.c +++ b/trunk/net/ipv6/inet6_hashtables.c @@ -68,7 +68,7 @@ struct sock *__inet6_lookup_established(struct net *net, /* Optimize here for direct hit, only listening connections can * have wildcards anyways. */ - unsigned int hash = inet6_ehashfn(net, daddr, hnum, saddr, sport); + unsigned int hash = inet6_ehashfn(daddr, hnum, saddr, sport); struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); @@ -104,8 +104,7 @@ struct sock *inet6_lookup_listener(struct net *net, int score, hiscore = 0; read_lock(&hashinfo->lhash_lock); - sk_for_each(sk, node, - &hashinfo->listening_hash[inet_lhashfn(net, hnum)]) { + sk_for_each(sk, node, &hashinfo->listening_hash[inet_lhashfn(hnum)]) { if (net_eq(sock_net(sk), net) && inet_sk(sk)->num == hnum && sk->sk_family == PF_INET6) { const struct ipv6_pinfo *np = inet6_sk(sk); @@ -166,14 +165,14 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, const struct in6_addr *saddr = &np->daddr; const int dif = sk->sk_bound_dev_if; const __portpair ports = INET_COMBINED_PORTS(inet->dport, lport); - struct net *net = sock_net(sk); - const unsigned int hash = inet6_ehashfn(net, daddr, lport, saddr, + const unsigned int hash = inet6_ehashfn(daddr, lport, saddr, inet->dport); struct inet_ehash_bucket *head = inet_ehash_bucket(hinfo, hash); rwlock_t *lock = inet_ehash_lockp(hinfo, hash); struct sock *sk2; const struct hlist_node *node; struct inet_timewait_sock *tw; + struct net *net = sock_net(sk); prefetch(head->chain.first); write_lock(lock); diff --git a/trunk/net/ipv6/ip6mr.c b/trunk/net/ipv6/ip6mr.c index 90e763073dc5..bf268b386963 100644 --- a/trunk/net/ipv6/ip6mr.c +++ b/trunk/net/ipv6/ip6mr.c @@ -197,7 +197,7 @@ static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) const char *name = vif->dev ? vif->dev->name : "none"; seq_printf(seq, - "%2td %-10s %8ld %7ld %8ld %7ld %05X\n", + "%2Zd %-10s %8ld %7ld %8ld %7ld %05X\n", vif - vif6_table, name, vif->bytes_in, vif->pkt_in, vif->bytes_out, vif->pkt_out, @@ -1240,7 +1240,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int #endif /* - * Spurious command, or MRT6_VERSION which you cannot + * Spurious command, or MRT_VERSION which you cannot * set. */ default: diff --git a/trunk/net/ipv6/ipv6_sockglue.c b/trunk/net/ipv6/ipv6_sockglue.c index a9988841172a..237ebbb9383b 100644 --- a/trunk/net/ipv6/ipv6_sockglue.c +++ b/trunk/net/ipv6/ipv6_sockglue.c @@ -65,7 +65,7 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) /* RA packet may be delivered ONLY to IPPROTO_RAW socket */ if (sk->sk_type != SOCK_RAW || inet_sk(sk)->num != IPPROTO_RAW) - return -ENOPROTOOPT; + return -EINVAL; new_ra = (sel>=0) ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL; @@ -444,7 +444,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, case IPV6_MULTICAST_HOPS: if (sk->sk_type == SOCK_STREAM) - break; + goto e_inval; if (optlen < sizeof(int)) goto e_inval; if (val > 255 || val < -1) @@ -456,15 +456,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, case IPV6_MULTICAST_LOOP: if (optlen < sizeof(int)) goto e_inval; - if (val != valbool) - goto e_inval; np->mc_loop = valbool; retv = 0; break; case IPV6_MULTICAST_IF: if (sk->sk_type == SOCK_STREAM) - break; + goto e_inval; if (optlen < sizeof(int)) goto e_inval; @@ -860,7 +858,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, if (sk->sk_protocol != IPPROTO_UDP && sk->sk_protocol != IPPROTO_UDPLITE && sk->sk_protocol != IPPROTO_TCP) - return -ENOPROTOOPT; + return -EINVAL; if (sk->sk_state != TCP_ESTABLISHED) return -ENOTCONN; val = sk->sk_family; @@ -874,8 +872,6 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, return -EINVAL; if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) return -EFAULT; - if (gsf.gf_group.ss_family != AF_INET6) - return -EADDRNOTAVAIL; lock_sock(sk); err = ip6_mc_msfget(sk, &gsf, (struct group_filter __user *)optval, optlen); diff --git a/trunk/net/ipv6/mcast.c b/trunk/net/ipv6/mcast.c index bd2fe4cfafa7..fbb2d12c41bc 100644 --- a/trunk/net/ipv6/mcast.c +++ b/trunk/net/ipv6/mcast.c @@ -162,6 +162,7 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml, ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) +#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value) #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) #define IPV6_MLD_MAX_MSF 64 diff --git a/trunk/net/ipv6/raw.c b/trunk/net/ipv6/raw.c index 34cfb3f41c2c..e03c1898ab2e 100644 --- a/trunk/net/ipv6/raw.c +++ b/trunk/net/ipv6/raw.c @@ -1162,13 +1162,12 @@ static void rawv6_close(struct sock *sk, long timeout) sk_common_release(sk); } -static void raw6_destroy(struct sock *sk) +static int raw6_destroy(struct sock *sk) { lock_sock(sk); ip6_flush_pending_frames(sk); release_sock(sk); - - inet6_destroy_sock(sk); + return 0; } static int rawv6_init_sk(struct sock *sk) @@ -1199,6 +1198,7 @@ struct proto rawv6_prot = { .disconnect = udp_disconnect, .ioctl = rawv6_ioctl, .init = rawv6_init_sk, + .destroy = inet6_destroy_sock, .setsockopt = rawv6_setsockopt, .getsockopt = rawv6_getsockopt, .sendmsg = rawv6_sendmsg, @@ -1251,7 +1251,7 @@ static int raw6_seq_show(struct seq_file *seq, void *v) "local_address " "remote_address " "st tx_queue rx_queue tr tm->when retrnsmt" - " uid timeout inode ref pointer drops\n"); + " uid timeout inode drops\n"); else raw6_sock_seq_show(seq, v, raw_seq_private(seq)->bucket); return 0; diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index efe036aa3dd1..edae81319b51 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -2194,12 +2194,8 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); - if (!(rt->rt6i_flags & RTF_EXPIRES)) - expires = 0; - else if (rt->rt6i_expires - jiffies < INT_MAX) - expires = rt->rt6i_expires - jiffies; - else - expires = INT_MAX; + expires = (rt->rt6i_flags & RTF_EXPIRES) ? + rt->rt6i_expires - jiffies : 0; if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, expires, rt->u.dst.error) < 0) diff --git a/trunk/net/ipv6/sit.c b/trunk/net/ipv6/sit.c index b7a50e968506..b0c5080420a8 100644 --- a/trunk/net/ipv6/sit.c +++ b/trunk/net/ipv6/sit.c @@ -220,18 +220,15 @@ __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr) } -static int ipip6_tunnel_get_prl(struct ip_tunnel *t, - struct ip_tunnel_prl __user *a) +static int ipip6_tunnel_get_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a) { - struct ip_tunnel_prl kprl, *kp; + struct ip_tunnel_prl *kp; struct ip_tunnel_prl_entry *prl; unsigned int cmax, c = 0, ca, len; int ret = 0; - if (copy_from_user(&kprl, a, sizeof(kprl))) - return -EFAULT; - cmax = kprl.datalen / sizeof(kprl); - if (cmax > 1 && kprl.addr != htonl(INADDR_ANY)) + cmax = a->datalen / sizeof(*a); + if (cmax > 1 && a->addr != htonl(INADDR_ANY)) cmax = 1; /* For simple GET or for root users, @@ -262,25 +259,26 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t, for (prl = t->prl; prl; prl = prl->next) { if (c > cmax) break; - if (kprl.addr != htonl(INADDR_ANY) && prl->addr != kprl.addr) + if (a->addr != htonl(INADDR_ANY) && prl->addr != a->addr) continue; kp[c].addr = prl->addr; kp[c].flags = prl->flags; c++; - if (kprl.addr != htonl(INADDR_ANY)) + if (a->addr != htonl(INADDR_ANY)) break; } out: read_unlock(&ipip6_lock); len = sizeof(*kp) * c; - ret = 0; - if ((len && copy_to_user(a + 1, kp, len)) || put_user(len, &a->datalen)) - ret = -EFAULT; + ret = len ? copy_to_user(a->data, kp, len) : 0; kfree(kp); + if (ret) + return -EFAULT; - return ret; + a->datalen = len; + return 0; } static int @@ -873,20 +871,11 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) break; case SIOCGETPRL: - err = -EINVAL; - if (dev == sitn->fb_tunnel_dev) - goto done; - err = -ENOENT; - if (!(t = netdev_priv(dev))) - goto done; - err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); - break; - case SIOCADDPRL: case SIOCDELPRL: case SIOCCHGPRL: err = -EPERM; - if (!capable(CAP_NET_ADMIN)) + if (cmd != SIOCGETPRL && !capable(CAP_NET_ADMIN)) goto done; err = -EINVAL; if (dev == sitn->fb_tunnel_dev) @@ -899,6 +888,12 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) goto done; switch (cmd) { + case SIOCGETPRL: + err = ipip6_tunnel_get_prl(t, &prl); + if (!err && copy_to_user(ifr->ifr_ifru.ifru_data, + &prl, sizeof(prl))) + err = -EFAULT; + break; case SIOCDELPRL: err = ipip6_tunnel_del_prl(t, &prl); break; @@ -907,7 +902,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); break; } - netdev_state_change(dev); + if (cmd != SIOCGETPRL) + netdev_state_change(dev); break; default: diff --git a/trunk/net/ipv6/syncookies.c b/trunk/net/ipv6/syncookies.c index 3ecc1157994e..938ce4ecde55 100644 --- a/trunk/net/ipv6/syncookies.c +++ b/trunk/net/ipv6/syncookies.c @@ -198,6 +198,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) ireq = inet_rsk(req); ireq6 = inet6_rsk(req); treq = tcp_rsk(req); + ireq6->pktopts = NULL; if (security_inet_conn_request(sk, skb, req)) { reqsk_free(req); diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index daefc18d50a0..155499197fc5 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -80,12 +80,6 @@ static struct inet_connection_sock_af_ops ipv6_specific; #ifdef CONFIG_TCP_MD5SIG static struct tcp_sock_af_ops tcp_sock_ipv6_specific; static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; -#else -static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, - struct in6_addr *addr) -{ - return NULL; -} #endif static void tcp_v6_hash(struct sock *sk) @@ -740,34 +734,78 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval, static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, struct in6_addr *saddr, struct in6_addr *daddr, - struct tcphdr *th, unsigned int tcplen) + struct tcphdr *th, int protocol, + unsigned int tcplen) { + struct scatterlist sg[4]; + __u16 data_len; + int block = 0; + __sum16 cksum; struct tcp_md5sig_pool *hp; struct tcp6_pseudohdr *bp; + struct hash_desc *desc; int err; + unsigned int nbytes = 0; hp = tcp_get_md5sig_pool(); if (!hp) { printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); goto clear_hash_noput; } - bp = &hp->md5_blk.ip6; + desc = &hp->md5_desc; /* 1. TCP pseudo-header (RFC2460) */ ipv6_addr_copy(&bp->saddr, saddr); ipv6_addr_copy(&bp->daddr, daddr); bp->len = htonl(tcplen); - bp->protocol = htonl(IPPROTO_TCP); + bp->protocol = htonl(protocol); - err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp), - th, tcplen, hp); + sg_init_table(sg, 4); - if (err) + sg_set_buf(&sg[block++], bp, sizeof(*bp)); + nbytes += sizeof(*bp); + + /* 2. TCP header, excluding options */ + cksum = th->check; + th->check = 0; + sg_set_buf(&sg[block++], th, sizeof(*th)); + nbytes += sizeof(*th); + + /* 3. TCP segment data (if any) */ + data_len = tcplen - (th->doff << 2); + if (data_len > 0) { + u8 *data = (u8 *)th + (th->doff << 2); + sg_set_buf(&sg[block++], data, data_len); + nbytes += data_len; + } + + /* 4. shared key */ + sg_set_buf(&sg[block++], key->key, key->keylen); + nbytes += key->keylen; + + sg_mark_end(&sg[block - 1]); + + /* Now store the hash into the packet */ + err = crypto_hash_init(desc); + if (err) { + printk(KERN_WARNING "%s(): hash_init failed\n", __func__); + goto clear_hash; + } + err = crypto_hash_update(desc, sg, nbytes); + if (err) { + printk(KERN_WARNING "%s(): hash_update failed\n", __func__); goto clear_hash; + } + err = crypto_hash_final(desc, md5_hash); + if (err) { + printk(KERN_WARNING "%s(): hash_final failed\n", __func__); + goto clear_hash; + } - /* Free up the crypto pool */ + /* Reset header, and free up the crypto */ tcp_put_md5sig_pool(); + th->check = cksum; out: return 0; clear_hash: @@ -781,7 +819,8 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct tcphdr *th, unsigned int tcplen) + struct tcphdr *th, int protocol, + unsigned int tcplen) { struct in6_addr *saddr, *daddr; @@ -794,7 +833,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, } return tcp_v6_do_calc_md5_hash(md5_hash, key, saddr, daddr, - th, tcplen); + th, protocol, tcplen); } static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) @@ -803,12 +842,43 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) struct tcp_md5sig_key *hash_expected; struct ipv6hdr *ip6h = ipv6_hdr(skb); struct tcphdr *th = tcp_hdr(skb); + int length = (th->doff << 2) - sizeof (*th); int genhash; + u8 *ptr; u8 newhash[16]; hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); - hash_location = tcp_parse_md5sig_option(th); + /* If the TCP option is too short, we can short cut */ + if (length < TCPOLEN_MD5SIG) + return hash_expected ? 1 : 0; + + /* parse options */ + ptr = (u8*)(th + 1); + while (length > 0) { + int opcode = *ptr++; + int opsize; + + switch(opcode) { + case TCPOPT_EOL: + goto done_opts; + case TCPOPT_NOP: + length--; + continue; + default: + opsize = *ptr++; + if (opsize < 2 || opsize > length) + goto done_opts; + if (opcode == TCPOPT_MD5SIG) { + hash_location = ptr; + goto done_opts; + } + } + ptr += opsize - 2; + length -= opsize; + } + +done_opts: /* do we have a hash as expected? */ if (!hash_expected) { if (!hash_location) @@ -838,7 +908,8 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) genhash = tcp_v6_do_calc_md5_hash(newhash, hash_expected, &ip6h->saddr, &ip6h->daddr, - th, skb->len); + th, sk->sk_protocol, + skb->len); if (genhash || memcmp(hash_location, newhash, 16) != 0) { if (net_ratelimit()) { printk(KERN_INFO "MD5 Hash %s for " @@ -978,7 +1049,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, &ipv6_hdr(skb)->daddr, &ipv6_hdr(skb)->saddr, - t1, tot_len); + t1, IPPROTO_TCP, tot_len); } #endif @@ -1015,8 +1086,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) kfree_skb(buff); } -static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts, - struct tcp_md5sig_key *key) +static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, + struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) { struct tcphdr *th = tcp_hdr(skb), *t1; struct sk_buff *buff; @@ -1025,6 +1096,22 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 struct sock *ctl_sk = net->ipv6.tcp_sk; unsigned int tot_len = sizeof(struct tcphdr); __be32 *topt; +#ifdef CONFIG_TCP_MD5SIG + struct tcp_md5sig_key *key; + struct tcp_md5sig_key tw_key; +#endif + +#ifdef CONFIG_TCP_MD5SIG + if (!tw && skb->sk) { + key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr); + } else if (tw && tw->tw_md5_keylen) { + tw_key.key = tw->tw_md5_key; + tw_key.keylen = tw->tw_md5_keylen; + key = &tw_key; + } else { + key = NULL; + } +#endif if (ts) tot_len += TCPOLEN_TSTAMP_ALIGNED; @@ -1068,7 +1155,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, &ipv6_hdr(skb)->daddr, &ipv6_hdr(skb)->saddr, - t1, tot_len); + t1, IPPROTO_TCP, tot_len); } #endif @@ -1104,17 +1191,16 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) struct inet_timewait_sock *tw = inet_twsk(sk); struct tcp_timewait_sock *tcptw = tcp_twsk(sk); - tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, + tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, - tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw)); + tcptw->tw_ts_recent); inet_twsk_put(tw); } static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) { - tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent, - tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr)); + tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); } @@ -1211,6 +1297,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) treq = inet6_rsk(req); ipv6_addr_copy(&treq->rmt_addr, &ipv6_hdr(skb)->saddr); ipv6_addr_copy(&treq->loc_addr, &ipv6_hdr(skb)->daddr); + treq->pktopts = NULL; if (!want_cookie) TCP_ECN_create_request(req, tcp_hdr(skb)); @@ -1872,7 +1959,7 @@ static int tcp_v6_init_sock(struct sock *sk) return 0; } -static void tcp_v6_destroy_sock(struct sock *sk) +static int tcp_v6_destroy_sock(struct sock *sk) { #ifdef CONFIG_TCP_MD5SIG /* Clean up the MD5 key list */ @@ -1880,7 +1967,7 @@ static void tcp_v6_destroy_sock(struct sock *sk) tcp_v6_clear_md5_list(sk); #endif tcp_v4_destroy_sock(sk); - inet6_destroy_sock(sk); + return inet6_destroy_sock(sk); } #ifdef CONFIG_PROC_FS diff --git a/trunk/net/ipv6/udp.c b/trunk/net/ipv6/udp.c index f91e1df0d25e..e0693fffc9bd 100644 --- a/trunk/net/ipv6/udp.c +++ b/trunk/net/ipv6/udp.c @@ -65,7 +65,7 @@ static struct sock *__udp6_lib_lookup(struct net *net, int badness = -1; read_lock(&udp_hash_lock); - sk_for_each(sk, node, &udptable[udp_hashfn(net, hnum)]) { + sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) { struct inet_sock *inet = inet_sk(sk); if (net_eq(sock_net(sk), net) && sk->sk_hash == hnum && @@ -297,10 +297,8 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { /* Note that an ENOMEM error is charged twice */ - if (rc == -ENOMEM) { + if (rc == -ENOMEM) UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, is_udplite); - atomic_inc(&sk->sk_drops); - } goto drop; } @@ -355,16 +353,15 @@ static struct sock *udp_v6_mcast_next(struct sock *sk, * Note: called only from the BH handler context, * so we don't need to lock the hashes. */ -static int __udp6_lib_mcast_deliver(struct net *net, struct sk_buff *skb, - struct in6_addr *saddr, struct in6_addr *daddr, - struct hlist_head udptable[]) +static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr, + struct in6_addr *daddr, struct hlist_head udptable[]) { struct sock *sk, *sk2; const struct udphdr *uh = udp_hdr(skb); int dif; read_lock(&udp_hash_lock); - sk = sk_head(&udptable[udp_hashfn(net, ntohs(uh->dest))]); + sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); dif = inet6_iif(skb); sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); if (!sk) { @@ -438,7 +435,6 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], struct net_device *dev = skb->dev; struct in6_addr *saddr, *daddr; u32 ulen = 0; - struct net *net; if (!pskb_may_pull(skb, sizeof(struct udphdr))) goto short_packet; @@ -473,13 +469,11 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], if (udp6_csum_init(skb, uh, proto)) goto discard; - net = dev_net(skb->dev); /* * Multicast receive code */ if (ipv6_addr_is_multicast(daddr)) - return __udp6_lib_mcast_deliver(net, skb, - saddr, daddr, udptable); + return __udp6_lib_mcast_deliver(skb, saddr, daddr, udptable); /* Unicast */ @@ -487,7 +481,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[], * check socket cache ... must talk to Alan about his plans * for sock caches... i'll skip this for now. */ - sk = __udp6_lib_lookup(net, saddr, uh->source, + sk = __udp6_lib_lookup(dev_net(skb->dev), saddr, uh->source, daddr, uh->dest, inet6_iif(skb), udptable); if (sk == NULL) { @@ -885,13 +879,15 @@ int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, goto out; } -void udpv6_destroy_sock(struct sock *sk) +int udpv6_destroy_sock(struct sock *sk) { lock_sock(sk); udp_v6_flush_pending_frames(sk); release_sock(sk); inet6_destroy_sock(sk); + + return 0; } /* @@ -957,7 +953,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket srcp = ntohs(inet->sport); seq_printf(seq, "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n", + "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p\n", bucket, src->s6_addr32[0], src->s6_addr32[1], src->s6_addr32[2], src->s6_addr32[3], srcp, @@ -969,8 +965,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket 0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp), - atomic_read(&sp->sk_refcnt), sp, - atomic_read(&sp->sk_drops)); + atomic_read(&sp->sk_refcnt), sp); } int udp6_seq_show(struct seq_file *seq, void *v) @@ -981,7 +976,7 @@ int udp6_seq_show(struct seq_file *seq, void *v) "local_address " "remote_address " "st tx_queue rx_queue tr tm->when retrnsmt" - " uid timeout inode ref pointer drops\n"); + " uid timeout inode\n"); else udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket); return 0; diff --git a/trunk/net/ipv6/udp_impl.h b/trunk/net/ipv6/udp_impl.h index 92dd7da766d8..321b81a4d418 100644 --- a/trunk/net/ipv6/udp_impl.h +++ b/trunk/net/ipv6/udp_impl.h @@ -29,7 +29,7 @@ extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, size_t len, int noblock, int flags, int *addr_len); extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb); -extern void udpv6_destroy_sock(struct sock *sk); +extern int udpv6_destroy_sock(struct sock *sk); #ifdef CONFIG_PROC_FS extern int udp6_seq_show(struct seq_file *seq, void *v); diff --git a/trunk/net/key/af_key.c b/trunk/net/key/af_key.c index f0fc46c8038d..9bba7ac5fee0 100644 --- a/trunk/net/key/af_key.c +++ b/trunk/net/key/af_key.c @@ -579,43 +579,25 @@ static uint8_t pfkey_proto_from_xfrm(uint8_t proto) return (proto ? proto : IPSEC_PROTO_ANY); } -static inline int pfkey_sockaddr_len(sa_family_t family) +static int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, + xfrm_address_t *xaddr) { - switch (family) { - case AF_INET: - return sizeof(struct sockaddr_in); -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - return sizeof(struct sockaddr_in6); -#endif - } - return 0; -} - -static -int pfkey_sockaddr_extract(const struct sockaddr *sa, xfrm_address_t *xaddr) -{ - switch (sa->sa_family) { + switch (((struct sockaddr*)(addr + 1))->sa_family) { case AF_INET: xaddr->a4 = - ((struct sockaddr_in *)sa)->sin_addr.s_addr; + ((struct sockaddr_in *)(addr + 1))->sin_addr.s_addr; return AF_INET; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: memcpy(xaddr->a6, - &((struct sockaddr_in6 *)sa)->sin6_addr, + &((struct sockaddr_in6 *)(addr + 1))->sin6_addr, sizeof(struct in6_addr)); return AF_INET6; #endif + default: + return 0; } - return 0; -} - -static -int pfkey_sadb_addr2xfrm_addr(struct sadb_address *addr, xfrm_address_t *xaddr) -{ - return pfkey_sockaddr_extract((struct sockaddr *)(addr + 1), - xaddr); + /* NOTREACHED */ } static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void **ext_hdrs) @@ -660,11 +642,20 @@ static struct xfrm_state *pfkey_xfrm_state_lookup(struct sadb_msg *hdr, void ** } #define PFKEY_ALIGN8(a) (1 + (((a) - 1) | (8 - 1))) - static int pfkey_sockaddr_size(sa_family_t family) { - return PFKEY_ALIGN8(pfkey_sockaddr_len(family)); + switch (family) { + case AF_INET: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in)); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in6)); +#endif + default: + return 0; + } + /* NOTREACHED */ } static inline int pfkey_mode_from_xfrm(int mode) @@ -696,36 +687,6 @@ static inline int pfkey_mode_to_xfrm(int mode) } } -static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port, - struct sockaddr *sa, - unsigned short family) -{ - switch (family) { - case AF_INET: - { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - sin->sin_family = AF_INET; - sin->sin_port = port; - sin->sin_addr.s_addr = xaddr->a4; - memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - return 32; - } -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) - case AF_INET6: - { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - sin6->sin6_family = AF_INET6; - sin6->sin6_port = port; - sin6->sin6_flowinfo = 0; - ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6); - sin6->sin6_scope_id = 0; - return 128; - } -#endif - } - return 0; -} - static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, int add_keys, int hsc) { @@ -736,9 +697,13 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, struct sadb_address *addr; struct sadb_key *key; struct sadb_x_sa2 *sa2; + struct sockaddr_in *sin; struct sadb_x_sec_ctx *sec_ctx; struct xfrm_sec_ctx *xfrm_ctx; int ctx_size = 0; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int size; int auth_key_size = 0; int encrypt_key_size = 0; @@ -767,7 +732,14 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, } /* identity & sensitivity */ - if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, x->props.family)) + + if ((x->props.family == AF_INET && + x->sel.saddr.a4 != x->props.saddr.a4) +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + || (x->props.family == AF_INET6 && + memcmp (x->sel.saddr.a6, x->props.saddr.a6, sizeof (struct in6_addr))) +#endif + ) size += sizeof(struct sadb_address) + sockaddr_size; if (add_keys) { @@ -889,12 +861,29 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, protocol's number." - RFC2367 */ addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(&x->props.saddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->props.saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); /* dst address */ @@ -905,32 +894,70 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x, sizeof(uint64_t); addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; + addr->sadb_address_prefixlen = 32; /* XXX */ addr->sadb_address_reserved = 0; + if (x->props.family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->id.daddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(&x->id.daddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) - BUG(); + if (x->sel.saddr.a4 != x->props.saddr.a4) { + addr = (struct sadb_address*) skb_put(skb, + sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ + sizeof(uint64_t); + addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; + addr->sadb_address_proto = + pfkey_proto_from_xfrm(x->sel.proto); + addr->sadb_address_prefixlen = x->sel.prefixlen_s; + addr->sadb_address_reserved = 0; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->sel.saddr.a4; + sin->sin_port = x->sel.sport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; - if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr, - x->props.family)) { - addr = (struct sadb_address*) skb_put(skb, - sizeof(struct sadb_address)+sockaddr_size); - addr->sadb_address_len = - (sizeof(struct sadb_address)+sockaddr_size)/ - sizeof(uint64_t); - addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; - addr->sadb_address_proto = - pfkey_proto_from_xfrm(x->sel.proto); - addr->sadb_address_prefixlen = x->sel.prefixlen_s; - addr->sadb_address_reserved = 0; + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; - pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport, - (struct sockaddr *) (addr + 1), - x->props.family); + if (memcmp (x->sel.saddr.a6, x->props.saddr.a6, + sizeof(struct in6_addr))) { + addr = (struct sadb_address *) skb_put(skb, + sizeof(struct sadb_address)+sockaddr_size); + addr->sadb_address_len = + (sizeof(struct sadb_address)+sockaddr_size)/ + sizeof(uint64_t); + addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY; + addr->sadb_address_proto = + pfkey_proto_from_xfrm(x->sel.proto); + addr->sadb_address_prefixlen = x->sel.prefixlen_s; + addr->sadb_address_reserved = 0; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = x->sel.sport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, x->sel.saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } } +#endif + else + BUG(); /* auth key */ if (add_keys && auth_key_size) { @@ -1826,6 +1853,10 @@ static int parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) { struct xfrm_tmpl *t = xp->xfrm_vec + xp->xfrm_nr; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int mode; if (xp->xfrm_nr >= XFRM_MAX_DEPTH) @@ -1850,19 +1881,31 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) /* addresses present only in tunnel mode */ if (t->mode == XFRM_MODE_TUNNEL) { - u8 *sa = (u8 *) (rq + 1); - int family, socklen; - - family = pfkey_sockaddr_extract((struct sockaddr *)sa, - &t->saddr); - if (!family) - return -EINVAL; - - socklen = pfkey_sockaddr_len(family); - if (pfkey_sockaddr_extract((struct sockaddr *)(sa + socklen), - &t->id.daddr) != family) + struct sockaddr *sa; + sa = (struct sockaddr *)(rq+1); + switch(sa->sa_family) { + case AF_INET: + sin = (struct sockaddr_in*)sa; + t->saddr.a4 = sin->sin_addr.s_addr; + sin++; + if (sin->sin_family != AF_INET) + return -EINVAL; + t->id.daddr.a4 = sin->sin_addr.s_addr; + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + sin6 = (struct sockaddr_in6*)sa; + memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); + sin6++; + if (sin6->sin6_family != AF_INET6) + return -EINVAL; + memcpy(t->id.daddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); + break; +#endif + default: return -EINVAL; - t->encap_family = family; + } + t->encap_family = sa->sa_family; } else t->encap_family = xp->family; @@ -1909,7 +1952,9 @@ static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) for (i=0; ixfrm_nr; i++) { t = xp->xfrm_vec + i; - socklen += pfkey_sockaddr_len(t->encap_family); + socklen += (t->encap_family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); } return sizeof(struct sadb_msg) + @@ -1942,12 +1987,18 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in struct sadb_address *addr; struct sadb_lifetime *lifetime; struct sadb_x_policy *pol; + struct sockaddr_in *sin; struct sadb_x_sec_ctx *sec_ctx; struct xfrm_sec_ctx *xfrm_ctx; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int i; int size; int sockaddr_size = pfkey_sockaddr_size(xp->family); - int socklen = pfkey_sockaddr_len(xp->family); + int socklen = (xp->family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); size = pfkey_xfrm_policy2msg_size(xp); @@ -1965,10 +2016,26 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); addr->sadb_address_prefixlen = xp->selector.prefixlen_s; addr->sadb_address_reserved = 0; - if (!pfkey_sockaddr_fill(&xp->selector.saddr, - xp->selector.sport, - (struct sockaddr *) (addr + 1), - xp->family)) + /* src address */ + if (xp->family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = xp->selector.saddr.a4; + sin->sin_port = xp->selector.sport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (xp->family == AF_INET6) { + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = xp->selector.sport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, xp->selector.saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); /* dst address */ @@ -1981,10 +2048,26 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto); addr->sadb_address_prefixlen = xp->selector.prefixlen_d; addr->sadb_address_reserved = 0; - - pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport, - (struct sockaddr *) (addr + 1), - xp->family); + if (xp->family == AF_INET) { + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = xp->selector.daddr.a4; + sin->sin_port = xp->selector.dport; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (xp->family == AF_INET6) { + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = xp->selector.dport; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, xp->selector.daddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else + BUG(); /* hard time */ lifetime = (struct sadb_lifetime *) skb_put(skb, @@ -2038,13 +2121,12 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in int mode; req_size = sizeof(struct sadb_x_ipsecrequest); - if (t->mode == XFRM_MODE_TUNNEL) { - socklen = pfkey_sockaddr_len(t->encap_family); - req_size += socklen * 2; - } else { + if (t->mode == XFRM_MODE_TUNNEL) + req_size += ((t->encap_family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)) * 2); + else size -= 2*socklen; - socklen = 0; - } rq = (void*)skb_put(skb, req_size); pol->sadb_x_policy_len += req_size/8; memset(rq, 0, sizeof(*rq)); @@ -2059,15 +2141,42 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in if (t->optional) rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; rq->sadb_x_ipsecrequest_reqid = t->reqid; - if (t->mode == XFRM_MODE_TUNNEL) { - u8 *sa = (void *)(rq + 1); - pfkey_sockaddr_fill(&t->saddr, 0, - (struct sockaddr *)sa, - t->encap_family); - pfkey_sockaddr_fill(&t->id.daddr, 0, - (struct sockaddr *) (sa + socklen), - t->encap_family); + switch (t->encap_family) { + case AF_INET: + sin = (void*)(rq+1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = t->saddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + sin++; + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = t->id.daddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + sin6 = (void*)(rq+1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, t->saddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + + sin6++; + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, t->id.daddr.a6, + sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + break; +#endif + default: + break; + } } } @@ -2350,31 +2459,61 @@ static int key_pol_get_resp(struct sock *sk, struct xfrm_policy *xp, struct sadb #ifdef CONFIG_NET_KEY_MIGRATE static int pfkey_sockaddr_pair_size(sa_family_t family) { - return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2); + switch (family) { + case AF_INET: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in) * 2); +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + return PFKEY_ALIGN8(sizeof(struct sockaddr_in6) * 2); +#endif + default: + return 0; + } + /* NOTREACHED */ } static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, xfrm_address_t *saddr, xfrm_address_t *daddr, u16 *family) { - u8 *sa = (u8 *) (rq + 1); - int af, socklen; - + struct sockaddr *sa = (struct sockaddr *)(rq + 1); if (rq->sadb_x_ipsecrequest_len < - pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family)) + pfkey_sockaddr_pair_size(sa->sa_family)) return -EINVAL; - af = pfkey_sockaddr_extract((struct sockaddr *) sa, - saddr); - if (!af) - return -EINVAL; - - socklen = pfkey_sockaddr_len(af); - if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen), - daddr) != af) + switch (sa->sa_family) { + case AF_INET: + { + struct sockaddr_in *sin; + sin = (struct sockaddr_in *)sa; + if ((sin+1)->sin_family != AF_INET) + return -EINVAL; + memcpy(&saddr->a4, &sin->sin_addr, sizeof(saddr->a4)); + sin++; + memcpy(&daddr->a4, &sin->sin_addr, sizeof(daddr->a4)); + *family = AF_INET; + break; + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)sa; + if ((sin6+1)->sin6_family != AF_INET6) + return -EINVAL; + memcpy(&saddr->a6, &sin6->sin6_addr, + sizeof(saddr->a6)); + sin6++; + memcpy(&daddr->a6, &sin6->sin6_addr, + sizeof(daddr->a6)); + *family = AF_INET6; + break; + } +#endif + default: return -EINVAL; + } - *family = af; return 0; } @@ -2891,9 +3030,6 @@ static int key_notify_sa_expire(struct xfrm_state *x, struct km_event *c) static int pfkey_send_notify(struct xfrm_state *x, struct km_event *c) { - if (atomic_read(&pfkey_socks_nr) == 0) - return 0; - switch (c->event) { case XFRM_MSG_EXPIRE: return key_notify_sa_expire(x, c); @@ -2955,6 +3091,10 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct struct sadb_msg *hdr; struct sadb_address *addr; struct sadb_x_policy *pol; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int sockaddr_size; int size; struct sadb_x_sec_ctx *sec_ctx; @@ -3003,11 +3143,29 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(&x->props.saddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->props.saddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); /* dst address */ @@ -3019,11 +3177,29 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(&x->id.daddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->id.daddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->id.daddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy)); @@ -3149,6 +3325,10 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, struct sadb_sa *sa; struct sadb_address *addr; struct sadb_x_nat_t_port *n_port; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int sockaddr_size; int size; __u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0); @@ -3212,11 +3392,29 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC; addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(&x->props.saddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = x->props.saddr.a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, + x->props.saddr.a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); /* NAT_T_SPORT (old port) */ @@ -3235,11 +3433,28 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST; addr->sadb_address_proto = 0; addr->sadb_address_reserved = 0; - addr->sadb_address_prefixlen = - pfkey_sockaddr_fill(ipaddr, 0, - (struct sockaddr *) (addr + 1), - x->props.family); - if (!addr->sadb_address_prefixlen) + if (x->props.family == AF_INET) { + addr->sadb_address_prefixlen = 32; + + sin = (struct sockaddr_in *) (addr + 1); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = ipaddr->a4; + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (x->props.family == AF_INET6) { + addr->sadb_address_prefixlen = 128; + + sin6 = (struct sockaddr_in6 *) (addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr)); + sin6->sin6_scope_id = 0; + } +#endif + else BUG(); /* NAT_T_DPORT (new port) */ @@ -3257,6 +3472,10 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type, struct xfrm_selector *sel) { struct sadb_address *addr; + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize); addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8; addr->sadb_address_exttype = type; @@ -3265,16 +3484,50 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type, switch (type) { case SADB_EXT_ADDRESS_SRC: - addr->sadb_address_prefixlen = sel->prefixlen_s; - pfkey_sockaddr_fill(&sel->saddr, 0, - (struct sockaddr *)(addr + 1), - sel->family); + if (sel->family == AF_INET) { + addr->sadb_address_prefixlen = sel->prefixlen_s; + sin = (struct sockaddr_in *)(addr + 1); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr.s_addr, &sel->saddr, + sizeof(sin->sin_addr.s_addr)); + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (sel->family == AF_INET6) { + addr->sadb_address_prefixlen = sel->prefixlen_s; + sin6 = (struct sockaddr_in6 *)(addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + sin6->sin6_scope_id = 0; + memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr, + sizeof(sin6->sin6_addr.s6_addr)); + } +#endif break; case SADB_EXT_ADDRESS_DST: - addr->sadb_address_prefixlen = sel->prefixlen_d; - pfkey_sockaddr_fill(&sel->daddr, 0, - (struct sockaddr *)(addr + 1), - sel->family); + if (sel->family == AF_INET) { + addr->sadb_address_prefixlen = sel->prefixlen_d; + sin = (struct sockaddr_in *)(addr + 1); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr.s_addr, &sel->daddr, + sizeof(sin->sin_addr.s_addr)); + sin->sin_port = 0; + memset(sin->sin_zero, 0, sizeof(sin->sin_zero)); + } +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + else if (sel->family == AF_INET6) { + addr->sadb_address_prefixlen = sel->prefixlen_d; + sin6 = (struct sockaddr_in6 *)(addr + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + sin6->sin6_scope_id = 0; + memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr, + sizeof(sin6->sin6_addr.s6_addr)); + } +#endif break; default: return -EINVAL; @@ -3289,8 +3542,10 @@ static int set_ipsecrequest(struct sk_buff *skb, xfrm_address_t *src, xfrm_address_t *dst) { struct sadb_x_ipsecrequest *rq; - u8 *sa; - int socklen = pfkey_sockaddr_len(family); + struct sockaddr_in *sin; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct sockaddr_in6 *sin6; +#endif int size_req; size_req = sizeof(struct sadb_x_ipsecrequest) + @@ -3304,10 +3559,38 @@ static int set_ipsecrequest(struct sk_buff *skb, rq->sadb_x_ipsecrequest_level = level; rq->sadb_x_ipsecrequest_reqid = reqid; - sa = (u8 *) (rq + 1); - if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) || - !pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family)) + switch (family) { + case AF_INET: + sin = (struct sockaddr_in *)(rq + 1); + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr.s_addr, src, + sizeof(sin->sin_addr.s_addr)); + sin++; + sin->sin_family = AF_INET; + memcpy(&sin->sin_addr.s_addr, dst, + sizeof(sin->sin_addr.s_addr)); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + sin6 = (struct sockaddr_in6 *)(rq + 1); + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + sin6->sin6_scope_id = 0; + memcpy(&sin6->sin6_addr.s6_addr, src, + sizeof(sin6->sin6_addr.s6_addr)); + sin6++; + sin6->sin6_family = AF_INET6; + sin6->sin6_port = 0; + sin6->sin6_flowinfo = 0; + sin6->sin6_scope_id = 0; + memcpy(&sin6->sin6_addr.s6_addr, dst, + sizeof(sin6->sin6_addr.s6_addr)); + break; +#endif + default: return -EINVAL; + } return 0; } diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 5bcc452a247f..97101dcde4c0 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -128,8 +128,10 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock) static void llc_ui_sk_init(struct socket *sock, struct sock *sk) { - sock_graft(sk, sock); sk->sk_type = sock->type; + sk->sk_sleep = &sock->wait; + sk->sk_socket = sock; + sock->sk = sk; sock->ops = &llc_ui_ops; } diff --git a/trunk/net/mac80211/ieee80211_i.h b/trunk/net/mac80211/ieee80211_i.h index 14fccf16b80f..b19bd16703b2 100644 --- a/trunk/net/mac80211/ieee80211_i.h +++ b/trunk/net/mac80211/ieee80211_i.h @@ -876,7 +876,7 @@ void ieee80211_rx_bss_list_deinit(struct net_device *dev); int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, struct sk_buff *skb, u8 *bssid, - u8 *addr, u64 supp_rates); + u8 *addr); int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, diff --git a/trunk/net/mac80211/main.c b/trunk/net/mac80211/main.c index 5c5396edad32..b182f018a187 100644 --- a/trunk/net/mac80211/main.c +++ b/trunk/net/mac80211/main.c @@ -1707,8 +1707,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) debugfs_hw_add(local); - if (local->hw.conf.beacon_int < 10) - local->hw.conf.beacon_int = 100; + local->hw.conf.beacon_int = 1000; local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | IEEE80211_HW_SIGNAL_DB | diff --git a/trunk/net/mac80211/mlme.c b/trunk/net/mac80211/mlme.c index 55659a730dc1..7f05820dc629 100644 --- a/trunk/net/mac80211/mlme.c +++ b/trunk/net/mac80211/mlme.c @@ -2863,8 +2863,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev, dev->name, print_mac(mac, mgmt->bssid)); ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); ieee80211_ibss_add_sta(dev, NULL, - mgmt->bssid, mgmt->sa, - BIT(rx_status->rate_idx)); + mgmt->bssid, mgmt->sa); } } @@ -3584,7 +3583,7 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, sband = local->hw.wiphy->bands[bss->band]; if (local->hw.conf.beacon_int == 0) - local->hw.conf.beacon_int = 100; + local->hw.conf.beacon_int = 10000; bss->beacon_int = local->hw.conf.beacon_int; bss->last_update = jiffies; bss->capability = WLAN_CAPABILITY_IBSS; @@ -4308,13 +4307,12 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, struct sk_buff *skb, u8 *bssid, - u8 *addr, u64 supp_rates) + u8 *addr) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); DECLARE_MAC_BUF(mac); - int band = local->hw.conf.channel->band; /* TODO: Could consider removing the least recently used entry and * allow new one to be added. */ @@ -4326,9 +4324,6 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, return NULL; } - if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) - return NULL; - printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); @@ -4338,10 +4333,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, set_sta_flags(sta, WLAN_STA_AUTHORIZED); - if (supp_rates) - sta->supp_rates[band] = supp_rates; - else - sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band]; + sta->supp_rates[local->hw.conf.channel->band] = + sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; rate_control_rate_init(sta, local); diff --git a/trunk/net/mac80211/rx.c b/trunk/net/mac80211/rx.c index c32a0bcd53b7..a3643fd86af9 100644 --- a/trunk/net/mac80211/rx.c +++ b/trunk/net/mac80211/rx.c @@ -67,9 +67,12 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status, return 1; if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) return 1; - if (ieee80211_is_ctl(hdr->frame_control) && - !ieee80211_is_pspoll(hdr->frame_control) && - !ieee80211_is_back_req(hdr->frame_control)) + if (((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == + cpu_to_le16(IEEE80211_FTYPE_CTL)) && + ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != + cpu_to_le16(IEEE80211_STYPE_PSPOLL)) && + ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != + cpu_to_le16(IEEE80211_STYPE_BACK_REQ))) return 1; return 0; } @@ -1823,13 +1826,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, if (!bssid) return 0; if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && - (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { - if (!rx->sta) - rx->sta = ieee80211_ibss_add_sta(sdata->dev, - rx->skb, bssid, hdr->addr2, - BIT(rx->status->rate_idx)); + (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) return 1; - } else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { if (!(rx->flags & IEEE80211_RX_IN_SCAN)) return 0; @@ -1842,8 +1840,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, rx->flags &= ~IEEE80211_RX_RA_MATCH; } else if (!rx->sta) rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, - bssid, hdr->addr2, - BIT(rx->status->rate_idx)); + bssid, hdr->addr2); break; case IEEE80211_IF_TYPE_MESH_POINT: if (!multicast && @@ -2121,7 +2118,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct sta_info *sta; struct tid_ampdu_rx *tid_agg_rx; - u16 sc; + u16 fc, sc; u16 mpdu_seq_num; u8 ret = 0, *qc; int tid; @@ -2130,12 +2127,14 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, if (!sta) return ret; + fc = le16_to_cpu(hdr->frame_control); + /* filter the QoS data rx stream according to * STA/TID and check if this STA/TID is on aggregation */ - if (!ieee80211_is_data_qos(hdr->frame_control)) + if (!WLAN_FC_IS_QOS_DATA(fc)) goto end_reorder; - qc = ieee80211_get_qos_ctl(hdr); + qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN; tid = qc[0] & QOS_CONTROL_TID_MASK; if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) @@ -2144,7 +2143,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; /* null data frames are excluded */ - if (unlikely(ieee80211_is_nullfunc(hdr->frame_control))) + if (unlikely(fc & IEEE80211_STYPE_NULLFUNC)) goto end_reorder; /* new un-ordered ampdu frame - process it */ diff --git a/trunk/net/mac80211/tkip.c b/trunk/net/mac80211/tkip.c index e710243d82e2..a00cf1ea7719 100644 --- a/trunk/net/mac80211/tkip.c +++ b/trunk/net/mac80211/tkip.c @@ -64,14 +64,6 @@ static u16 tkipS(u16 val) return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); } -static u8 *write_tkip_iv(u8 *pos, u16 iv16) -{ - *pos++ = iv16 >> 8; - *pos++ = ((iv16 >> 8) | 0x20) & 0x7f; - *pos++ = iv16 & 0xFF; - return pos; -} - /* * P1K := Phase1(TA, TK, TSC) * TA = transmitter address (48 bits) @@ -79,10 +71,11 @@ static u8 *write_tkip_iv(u8 *pos, u16 iv16) * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) * P1K: 80 bits */ -static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, - const u8 *ta, u32 tsc_IV32) +static void tkip_mixing_phase1(struct ieee80211_key *key, const u8 *ta, + struct tkip_ctx *ctx, u32 tsc_IV32) { int i, j; + const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; u16 *p1k = ctx->p1k; p1k[0] = tsc_IV32 & 0xFFFF; @@ -102,11 +95,12 @@ static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, ctx->initialized = 1; } -static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, +static void tkip_mixing_phase2(struct ieee80211_key *key, struct tkip_ctx *ctx, u16 tsc_IV16, u8 *rc4key) { u16 ppk[6]; const u16 *p1k = ctx->p1k; + const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; int i; ppk[0] = p1k[0]; @@ -129,9 +123,12 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, ppk[4] += ror16(ppk[3], 1); ppk[5] += ror16(ppk[4], 1); - rc4key = write_tkip_iv(rc4key, tsc_IV16); - *rc4key++ = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; + rc4key[0] = tsc_IV16 >> 8; + rc4key[1] = ((tsc_IV16 >> 8) | 0x20) & 0x7f; + rc4key[2] = tsc_IV16 & 0xFF; + rc4key[3] = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; + rc4key += 4; for (i = 0; i < 6; i++) put_unaligned_le16(ppk[i], rc4key + 2 * i); } @@ -139,41 +136,51 @@ static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets * of the IV. Returns pointer to the octet following IVs (i.e., beginning of * the packet payload). */ -u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) +u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, + u8 iv0, u8 iv1, u8 iv2) { - pos = write_tkip_iv(pos, iv16); + *pos++ = iv0; + *pos++ = iv1; + *pos++ = iv2; *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; put_unaligned_le32(key->u.tkip.tx.iv32, pos); return pos + 4; } +static void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, + u8 *rc4key) +{ + /* Calculate per-packet key */ + if (key->u.tkip.tx.iv16 == 0 || !key->u.tkip.tx.initialized) + tkip_mixing_phase1(key, ta, &key->u.tkip.tx, key->u.tkip.tx.iv32); + + tkip_mixing_phase2(key, &key->u.tkip.tx, key->u.tkip.tx.iv16, rc4key); +} + void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, struct sk_buff *skb, enum ieee80211_tkip_key_type type, u8 *outkey) { struct ieee80211_key *key = (struct ieee80211_key *) container_of(keyconf, struct ieee80211_key, conf); - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - u8 *data; - const u8 *tk; - struct tkip_ctx *ctx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + u8 *data = (u8 *) hdr; + u16 fc = le16_to_cpu(hdr->frame_control); + int hdr_len = ieee80211_get_hdrlen(fc); + u8 *ta = hdr->addr2; u16 iv16; u32 iv32; - data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); - iv16 = data[2] | (data[0] << 8); - iv32 = get_unaligned_le32(&data[4]); - - tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; - ctx = &key->u.tkip.tx; + iv16 = data[hdr_len + 2] | (data[hdr_len] << 8); + iv32 = get_unaligned_le32(data + hdr_len + 4); #ifdef CONFIG_TKIP_DEBUG printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", iv16, iv32); - if (iv32 != ctx->iv32) { + if (iv32 != key->u.tkip.tx.iv32) { printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", - iv32, ctx->iv32); + iv32, key->u.tkip.tx.iv32); printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " "fragmented packet\n"); } @@ -182,15 +189,15 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, /* Update the p1k only when the iv16 in the packet wraps around, this * might occur after the wrap around of iv16 in the key in case of * fragmented packets. */ - if (iv16 == 0 || !ctx->initialized) - tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); + if (iv16 == 0 || !key->u.tkip.tx.initialized) + tkip_mixing_phase1(key, ta, &key->u.tkip.tx, iv32); if (type == IEEE80211_TKIP_P1_KEY) { - memcpy(outkey, ctx->p1k, sizeof(u16) * 5); + memcpy(outkey, key->u.tkip.tx.p1k, sizeof(u16) * 5); return; } - tkip_mixing_phase2(tk, ctx, iv16, outkey); + tkip_mixing_phase2(key, &key->u.tkip.tx, iv16, outkey); } EXPORT_SYMBOL(ieee80211_get_tkip_key); @@ -204,16 +211,9 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, u8 *pos, size_t payload_len, u8 *ta) { u8 rc4key[16]; - struct tkip_ctx *ctx = &key->u.tkip.tx; - const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; - /* Calculate per-packet key */ - if (ctx->iv16 == 0 || !ctx->initialized) - tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); - - tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); - - pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); + ieee80211_tkip_gen_rc4key(key, ta, rc4key); + pos = ieee80211_tkip_add_iv(pos, key, rc4key[0], rc4key[1], rc4key[2]); ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); } @@ -231,7 +231,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, u32 iv16; u8 rc4key[16], keyid, *pos = payload; int res; - const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; if (payload_len < 12) return -1; @@ -282,7 +281,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, if (!key->u.tkip.rx[queue].initialized || key->u.tkip.rx[queue].iv32 != iv32) { /* IV16 wrapped around - perform TKIP phase 1 */ - tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); + tkip_mixing_phase1(key, ta, &key->u.tkip.rx[queue], iv32); #ifdef CONFIG_TKIP_DEBUG { int i; @@ -315,7 +314,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, } } - tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); + tkip_mixing_phase2(key, &key->u.tkip.rx[queue], iv16, rc4key); #ifdef CONFIG_TKIP_DEBUG { int i; diff --git a/trunk/net/mac80211/tkip.h b/trunk/net/mac80211/tkip.h index d4714383f5fc..b890427fc959 100644 --- a/trunk/net/mac80211/tkip.h +++ b/trunk/net/mac80211/tkip.h @@ -13,8 +13,8 @@ #include #include "key.h" -u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); - +u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, + u8 iv0, u8 iv1, u8 iv2); void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, struct ieee80211_key *key, u8 *pos, size_t payload_len, u8 *ta); diff --git a/trunk/net/mac80211/tx.c b/trunk/net/mac80211/tx.c index 195cb6dd02a0..1ad9e664f287 100644 --- a/trunk/net/mac80211/tx.c +++ b/trunk/net/mac80211/tx.c @@ -660,8 +660,9 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) /* * Warn when submitting a fragmented A-MPDU frame and drop it. - * This scenario is handled in __ieee80211_tx_prepare but extra - * caution taken here as fragmented ampdu may cause Tx stop. + * This is an error and needs to be fixed elsewhere, but when + * done needs to take care of monitor interfaces (injection) + * etc. */ if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || skb_get_queue_mapping(tx->skb) >= @@ -980,8 +981,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, if (tx->flags & IEEE80211_TX_FRAGMENTED) { if ((tx->flags & IEEE80211_TX_UNICAST) && skb->len + FCS_LEN > local->fragmentation_threshold && - !local->ops->set_frag_threshold && - !(info->flags & IEEE80211_TX_CTL_AMPDU)) + !local->ops->set_frag_threshold) tx->flags |= IEEE80211_TX_FRAGMENTED; else tx->flags &= ~IEEE80211_TX_FRAGMENTED; diff --git a/trunk/net/mac80211/util.c b/trunk/net/mac80211/util.c index ce62b163b82c..6513bc2d2707 100644 --- a/trunk/net/mac80211/util.c +++ b/trunk/net/mac80211/util.c @@ -45,37 +45,38 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, enum ieee80211_if_types type) { - __le16 fc = hdr->frame_control; + u16 fc; /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ if (len < 16) return NULL; - if (ieee80211_is_data(fc)) { - if (len < 24) /* drop incorrect hdr len (data) */ - return NULL; + fc = le16_to_cpu(hdr->frame_control); - if (ieee80211_has_a4(fc)) + switch (fc & IEEE80211_FCTL_FTYPE) { + case IEEE80211_FTYPE_DATA: + if (len < 24) /* drop incorrect hdr len (data) */ return NULL; - if (ieee80211_has_tods(fc)) + switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { + case IEEE80211_FCTL_TODS: return hdr->addr1; - if (ieee80211_has_fromds(fc)) + case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): + return NULL; + case IEEE80211_FCTL_FROMDS: return hdr->addr2; - - return hdr->addr3; - } - - if (ieee80211_is_mgmt(fc)) { + case 0: + return hdr->addr3; + } + break; + case IEEE80211_FTYPE_MGMT: if (len < 24) /* drop incorrect hdr len (mgmt) */ return NULL; return hdr->addr3; - } - - if (ieee80211_is_ctl(fc)) { - if(ieee80211_is_pspoll(fc)) + case IEEE80211_FTYPE_CTL: + if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL) return hdr->addr1; - - if (ieee80211_is_back_req(fc)) { + else if ((fc & IEEE80211_FCTL_STYPE) == + IEEE80211_STYPE_BACK_REQ) { switch (type) { case IEEE80211_IF_TYPE_STA: return hdr->addr2; @@ -83,9 +84,11 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, case IEEE80211_IF_TYPE_VLAN: return hdr->addr1; default: - break; /* fall through to the return */ + return NULL; } } + else + return NULL; } return NULL; @@ -130,46 +133,14 @@ int ieee80211_get_hdrlen(u16 fc) } EXPORT_SYMBOL(ieee80211_get_hdrlen); -unsigned int ieee80211_hdrlen(__le16 fc) -{ - unsigned int hdrlen = 24; - - if (ieee80211_is_data(fc)) { - if (ieee80211_has_a4(fc)) - hdrlen = 30; - if (ieee80211_is_data_qos(fc)) - hdrlen += IEEE80211_QOS_CTL_LEN; - goto out; - } - - if (ieee80211_is_ctl(fc)) { - /* - * ACK and CTS are 10 bytes, all others 16. To see how - * to get this condition consider - * subtype mask: 0b0000000011110000 (0x00F0) - * ACK subtype: 0b0000000011010000 (0x00D0) - * CTS subtype: 0b0000000011000000 (0x00C0) - * bits that matter: ^^^ (0x00E0) - * value of those: 0b0000000011000000 (0x00C0) - */ - if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0)) - hdrlen = 10; - else - hdrlen = 16; - } -out: - return hdrlen; -} -EXPORT_SYMBOL(ieee80211_hdrlen); - -unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) +int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) { - const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; - unsigned int hdrlen; + const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data; + int hdrlen; if (unlikely(skb->len < 10)) return 0; - hdrlen = ieee80211_hdrlen(hdr->frame_control); + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); if (unlikely(hdrlen > skb->len)) return 0; return hdrlen; diff --git a/trunk/net/mac80211/wext.c b/trunk/net/mac80211/wext.c index 5af3862e7191..4806d96b9877 100644 --- a/trunk/net/mac80211/wext.c +++ b/trunk/net/mac80211/wext.c @@ -508,8 +508,7 @@ static int ieee80211_ioctl_giwap(struct net_device *dev, sdata = IEEE80211_DEV_TO_SUB_IF(dev); if (sdata->vif.type == IEEE80211_IF_TYPE_STA || sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { - if (sdata->u.sta.state == IEEE80211_ASSOCIATED || - sdata->u.sta.state == IEEE80211_IBSS_JOINED) { + if (sdata->u.sta.state == IEEE80211_ASSOCIATED) { ap_addr->sa_family = ARPHRD_ETHER; memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); return 0; diff --git a/trunk/net/mac80211/wme.c b/trunk/net/mac80211/wme.c index cfa8fbb0736a..14a9ff10a1e9 100644 --- a/trunk/net/mac80211/wme.c +++ b/trunk/net/mac80211/wme.c @@ -105,8 +105,11 @@ static int classify80211(struct sk_buff *skb, struct Qdisc *qd) { struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + unsigned short fc = le16_to_cpu(hdr->frame_control); + int qos; - if (!ieee80211_is_data(hdr->frame_control)) { + /* see if frame is data or non data frame */ + if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { /* management frames go on AC_VO queue, but are sent * without QoS control fields */ return 0; @@ -116,7 +119,10 @@ static int classify80211(struct sk_buff *skb, struct Qdisc *qd) /* use AC from radiotap */ } - if (!ieee80211_is_data_qos(hdr->frame_control)) { + /* is this a QoS frame? */ + qos = fc & IEEE80211_STYPE_QOS_DATA; + + if (!qos) { skb->priority = 0; /* required for correct WPA/11i MIC */ return ieee802_1d_to_ac[skb->priority]; } @@ -145,6 +151,7 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) struct ieee80211_sched_data *q = qdisc_priv(qd); struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + unsigned short fc = le16_to_cpu(hdr->frame_control); struct Qdisc *qdisc; struct sta_info *sta; int err, queue; @@ -178,15 +185,16 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) /* now we know the 1d priority, fill in the QoS header if there is one */ - if (ieee80211_is_data_qos(hdr->frame_control)) { - u8 *p = ieee80211_get_qos_ctl(hdr); + if (WLAN_FC_IS_QOS_DATA(fc)) { + u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; u8 ack_policy = 0; tid = skb->priority & QOS_CONTROL_TAG1D_MASK; if (local->wifi_wme_noack_test) ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << QOS_CONTROL_ACK_POLICY_SHIFT; /* qos header is 2 bytes, second reserved */ - *p++ = ack_policy | tid; + *p = ack_policy | tid; + p++; *p = 0; rcu_read_lock(); @@ -637,7 +645,7 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, #ifdef CONFIG_MAC80211_HT_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "allocated aggregation queue" - " %d tid %d addr %s pool=0x%lX\n", + " %d tid %d addr %s pool=0x%lX", i, tid, print_mac(mac, sta->addr), q->qdisc_pool[0]); #endif /* CONFIG_MAC80211_HT_DEBUG */ diff --git a/trunk/net/mac80211/wpa.c b/trunk/net/mac80211/wpa.c index 345e10e9b313..9f6fd20374e1 100644 --- a/trunk/net/mac80211/wpa.c +++ b/trunk/net/mac80211/wpa.c @@ -24,22 +24,46 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, { struct ieee80211_hdr *hdr; size_t hdrlen; - __le16 fc; - - hdr = (struct ieee80211_hdr *)skb->data; - fc = hdr->frame_control; + u16 fc; + int a4_included; + u8 *pos; - hdrlen = ieee80211_hdrlen(fc); + hdr = (struct ieee80211_hdr *) skb->data; + fc = le16_to_cpu(hdr->frame_control); + + hdrlen = 24; + if ((fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) == + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { + hdrlen += ETH_ALEN; + *sa = hdr->addr4; + *da = hdr->addr3; + } else if (fc & IEEE80211_FCTL_FROMDS) { + *sa = hdr->addr3; + *da = hdr->addr1; + } else if (fc & IEEE80211_FCTL_TODS) { + *sa = hdr->addr2; + *da = hdr->addr3; + } else { + *sa = hdr->addr2; + *da = hdr->addr1; + } - *sa = ieee80211_get_SA(hdr); - *da = ieee80211_get_DA(hdr); + if (fc & 0x80) + hdrlen += 2; *data = skb->data + hdrlen; *data_len = skb->len - hdrlen; - if (ieee80211_is_data_qos(fc)) - *qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80; - else + a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); + if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && + fc & IEEE80211_STYPE_QOS_DATA) { + pos = (u8 *) &hdr->addr4; + if (a4_included) + pos += 6; + *qos_tid = pos[0] & 0x0f; + *qos_tid |= 0x80; /* qos_included flag */ + } else *qos_tid = 0; return skb->len < hdrlen ? -1 : 0; @@ -162,8 +186,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; struct ieee80211_key *key = tx->key; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - unsigned int hdrlen; - int len, tail; + int hdrlen, len, tail; + u16 fc; u8 *pos; info->control.icv_len = TKIP_ICV_LEN; @@ -176,7 +200,8 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) return 0; } - hdrlen = ieee80211_hdrlen(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_control); + hdrlen = ieee80211_get_hdrlen(fc); len = skb->len - hdrlen; if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) @@ -198,8 +223,14 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) key->u.tkip.tx.iv32++; if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { + hdr = (struct ieee80211_hdr *)skb->data; + /* hwaccel - with preallocated room for IV */ - ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); + ieee80211_tkip_add_iv(pos, key, + (u8) (key->u.tkip.tx.iv16 >> 8), + (u8) (((key->u.tkip.tx.iv16 >> 8) | 0x20) & + 0x7f), + (u8) key->u.tkip.tx.iv16); info->control.hw_key = &tx->key->conf; return 0; @@ -241,12 +272,14 @@ ieee80211_rx_result ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; + u16 fc; int hdrlen, res, hwaccel = 0, wpa_test = 0; struct ieee80211_key *key = rx->key; struct sk_buff *skb = rx->skb; DECLARE_MAC_BUF(mac); - hdrlen = ieee80211_hdrlen(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_control); + hdrlen = ieee80211_get_hdrlen(fc); if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) return RX_CONTINUE; @@ -394,6 +427,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) struct ieee80211_key *key = tx->key; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); int hdrlen, len, tail; + u16 fc; u8 *pos, *pn, *b_0, *aad, *scratch; int i; @@ -412,7 +446,8 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) b_0 = scratch + 3 * AES_BLOCK_LEN; aad = scratch + 4 * AES_BLOCK_LEN; - hdrlen = ieee80211_hdrlen(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_control); + hdrlen = ieee80211_get_hdrlen(fc); len = skb->len - hdrlen; if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) @@ -481,6 +516,7 @@ ieee80211_rx_result ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; + u16 fc; int hdrlen; struct ieee80211_key *key = rx->key; struct sk_buff *skb = rx->skb; @@ -488,7 +524,8 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) int data_len; DECLARE_MAC_BUF(mac); - hdrlen = ieee80211_hdrlen(hdr->frame_control); + fc = le16_to_cpu(hdr->frame_control); + hdrlen = ieee80211_get_hdrlen(fc); if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) return RX_CONTINUE; diff --git a/trunk/net/netfilter/nf_conntrack_core.c b/trunk/net/netfilter/nf_conntrack_core.c index f27c99246a4c..e6d645221d5c 100644 --- a/trunk/net/netfilter/nf_conntrack_core.c +++ b/trunk/net/netfilter/nf_conntrack_core.c @@ -196,6 +196,8 @@ destroy_conntrack(struct nf_conntrack *nfct) if (l4proto && l4proto->destroy) l4proto->destroy(ct); + nf_ct_ext_destroy(ct); + rcu_read_unlock(); spin_lock_bh(&nf_conntrack_lock); @@ -518,7 +520,6 @@ static void nf_conntrack_free_rcu(struct rcu_head *head) void nf_conntrack_free(struct nf_conn *ct) { - nf_ct_ext_destroy(ct); call_rcu(&ct->rcu, nf_conntrack_free_rcu); } EXPORT_SYMBOL_GPL(nf_conntrack_free); diff --git a/trunk/net/netfilter/nf_log.c b/trunk/net/netfilter/nf_log.c index 9fda6ee95a31..bc11d7092032 100644 --- a/trunk/net/netfilter/nf_log.c +++ b/trunk/net/netfilter/nf_log.c @@ -92,6 +92,10 @@ void nf_log_packet(int pf, vsnprintf(prefix, sizeof(prefix), fmt, args); va_end(args); logger->logfn(pf, hooknum, skb, in, out, loginfo, prefix); + } else if (net_ratelimit()) { + printk(KERN_WARNING "nf_log_packet: can\'t log since " + "no backend logging module loaded in! Please either " + "load one, or disable logging explicitly\n"); } rcu_read_unlock(); } diff --git a/trunk/net/netrom/af_netrom.c b/trunk/net/netrom/af_netrom.c index 74884f4a6255..4bae8b998cab 100644 --- a/trunk/net/netrom/af_netrom.c +++ b/trunk/net/netrom/af_netrom.c @@ -475,11 +475,13 @@ static struct sock *nr_make_new(struct sock *osk) sock_init_data(NULL, sk); sk->sk_type = osk->sk_type; + sk->sk_socket = osk->sk_socket; sk->sk_priority = osk->sk_priority; sk->sk_protocol = osk->sk_protocol; sk->sk_rcvbuf = osk->sk_rcvbuf; sk->sk_sndbuf = osk->sk_sndbuf; sk->sk_state = TCP_ESTABLISHED; + sk->sk_sleep = osk->sk_sleep; sock_copy_flags(sk, osk); skb_queue_head_init(&nr->ack_queue); @@ -536,9 +538,11 @@ static int nr_release(struct socket *sock) sk->sk_state_change(sk); sock_orphan(sk); sock_set_flag(sk, SOCK_DESTROY); + sk->sk_socket = NULL; break; default: + sk->sk_socket = NULL; break; } @@ -806,11 +810,13 @@ static int nr_accept(struct socket *sock, struct socket *newsock, int flags) goto out_release; newsk = skb->sk; - sock_graft(newsk, newsock); + newsk->sk_socket = newsock; + newsk->sk_sleep = &newsock->wait; /* Now attach up the new socket */ kfree_skb(skb); sk_acceptq_removed(sk); + newsock->sk = newsk; out_release: release_sock(sk); diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index 46461a69cd0f..1ebf65294405 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -566,11 +566,13 @@ static struct sock *rose_make_new(struct sock *osk) #endif sk->sk_type = osk->sk_type; + sk->sk_socket = osk->sk_socket; sk->sk_priority = osk->sk_priority; sk->sk_protocol = osk->sk_protocol; sk->sk_rcvbuf = osk->sk_rcvbuf; sk->sk_sndbuf = osk->sk_sndbuf; sk->sk_state = TCP_ESTABLISHED; + sk->sk_sleep = osk->sk_sleep; sock_copy_flags(sk, osk); init_timer(&rose->timer); @@ -757,7 +759,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le sock->state = SS_UNCONNECTED; rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, - &diagnostic, 0); + &diagnostic); if (!rose->neighbour) { err = -ENETUNREACH; goto out_release; @@ -853,7 +855,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le if (sk->sk_state != TCP_ESTABLISHED) { /* Try next neighbour */ - rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic, 0); + rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic); if (rose->neighbour) goto rose_try_next_neigh; @@ -922,12 +924,14 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags) goto out_release; newsk = skb->sk; - sock_graft(newsk, newsock); + newsk->sk_socket = newsock; + newsk->sk_sleep = &newsock->wait; /* Now attach up the new socket */ skb->sk = NULL; kfree_skb(skb); sk->sk_ack_backlog--; + newsock->sk = newsk; out_release: release_sock(sk); diff --git a/trunk/net/rose/rose_route.c b/trunk/net/rose/rose_route.c index a81066a1010a..bd593871c81e 100644 --- a/trunk/net/rose/rose_route.c +++ b/trunk/net/rose/rose_route.c @@ -662,34 +662,27 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig } /* - * Find a neighbour or a route given a ROSE address. + * Find a neighbour given a ROSE address. */ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, - unsigned char *diagnostic, int new) + unsigned char *diagnostic) { struct rose_neigh *res = NULL; struct rose_node *node; int failed = 0; int i; - if (!new) spin_lock_bh(&rose_node_list_lock); + spin_lock_bh(&rose_node_list_lock); for (node = rose_node_list; node != NULL; node = node->next) { if (rosecmpm(addr, &node->address, node->mask) == 0) { for (i = 0; i < node->count; i++) { - if (new) { - if (node->neighbour[i]->restarted) { - res = node->neighbour[i]; - goto out; - } - } - else { - if (!rose_ftimer_running(node->neighbour[i])) { - res = node->neighbour[i]; - goto out; - } else - failed = 1; - } + if (!rose_ftimer_running(node->neighbour[i])) { + res = node->neighbour[i]; + goto out; + } else + failed = 1; } + break; } } @@ -702,7 +695,7 @@ struct rose_neigh *rose_get_neigh(rose_address *addr, unsigned char *cause, } out: - if (!new) spin_unlock_bh(&rose_node_list_lock); + spin_unlock_bh(&rose_node_list_lock); return res; } @@ -1025,7 +1018,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) rose_route = rose_route->next; } - if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic, 1)) == NULL) { + if ((new_neigh = rose_get_neigh(dest_addr, &cause, &diagnostic)) == NULL) { rose_transmit_clear_request(rose_neigh, lci, cause, diagnostic); goto out; } diff --git a/trunk/net/sched/sch_htb.c b/trunk/net/sched/sch_htb.c index 2cef8f34b2cb..213071859030 100644 --- a/trunk/net/sched/sch_htb.c +++ b/trunk/net/sched/sch_htb.c @@ -26,7 +26,6 @@ * and many others. thanks. */ #include -#include #include #include #include @@ -52,17 +51,13 @@ */ #define HTB_HSIZE 16 /* classid hash size */ -static int htb_hysteresis __read_mostly = 0; /* whether to use mode hysteresis for speedup */ +#define HTB_HYSTERESIS 1 /* whether to use mode hysteresis for speedup */ #define HTB_VER 0x30011 /* major must be matched with number suplied by TC as version */ #if HTB_VER >> 16 != TC_HTB_PROTOVER #error "Mismatched sch_htb.c and pkt_sch.h" #endif -/* Module parameter and sysfs export */ -module_param (htb_hysteresis, int, 0640); -MODULE_PARM_DESC(htb_hysteresis, "Hysteresis mode, less CPU load, less accurate"); - /* used internaly to keep status of single class */ enum htb_cmode { HTB_CANT_SEND, /* class can't send and can't borrow */ @@ -465,21 +460,19 @@ static void htb_deactivate_prios(struct htb_sched *q, struct htb_class *cl) htb_remove_class_from_row(q, cl, mask); } +#if HTB_HYSTERESIS static inline long htb_lowater(const struct htb_class *cl) { - if (htb_hysteresis) - return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0; - else - return 0; + return cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : 0; } static inline long htb_hiwater(const struct htb_class *cl) { - if (htb_hysteresis) - return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0; - else - return 0; + return cl->cmode == HTB_CAN_SEND ? -cl->buffer : 0; } - +#else +#define htb_lowater(cl) (0) +#define htb_hiwater(cl) (0) +#endif /** * htb_class_mode - computes and returns current class mode diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index 35b6a023a6d0..d5cc731b6798 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/net/sctp/associola.c @@ -476,15 +476,6 @@ static void sctp_association_destroy(struct sctp_association *asoc) void sctp_assoc_set_primary(struct sctp_association *asoc, struct sctp_transport *transport) { - int changeover = 0; - - /* it's a changeover only if we already have a primary path - * that we are changing - */ - if (asoc->peer.primary_path != NULL && - asoc->peer.primary_path != transport) - changeover = 1 ; - asoc->peer.primary_path = transport; /* Set a default msg_name for events. */ @@ -510,12 +501,12 @@ void sctp_assoc_set_primary(struct sctp_association *asoc, * double switch to the same destination address. */ if (transport->cacc.changeover_active) - transport->cacc.cycling_changeover = changeover; + transport->cacc.cycling_changeover = 1; /* 2) The sender MUST set CHANGEOVER_ACTIVE to indicate that * a changeover has occurred. */ - transport->cacc.changeover_active = changeover; + transport->cacc.changeover_active = 1; /* 3) The sender MUST store the next TSN to be sent in * next_tsn_at_change. diff --git a/trunk/net/sctp/protocol.c b/trunk/net/sctp/protocol.c index 98c6a882016a..d6af466091d2 100644 --- a/trunk/net/sctp/protocol.c +++ b/trunk/net/sctp/protocol.c @@ -108,27 +108,16 @@ static __init int sctp_proc_init(void) } if (sctp_snmp_proc_init()) - goto out_snmp_proc_init; + goto out_nomem; if (sctp_eps_proc_init()) - goto out_eps_proc_init; + goto out_nomem; if (sctp_assocs_proc_init()) - goto out_assocs_proc_init; + goto out_nomem; if (sctp_remaddr_proc_init()) - goto out_remaddr_proc_init; + goto out_nomem; return 0; -out_remaddr_proc_init: - sctp_assocs_proc_exit(); -out_assocs_proc_init: - sctp_eps_proc_exit(); -out_eps_proc_init: - sctp_snmp_proc_exit(); -out_snmp_proc_init: - if (proc_net_sctp) { - proc_net_sctp = NULL; - remove_proc_entry("sctp", init_net.proc_net); - } out_nomem: return -ENOMEM; } diff --git a/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index f98650cc48d8..253e5ea7e1e8 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/net/sctp/socket.c @@ -3588,7 +3588,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) } /* Cleanup any SCTP per socket resources. */ -SCTP_STATIC void sctp_destroy_sock(struct sock *sk) +SCTP_STATIC int sctp_destroy_sock(struct sock *sk) { struct sctp_endpoint *ep; @@ -3598,6 +3598,7 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) ep = sctp_sk(sk)->ep; sctp_endpoint_free(ep); atomic_dec(&sctp_sockets_allocated); + return 0; } /* API 4.1.7 shutdown() - TCP Style Syntax diff --git a/trunk/net/wireless/reg.c b/trunk/net/wireless/reg.c index 855bff4b3250..185488da2466 100644 --- a/trunk/net/wireless/reg.c +++ b/trunk/net/wireless/reg.c @@ -80,23 +80,6 @@ static const struct ieee80211_channel_range ieee80211_JP_channels[] = { IEEE80211_CHAN_RADAR), }; -static const struct ieee80211_channel_range ieee80211_EU_channels[] = { - /* IEEE 802.11b/g, channels 1..13 */ - RANGE_PWR(2412, 2472, 20, 6, 0), - /* IEEE 802.11a, channel 36*/ - RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channel 40*/ - RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channel 44*/ - RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), - /* IEEE 802.11a, channels 48..64 */ - RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR), - /* IEEE 802.11a, channels 100..140 */ - RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS | - IEEE80211_CHAN_RADAR), -}; - #define REGDOM(_code) \ { \ .code = __stringify(_code), \ @@ -107,7 +90,6 @@ static const struct ieee80211_channel_range ieee80211_EU_channels[] = { static const struct ieee80211_regdomain ieee80211_regdoms[] = { REGDOM(US), REGDOM(JP), - REGDOM(EU), }; diff --git a/trunk/net/x25/af_x25.c b/trunk/net/x25/af_x25.c index 7b1c6ef04553..6ba67c523c16 100644 --- a/trunk/net/x25/af_x25.c +++ b/trunk/net/x25/af_x25.c @@ -555,11 +555,13 @@ static struct sock *x25_make_new(struct sock *osk) x25 = x25_sk(sk); sk->sk_type = osk->sk_type; + sk->sk_socket = osk->sk_socket; sk->sk_priority = osk->sk_priority; sk->sk_protocol = osk->sk_protocol; sk->sk_rcvbuf = osk->sk_rcvbuf; sk->sk_sndbuf = osk->sk_sndbuf; sk->sk_state = TCP_ESTABLISHED; + sk->sk_sleep = osk->sk_sleep; sk->sk_backlog_rcv = osk->sk_backlog_rcv; sock_copy_flags(sk, osk); @@ -612,7 +614,8 @@ static int x25_release(struct socket *sock) break; } - sock_orphan(sk); + sock->sk = NULL; + sk->sk_socket = NULL; /* Not used, but we should do this */ out: return 0; } @@ -805,12 +808,14 @@ static int x25_accept(struct socket *sock, struct socket *newsock, int flags) if (!skb->sk) goto out2; newsk = skb->sk; - sock_graft(newsk, newsock); + newsk->sk_socket = newsock; + newsk->sk_sleep = &newsock->wait; /* Now attach up the new socket */ skb->sk = NULL; kfree_skb(skb); sk->sk_ack_backlog--; + newsock->sk = newsk; newsock->state = SS_CONNECTED; rc = 0; out2: diff --git a/trunk/scripts/checkpatch.pl b/trunk/scripts/checkpatch.pl index 6971bf078d13..b6bbbcdc557e 100755 --- a/trunk/scripts/checkpatch.pl +++ b/trunk/scripts/checkpatch.pl @@ -9,7 +9,7 @@ my $P = $0; $P =~ s@.*/@@g; -my $V = '0.19'; +my $V = '0.18'; use Getopt::Long qw(:config no_auto_abbrev); @@ -115,7 +115,6 @@ __kprobes| __(?:mem|cpu|dev|)(?:initdata|init) }x; -our $Modifier; our $Inline = qr{inline|__always_inline|noinline}; our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]}; our $Lval = qr{$Ident(?:$Member)*}; @@ -145,17 +144,17 @@ our @typeList = ( qr{void}, - qr{(?:unsigned\s+)?char}, - qr{(?:unsigned\s+)?short}, - qr{(?:unsigned\s+)?int}, - qr{(?:unsigned\s+)?long}, - qr{(?:unsigned\s+)?long\s+int}, - qr{(?:unsigned\s+)?long\s+long}, - qr{(?:unsigned\s+)?long\s+long\s+int}, + qr{char}, + qr{short}, + qr{int}, + qr{long}, qr{unsigned}, qr{float}, qr{double}, qr{bool}, + qr{long\s+int}, + qr{long\s+long}, + qr{long\s+long\s+int}, qr{(?:__)?(?:u|s|be|le)(?:8|16|32|64)}, qr{struct\s+$Ident}, qr{union\s+$Ident}, @@ -164,29 +163,26 @@ qr{${Ident}_handler}, qr{${Ident}_handler_fn}, ); -our @modifierList = ( - qr{fastcall}, -); sub build_types { - my $mods = "(?: \n" . join("|\n ", @modifierList) . "\n)"; my $all = "(?: \n" . join("|\n ", @typeList) . "\n)"; $NonptrType = qr{ + \b (?:const\s+)? - (?:$mods\s+)? + (?:unsigned\s+)? (?: - (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\)| - (?:${all}\b) + $all| + (?:typeof|__typeof__)\s*\(\s*\**\s*$Ident\s*\) ) (?:\s+$Sparse|\s+const)* + \b }x; $Type = qr{ - $NonptrType + \b$NonptrType\b (?:\s*\*+\s*const|\s*\*+|(?:\s*\[\s*\])+)? - (?:\s+$Inline|\s+$Sparse|\s+$Attribute|\s+$mods)* + (?:\s+$Inline|\s+$Sparse|\s+$Attribute)* }x; $Declare = qr{(?:$Storage\s+)?$Type}; - $Modifier = qr{(?:$Attribute|$Sparse|$mods)}; } build_types(); @@ -333,7 +329,7 @@ sub sanitise_line { $off++; next; } - if (substr($line, $off, 2) eq '*/') { + if (substr($line, $off, 2) eq $sanitise_quote) { $sanitise_quote = ''; substr($res, $off, 2, "$;$;"); $off++; @@ -370,14 +366,14 @@ sub sanitise_line { } # The pathname on a #include may be surrounded by '<' and '>'. - if ($res =~ /^.\s*\#\s*include\s+\<(.*)\>/) { + if ($res =~ /^.#\s*include\s+\<(.*)\>/) { my $clean = 'X' x length($1); $res =~ s@\<.*\>@<$clean>@; # The whole of a #error is a string. - } elsif ($res =~ /^.\s*\#\s*(?:error|warning)\s+(.*)\b/) { + } elsif ($res =~ /^.#\s*(?:error|warning)\s+(.*)\b/) { my $clean = 'X' x length($1); - $res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@; + $res =~ s@(#\s*(?:error|warning)\s+).*@$1$clean@; } return $res; @@ -719,7 +715,7 @@ sub annotate_values { print "DECLARE($1)\n" if ($dbg_values > 1); $type = 'T'; - } elsif ($cur =~ /^(\#\s*define\s*$Ident)(\(?)/o) { + } elsif ($cur =~ /^(#\s*define\s*$Ident)(\(?)/o) { print "DEFINE($1,$2)\n" if ($dbg_values > 1); $av_preprocessor = 1; push(@av_paren_type, $type); @@ -728,12 +724,12 @@ sub annotate_values { } $type = 'E'; - } elsif ($cur =~ /^(\#\s*(?:undef\s*$Ident|include\b))/o) { + } elsif ($cur =~ /^(#\s*undef\s*$Ident)/o) { print "UNDEF($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; push(@av_paren_type, $type); - } elsif ($cur =~ /^(\#\s*(?:ifdef|ifndef|if))/o) { + } elsif ($cur =~ /^(#\s*(?:ifdef|ifndef|if))/o) { print "PRE_START($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; @@ -741,7 +737,7 @@ sub annotate_values { push(@av_paren_type, $type); $type = 'E'; - } elsif ($cur =~ /^(\#\s*(?:else|elif))/o) { + } elsif ($cur =~ /^(#\s*(?:else|elif))/o) { print "PRE_RESTART($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; @@ -749,7 +745,7 @@ sub annotate_values { $type = 'E'; - } elsif ($cur =~ /^(\#\s*(?:endif))/o) { + } elsif ($cur =~ /^(#\s*(?:endif))/o) { print "PRE_END($1)\n" if ($dbg_values > 1); $av_preprocessor = 1; @@ -841,26 +837,14 @@ sub annotate_values { sub possible { my ($possible, $line) = @_; - print "CHECK<$possible> ($line)\n" if ($dbg_possible > 1); + #print "CHECK<$possible>\n"; if ($possible !~ /^(?:$Storage|$Type|DEFINE_\S+)$/ && $possible ne 'goto' && $possible ne 'return' && + $possible ne 'struct' && $possible ne 'enum' && $possible ne 'case' && $possible ne 'else' && - $possible ne 'asm' && - $possible !~ /^(typedef|struct|enum)\b/) { - # Check for modifiers. - $possible =~ s/\s*$Storage\s*//g; - $possible =~ s/\s*$Sparse\s*//g; - if ($possible =~ /^\s*$/) { - - } elsif ($possible =~ /\s/) { - $possible =~ s/\s*$Type\s*//g; - warn "MODIFIER: $possible ($line)\n" if ($dbg_possible); - push(@modifierList, $possible); - - } else { - warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); - push(@typeList, $possible); - } + $possible ne 'typedef') { + warn "POSSIBLE: $possible ($line)\n" if ($dbg_possible); + push(@typeList, $possible); build_types(); } } @@ -965,7 +949,6 @@ sub process { } else { $realcnt=1+1; } - $in_comment = 0; # Guestimate if this is a continuing comment. Run # the context looking for a comment "edge". If this @@ -1134,9 +1117,7 @@ sub process { ERROR("trailing whitespace\n" . $herevet); } #80 column limit - if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ && - $rawline !~ /^.\s*\*\s*\@$Ident\s/ && $length > 80) - { + if ($line =~ /^\+/ && !($prevrawline=~/\/\*\*/) && $length > 80) { WARN("line over 80 characters\n" . $herecurr); } @@ -1178,20 +1159,18 @@ sub process { # Ignore functions being called } elsif ($s =~ /^.\s*$Ident\s*\(/s) { - # declarations always start with types - } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?((?:\s*$Ident)+)\b(?:\s+$Sparse)?\s*\**\s*(?:$Ident|\(\*[^\)]*\))\s*(?:;|=|,|\()/s) { - my $type = $1; - $type =~ s/\s+/ /g; - possible($type, "A:" . $s); - # definitions in global scope can only start with types } elsif ($s =~ /^.(?:$Storage\s+)?(?:$Inline\s+)?(?:const\s+)?($Ident)\b/s) { - possible($1, "B:" . $s); + possible($1, $s); + + # declarations always start with types + } elsif ($prev_values eq 'E' && $s =~ /^.\s*(?:$Storage\s+)?(?:const\s+)?($Ident)\b(:?\s+$Sparse)?\s*\**\s*$Ident\s*(?:;|=|,)/s) { + possible($1, $s); } # any (foo ... *) is a pointer cast, and foo is a type while ($s =~ /\(($Ident)(?:\s+$Sparse)*\s*\*+\s*\)/sg) { - possible($1, "C:" . $s); + possible($1, $s); } # Check for any sort of function declaration. @@ -1205,9 +1184,9 @@ sub process { $ctx =~ s/\)[^\)]*$//; for my $arg (split(/\s*,\s*/, $ctx)) { - if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/s || $arg =~ /^($Ident)$/s) { + if ($arg =~ /^(?:const\s+)?($Ident)(?:\s+$Sparse)*\s*\**\s*(:?\b$Ident)?$/ || $arg =~ /^($Ident)$/) { - possible($1, "D:" . $s); + possible($1, $s); } } } @@ -1242,7 +1221,7 @@ sub process { # if/while/etc brace do not go on next line, unless defining a do while loop, # or if that brace on the next line is for something else - if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.\s*\#/) { + if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) { my $pre_ctx = "$1$2"; my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0); @@ -1260,7 +1239,7 @@ sub process { if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) { ERROR("that open brace { should be on the previous line\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); + "$here\n$ctx\n$lines[$ctx_ln - 1]"); } if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ && $ctx =~ /\)\s*\;\s*$/ && @@ -1269,7 +1248,7 @@ sub process { my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]); if ($nindent > $indent) { WARN("trailing semicolon indicates no statements, indent implies otherwise\n" . - "$here\n$ctx\n$lines[$ctx_ln - 1]\n"); + "$here\n$ctx\n$lines[$ctx_ln - 1]"); } } } @@ -1305,7 +1284,7 @@ sub process { # # check for malformed paths in #include statements (uses RAW line) - if ($rawline =~ m{^.\s*\#\s*include\s+[<"](.*)[">]}) { + if ($rawline =~ m{^.#\s*include\s+[<"](.*)[">]}) { my $path = $1; if ($path =~ m{//}) { ERROR("malformed #include filename\n" . @@ -1337,7 +1316,7 @@ sub process { } # check for external initialisers. - if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) { + if ($line =~ /^.$Type\s*$Ident\s*=\s*(0|NULL|false)\s*;/) { ERROR("do not initialise externals to 0 or NULL\n" . $herecurr); } @@ -1351,7 +1330,6 @@ sub process { # make sense. if ($line =~ /\btypedef\s/ && $line !~ /\btypedef\s+$Type\s+\(\s*\*?$Ident\s*\)\s*\(/ && - $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && $line !~ /\b__bitwise(?:__|)\b/) { WARN("do not add new typedefs\n" . $herecurr); } @@ -1410,8 +1388,8 @@ sub process { # function brace can't be on same line, except for #defines of do while, # or if closed on same line - if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and - !($line=~/\#\s*define.*do\s{/) and !($line=~/}/)) { + if (($line=~/$Type\s*[A-Za-z\d_]+\(.*\).*\s{/) and + !($line=~/\#define.*do\s{/) and !($line=~/}/)) { ERROR("open brace '{' following function declarations go on the next line\n" . $herecurr); } @@ -1438,10 +1416,10 @@ sub process { # cpp #define statements have non-optional spaces, ie # if there is a space between the name and the open # parenthesis it is simply not a parameter group. - } elsif ($ctx_before =~ /^.\s*\#\s*define\s*$/) { + } elsif ($ctx_before =~ /^.\#\s*define\s*$/) { # cpp #elif statement condition may start with a ( - } elsif ($ctx =~ /^.\s*\#\s*elif\s*$/) { + } elsif ($ctx =~ /^.\#\s*elif\s*$/) { # If this whole things ends with a type its most # likely a typedef for a function. @@ -1647,14 +1625,13 @@ sub process { ERROR("space prohibited before that close square bracket ']'\n" . $herecurr); } -# check spacing on parentheses +# check spacing on paretheses if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ && $line !~ /for\s*\(\s+;/) { ERROR("space prohibited after that open parenthesis '('\n" . $herecurr); } if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ && - $line !~ /for\s*\(.*;\s+\)/ && - $line !~ /:\s+\)/) { + $line !~ /for\s*\(.*;\s+\)/) { ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr); } @@ -1664,23 +1641,6 @@ sub process { WARN("labels should not be indented\n" . $herecurr); } -# Return is not a function. - if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) { - my $spacing = $1; - my $value = $2; - - # Flatten any parentheses and braces - while ($value =~ s/\([^\(\)]*\)/1/) { - } - - if ($value =~ /^(?:$Ident|-?$Constant)$/) { - ERROR("return is not a function, parentheses are not required\n" . $herecurr); - - } elsif ($spacing !~ /\s+/) { - ERROR("space required before the open parenthesis '('\n" . $herecurr); - } - } - # Need a space before open parenthesis after if, while etc if ($line=~/\b(if|while|for|switch)\(/) { ERROR("space required before the open parenthesis '('\n" . $herecurr); @@ -1700,7 +1660,7 @@ sub process { $s =~ s/\n.*//g; $s =~ s/$;//g; # Remove any comments if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/ && - $c !~ /^.\s*\#\s*if/) + $c !~ /^.\#\s*if/) { ERROR("trailing statements should be on next line\n" . $herecurr); } @@ -1759,16 +1719,14 @@ sub process { # } #no spaces allowed after \ in define - if ($line=~/\#\s*define.*\\\s$/) { + if ($line=~/\#define.*\\\s$/) { WARN("Whitepspace after \\ makes next lines useless\n" . $herecurr); } #warn if is #included and is available (uses RAW line) - if ($tree && $rawline =~ m{^.\s*\#\s*include\s*\}) { - my $checkfile = "include/linux/$1.h"; - if (-f "$root/$checkfile" && $realfile ne $checkfile && - $1 ne 'irq') - { + if ($tree && $rawline =~ m{^.\#\s*include\s*\}) { + my $checkfile = "$root/include/linux/$1.h"; + if (-f $checkfile && $1 ne 'irq') { WARN("Use #include instead of \n" . $herecurr); } @@ -1777,87 +1735,45 @@ sub process { # multi-statement macros should be enclosed in a do while loop, grab the # first statement and ensure its the whole macro if its not enclosed # in a known good container - if ($line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { + if ($prevline =~ /\#define.*\\/ && + $prevline !~/(?:do\s+{|\(\{|\{)/ && + $line !~ /(?:do\s+{|\(\{|\{)/ && + $line !~ /^.\s*$Declare\s/) { + # Grab the first statement, if that is the entire macro + # its ok. This may start either on the #define line + # or the one below. my $ln = $linenr; my $cnt = $realcnt; - my ($off, $dstat, $dcond, $rest); - my $ctx = ''; - - my $args = defined($1); + my $off = 0; - # Find the end of the macro and limit our statement - # search to that. - while ($cnt > 0 && defined $lines[$ln - 1] && - $lines[$ln - 1] =~ /^(?:-|..*\\$)/) - { - $ctx .= $rawlines[$ln - 1] . "\n"; - $ln++; - $cnt--; - } - $ctx .= $rawlines[$ln - 1]; - - ($dstat, $dcond, $ln, $cnt, $off) = - ctx_statement_block($linenr, $ln - $linenr + 1, 0); - #print "dstat<$dstat> dcond<$dcond> cnt<$cnt> off<$off>\n"; - #print "LINE<$lines[$ln]> len<" . length($lines[$ln]) . "\n"; - - # Extract the remainder of the define (if any) and - # rip off surrounding spaces, and trailing \'s. - $rest = ''; - if (defined $lines[$ln - 1] && - $off > length($lines[$ln - 1])) - { - $ln++; - $cnt--; - $off = 0; - } - while ($cnt > 0) { - $rest .= substr($lines[$ln - 1], $off) . "\n"; - $ln++; - $cnt--; - $off = 0; - } - $rest =~ s/\\\n.//g; - $rest =~ s/^\s*//s; - $rest =~ s/\s*$//s; - - # Clean up the original statement. - if ($args) { - substr($dstat, 0, length($dcond), ''); - } else { - $dstat =~ s/^.\s*\#\s*define\s+$Ident\s*//; + # If the macro starts on the define line start + # grabbing the statement after the identifier + $prevline =~ m{^(.#\s*define\s*$Ident(?:\([^\)]*\))?\s*)(.*)\\\s*$}; + ##print "1<$1> 2<$2>\n"; + if (defined $2 && $2 ne '') { + $off = length($1); + $ln--; + $cnt++; + while ($lines[$ln - 1] =~ /^-/) { + $ln--; + $cnt++; + } } - $dstat =~ s/\\\n.//g; - $dstat =~ s/^\s*//s; - $dstat =~ s/\s*$//s; + my @ctx = ctx_statement($ln, $cnt, $off); + my $ctx_ln = $ln + $#ctx + 1; + my $ctx = join("\n", @ctx); - # Flatten any parentheses and braces - while ($dstat =~ s/\([^\(\)]*\)/1/) { - } - while ($dstat =~ s/\{[^\{\}]*\}/1/) { + # Pull in any empty extension lines. + while ($ctx =~ /\\$/ && + $lines[$ctx_ln - 1] =~ /^.\s*(?:\\)?$/) { + $ctx .= $lines[$ctx_ln - 1]; + $ctx_ln++; } - my $exceptions = qr{ - $Declare| - module_param_named| - MODULE_PARAM_DESC| - DECLARE_PER_CPU| - DEFINE_PER_CPU| - __typeof__\( - }x; - if ($rest ne '') { - if ($rest !~ /while\s*\(/ && - $dstat !~ /$exceptions/) - { + if ($ctx =~ /\\$/) { + if ($ctx =~ /;/) { ERROR("Macros with multiple statements should be enclosed in a do - while loop\n" . "$here\n$ctx\n"); - } - - } elsif ($ctx !~ /;/) { - if ($dstat ne '' && - $dstat !~ /^(?:$Ident|-?$Constant)$/ && - $dstat !~ /$exceptions/ && - $dstat =~ /$Operators/) - { + } else { ERROR("Macros with complex values should be enclosed in parenthesis\n" . "$here\n$ctx\n"); } } @@ -1968,7 +1884,7 @@ sub process { # don't include deprecated include files (uses RAW line) for my $inc (@dep_includes) { - if ($rawline =~ m@^.\s*\#\s*include\s*\<$inc>@) { + if ($rawline =~ m@\#\s*include\s*\<$inc>@) { ERROR("Don't use <$inc>: see Documentation/feature-removal-schedule.txt\n" . $herecurr); } } @@ -1992,7 +1908,7 @@ sub process { } # warn about #if 0 - if ($line =~ /^.\s*\#\s*if\s+0\b/) { + if ($line =~ /^.#\s*if\s+0\b/) { CHK("if this code is redundant consider removing it\n" . $herecurr); } @@ -2004,16 +1920,23 @@ sub process { WARN("kfree(NULL) is safe this check is probabally not required\n" . $hereprev); } } +# check for needless usb_free_urb() checks + if ($prevline =~ /\bif\s*\(([^\)]*)\)/) { + my $expr = $1; + if ($line =~ /\busb_free_urb\(\Q$expr\E\);/) { + WARN("usb_free_urb(NULL) is safe this check is probabally not required\n" . $hereprev); + } + } # warn about #ifdefs in C files -# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { +# if ($line =~ /^.#\s*if(|n)def/ && ($realfile =~ /\.c$/)) { # print "#ifdef in C files should be avoided\n"; # print "$herecurr"; # $clean = 0; # } # warn about spacing in #ifdefs - if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) { + if ($line =~ /^.#\s*(ifdef|ifndef|elif)\s\s+/) { ERROR("exactly one space required after that #$1\n" . $herecurr); } @@ -2032,7 +1955,7 @@ sub process { } } # check of hardware specific defines - if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { + if ($line =~ m@^.#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { CHK("architecture specific defines should be avoided\n" . $herecurr); } @@ -2050,18 +1973,15 @@ sub process { # check for new externs in .c files. if ($realfile =~ /\.c$/ && defined $stat && - $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s) + $stat =~ /^.\s*(?:extern\s+)?$Type\s+$Ident(\s*)\(/s) { - my $function_name = $1; - my $paren_space = $2; + my $paren_space = $1; my $s = $stat; if (defined $cond) { substr($s, 0, length($cond), ''); } - if ($s =~ /^\s*;/ && - $function_name ne 'uninitialized_var') - { + if ($s =~ /^\s*;/) { WARN("externs should be avoided in .c files\n" . $herecurr); } @@ -2110,8 +2030,8 @@ sub process { # use of NR_CPUS is usually wrong # ignore definitions of NR_CPUS and usage to define arrays as likely right if ($line =~ /\bNR_CPUS\b/ && - $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ && - $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ && + $line !~ /^.#\s*if\b.*\bNR_CPUS\b/ && + $line !~ /^.#\s*define\b.*\bNR_CPUS\b/ && $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ && $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ && $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/) diff --git a/trunk/scripts/mod/modpost.c b/trunk/scripts/mod/modpost.c index a07f91aac920..508c5895c680 100644 --- a/trunk/scripts/mod/modpost.c +++ b/trunk/scripts/mod/modpost.c @@ -467,25 +467,6 @@ static void parse_elf_finish(struct elf_info *info) release_file(info->hdr, info->size); } -static int ignore_undef_symbol(struct elf_info *info, const char *symname) -{ - /* ignore __this_module, it will be resolved shortly */ - if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) - return 1; - /* ignore global offset table */ - if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) - return 1; - if (info->hdr->e_machine == EM_PPC) - /* Special register function linked on all modules during final link of .ko */ - if (strncmp(symname, "_restgpr_", sizeof("_restgpr_") - 1) == 0 || - strncmp(symname, "_savegpr_", sizeof("_savegpr_") - 1) == 0 || - strncmp(symname, "_rest32gpr_", sizeof("_rest32gpr_") - 1) == 0 || - strncmp(symname, "_save32gpr_", sizeof("_save32gpr_") - 1) == 0) - return 1; - /* Do not ignore this symbol */ - return 0; -} - #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" @@ -512,7 +493,11 @@ static void handle_modversions(struct module *mod, struct elf_info *info, if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && ELF_ST_BIND(sym->st_info) != STB_WEAK) break; - if (ignore_undef_symbol(info, symname)) + /* ignore global offset table */ + if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) + break; + /* ignore __this_module, it will be resolved shortly */ + if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) break; /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */ #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER) diff --git a/trunk/security/device_cgroup.c b/trunk/security/device_cgroup.c index baf348834b66..4ea583689eec 100644 --- a/trunk/security/device_cgroup.c +++ b/trunk/security/device_cgroup.c @@ -49,14 +49,10 @@ struct dev_cgroup { spinlock_t lock; }; -static inline struct dev_cgroup *css_to_devcgroup(struct cgroup_subsys_state *s) -{ - return container_of(s, struct dev_cgroup, css); -} - static inline struct dev_cgroup *cgroup_to_devcgroup(struct cgroup *cgroup) { - return css_to_devcgroup(cgroup_subsys_state(cgroup, devices_subsys_id)); + return container_of(cgroup_subsys_state(cgroup, devices_subsys_id), + struct dev_cgroup, css); } struct cgroup_subsys devices_subsys; @@ -106,7 +102,7 @@ static int dev_whitelist_copy(struct list_head *dest, struct list_head *orig) static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, struct dev_whitelist_item *wh) { - struct dev_whitelist_item *whcopy, *walk; + struct dev_whitelist_item *whcopy; whcopy = kmalloc(sizeof(*whcopy), GFP_KERNEL); if (!whcopy) @@ -114,21 +110,7 @@ static int dev_whitelist_add(struct dev_cgroup *dev_cgroup, memcpy(whcopy, wh, sizeof(*whcopy)); spin_lock(&dev_cgroup->lock); - list_for_each_entry(walk, &dev_cgroup->whitelist, list) { - if (walk->type != wh->type) - continue; - if (walk->major != wh->major) - continue; - if (walk->minor != wh->minor) - continue; - - walk->access |= wh->access; - kfree(whcopy); - whcopy = NULL; - } - - if (whcopy != NULL) - list_add_tail(&whcopy->list, &dev_cgroup->whitelist); + list_add_tail(&whcopy->list, &dev_cgroup->whitelist); spin_unlock(&dev_cgroup->lock); return 0; } @@ -520,6 +502,7 @@ struct cgroup_subsys devices_subsys = { int devcgroup_inode_permission(struct inode *inode, int mask) { + struct cgroup *cgroup; struct dev_cgroup *dev_cgroup; struct dev_whitelist_item *wh; @@ -528,8 +511,8 @@ int devcgroup_inode_permission(struct inode *inode, int mask) return 0; if (!S_ISBLK(inode->i_mode) && !S_ISCHR(inode->i_mode)) return 0; - dev_cgroup = css_to_devcgroup(task_subsys_state(current, - devices_subsys_id)); + cgroup = task_cgroup(current, devices_subsys.subsys_id); + dev_cgroup = cgroup_to_devcgroup(cgroup); if (!dev_cgroup) return 0; @@ -560,11 +543,12 @@ int devcgroup_inode_permission(struct inode *inode, int mask) int devcgroup_inode_mknod(int mode, dev_t dev) { + struct cgroup *cgroup; struct dev_cgroup *dev_cgroup; struct dev_whitelist_item *wh; - dev_cgroup = css_to_devcgroup(task_subsys_state(current, - devices_subsys_id)); + cgroup = task_cgroup(current, devices_subsys.subsys_id); + dev_cgroup = cgroup_to_devcgroup(cgroup); if (!dev_cgroup) return 0; diff --git a/trunk/security/dummy.c b/trunk/security/dummy.c index b8916883b77f..f50c6c3c32c9 100644 --- a/trunk/security/dummy.c +++ b/trunk/security/dummy.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) { @@ -609,27 +607,7 @@ static int dummy_task_kill (struct task_struct *p, struct siginfo *info, static int dummy_task_prctl (int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5, long *rc_p) { - switch (option) { - case PR_CAPBSET_READ: - *rc_p = (cap_valid(arg2) ? 1 : -EINVAL); - break; - case PR_GET_KEEPCAPS: - *rc_p = issecure(SECURE_KEEP_CAPS); - break; - case PR_SET_KEEPCAPS: - if (arg2 > 1) - *rc_p = -EINVAL; - else if (arg2) - current->securebits |= issecure_mask(SECURE_KEEP_CAPS); - else - current->securebits &= - ~issecure_mask(SECURE_KEEP_CAPS); - break; - default: - return 0; - } - - return 1; + return 0; } static void dummy_task_reparent_to_init (struct task_struct *p) diff --git a/trunk/security/keys/internal.h b/trunk/security/keys/internal.h index b39f5c2e2c4b..8c05587f5018 100644 --- a/trunk/security/keys/internal.h +++ b/trunk/security/keys/internal.h @@ -78,6 +78,7 @@ extern unsigned key_quota_maxbytes; extern struct rb_root key_serial_tree; extern spinlock_t key_serial_lock; +extern struct semaphore key_alloc_sem; extern struct mutex key_construction_mutex; extern wait_queue_head_t request_key_conswq; diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index 4a09293efa00..b5c8f9237008 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -1880,18 +1880,6 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) */ final = sbsp->smk_default; - /* - * If this is the root inode the superblock - * may be in the process of initialization. - * If that is the case use the root value out - * of the superblock. - */ - if (opt_dentry->d_parent == opt_dentry) { - isp->smk_inode = sbsp->smk_root; - isp->smk_flags |= SMK_INODE_INSTANT; - goto unlockandout; - } - /* * This is pretty hackish. * Casey says that we shouldn't have to do diff --git a/trunk/sound/pci/ac97/ac97_patch.c b/trunk/sound/pci/ac97/ac97_patch.c index 1292dcee072d..2da89810ca10 100644 --- a/trunk/sound/pci/ac97/ac97_patch.c +++ b/trunk/sound/pci/ac97/ac97_patch.c @@ -1971,9 +1971,6 @@ static int snd_ac97_ad1888_lohpsel_get(struct snd_kcontrol *kcontrol, struct snd val = ac97->regs[AC97_AD_MISC]; ucontrol->value.integer.value[0] = !(val & AC97_AD198X_LOSEL); - if (ac97->spec.ad18xx.lo_as_master) - ucontrol->value.integer.value[0] = - !ucontrol->value.integer.value[0]; return 0; } @@ -1982,10 +1979,8 @@ static int snd_ac97_ad1888_lohpsel_put(struct snd_kcontrol *kcontrol, struct snd struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); unsigned short val; - val = !ucontrol->value.integer.value[0]; - if (ac97->spec.ad18xx.lo_as_master) - val = !val; - val = val ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; + val = !ucontrol->value.integer.value[0] + ? (AC97_AD198X_LOSEL | AC97_AD198X_HPSEL) : 0; return snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD198X_LOSEL | AC97_AD198X_HPSEL, val); } @@ -2036,7 +2031,7 @@ static void ad1888_update_jacks(struct snd_ac97 *ac97) { unsigned short val = 0; /* clear LODIS if shared jack is to be used for Surround out */ - if (!ac97->spec.ad18xx.lo_as_master && is_shared_linein(ac97)) + if (is_shared_linein(ac97)) val |= (1 << 12); /* clear CLDIS if shared jack is to be used for C/LFE out */ if (is_shared_micin(ac97)) @@ -2072,13 +2067,9 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = { static int patch_ad1888_specific(struct snd_ac97 *ac97) { - if (!ac97->spec.ad18xx.lo_as_master) { - /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ - snd_ac97_rename_vol_ctl(ac97, "Master Playback", - "Master Surround Playback"); - snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", - "Master Playback"); - } + /* rename 0x04 as "Master" and 0x02 as "Master Surround" */ + snd_ac97_rename_vol_ctl(ac97, "Master Playback", "Master Surround Playback"); + snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback"); return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); } @@ -2097,27 +2088,16 @@ static int patch_ad1888(struct snd_ac97 * ac97) patch_ad1881(ac97); ac97->build_ops = &patch_ad1888_build_ops; - - /* - * LO can be used as a real line-out on some devices, - * and we need to revert the front/surround mixer switches - */ - if (ac97->subsystem_vendor == 0x1043 && - ac97->subsystem_device == 0x1193) /* ASUS A9T laptop */ - ac97->spec.ad18xx.lo_as_master = 1; - - misc = snd_ac97_read(ac97, AC97_AD_MISC); + /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ + /* it seems that most vendors connect line-out connector to headphone out of AC'97 */ /* AD-compatible mode */ /* Stereo mutes enabled */ - misc |= AC97_AD198X_MSPLT | AC97_AD198X_AC97NC; - if (!ac97->spec.ad18xx.lo_as_master) - /* Switch FRONT/SURROUND LINE-OUT/HP-OUT default connection */ - /* it seems that most vendors connect line-out connector to - * headphone out of AC'97 - */ - misc |= AC97_AD198X_LOSEL | AC97_AD198X_HPSEL; - - snd_ac97_write_cache(ac97, AC97_AD_MISC, misc); + misc = snd_ac97_read(ac97, AC97_AD_MISC); + snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | + AC97_AD198X_LOSEL | + AC97_AD198X_HPSEL | + AC97_AD198X_MSPLT | + AC97_AD198X_AC97NC); ac97->flags |= AC97_STEREO_MUTES; return 0; } diff --git a/trunk/sound/pci/emu10k1/emu10k1_main.c b/trunk/sound/pci/emu10k1/emu10k1_main.c index 548c9cc81af5..abde5b901884 100644 --- a/trunk/sound/pci/emu10k1/emu10k1_main.c +++ b/trunk/sound/pci/emu10k1/emu10k1_main.c @@ -1818,6 +1818,13 @@ int __devinit snd_emu10k1_create(struct snd_card *card, } emu->port = pci_resource_start(pci, 0); + if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, + "EMU10K1", emu)) { + err = -EBUSY; + goto error; + } + emu->irq = pci->irq; + emu->max_cache_pages = max_cache_bytes >> PAGE_SHIFT; if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 32 * 1024, &emu->ptb_pages) < 0) { @@ -1880,14 +1887,6 @@ int __devinit snd_emu10k1_create(struct snd_card *card, emu->fx8010.etram_pages.area = NULL; emu->fx8010.etram_pages.bytes = 0; - /* irq handler must be registered after I/O ports are activated */ - if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED, - "EMU10K1", emu)) { - err = -EBUSY; - goto error; - } - emu->irq = pci->irq; - /* * Init to 0x02109204 : * Clock accuracy = 0 (1000ppm) diff --git a/trunk/sound/pci/hda/patch_analog.c b/trunk/sound/pci/hda/patch_analog.c index a99e86d74278..ff1b922c610b 100644 --- a/trunk/sound/pci/hda/patch_analog.c +++ b/trunk/sound/pci/hda/patch_analog.c @@ -3644,17 +3644,33 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { { } /* end */ }; +static struct hda_input_mux ad1884a_mobile_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, /* port-C */ + { "Mix", 0x3 }, + }, +}; + static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = ad198x_mux_enum_info, + .get = ad198x_mux_enum_get, + .put = ad198x_mux_enum_put, + }, { } /* end */ }; @@ -3671,31 +3687,14 @@ static void ad1884a_hp_automute(struct hda_codec *codec) present ? 0x00 : 0x02); } -/* switch to external mic if plugged */ -static void ad1884a_hp_automic(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_codec_read(codec, 0x14, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, - present ? 0 : 1); -} - #define AD1884A_HP_EVENT 0x37 -#define AD1884A_MIC_EVENT 0x36 /* unsolicited event for HP jack sensing */ static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) { - switch (res >> 26) { - case AD1884A_HP_EVENT: - ad1884a_hp_automute(codec); - break; - case AD1884A_MIC_EVENT: - ad1884a_hp_automic(codec); - break; - } + if ((res >> 26) != AD1884A_HP_EVENT) + return; + ad1884a_hp_automute(codec); } /* initialize jack-sensing, too */ @@ -3703,7 +3702,6 @@ static int ad1884a_hp_init(struct hda_codec *codec) { ad198x_init(codec); ad1884a_hp_automute(codec); - ad1884a_hp_automic(codec); return 0; } @@ -3717,15 +3715,10 @@ static struct hda_verb ad1884a_laptop_verbs[] = { /* Port-F pin */ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - /* Port-C pin - internal mic-in */ - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ /* analog mix */ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* unsolicited event for pin-sense */ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, { } /* end */ }; @@ -3885,6 +3878,7 @@ static int patch_ad1884a(struct hda_codec *codec) spec->mixers[0] = ad1884a_mobile_mixers; spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; spec->multiout.dig_out_nid = 0; + spec->input_mux = &ad1884a_mobile_capture_source; codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; codec->patch_ops.init = ad1884a_hp_init; break; diff --git a/trunk/sound/pci/hda/patch_cmedia.c b/trunk/sound/pci/hda/patch_cmedia.c index 6ef57fbfb6eb..c73ce074a6ea 100644 --- a/trunk/sound/pci/hda/patch_cmedia.c +++ b/trunk/sound/pci/hda/patch_cmedia.c @@ -611,7 +611,6 @@ static const char *cmi9880_models[CMI_MODELS] = { static struct snd_pci_quirk cmi9880_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), - SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), {} /* terminator */ }; diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index b0a2a262ece2..8f31247c52bd 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -942,6 +942,7 @@ static void alc_subsystem_id(struct hda_codec *codec, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT); spec->unsol_event = alc_sku_unsol_event; + spec->init_hook = alc_sku_automute; } /* @@ -8642,7 +8643,6 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {} }; /* mute/unmute internal speaker according to the hp jack and mute state */ @@ -10513,7 +10513,6 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), - SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), diff --git a/trunk/virt/kvm/ioapic.c b/trunk/virt/kvm/ioapic.c index 98778cb69c6e..4232fd75dd20 100644 --- a/trunk/virt/kvm/ioapic.c +++ b/trunk/virt/kvm/ioapic.c @@ -45,7 +45,7 @@ #else #define ioapic_debug(fmt, arg...) #endif -static int ioapic_deliver(struct kvm_ioapic *vioapic, int irq); +static void ioapic_deliver(struct kvm_ioapic *vioapic, int irq); static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, unsigned long addr, @@ -89,8 +89,8 @@ static void ioapic_service(struct kvm_ioapic *ioapic, unsigned int idx) pent = &ioapic->redirtbl[idx]; if (!pent->fields.mask) { - int injected = ioapic_deliver(ioapic, idx); - if (injected && pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) + ioapic_deliver(ioapic, idx); + if (pent->fields.trig_mode == IOAPIC_LEVEL_TRIG) pent->fields.remote_irr = 1; } if (!pent->fields.trig_mode) @@ -133,7 +133,7 @@ static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) } } -static int ioapic_inj_irq(struct kvm_ioapic *ioapic, +static void ioapic_inj_irq(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu, u8 vector, u8 trig_mode, u8 delivery_mode) { @@ -143,7 +143,7 @@ static int ioapic_inj_irq(struct kvm_ioapic *ioapic, ASSERT((delivery_mode == IOAPIC_FIXED) || (delivery_mode == IOAPIC_LOWEST_PRIORITY)); - return kvm_apic_set_irq(vcpu, vector, trig_mode); + kvm_apic_set_irq(vcpu, vector, trig_mode); } static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, @@ -186,7 +186,7 @@ static u32 ioapic_get_delivery_bitmask(struct kvm_ioapic *ioapic, u8 dest, return mask; } -static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) +static void ioapic_deliver(struct kvm_ioapic *ioapic, int irq) { u8 dest = ioapic->redirtbl[irq].fields.dest_id; u8 dest_mode = ioapic->redirtbl[irq].fields.dest_mode; @@ -195,7 +195,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) u8 trig_mode = ioapic->redirtbl[irq].fields.trig_mode; u32 deliver_bitmask; struct kvm_vcpu *vcpu; - int vcpu_id, r = 0; + int vcpu_id; ioapic_debug("dest=%x dest_mode=%x delivery_mode=%x " "vector=%x trig_mode=%x\n", @@ -204,7 +204,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) deliver_bitmask = ioapic_get_delivery_bitmask(ioapic, dest, dest_mode); if (!deliver_bitmask) { ioapic_debug("no target on destination\n"); - return 0; + return; } switch (delivery_mode) { @@ -216,7 +216,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) vcpu = ioapic->kvm->vcpus[0]; #endif if (vcpu != NULL) - r = ioapic_inj_irq(ioapic, vcpu, vector, + ioapic_inj_irq(ioapic, vcpu, vector, trig_mode, delivery_mode); else ioapic_debug("null lowest prio vcpu: " @@ -234,7 +234,7 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) deliver_bitmask &= ~(1 << vcpu_id); vcpu = ioapic->kvm->vcpus[vcpu_id]; if (vcpu) { - r = ioapic_inj_irq(ioapic, vcpu, vector, + ioapic_inj_irq(ioapic, vcpu, vector, trig_mode, delivery_mode); } } @@ -246,7 +246,6 @@ static int ioapic_deliver(struct kvm_ioapic *ioapic, int irq) delivery_mode); break; } - return r; } void kvm_ioapic_set_irq(struct kvm_ioapic *ioapic, int irq, int level)