diff --git a/[refs] b/[refs] index c65aacdeab25..663c6338d321 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d200ccce6d01fde887aca08156cc875a9aa8b62b +refs/heads/master: 5cd3955cb8adfc1edf481e9e1cb2289db50ccacb diff --git a/trunk/Documentation/networking/00-INDEX b/trunk/Documentation/networking/00-INDEX index c485ee028bd9..02e56d447a8f 100644 --- a/trunk/Documentation/networking/00-INDEX +++ b/trunk/Documentation/networking/00-INDEX @@ -84,6 +84,9 @@ policy-routing.txt - IP policy-based routing ray_cs.txt - Raylink Wireless LAN card driver info. +sk98lin.txt + - Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit + Ethernet Adapter family driver info skfp.txt - SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info. smc9.txt diff --git a/trunk/Documentation/networking/sk98lin.txt b/trunk/Documentation/networking/sk98lin.txt new file mode 100644 index 000000000000..8590a954df1d --- /dev/null +++ b/trunk/Documentation/networking/sk98lin.txt @@ -0,0 +1,568 @@ +(C)Copyright 1999-2004 Marvell(R). +All rights reserved +=========================================================================== + +sk98lin.txt created 13-Feb-2004 + +Readme File for sk98lin v6.23 +Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX + +This file contains + 1 Overview + 2 Required Files + 3 Installation + 3.1 Driver Installation + 3.2 Inclusion of adapter at system start + 4 Driver Parameters + 4.1 Per-Port Parameters + 4.2 Adapter Parameters + 5 Large Frame Support + 6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) + 7 Troubleshooting + +=========================================================================== + + +1 Overview +=========== + +The sk98lin driver supports the Marvell Yukon and SysKonnect +SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has +been tested with Linux on Intel/x86 machines. +*** + + +2 Required Files +================= + +The linux kernel source. +No additional files required. +*** + + +3 Installation +=============== + +It is recommended to download the latest version of the driver from the +SysKonnect web site www.syskonnect.com. If you have downloaded the latest +driver, the Linux kernel has to be patched before the driver can be +installed. For details on how to patch a Linux kernel, refer to the +patch.txt file. + +3.1 Driver Installation +------------------------ + +The following steps describe the actions that are required to install +the driver and to start it manually. These steps should be carried +out for the initial driver setup. Once confirmed to be ok, they can +be included in the system start. + +NOTE 1: To perform the following tasks you need 'root' access. + +NOTE 2: In case of problems, please read the section "Troubleshooting" + below. + +The driver can either be integrated into the kernel or it can be compiled +as a module. Select the appropriate option during the kernel +configuration. + +Compile/use the driver as a module +---------------------------------- +To compile the driver, go to the directory /usr/src/linux and +execute the command "make menuconfig" or "make xconfig" and proceed as +follows: + +To integrate the driver permanently into the kernel, proceed as follows: + +1. Select the menu "Network device support" and then "Ethernet(1000Mbit)" +2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" + with (*) +3. Build a new kernel when the configuration of the above options is + finished. +4. Install the new kernel. +5. Reboot your system. + +To use the driver as a module, proceed as follows: + +1. Enable 'loadable module support' in the kernel. +2. For automatic driver start, enable the 'Kernel module loader'. +3. Select the menu "Network device support" and then "Ethernet(1000Mbit)" +4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" + with (M) +5. Execute the command "make modules". +6. Execute the command "make modules_install". + The appropriate modules will be installed. +7. Reboot your system. + + +Load the module manually +------------------------ +To load the module manually, proceed as follows: + +1. Enter "modprobe sk98lin". +2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in + your computer and you have a /proc file system, execute the command: + "ls /proc/net/sk98lin/" + This should produce an output containing a line with the following + format: + eth0 eth1 ... + which indicates that your adapter has been found and initialized. + + NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx + adapter installed, the adapters will be listed as 'eth0', + 'eth1', 'eth2', etc. + For each adapter, repeat steps 3 and 4 below. + + NOTE 2: If you have other Ethernet adapters installed, your Marvell + Yukon or SysKonnect SK-98xx adapter will be mapped to the + next available number, e.g. 'eth1'. The mapping is executed + automatically. + The module installation message (displayed either in a system + log file or on the console) prints a line for each adapter + found containing the corresponding 'ethX'. + +3. Select an IP address and assign it to the respective adapter by + entering: + ifconfig eth0 + With this command, the adapter is connected to the Ethernet. + + SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter + is now active, the link status LED of the primary port is active and + the link status LED of the secondary port (on dual port adapters) is + blinking (if the ports are connected to a switch or hub). + SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active. + In addition, you will receive a status message on the console stating + "ethX: network connection up using port Y" and showing the selected + connection parameters (x stands for the ethernet device number + (0,1,2, etc), y stands for the port name (A or B)). + + NOTE: If you are in doubt about IP addresses, ask your network + administrator for assistance. + +4. Your adapter should now be fully operational. + Use 'ping ' to verify the connection to other computers + on your network. +5. To check the adapter configuration view /proc/net/sk98lin/[devicename]. + For example by executing: + "cat /proc/net/sk98lin/eth0" + +Unload the module +----------------- +To stop and unload the driver modules, proceed as follows: + +1. Execute the command "ifconfig eth0 down". +2. Execute the command "rmmod sk98lin". + +3.2 Inclusion of adapter at system start +----------------------------------------- + +Since a large number of different Linux distributions are +available, we are unable to describe a general installation procedure +for the driver module. +Because the driver is now integrated in the kernel, installation should +be easy, using the standard mechanism of your distribution. +Refer to the distribution's manual for installation of ethernet adapters. + +*** + +4 Driver Parameters +==================== + +Parameters can be set at the command line after the module has been +loaded with the command 'modprobe'. +In some distributions, the configuration tools are able to pass parameters +to the driver module. + +If you use the kernel module loader, you can set driver parameters +in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier). +To set the driver parameters in this file, proceed as follows: + +1. Insert a line of the form : + options sk98lin ... + For "...", the same syntax is required as described for the command + line parameters of modprobe below. +2. To activate the new parameters, either reboot your computer + or + unload and reload the driver. + The syntax of the driver parameters is: + + modprobe sk98lin parameter=value1[,value2[,value3...]] + + where value1 refers to the first adapter, value2 to the second etc. + +NOTE: All parameters are case sensitive. Write them exactly as shown + below. + +Example: +Suppose you have two adapters. You want to set auto-negotiation +on the first adapter to ON and on the second adapter to OFF. +You also want to set DuplexCapabilities on the first adapter +to FULL, and on the second adapter to HALF. +Then, you must enter: + + modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half + +NOTE: The number of adapters that can be configured this way is + limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM). + The current limit is 16. If you happen to install + more adapters, adjust this and recompile. + + +4.1 Per-Port Parameters +------------------------ + +These settings are available for each port on the adapter. +In the following description, '?' stands for the port for +which you set the parameter (A or B). + +Speed +----- +Parameter: Speed_? +Values: 10, 100, 1000, Auto +Default: Auto + +This parameter is used to set the speed capabilities. It is only valid +for the SK-98xx V2.0 copper adapters. +Usually, the speed is negotiated between the two ports during link +establishment. If this fails, a port can be forced to a specific setting +with this parameter. + +Auto-Negotiation +---------------- +Parameter: AutoNeg_? +Values: On, Off, Sense +Default: On + +The "Sense"-mode automatically detects whether the link partner supports +auto-negotiation or not. + +Duplex Capabilities +------------------- +Parameter: DupCap_? +Values: Half, Full, Both +Default: Both + +This parameters is only relevant if auto-negotiation for this port is +not set to "Sense". If auto-negotiation is set to "On", all three values +are possible. If it is set to "Off", only "Full" and "Half" are allowed. +This parameter is useful if your link partner does not support all +possible combinations. + +Flow Control +------------ +Parameter: FlowCtrl_? +Values: Sym, SymOrRem, LocSend, None +Default: SymOrRem + +This parameter can be used to set the flow control capabilities the +port reports during auto-negotiation. It can be set for each port +individually. +Possible modes: + -- Sym = Symmetric: both link partners are allowed to send + PAUSE frames + -- SymOrRem = SymmetricOrRemote: both or only remote partner + are allowed to send PAUSE frames + -- LocSend = LocalSend: only local link partner is allowed + to send PAUSE frames + -- None = no link partner is allowed to send PAUSE frames + +NOTE: This parameter is ignored if auto-negotiation is set to "Off". + +Role in Master-Slave-Negotiation (1000Base-T only) +-------------------------------------------------- +Parameter: Role_? +Values: Auto, Master, Slave +Default: Auto + +This parameter is only valid for the SK-9821 and SK-9822 adapters. +For two 1000Base-T ports to communicate, one must take the role of the +master (providing timing information), while the other must be the +slave. Usually, this is negotiated between the two ports during link +establishment. If this fails, a port can be forced to a specific setting +with this parameter. + + +4.2 Adapter Parameters +----------------------- + +Connection Type (SK-98xx V2.0 copper adapters only) +--------------- +Parameter: ConType +Values: Auto, 100FD, 100HD, 10FD, 10HD +Default: Auto + +The parameter 'ConType' is a combination of all five per-port parameters +within one single parameter. This simplifies the configuration of both ports +of an adapter card! The different values of this variable reflect the most +meaningful combinations of port parameters. + +The following table shows the values of 'ConType' and the corresponding +combinations of the per-port parameters: + + ConType | DupCap AutoNeg FlowCtrl Role Speed + ----------+------------------------------------------------------ + Auto | Both On SymOrRem Auto Auto + 100FD | Full Off None Auto (ignored) 100 + 100HD | Half Off None Auto (ignored) 100 + 10FD | Full Off None Auto (ignored) 10 + 10HD | Half Off None Auto (ignored) 10 + +Stating any other port parameter together with this 'ConType' variable +will result in a merged configuration of those settings. This due to +the fact, that the per-port parameters (e.g. Speed_? ) have a higher +priority than the combined variable 'ConType'. + +NOTE: This parameter is always used on both ports of the adapter card. + +Interrupt Moderation +-------------------- +Parameter: Moderation +Values: None, Static, Dynamic +Default: None + +Interrupt moderation is employed to limit the maximum number of interrupts +the driver has to serve. That is, one or more interrupts (which indicate any +transmit or receive packet to be processed) are queued until the driver +processes them. When queued interrupts are to be served, is determined by the +'IntsPerSec' parameter, which is explained later below. + +Possible modes: + + -- None - No interrupt moderation is applied on the adapter card. + Therefore, each transmit or receive interrupt is served immediately + as soon as it appears on the interrupt line of the adapter card. + + -- Static - Interrupt moderation is applied on the adapter card. + All transmit and receive interrupts are queued until a complete + moderation interval ends. If such a moderation interval ends, all + queued interrupts are processed in one big bunch without any delay. + The term 'static' reflects the fact, that interrupt moderation is + always enabled, regardless how much network load is currently + passing via a particular interface. In addition, the duration of + the moderation interval has a fixed length that never changes while + the driver is operational. + + -- Dynamic - Interrupt moderation might be applied on the adapter card, + depending on the load of the system. If the driver detects that the + system load is too high, the driver tries to shield the system against + too much network load by enabling interrupt moderation. If - at a later + time - the CPU utilization decreases again (or if the network load is + negligible) the interrupt moderation will automatically be disabled. + +Interrupt moderation should be used when the driver has to handle one or more +interfaces with a high network load, which - as a consequence - leads also to a +high CPU utilization. When moderation is applied in such high network load +situations, CPU load might be reduced by 20-30%. + +NOTE: The drawback of using interrupt moderation is an increase of the round- +trip-time (RTT), due to the queueing and serving of interrupts at dedicated +moderation times. + +Interrupts per second +--------------------- +Parameter: IntsPerSec +Values: 30...40000 (interrupts per second) +Default: 2000 + +This parameter is only used if either static or dynamic interrupt moderation +is used on a network adapter card. Using this parameter if no moderation is +applied will lead to no action performed. + +This parameter determines the length of any interrupt moderation interval. +Assuming that static interrupt moderation is to be used, an 'IntsPerSec' +parameter value of 2000 will lead to an interrupt moderation interval of +500 microseconds. + +NOTE: The duration of the moderation interval is to be chosen with care. +At first glance, selecting a very long duration (e.g. only 100 interrupts per +second) seems to be meaningful, but the increase of packet-processing delay +is tremendous. On the other hand, selecting a very short moderation time might +compensate the use of any moderation being applied. + + +Preferred Port +-------------- +Parameter: PrefPort +Values: A, B +Default: A + +This is used to force the preferred port to A or B (on dual-port network +adapters). The preferred port is the one that is used if both are detected +as fully functional. + +RLMT Mode (Redundant Link Management Technology) +------------------------------------------------ +Parameter: RlmtMode +Values: CheckLinkState,CheckLocalPort, CheckSeg, DualNet +Default: CheckLinkState + +RLMT monitors the status of the port. If the link of the active port +fails, RLMT switches immediately to the standby link. The virtual link is +maintained as long as at least one 'physical' link is up. + +Possible modes: + + -- CheckLinkState - Check link state only: RLMT uses the link state + reported by the adapter hardware for each individual port to + determine whether a port can be used for all network traffic or + not. + + -- CheckLocalPort - In this mode, RLMT monitors the network path + between the two ports of an adapter by regularly exchanging packets + between them. This mode requires a network configuration in which + the two ports are able to "see" each other (i.e. there must not be + any router between the ports). + + -- CheckSeg - Check local port and segmentation: This mode supports the + same functions as the CheckLocalPort mode and additionally checks + network segmentation between the ports. Therefore, this mode is only + to be used if Gigabit Ethernet switches are installed on the network + that have been configured to use the Spanning Tree protocol. + + -- DualNet - In this mode, ports A and B are used as separate devices. + If you have a dual port adapter, port A will be configured as eth0 + and port B as eth1. Both ports can be used independently with + distinct IP addresses. The preferred port setting is not used. + RLMT is turned off. + +NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations + where a network path between the ports on one adapter exists. + Moreover, they are not designed to work where adapters are connected + back-to-back. +*** + + +5 Large Frame Support +====================== + +The driver supports large frames (also called jumbo frames). Using large +frames can result in an improved throughput if transferring large amounts +of data. +To enable large frames, set the MTU (maximum transfer unit) of the +interface to the desired value (up to 9000), execute the following +command: + ifconfig eth0 mtu 9000 +This will only work if you have two adapters connected back-to-back +or if you use a switch that supports large frames. When using a switch, +it should be configured to allow large frames and auto-negotiation should +be set to OFF. The setting must be configured on all adapters that can be +reached by the large frames. If one adapter is not set to receive large +frames, it will simply drop them. + +You can switch back to the standard ethernet frame size by executing the +following command: + ifconfig eth0 mtu 1500 + +To permanently configure this setting, add a script with the 'ifconfig' +line to the system startup sequence (named something like "S99sk98lin" +in /etc/rc.d/rc2.d). +*** + + +6 VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad) +================================================================== + +The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and +Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. +These features are only available after installation of open source +modules available on the Internet: +For VLAN go to: http://www.candelatech.com/~greear/vlan.html +For Link Aggregation go to: http://www.st.rim.or.jp/~yumo + +NOTE: SysKonnect GmbH does not offer any support for these open source + modules and does not take the responsibility for any kind of + failures or problems arising in connection with these modules. + +NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may + cause problems when unloading the driver. + + +7 Troubleshooting +================== + +If any problems occur during the installation process, check the +following list: + + +Problem: The SK-98xx adapter cannot be found by the driver. +Solution: In /proc/pci search for the following entry: + 'Ethernet controller: SysKonnect SK-98xx ...' + If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has + been found by the system and should be operational. + If this entry does not exist or if the file '/proc/pci' is not + found, there may be a hardware problem or the PCI support may + not be enabled in your kernel. + The adapter can be checked using the diagnostics program which + is available on the SysKonnect web site: + www.syskonnect.com + + Some COMPAQ machines have problems dealing with PCI under Linux. + This problem is described in the 'PCI howto' document + (included in some distributions or available from the + web, e.g. at 'www.linux.org'). + + +Problem: Programs such as 'ifconfig' or 'route' cannot be found or the + error message 'Operation not permitted' is displayed. +Reason: You are not logged in as user 'root'. +Solution: Logout and login as 'root' or change to 'root' via 'su'. + + +Problem: Upon use of the command 'ping
' the message + "ping: sendto: Network is unreachable" is displayed. +Reason: Your route is not set correctly. +Solution: If you are using RedHat, you probably forgot to set up the + route in the 'network configuration'. + Check the existing routes with the 'route' command and check + if an entry for 'eth0' exists, and if so, if it is set correctly. + + +Problem: The driver can be started, the adapter is connected to the + network, but you cannot receive or transmit any packets; + e.g. 'ping' does not work. +Reason: There is an incorrect route in your routing table. +Solution: Check the routing table with the command 'route' and read the + manual help pages dealing with routes (enter 'man route'). + +NOTE: Although the 2.2.x kernel versions generate the routing entry + automatically, problems of this kind may occur here as well. We've + come across a situation in which the driver started correctly at + system start, but after the driver has been removed and reloaded, + the route of the adapter's network pointed to the 'dummy0'device + and had to be corrected manually. + + +Problem: Your computer should act as a router between multiple + IP subnetworks (using multiple adapters), but computers in + other subnetworks cannot be reached. +Reason: Either the router's kernel is not configured for IP forwarding + or the routing table and gateway configuration of at least one + computer is not working. + +Problem: Upon driver start, the following error message is displayed: + "eth0: -- ERROR -- + Class: internal Software error + Nr: 0xcc + Msg: SkGeInitPort() cannot init running ports" +Reason: You are using a driver compiled for single processor machines + on a multiprocessor machine with SMP (Symmetric MultiProcessor) + kernel. +Solution: Configure your kernel appropriately and recompile the kernel or + the modules. + + + +If your problem is not listed here, please contact SysKonnect's technical +support for help (linux@syskonnect.de). +When contacting our technical support, please ensure that the following +information is available: +- System Manufacturer and HW Informations (CPU, Memory... ) +- PCI-Boards in your system +- Distribution +- Kernel version +- Driver version +*** + + + +***End of Readme File*** diff --git a/trunk/arch/sparc64/kernel/iommu.c b/trunk/arch/sparc64/kernel/iommu.c index 756fa24eeefa..b781d3d54fb8 100644 --- a/trunk/arch/sparc64/kernel/iommu.c +++ b/trunk/arch/sparc64/kernel/iommu.c @@ -516,11 +516,9 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, unsigned long flags, handle, prot, ctx; dma_addr_t dma_next = 0, dma_addr; unsigned int max_seg_size; - unsigned long seg_boundary_size; int outcount, incount, i; struct strbuf *strbuf; struct iommu *iommu; - unsigned long base_shift; BUG_ON(direction == DMA_NONE); @@ -551,11 +549,8 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, outs->dma_length = 0; max_seg_size = dma_get_max_seg_size(dev); - seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - IO_PAGE_SIZE) >> IO_PAGE_SHIFT; - base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT; for_each_sg(sglist, s, nelems, i) { - unsigned long paddr, npages, entry, out_entry = 0, slen; + unsigned long paddr, npages, entry, slen; iopte_t *base; slen = s->length; @@ -598,9 +593,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, * - allocated dma_addr isn't contiguous to previous allocation */ if ((dma_addr != dma_next) || - (outs->dma_length + s->length > max_seg_size) || - (is_span_boundary(out_entry, base_shift, - seg_boundary_size, outs, s))) { + (outs->dma_length + s->length > max_seg_size)) { /* Can't merge: create a new segment */ segstart = s; outcount++; @@ -614,7 +607,6 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, /* This is a new segment, fill entries */ outs->dma_address = dma_addr; outs->dma_length = slen; - out_entry = entry; } /* Calculate next page pointer for contiguous check */ diff --git a/trunk/arch/sparc64/kernel/iommu_common.h b/trunk/arch/sparc64/kernel/iommu_common.h index f3575a614fa2..0713bd58499c 100644 --- a/trunk/arch/sparc64/kernel/iommu_common.h +++ b/trunk/arch/sparc64/kernel/iommu_common.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -46,16 +45,17 @@ static inline unsigned long iommu_num_pages(unsigned long vaddr, return npages; } -static inline int is_span_boundary(unsigned long entry, - unsigned long shift, - unsigned long boundary_size, - struct scatterlist *outs, - struct scatterlist *sg) +static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems) { - unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs); - int nr = iommu_num_pages(paddr, outs->dma_length + sg->length); + unsigned long i, npages = 0; + struct scatterlist *sg; - return iommu_is_span_boundary(entry, nr, shift, boundary_size); + for_each_sg(sglist, sg, nelems, i) { + unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg); + npages += iommu_num_pages(paddr, sg->length); + } + + return npages; } extern unsigned long iommu_range_alloc(struct device *dev, diff --git a/trunk/arch/sparc64/kernel/pci_sun4v.c b/trunk/arch/sparc64/kernel/pci_sun4v.c index 01839706bd52..ddca6c6c0b49 100644 --- a/trunk/arch/sparc64/kernel/pci_sun4v.c +++ b/trunk/arch/sparc64/kernel/pci_sun4v.c @@ -335,10 +335,8 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, unsigned long flags, handle, prot; dma_addr_t dma_next = 0, dma_addr; unsigned int max_seg_size; - unsigned long seg_boundary_size; int outcount, incount, i; struct iommu *iommu; - unsigned long base_shift; long err; BUG_ON(direction == DMA_NONE); @@ -364,11 +362,8 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, iommu_batch_start(dev, prot, ~0UL); max_seg_size = dma_get_max_seg_size(dev); - seg_boundary_size = ALIGN(dma_get_seg_boundary(dev) + 1, - IO_PAGE_SIZE) >> IO_PAGE_SHIFT; - base_shift = iommu->page_table_map_base >> IO_PAGE_SHIFT; for_each_sg(sglist, s, nelems, i) { - unsigned long paddr, npages, entry, out_entry = 0, slen; + unsigned long paddr, npages, entry, slen; slen = s->length; /* Sanity check */ @@ -411,9 +406,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, * - allocated dma_addr isn't contiguous to previous allocation */ if ((dma_addr != dma_next) || - (outs->dma_length + s->length > max_seg_size) || - (is_span_boundary(out_entry, base_shift, - seg_boundary_size, outs, s))) { + (outs->dma_length + s->length > max_seg_size)) { /* Can't merge: create a new segment */ segstart = s; outcount++; @@ -427,7 +420,6 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, /* This is a new segment, fill entries */ outs->dma_address = dma_addr; outs->dma_length = slen; - out_entry = entry; } /* Calculate next page pointer for contiguous check */ diff --git a/trunk/arch/sparc64/mm/tlb.c b/trunk/arch/sparc64/mm/tlb.c index ae24919cba7c..a0f000b293de 100644 --- a/trunk/arch/sparc64/mm/tlb.c +++ b/trunk/arch/sparc64/mm/tlb.c @@ -23,8 +23,11 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, }; void flush_tlb_pending(void) { - struct mmu_gather *mp = &get_cpu_var(mmu_gathers); + struct mmu_gather *mp; + preempt_disable(); + + mp = &__get_cpu_var(mmu_gathers); if (mp->tlb_nr) { flush_tsb_user(mp); @@ -40,7 +43,7 @@ void flush_tlb_pending(void) mp->tlb_nr = 0; } - put_cpu_var(mmu_gathers); + preempt_enable(); } void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig) diff --git a/trunk/block/blk-settings.c b/trunk/block/blk-settings.c index 5713f7e5cbd2..1344a0ea5cc6 100644 --- a/trunk/block/blk-settings.c +++ b/trunk/block/blk-settings.c @@ -140,7 +140,7 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_addr) /* Assume anything <= 4GB can be handled by IOMMU. Actually some IOMMUs can handle everything, but I don't know of a way to test this here. */ - if (b_pfn < (min_t(u64, 0x100000000UL, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) + if (b_pfn <= (min_t(u64, 0xffffffff, BLK_BOUNCE_HIGH) >> PAGE_SHIFT)) dma = 1; q->bounce_pfn = max_low_pfn; #else diff --git a/trunk/block/cfq-iosched.c b/trunk/block/cfq-iosched.c index f26da2bfcc15..0f962ecae91f 100644 --- a/trunk/block/cfq-iosched.c +++ b/trunk/block/cfq-iosched.c @@ -1143,37 +1143,24 @@ static void cfq_put_queue(struct cfq_queue *cfqq) } /* - * Call func for each cic attached to this ioc. + * Call func for each cic attached to this ioc. Returns number of cic's seen. */ -static void +static unsigned int call_for_each_cic(struct io_context *ioc, void (*func)(struct io_context *, struct cfq_io_context *)) { struct cfq_io_context *cic; struct hlist_node *n; + int called = 0; rcu_read_lock(); - hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) + hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) { func(ioc, cic); + called++; + } rcu_read_unlock(); -} - -static void cfq_cic_free_rcu(struct rcu_head *head) -{ - struct cfq_io_context *cic; - - cic = container_of(head, struct cfq_io_context, rcu_head); - - kmem_cache_free(cfq_ioc_pool, cic); - elv_ioc_count_dec(ioc_count); - - if (ioc_gone && !elv_ioc_count_read(ioc_count)) - complete(ioc_gone); -} -static void cfq_cic_free(struct cfq_io_context *cic) -{ - call_rcu(&cic->rcu_head, cfq_cic_free_rcu); + return called; } static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) @@ -1187,18 +1174,24 @@ static void cic_free_func(struct io_context *ioc, struct cfq_io_context *cic) hlist_del_rcu(&cic->cic_list); spin_unlock_irqrestore(&ioc->lock, flags); - cfq_cic_free(cic); + kmem_cache_free(cfq_ioc_pool, cic); } static void cfq_free_io_context(struct io_context *ioc) { + int freed; + /* - * ioc->refcount is zero here, or we are called from elv_unregister(), - * so no more cic's are allowed to be linked into this ioc. So it - * should be ok to iterate over the known list, we will see all cic's - * since no new ones are added. + * ioc->refcount is zero here, so no more cic's are allowed to be + * linked into this ioc. So it should be ok to iterate over the known + * list, we will see all cic's since no new ones are added. */ - call_for_each_cic(ioc, cic_free_func); + freed = call_for_each_cic(ioc, cic_free_func); + + elv_ioc_count_mod(ioc_count, -freed); + + if (ioc_gone && !elv_ioc_count_read(ioc_count)) + complete(ioc_gone); } static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) @@ -1465,6 +1458,15 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct io_context *ioc, return cfqq; } +static void cfq_cic_free(struct cfq_io_context *cic) +{ + kmem_cache_free(cfq_ioc_pool, cic); + elv_ioc_count_dec(ioc_count); + + if (ioc_gone && !elv_ioc_count_read(ioc_count)) + complete(ioc_gone); +} + /* * We drop cfq io contexts lazily, so we may find a dead one. */ @@ -2136,7 +2138,7 @@ static int __init cfq_slab_setup(void) if (!cfq_pool) goto fail; - cfq_ioc_pool = KMEM_CACHE(cfq_io_context, 0); + cfq_ioc_pool = KMEM_CACHE(cfq_io_context, SLAB_DESTROY_BY_RCU); if (!cfq_ioc_pool) goto fail; @@ -2284,6 +2286,7 @@ static void __exit cfq_exit(void) smp_wmb(); if (elv_ioc_count_read(ioc_count)) wait_for_completion(ioc_gone); + synchronize_rcu(); cfq_slab_kill(); } diff --git a/trunk/crypto/xcbc.c b/trunk/crypto/xcbc.c index b63b633e549c..2feb0f239c38 100644 --- a/trunk/crypto/xcbc.c +++ b/trunk/crypto/xcbc.c @@ -116,11 +116,13 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, struct crypto_xcbc_ctx *ctx = crypto_hash_ctx_aligned(parent); struct crypto_cipher *tfm = ctx->child; int bs = crypto_hash_blocksize(parent); + unsigned int i = 0; - for (;;) { - struct page *pg = sg_page(sg); - unsigned int offset = sg->offset; - unsigned int slen = sg->length; + do { + + struct page *pg = sg_page(&sg[i]); + unsigned int offset = sg[i].offset; + unsigned int slen = sg[i].length; if (unlikely(slen > nbytes)) slen = nbytes; @@ -180,11 +182,8 @@ static int crypto_xcbc_digest_update2(struct hash_desc *pdesc, offset = 0; pg++; } - - if (!nbytes) - break; - sg = scatterwalk_sg_next(sg); - } + i++; + } while (nbytes>0); return 0; } diff --git a/trunk/drivers/atm/firestream.c b/trunk/drivers/atm/firestream.c index 98099f526d82..47c57a4294b7 100644 --- a/trunk/drivers/atm/firestream.c +++ b/trunk/drivers/atm/firestream.c @@ -978,7 +978,6 @@ static int fs_open(struct atm_vcc *atm_vcc) /* Docs are vague about this atm_hdr field. By the way, the FS * chip makes odd errors if lower bits are set.... -- REW */ tc->atm_hdr = (vpi << 20) | (vci << 4); - tmc0 = 0; { int pcr = atm_pcr_goal (txtp); diff --git a/trunk/drivers/atm/he.c b/trunk/drivers/atm/he.c index ffc4a5a41946..2e3395b7e8c1 100644 --- a/trunk/drivers/atm/he.c +++ b/trunk/drivers/atm/he.c @@ -3000,7 +3000,8 @@ he_proc_read(struct atm_dev *dev, loff_t *pos, char *page) /* eeprom routines -- see 4.7 */ -static u8 read_prom_byte(struct he_dev *he_dev, int addr) +u8 +read_prom_byte(struct he_dev *he_dev, int addr) { u32 val = 0, tmp_read = 0; int i, j = 0; diff --git a/trunk/drivers/atm/idt77252.c b/trunk/drivers/atm/idt77252.c index 28d77b5195de..b967919fb7e2 100644 --- a/trunk/drivers/atm/idt77252.c +++ b/trunk/drivers/atm/idt77252.c @@ -2016,7 +2016,8 @@ idt77252_send_skb(struct atm_vcc *vcc, struct sk_buff *skb, int oam) return 0; } -static int idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb) +int +idt77252_send(struct atm_vcc *vcc, struct sk_buff *skb) { return idt77252_send_skb(vcc, skb, 0); } @@ -3071,7 +3072,8 @@ idt77252_dev_open(struct idt77252_dev *card) return 0; } -static void idt77252_dev_close(struct atm_dev *dev) +void +idt77252_dev_close(struct atm_dev *dev) { struct idt77252_dev *card = dev->dev_data; u32 conf; diff --git a/trunk/drivers/atm/iphase.c b/trunk/drivers/atm/iphase.c index 670c093ed25f..ef52452640e0 100644 --- a/trunk/drivers/atm/iphase.c +++ b/trunk/drivers/atm/iphase.c @@ -958,7 +958,6 @@ static void ia_suni_pm7345_init (IADEV *iadev) /***************************** IA_LIB END *****************************/ -#ifdef CONFIG_ATM_IA_DEBUG static int tcnter = 0; static void xdump( u_char* cp, int length, char* prefix ) { @@ -993,7 +992,6 @@ static void xdump( u_char* cp, int length, char* prefix ) } } /* close xdump(... */ -#endif /* CONFIG_ATM_IA_DEBUG */ static struct atm_dev *ia_boards = NULL; diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index a080c149cc6c..fc3f57adb729 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -3415,6 +3415,7 @@ static int radio_open(struct inode *inode, struct file *file) { int minor = iminor(inode); struct bttv *btv = NULL; + struct bttv_fh *fh; unsigned int i; dprintk("bttv: open minor=%d\n",minor); @@ -3429,12 +3430,19 @@ static int radio_open(struct inode *inode, struct file *file) return -ENODEV; dprintk("bttv%d: open called (radio)\n",btv->c.nr); + + /* allocate per filehandle data */ + fh = kmalloc(sizeof(*fh), GFP_KERNEL); + if (NULL == fh) + return -ENOMEM; + file->private_data = fh; + *fh = btv->init; + v4l2_prio_open(&btv->prio, &fh->prio); + mutex_lock(&btv->lock); btv->radio_user++; - file->private_data = btv; - bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL); audio_input(btv,TVAUDIO_INPUT_RADIO); @@ -3444,7 +3452,8 @@ static int radio_open(struct inode *inode, struct file *file) static int radio_release(struct inode *inode, struct file *file) { - struct bttv *btv = file->private_data; + struct bttv_fh *fh = file->private_data; + struct bttv *btv = fh->btv; struct rds_command cmd; btv->radio_user--; @@ -3569,7 +3578,8 @@ static int radio_g_input(struct file *filp, void *priv, unsigned int *i) static ssize_t radio_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { - struct bttv *btv = file->private_data; + struct bttv_fh *fh = file->private_data; + struct bttv *btv = fh->btv; struct rds_command cmd; cmd.block_count = count/3; cmd.buffer = data; @@ -3583,7 +3593,8 @@ static ssize_t radio_read(struct file *file, char __user *data, static unsigned int radio_poll(struct file *file, poll_table *wait) { - struct bttv *btv = file->private_data; + struct bttv_fh *fh = file->private_data; + struct bttv *btv = fh->btv; struct rds_command cmd; cmd.instance = file; cmd.event_list = wait; diff --git a/trunk/drivers/net/Kconfig b/trunk/drivers/net/Kconfig index 3a0b20afec7b..fe7b5ec09708 100644 --- a/trunk/drivers/net/Kconfig +++ b/trunk/drivers/net/Kconfig @@ -2635,7 +2635,7 @@ config NIU config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" - depends on PPC_PASEMI && PCI + depends on PPC64 && PCI select PHYLIB select INET_LRO help diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index 26b2dd5016cd..c993a32b3f50 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -575,6 +575,7 @@ static void adjust_tx_list(void) static int bf537mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { + struct bf537mac_local *lp = netdev_priv(dev); unsigned int data; current_tx_ptr->skb = skb; @@ -633,6 +634,7 @@ static int bf537mac_hard_start_xmit(struct sk_buff *skb, static void bf537mac_rx(struct net_device *dev) { struct sk_buff *skb, *new_skb; + struct bf537mac_local *lp = netdev_priv(dev); unsigned short len; /* allocate a new skb for next time receive */ diff --git a/trunk/drivers/net/bonding/bond_sysfs.c b/trunk/drivers/net/bonding/bond_sysfs.c index 979c2d05ff9c..90a1f31e8e63 100644 --- a/trunk/drivers/net/bonding/bond_sysfs.c +++ b/trunk/drivers/net/bonding/bond_sysfs.c @@ -341,7 +341,6 @@ static ssize_t bonding_store_slaves(struct device *d, if (command[0] == '-') { dev = NULL; - original_mtu = 0; bond_for_each_slave(bond, slave, i) if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) { dev = slave->dev; diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 980c2c229a71..6f7e3fde9e7c 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -1854,7 +1854,6 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) struct ring_desc* start_tx; struct ring_desc* prev_tx; struct nv_skb_map* prev_tx_ctx; - unsigned long flags; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1864,10 +1863,10 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) empty_slots = nv_get_empty_tx_slots(np); if (unlikely(empty_slots <= entries)) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); netif_stop_queue(dev); np->tx_stop = 1; - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); return NETDEV_TX_BUSY; } @@ -1930,13 +1929,13 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ? NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0; - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); /* set tx flags */ start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); np->put_tx.orig = put_tx; - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for transmission. tx_flags_extra: %x\n", dev->name, entries, tx_flags_extra); @@ -1972,7 +1971,6 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) struct ring_desc_ex* prev_tx; struct nv_skb_map* prev_tx_ctx; struct nv_skb_map* start_tx_ctx; - unsigned long flags; /* add fragments to entries count */ for (i = 0; i < fragments; i++) { @@ -1982,10 +1980,10 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) empty_slots = nv_get_empty_tx_slots(np); if (unlikely(empty_slots <= entries)) { - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); netif_stop_queue(dev); np->tx_stop = 1; - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); return NETDEV_TX_BUSY; } @@ -2061,7 +2059,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) start_tx->txvlan = 0; } - spin_lock_irqsave(&np->lock, flags); + spin_lock_irq(&np->lock); if (np->tx_limit) { /* Limit the number of outstanding tx. Setup all fragments, but @@ -2087,7 +2085,7 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev) start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra); np->put_tx.ex = put_tx; - spin_unlock_irqrestore(&np->lock, flags); + spin_unlock_irq(&np->lock); dprintk(KERN_DEBUG "%s: nv_start_xmit_optimized: entries %d queued for transmission. tx_flags_extra: %x\n", dev->name, entries, tx_flags_extra); diff --git a/trunk/drivers/net/ibm_newemac/core.c b/trunk/drivers/net/ibm_newemac/core.c index 378a23963495..0789802d59ed 100644 --- a/trunk/drivers/net/ibm_newemac/core.c +++ b/trunk/drivers/net/ibm_newemac/core.c @@ -1242,8 +1242,8 @@ static int emac_close(struct net_device *ndev) static inline u16 emac_tx_csum(struct emac_instance *dev, struct sk_buff *skb) { - if (emac_has_feature(dev, EMAC_FTR_HAS_TAH) && - (skb->ip_summed == CHECKSUM_PARTIAL)) { + if (emac_has_feature(dev, EMAC_FTR_HAS_TAH && + skb->ip_summed == CHECKSUM_PARTIAL)) { ++dev->stats.tx_packets_csum; return EMAC_TX_CTRL_TAH_CSUM; } diff --git a/trunk/drivers/net/s2io.c b/trunk/drivers/net/s2io.c index c082cf0b1ac6..3c915b82e199 100644 --- a/trunk/drivers/net/s2io.c +++ b/trunk/drivers/net/s2io.c @@ -84,7 +84,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.20" +#define DRV_VERSION "2.0.26.15-2" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; diff --git a/trunk/drivers/net/tulip/eeprom.c b/trunk/drivers/net/tulip/eeprom.c index da2206f6021d..206918bad539 100644 --- a/trunk/drivers/net/tulip/eeprom.c +++ b/trunk/drivers/net/tulip/eeprom.c @@ -343,12 +343,6 @@ int __devinit tulip_read_eeprom(struct net_device *dev, int location, int addr_l void __iomem *ee_addr = tp->base_addr + CSR9; int read_cmd = location | (EE_READ_CMD << addr_len); - /* If location is past the end of what we can address, don't - * read some other location (ie truncate). Just return zero. - */ - if (location > (1 << addr_len) - 1) - return 0; - iowrite32(EE_ENB & ~EE_CS, ee_addr); iowrite32(EE_ENB, ee_addr); diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index 82f404b76d81..ed600bf56e78 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1437,7 +1437,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, EEPROM. */ ee_data = tp->eeprom; - memset(ee_data, 0, sizeof(tp->eeprom)); sum = 0; if (chip_idx == LC82C168) { for (i = 0; i < 3; i++) { @@ -1459,12 +1458,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, /* A serial EEPROM interface, we read now and sort it out later. */ int sa_offset = 0; int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6; - int ee_max_addr = ((1 << ee_addr_size) - 1) * sizeof(u16); - if (ee_max_addr > sizeof(tp->eeprom)) - ee_max_addr = sizeof(tp->eeprom); - - for (i = 0; i < ee_max_addr ; i += sizeof(u16)) { + for (i = 0; i < sizeof(tp->eeprom); i+=2) { u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size); ee_data[i] = data & 0xff; ee_data[i + 1] = data >> 8; diff --git a/trunk/drivers/net/usb/Kconfig b/trunk/drivers/net/usb/Kconfig index 0604f3faf043..a12c9c41b217 100644 --- a/trunk/drivers/net/usb/Kconfig +++ b/trunk/drivers/net/usb/Kconfig @@ -129,7 +129,7 @@ config USB_USBNET config USB_NET_AX8817X tristate "ASIX AX88xxx Based USB 2.0 Ethernet Adapters" - depends on USB_USBNET + depends on USB_USBNET && NET_ETHERNET select CRC32 default y help diff --git a/trunk/drivers/net/usb/dm9601.c b/trunk/drivers/net/usb/dm9601.c index 01660f68943a..0343b00cf1fd 100644 --- a/trunk/drivers/net/usb/dm9601.c +++ b/trunk/drivers/net/usb/dm9601.c @@ -354,7 +354,7 @@ static void dm9601_set_multicast(struct net_device *net) struct dev_mc_list *mc_list = net->mc_list; int i; - for (i = 0; i < net->mc_count; i++, mc_list = mc_list->next) { + for (i = 0; i < net->mc_count; i++) { u32 crc = ether_crc(ETH_ALEN, mc_list->dmi_addr) >> 26; hashes[crc >> 3] |= 1 << (crc & 0x7); } diff --git a/trunk/drivers/net/usb/pegasus.c b/trunk/drivers/net/usb/pegasus.c index b588c890ea70..d1ed68a11e70 100644 --- a/trunk/drivers/net/usb/pegasus.c +++ b/trunk/drivers/net/usb/pegasus.c @@ -1128,8 +1128,12 @@ pegasus_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { pegasus_t *pegasus; + if (in_atomic()) + return 0; + pegasus = netdev_priv(dev); mii_ethtool_gset(&pegasus->mii, ecmd); + return 0; } diff --git a/trunk/drivers/net/wan/lapbether.c b/trunk/drivers/net/wan/lapbether.c index 824df3b5ea49..fb37b8095231 100644 --- a/trunk/drivers/net/wan/lapbether.c +++ b/trunk/drivers/net/wan/lapbether.c @@ -58,7 +58,7 @@ struct lapbethdev { struct net_device_stats stats; /* some statistics */ }; -static LIST_HEAD(lapbeth_devices); +static struct list_head lapbeth_devices = LIST_HEAD_INIT(lapbeth_devices); /* ------------------------------------------------------------------------ */ diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 948eb1fe916b..cfbc1a26f601 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -619,7 +619,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, } if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { - b43err(ring->dev->wl, "RX DMA buffer allocation failed\n"); dev_kfree_skb_any(skb); return -EIO; } @@ -875,12 +874,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, DMA_TO_DEVICE); if (b43_dma_mapping_error(ring, dma_test, - b43_txhdr_size(dev), 1)) { - - b43err(dev->wl, - "TXHDR DMA allocation failed\n"); + b43_txhdr_size(dev), 1)) goto err_kfree_txhdr_cache; - } } dma_unmap_single(dev->dev->dev, diff --git a/trunk/drivers/net/wireless/b43/pcmcia.c b/trunk/drivers/net/wireless/b43/pcmcia.c index 371e4a119511..b79a6bd5396d 100644 --- a/trunk/drivers/net/wireless/b43/pcmcia.c +++ b/trunk/drivers/net/wireless/b43/pcmcia.c @@ -91,8 +91,6 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) dev->conf.ConfigBase = parse.config.base; dev->conf.Present = parse.config.rmask[0]; - dev->conf.Attributes = CONF_ENABLE_IRQ; - dev->conf.IntType = INT_MEMORY_AND_IO; dev->io.BasePort2 = 0; dev->io.NumPorts2 = 0; @@ -114,8 +112,8 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) if (res != CS_SUCCESS) goto err_disable; - dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; - dev->irq.IRQInfo1 = IRQ_LEVEL_ID; + dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED; + dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID; dev->irq.Handler = NULL; /* The handler is registered later. */ dev->irq.Instance = NULL; res = pcmcia_request_irq(dev, &dev->irq); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c index 65767570be68..d727de8b96fe 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-4965.c @@ -4589,7 +4589,7 @@ static u8 iwl4965_is_fat_tx_allowed(struct iwl4965_priv *priv, if (sta_ht_inf) { if ((!sta_ht_inf->ht_supported) || - (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH))) + (!sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH)) return 0; } diff --git a/trunk/drivers/net/wireless/libertas/if_cs.c b/trunk/drivers/net/wireless/libertas/if_cs.c index 038c66a98f15..5a9cadb97503 100644 --- a/trunk/drivers/net/wireless/libertas/if_cs.c +++ b/trunk/drivers/net/wireless/libertas/if_cs.c @@ -677,7 +677,9 @@ static int if_cs_get_int_status(struct lbs_private *priv, u8 *ireg) /* Card has a command result for us */ if (*ireg & IF_CS_C_S_CMD_UPLD_RDY) { + spin_lock(&priv->driver_lock); ret = if_cs_receive_cmdres(priv, priv->upld_buf, &priv->upld_len); + spin_unlock(&priv->driver_lock); if (ret < 0) lbs_pr_err("could not receive cmd from card\n"); } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c index e873a39fcce3..bd305f7f3efd 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1393,20 +1393,11 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) exit: /* - * Set device mode to sleep for power management, - * on some hardware this call seems to consistently fail. - * From the specifications it is hard to tell why it fails, - * and if this is a "bad thing". - * Overall it is safe to just ignore the failure and - * continue suspending. The only downside is that the - * device will not be in optimal power save mode, but with - * the radio and the other components already disabled the - * device is as good as disabled. + * Set device mode to sleep for power management. */ retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP); if (retval) - WARNING(rt2x00dev, "Device failed to enter sleep state, " - "continue suspending.\n"); + return retval; return 0; } diff --git a/trunk/drivers/scsi/hosts.c b/trunk/drivers/scsi/hosts.c index ed7e0a1fc34d..880c78bff0e1 100644 --- a/trunk/drivers/scsi/hosts.c +++ b/trunk/drivers/scsi/hosts.c @@ -218,24 +218,18 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev) get_device(&shost->shost_gendev); - if (shost->transportt->host_size) { - shost->shost_data = kzalloc(shost->transportt->host_size, - GFP_KERNEL); - if (shost->shost_data == NULL) { - error = -ENOMEM; - goto out_del_classdev; - } - } + if (shost->transportt->host_size && + (shost->shost_data = kzalloc(shost->transportt->host_size, + GFP_KERNEL)) == NULL) + goto out_del_classdev; if (shost->transportt->create_work_queue) { snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d", shost->host_no); shost->work_q = create_singlethread_workqueue( shost->work_q_name); - if (!shost->work_q) { - error = -EINVAL; + if (!shost->work_q) goto out_free_shost_data; - } } error = scsi_sysfs_add_host(shost); diff --git a/trunk/drivers/scsi/libsas/sas_discover.c b/trunk/drivers/scsi/libsas/sas_discover.c index 709a6f75ca9d..31b9af224243 100644 --- a/trunk/drivers/scsi/libsas/sas_discover.c +++ b/trunk/drivers/scsi/libsas/sas_discover.c @@ -295,14 +295,11 @@ static void sas_discover_domain(struct work_struct *work) case FANOUT_DEV: error = sas_discover_root_expander(dev); break; +#ifdef CONFIG_SCSI_SAS_ATA case SATA_DEV: case SATA_PM: -#ifdef CONFIG_SCSI_SAS_ATA error = sas_discover_sata(dev); break; -#else - SAS_DPRINTK("ATA device seen but CONFIG_SCSI_SAS_ATA=N so cannot attach\n"); - /* Fall through */ #endif default: error = -ENXIO; diff --git a/trunk/drivers/scsi/mvsas.c b/trunk/drivers/scsi/mvsas.c index e55b9037adb2..5ec0665b3a3d 100644 --- a/trunk/drivers/scsi/mvsas.c +++ b/trunk/drivers/scsi/mvsas.c @@ -37,13 +37,11 @@ #include #include #include -#include -#include #include #define DRV_NAME "mvsas" -#define DRV_VERSION "0.5.2" -#define _MV_DUMP 0 +#define DRV_VERSION "0.5.1" +#define _MV_DUMP 0 #define MVS_DISABLE_NVRAM #define MVS_DISABLE_MSI @@ -54,7 +52,7 @@ readl(regs + MVS_##reg); \ } while (0) -#define MVS_ID_NOT_MAPPED 0x7f +#define MVS_ID_NOT_MAPPED 0xff #define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) /* offset for D2H FIS in the Received FIS List Structure */ @@ -86,7 +84,6 @@ enum driver_configuration { MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */ MVS_QUEUE_SIZE = 30, /* Support Queue depth */ - MVS_CAN_QUEUE = MVS_SLOTS - 1, /* SCSI Queue depth */ }; /* unchangeable hardware details */ @@ -361,20 +358,7 @@ enum hw_register_bits { /* VSR */ /* PHYMODE 6 (CDB) */ - PHY_MODE6_LATECLK = (1U << 29), /* Lock Clock */ - PHY_MODE6_DTL_SPEED = (1U << 27), /* Digital Loop Speed */ - PHY_MODE6_FC_ORDER = (1U << 26), /* Fibre Channel Mode Order*/ - PHY_MODE6_MUCNT_EN = (1U << 24), /* u Count Enable */ - PHY_MODE6_SEL_MUCNT_LEN = (1U << 22), /* Training Length Select */ - PHY_MODE6_SELMUPI = (1U << 20), /* Phase Multi Select (init) */ - PHY_MODE6_SELMUPF = (1U << 18), /* Phase Multi Select (final) */ - PHY_MODE6_SELMUFF = (1U << 16), /* Freq Loop Multi Sel(final) */ - PHY_MODE6_SELMUFI = (1U << 14), /* Freq Loop Multi Sel(init) */ - PHY_MODE6_FREEZE_LOOP = (1U << 12), /* Freeze Rx CDR Loop */ - PHY_MODE6_INT_RXFOFFS = (1U << 3), /* Rx CDR Freq Loop Enable */ - PHY_MODE6_FRC_RXFOFFS = (1U << 2), /* Initial Rx CDR Offset */ - PHY_MODE6_STAU_0D8 = (1U << 1), /* Rx CDR Freq Loop Saturate */ - PHY_MODE6_RXSAT_DIS = (1U << 0), /* Saturate Ctl */ + PHY_MODE6_DTL_SPEED = (1U << 27), }; enum mvs_info_flags { @@ -527,43 +511,7 @@ enum status_buffer { }; enum error_info_rec { - CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */ - CMD_PI_ERR = (1U << 30), /* Protection info error. see flags2 */ - RSP_OVER = (1U << 29), /* rsp buffer overflow */ - RETRY_LIM = (1U << 28), /* FIS/frame retry limit exceeded */ - UNK_FIS = (1U << 27), /* unknown FIS */ - DMA_TERM = (1U << 26), /* DMA terminate primitive rx'd */ - SYNC_ERR = (1U << 25), /* SYNC rx'd during frame xmit */ - TFILE_ERR = (1U << 24), /* SATA taskfile Error bit set */ - R_ERR = (1U << 23), /* SATA returned R_ERR prim */ - RD_OFS = (1U << 20), /* Read DATA frame invalid offset */ - XFER_RDY_OFS = (1U << 19), /* XFER_RDY offset error */ - UNEXP_XFER_RDY = (1U << 18), /* unexpected XFER_RDY error */ - DATA_OVER_UNDER = (1U << 16), /* data overflow/underflow */ - INTERLOCK = (1U << 15), /* interlock error */ - NAK = (1U << 14), /* NAK rx'd */ - ACK_NAK_TO = (1U << 13), /* ACK/NAK timeout */ - CXN_CLOSED = (1U << 12), /* cxn closed w/out ack/nak */ - OPEN_TO = (1U << 11), /* I_T nexus lost, open cxn timeout */ - PATH_BLOCKED = (1U << 10), /* I_T nexus lost, pathway blocked */ - NO_DEST = (1U << 9), /* I_T nexus lost, no destination */ - STP_RES_BSY = (1U << 8), /* STP resources busy */ - BREAK = (1U << 7), /* break received */ - BAD_DEST = (1U << 6), /* bad destination */ - BAD_PROTO = (1U << 5), /* protocol not supported */ - BAD_RATE = (1U << 4), /* cxn rate not supported */ - WRONG_DEST = (1U << 3), /* wrong destination error */ - CREDIT_TO = (1U << 2), /* credit timeout */ - WDOG_TO = (1U << 1), /* watchdog timeout */ - BUF_PAR = (1U << 0), /* buffer parity error */ -}; - -enum error_info_rec_2 { - SLOT_BSY_ERR = (1U << 31), /* Slot Busy Error */ - GRD_CHK_ERR = (1U << 14), /* Guard Check Error */ - APP_CHK_ERR = (1U << 13), /* Application Check error */ - REF_CHK_ERR = (1U << 12), /* Reference Check Error */ - USR_BLK_NM = (1U << 0), /* User Block Number */ + CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */ }; struct mvs_chip_info { @@ -595,12 +543,28 @@ struct mvs_cmd_hdr { __le32 reserved[4]; }; +struct mvs_slot_info { + struct sas_task *task; + u32 n_elem; + u32 tx; + + /* DMA buffer for storing cmd tbl, open addr frame, status buffer, + * and PRD table + */ + void *buf; + dma_addr_t buf_dma; +#if _MV_DUMP + u32 cmd_size; +#endif + + void *response; +}; + struct mvs_port { struct asd_sas_port sas_port; u8 port_attached; u8 taskfileset; u8 wide_port_phymap; - struct list_head list; }; struct mvs_phy { @@ -618,27 +582,6 @@ struct mvs_phy { u32 frame_rcvd_size; u8 frame_rcvd[32]; u8 phy_attached; - enum sas_linkrate minimum_linkrate; - enum sas_linkrate maximum_linkrate; -}; - -struct mvs_slot_info { - struct list_head list; - struct sas_task *task; - u32 n_elem; - u32 tx; - - /* DMA buffer for storing cmd tbl, open addr frame, status buffer, - * and PRD table - */ - void *buf; - dma_addr_t buf_dma; -#if _MV_DUMP - u32 cmd_size; -#endif - - void *response; - struct mvs_port *port; }; struct mvs_info { @@ -669,14 +612,21 @@ struct mvs_info { const struct mvs_chip_info *chip; - u8 tags[MVS_SLOTS]; + unsigned long tags[MVS_SLOTS]; struct mvs_slot_info slot_info[MVS_SLOTS]; /* further per-slot information */ struct mvs_phy phy[MVS_MAX_PHYS]; struct mvs_port port[MVS_MAX_PHYS]; -#ifdef MVS_USE_TASKLET - struct tasklet_struct tasklet; -#endif + + u32 can_queue; /* per adapter */ + u32 tag_out; /*Get*/ + u32 tag_in; /*Give*/ +}; + +struct mvs_queue_task { + struct list_head list; + + void *uldd_task; }; static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, @@ -691,11 +641,10 @@ static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port); static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i); static void mvs_detect_porttype(struct mvs_info *mvi, int i); static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); -static void mvs_release_task(struct mvs_info *mvi, int phy_no); static int mvs_scan_finished(struct Scsi_Host *, unsigned long); static void mvs_scan_start(struct Scsi_Host *); -static int mvs_slave_configure(struct scsi_device *sdev); +static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev); static struct scsi_transport_template *mvs_stt; @@ -710,7 +659,7 @@ static struct scsi_host_template mvs_sht = { .name = DRV_NAME, .queuecommand = sas_queuecommand, .target_alloc = sas_target_alloc, - .slave_configure = mvs_slave_configure, + .slave_configure = sas_slave_configure, .slave_destroy = sas_slave_destroy, .scan_finished = mvs_scan_finished, .scan_start = mvs_scan_start, @@ -725,7 +674,7 @@ static struct scsi_host_template mvs_sht = { .use_clustering = ENABLE_CLUSTERING, .eh_device_reset_handler = sas_eh_device_reset_handler, .eh_bus_reset_handler = sas_eh_bus_reset_handler, - .slave_alloc = sas_slave_alloc, + .slave_alloc = mvs_sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, }; @@ -760,10 +709,10 @@ static void mvs_hexdump(u32 size, u8 *data, u32 baseaddr) printk("\n"); } -#if _MV_DUMP static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag, enum sas_protocol proto) { +#if _MV_DUMP u32 offset; struct pci_dev *pdev = mvi->pdev; struct mvs_slot_info *slot = &mvi->slot_info[tag]; @@ -774,14 +723,14 @@ static void mvs_hba_sb_dump(struct mvs_info *mvi, u32 tag, tag); mvs_hexdump(32, (u8 *) slot->response, (u32) slot->buf_dma + offset); -} #endif +} static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, enum sas_protocol proto) { #if _MV_DUMP - u32 sz, w_ptr; + u32 sz, w_ptr, r_ptr; u64 addr; void __iomem *regs = mvi->regs; struct pci_dev *pdev = mvi->pdev; @@ -789,10 +738,12 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, /*Delivery Queue */ sz = mr32(TX_CFG) & TX_RING_SZ_MASK; - w_ptr = slot->tx; + w_ptr = mr32(TX_PROD_IDX) & TX_RING_SZ_MASK; + r_ptr = mr32(TX_CONS_IDX) & TX_RING_SZ_MASK; addr = mr32(TX_HI) << 16 << 16 | mr32(TX_LO); dev_printk(KERN_DEBUG, &pdev->dev, - "Delivery Queue Size=%04d , WRT_PTR=%04X\n", sz, w_ptr); + "Delivery Queue Size=%04d , WRT_PTR=%04X , RD_PTR=%04X\n", + sz, w_ptr, r_ptr); dev_printk(KERN_DEBUG, &pdev->dev, "Delivery Queue Base Address=0x%llX (PA)" "(tx_dma=0x%llX), Entry=%04d\n", @@ -800,11 +751,11 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, mvs_hexdump(sizeof(u32), (u8 *)(&mvi->tx[mvi->tx_prod]), (u32) mvi->tx_dma + sizeof(u32) * w_ptr); /*Command List */ - addr = mvi->slot_dma; + addr = mr32(CMD_LIST_HI) << 16 << 16 | mr32(CMD_LIST_LO); dev_printk(KERN_DEBUG, &pdev->dev, "Command List Base Address=0x%llX (PA)" "(slot_dma=0x%llX), Header=%03d\n", - addr, slot->buf_dma, tag); + addr, mvi->slot_dma, tag); dev_printk(KERN_DEBUG, &pdev->dev, "Command Header[%03d]:\n", tag); /*mvs_cmd_hdr */ mvs_hexdump(sizeof(struct mvs_cmd_hdr), (u8 *)(&mvi->slot[tag]), @@ -828,7 +779,7 @@ static void mvs_hba_memory_dump(struct mvs_info *mvi, u32 tag, static void mvs_hba_cq_dump(struct mvs_info *mvi) { -#if (_MV_DUMP > 2) +#if _MV_DUMP u64 addr; void __iomem *regs = mvi->regs; struct pci_dev *pdev = mvi->pdev; @@ -837,8 +788,8 @@ static void mvs_hba_cq_dump(struct mvs_info *mvi) /*Completion Queue */ addr = mr32(RX_HI) << 16 << 16 | mr32(RX_LO); - dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%p\n", - mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task); + dev_printk(KERN_DEBUG, &pdev->dev, "Completion Task = 0x%08X\n", + (u32) mvi->slot_info[rx_desc & RXQ_SLOT_MASK].task); dev_printk(KERN_DEBUG, &pdev->dev, "Completion List Base Address=0x%llX (PA), " "CQ_Entry=%04d, CQ_WP=0x%08X\n", @@ -903,53 +854,34 @@ static int pci_go_64(struct pci_dev *pdev) return rc; } -static int mvs_find_tag(struct mvs_info *mvi, struct sas_task *task, u32 *tag) -{ - if (task->lldd_task) { - struct mvs_slot_info *slot; - slot = (struct mvs_slot_info *) task->lldd_task; - *tag = slot - mvi->slot_info; - return 1; - } - return 0; -} - static void mvs_tag_clear(struct mvs_info *mvi, u32 tag) { - void *bitmap = (void *) &mvi->tags; - clear_bit(tag, bitmap); + mvi->tag_in = (mvi->tag_in + 1) & (MVS_SLOTS - 1); + mvi->tags[mvi->tag_in] = tag; } static void mvs_tag_free(struct mvs_info *mvi, u32 tag) { - mvs_tag_clear(mvi, tag); -} - -static void mvs_tag_set(struct mvs_info *mvi, unsigned int tag) -{ - void *bitmap = (void *) &mvi->tags; - set_bit(tag, bitmap); + mvi->tag_out = (mvi->tag_out - 1) & (MVS_SLOTS - 1); } static int mvs_tag_alloc(struct mvs_info *mvi, u32 *tag_out) { - unsigned int index, tag; - void *bitmap = (void *) &mvi->tags; - - index = find_first_zero_bit(bitmap, MVS_SLOTS); - tag = index; - if (tag >= MVS_SLOTS) - return -SAS_QUEUE_FULL; - mvs_tag_set(mvi, tag); - *tag_out = tag; - return 0; + if (mvi->tag_out != mvi->tag_in) { + *tag_out = mvi->tags[mvi->tag_out]; + mvi->tag_out = (mvi->tag_out + 1) & (MVS_SLOTS - 1); + return 0; + } + return -EBUSY; } static void mvs_tag_init(struct mvs_info *mvi) { int i; for (i = 0; i < MVS_SLOTS; ++i) - mvs_tag_clear(mvi, i); + mvi->tags[i] = i; + mvi->tag_out = 0; + mvi->tag_in = MVS_SLOTS - 1; } #ifndef MVS_DISABLE_NVRAM @@ -1081,21 +1013,10 @@ static int mvs_nvram_read(struct mvs_info *mvi, u32 addr, static void mvs_bytes_dmaed(struct mvs_info *mvi, int i) { struct mvs_phy *phy = &mvi->phy[i]; - struct asd_sas_phy *sas_phy = mvi->sas.sas_phy[i]; if (!phy->phy_attached) return; - if (sas_phy->phy) { - struct sas_phy *sphy = sas_phy->phy; - - sphy->negotiated_linkrate = sas_phy->linkrate; - sphy->minimum_linkrate = phy->minimum_linkrate; - sphy->minimum_linkrate_hw = SAS_LINK_RATE_1_5_GBPS; - sphy->maximum_linkrate = phy->maximum_linkrate; - sphy->maximum_linkrate_hw = SAS_LINK_RATE_3_0_GBPS; - } - if (phy->phy_type & PORT_TYPE_SAS) { struct sas_identify_frame *id; @@ -1132,149 +1053,80 @@ static void mvs_scan_start(struct Scsi_Host *shost) } } -static int mvs_slave_configure(struct scsi_device *sdev) +static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev) { - struct domain_device *dev = sdev_to_domain_dev(sdev); - int ret = sas_slave_configure(sdev); - - if (ret) - return ret; + int rc; - if (dev_is_sata(dev)) { - /* struct ata_port *ap = dev->sata_dev.ap; */ - /* struct ata_device *adev = ap->link.device; */ + rc = sas_slave_alloc(scsi_dev); - /* clamp at no NCQ for the time being */ - /* adev->flags |= ATA_DFLAG_NCQ_OFF; */ - scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, 1); - } - return 0; + return rc; } -static void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) +static void mvs_int_port(struct mvs_info *mvi, int port_no, u32 events) { struct pci_dev *pdev = mvi->pdev; struct sas_ha_struct *sas_ha = &mvi->sas; - struct mvs_phy *phy = &mvi->phy[phy_no]; + struct mvs_phy *phy = &mvi->phy[port_no]; struct asd_sas_phy *sas_phy = &phy->sas_phy; - phy->irq_status = mvs_read_port_irq_stat(mvi, phy_no); + phy->irq_status = mvs_read_port_irq_stat(mvi, port_no); /* * events is port event now , * we need check the interrupt status which belongs to per port. */ dev_printk(KERN_DEBUG, &pdev->dev, "Port %d Event = %X\n", - phy_no, phy->irq_status); + port_no, phy->irq_status); if (phy->irq_status & (PHYEV_POOF | PHYEV_DEC_ERR)) { - mvs_release_task(mvi, phy_no); - if (!mvs_is_phy_ready(mvi, phy_no)) { + if (!mvs_is_phy_ready(mvi, port_no)) { sas_phy_disconnected(sas_phy); sas_ha->notify_phy_event(sas_phy, PHYE_LOSS_OF_SIGNAL); - dev_printk(KERN_INFO, &pdev->dev, - "Port %d Unplug Notice\n", phy_no); - } else mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, NULL); } if (!(phy->irq_status & PHYEV_DEC_ERR)) { if (phy->irq_status & PHYEV_COMWAKE) { - u32 tmp = mvs_read_port_irq_mask(mvi, phy_no); - mvs_write_port_irq_mask(mvi, phy_no, + u32 tmp = mvs_read_port_irq_mask(mvi, port_no); + mvs_write_port_irq_mask(mvi, port_no, tmp | PHYEV_SIG_FIS); } if (phy->irq_status & (PHYEV_SIG_FIS | PHYEV_ID_DONE)) { - phy->phy_status = mvs_is_phy_ready(mvi, phy_no); + phy->phy_status = mvs_is_phy_ready(mvi, port_no); if (phy->phy_status) { - mvs_detect_porttype(mvi, phy_no); + mvs_detect_porttype(mvi, port_no); if (phy->phy_type & PORT_TYPE_SATA) { u32 tmp = mvs_read_port_irq_mask(mvi, - phy_no); + port_no); tmp &= ~PHYEV_SIG_FIS; mvs_write_port_irq_mask(mvi, - phy_no, tmp); + port_no, tmp); } - mvs_update_phyinfo(mvi, phy_no, 0); + mvs_update_phyinfo(mvi, port_no, 0); sas_ha->notify_phy_event(sas_phy, PHYE_OOB_DONE); - mvs_bytes_dmaed(mvi, phy_no); + mvs_bytes_dmaed(mvi, port_no); } else { dev_printk(KERN_DEBUG, &pdev->dev, "plugin interrupt but phy is gone\n"); mvs_phy_control(sas_phy, PHY_FUNC_LINK_RESET, NULL); } - } else if (phy->irq_status & PHYEV_BROAD_CH) { - mvs_release_task(mvi, phy_no); + } else if (phy->irq_status & PHYEV_BROAD_CH) sas_ha->notify_port_event(sas_phy, PORTE_BROADCAST_RCVD); - } } - mvs_write_port_irq_stat(mvi, phy_no, phy->irq_status); + mvs_write_port_irq_stat(mvi, port_no, phy->irq_status); } static void mvs_int_sata(struct mvs_info *mvi) { - u32 tmp; - void __iomem *regs = mvi->regs; - tmp = mr32(INT_STAT_SRS); - mw32(INT_STAT_SRS, tmp & 0xFFFF); -} - -static void mvs_slot_reset(struct mvs_info *mvi, struct sas_task *task, - u32 slot_idx) -{ - void __iomem *regs = mvi->regs; - struct domain_device *dev = task->dev; - struct asd_sas_port *sas_port = dev->port; - struct mvs_port *port = mvi->slot_info[slot_idx].port; - u32 reg_set, phy_mask; - - if (!sas_protocol_ata(task->task_proto)) { - reg_set = 0; - phy_mask = (port->wide_port_phymap) ? port->wide_port_phymap : - sas_port->phy_mask; - } else { - reg_set = port->taskfileset; - phy_mask = sas_port->phy_mask; - } - mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | slot_idx | - (TXQ_CMD_SLOT_RESET << TXQ_CMD_SHIFT) | - (phy_mask << TXQ_PHY_SHIFT) | - (reg_set << TXQ_SRS_SHIFT)); - - mw32(TX_PROD_IDX, mvi->tx_prod); - mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); -} - -static int mvs_sata_done(struct mvs_info *mvi, struct sas_task *task, - u32 slot_idx, int err) -{ - struct mvs_port *port = mvi->slot_info[slot_idx].port; - struct task_status_struct *tstat = &task->task_status; - struct ata_task_resp *resp = (struct ata_task_resp *)tstat->buf; - int stat = SAM_GOOD; - - resp->frame_len = sizeof(struct dev_to_host_fis); - memcpy(&resp->ending_fis[0], - SATA_RECEIVED_D2H_FIS(port->taskfileset), - sizeof(struct dev_to_host_fis)); - tstat->buf_valid_size = sizeof(*resp); - if (unlikely(err)) - stat = SAS_PROTO_RESPONSE; - return stat; + /* FIXME */ } -static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc) -{ - u32 slot_idx = rx_desc & RXQ_SLOT_MASK; - mvs_tag_clear(mvi, slot_idx); -} - -static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, +static void mvs_slot_free(struct mvs_info *mvi, struct sas_task *task, struct mvs_slot_info *slot, u32 slot_idx) { if (!sas_protocol_ata(task->task_proto)) @@ -1297,58 +1149,38 @@ static void mvs_slot_task_free(struct mvs_info *mvi, struct sas_task *task, /* do nothing */ break; } - list_del(&slot->list); - task->lldd_task = NULL; + slot->task = NULL; - slot->port = NULL; + mvs_tag_clear(mvi, slot_idx); } -static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, +static void mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, u32 slot_idx) { struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; - u32 err_dw0 = le32_to_cpu(*(u32 *) (slot->response)); - u32 err_dw1 = le32_to_cpu(*(u32 *) (slot->response + 4)); - int stat = SAM_CHECK_COND; + u64 err_dw0 = *(u32 *) slot->response; + void __iomem *regs = mvi->regs; + u32 tmp; - if (err_dw1 & SLOT_BSY_ERR) { - stat = SAS_QUEUE_FULL; - mvs_slot_reset(mvi, task, slot_idx); - } - switch (task->task_proto) { - case SAS_PROTOCOL_SSP: - break; - case SAS_PROTOCOL_SMP: - break; - case SAS_PROTOCOL_SATA: - case SAS_PROTOCOL_STP: - case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: - if (err_dw0 & TFILE_ERR) - stat = mvs_sata_done(mvi, task, slot_idx, 1); - break; - default: - break; - } + if (err_dw0 & CMD_ISS_STPD) + if (sas_protocol_ata(task->task_proto)) { + tmp = mr32(INT_STAT_SRS); + mw32(INT_STAT_SRS, tmp & 0xFFFF); + } - mvs_hexdump(16, (u8 *) slot->response, 0); - return stat; + mvs_hba_sb_dump(mvi, slot_idx, task->task_proto); } -static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) +static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc) { u32 slot_idx = rx_desc & RXQ_SLOT_MASK; struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; struct sas_task *task = slot->task; - struct task_status_struct *tstat; - struct mvs_port *port; + struct task_status_struct *tstat = &task->task_status; + struct mvs_port *port = &mvi->port[task->dev->port->id]; bool aborted; void *to; - if (unlikely(!task || !task->lldd_task)) - return -1; - - mvs_hba_cq_dump(mvi); - spin_lock(&task->task_state_lock); aborted = task->task_state_flags & SAS_TASK_STATE_ABORTED; if (!aborted) { @@ -1358,27 +1190,22 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) } spin_unlock(&task->task_state_lock); - if (aborted) { - mvs_slot_task_free(mvi, task, slot, slot_idx); - mvs_slot_free(mvi, rx_desc); + if (aborted) return -1; - } - port = slot->port; - tstat = &task->task_status; memset(tstat, 0, sizeof(*tstat)); tstat->resp = SAS_TASK_COMPLETE; - if (unlikely(!port->port_attached || flags)) { - mvs_slot_err(mvi, task, slot_idx); - if (!sas_protocol_ata(task->task_proto)) - tstat->stat = SAS_PHY_DOWN; + + if (unlikely(!port->port_attached)) { + tstat->stat = SAS_PHY_DOWN; goto out; } /* error info record present */ - if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) { - tstat->stat = mvs_slot_err(mvi, task, slot_idx); + if ((rx_desc & RXQ_ERR) && (*(u64 *) slot->response)) { + tstat->stat = SAM_CHECK_COND; + mvs_slot_err(mvi, task, slot_idx); goto out; } @@ -1415,7 +1242,21 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: { - tstat->stat = mvs_sata_done(mvi, task, slot_idx, 0); + struct ata_task_resp *resp = + (struct ata_task_resp *)tstat->buf; + + if ((rx_desc & (RXQ_DONE | RXQ_ERR | RXQ_ATTN)) == + RXQ_DONE) + tstat->stat = SAM_GOOD; + else + tstat->stat = SAM_CHECK_COND; + + resp->frame_len = sizeof(struct dev_to_host_fis); + memcpy(&resp->ending_fis[0], + SATA_RECEIVED_D2H_FIS(port->taskfileset), + sizeof(struct dev_to_host_fis)); + if (resp->ending_fis[2] & ATA_ERR) + mvs_hexdump(16, resp->ending_fis, 0); break; } @@ -1425,34 +1266,11 @@ static int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) } out: - mvs_slot_task_free(mvi, task, slot, slot_idx); - if (unlikely(tstat->stat != SAS_QUEUE_FULL)) - mvs_slot_free(mvi, rx_desc); - - spin_unlock(&mvi->lock); + mvs_slot_free(mvi, task, slot, slot_idx); task->task_done(task); - spin_lock(&mvi->lock); return tstat->stat; } -static void mvs_release_task(struct mvs_info *mvi, int phy_no) -{ - struct list_head *pos, *n; - struct mvs_slot_info *slot; - struct mvs_phy *phy = &mvi->phy[phy_no]; - struct mvs_port *port = phy->port; - u32 rx_desc; - - if (!port) - return; - - list_for_each_safe(pos, n, &port->list) { - slot = container_of(pos, struct mvs_slot_info, list); - rx_desc = (u32) (slot - mvi->slot_info); - mvs_slot_complete(mvi, rx_desc, 1); - } -} - static void mvs_int_full(struct mvs_info *mvi) { void __iomem *regs = mvi->regs; @@ -1487,43 +1305,40 @@ static int mvs_int_rx(struct mvs_info *mvi, bool self_clear) * we don't have to stall the CPU reading that register. * The actual RX ring is offset by one dword, due to this. */ - rx_prod_idx = mvi->rx_cons; - mvi->rx_cons = le32_to_cpu(mvi->rx[0]); - if (mvi->rx_cons == 0xfff) /* h/w hasn't touched RX ring yet */ + rx_prod_idx = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK; + if (rx_prod_idx == 0xfff) { /* h/w hasn't touched RX ring yet */ + mvi->rx_cons = 0xfff; return 0; + } /* The CMPL_Q may come late, read from register and try again * note: if coalescing is enabled, * it will need to read from register every time for sure */ - if (mvi->rx_cons == rx_prod_idx) - mvi->rx_cons = mr32(RX_CONS_IDX) & RX_RING_SZ_MASK; - if (mvi->rx_cons == rx_prod_idx) return 0; + if (mvi->rx_cons == 0xfff) + mvi->rx_cons = MVS_RX_RING_SZ - 1; + while (mvi->rx_cons != rx_prod_idx) { /* increment our internal RX consumer pointer */ - rx_prod_idx = (rx_prod_idx + 1) & (MVS_RX_RING_SZ - 1); + mvi->rx_cons = (mvi->rx_cons + 1) & (MVS_RX_RING_SZ - 1); - rx_desc = le32_to_cpu(mvi->rx[rx_prod_idx + 1]); + rx_desc = le32_to_cpu(mvi->rx[mvi->rx_cons + 1]); + + mvs_hba_cq_dump(mvi); if (likely(rx_desc & RXQ_DONE)) - mvs_slot_complete(mvi, rx_desc, 0); + mvs_slot_complete(mvi, rx_desc); if (rx_desc & RXQ_ATTN) { attn = true; dev_printk(KERN_DEBUG, &pdev->dev, "ATTN %X\n", rx_desc); } else if (rx_desc & RXQ_ERR) { - if (!(rx_desc & RXQ_DONE)) - mvs_slot_complete(mvi, rx_desc, 0); dev_printk(KERN_DEBUG, &pdev->dev, "RXQ_ERR %X\n", rx_desc); - } else if (rx_desc & RXQ_SLOT_RESET) { - dev_printk(KERN_DEBUG, &pdev->dev, "Slot reset[%X]\n", - rx_desc); - mvs_slot_free(mvi, rx_desc); } } @@ -1533,23 +1348,6 @@ static int mvs_int_rx(struct mvs_info *mvi, bool self_clear) return 0; } -#ifdef MVS_USE_TASKLET -static void mvs_tasklet(unsigned long data) -{ - struct mvs_info *mvi = (struct mvs_info *) data; - unsigned long flags; - - spin_lock_irqsave(&mvi->lock, flags); - -#ifdef MVS_DISABLE_MSI - mvs_int_full(mvi); -#else - mvs_int_rx(mvi, true); -#endif - spin_unlock_irqrestore(&mvi->lock, flags); -} -#endif - static irqreturn_t mvs_interrupt(int irq, void *opaque) { struct mvs_info *mvi = opaque; @@ -1558,21 +1356,18 @@ static irqreturn_t mvs_interrupt(int irq, void *opaque) stat = mr32(GBL_INT_STAT); - if (stat == 0 || stat == 0xffffffff) - return IRQ_NONE; - /* clear CMD_CMPLT ASAP */ mw32_f(INT_STAT, CINT_DONE); -#ifndef MVS_USE_TASKLET + if (stat == 0 || stat == 0xffffffff) + return IRQ_NONE; + spin_lock(&mvi->lock); mvs_int_full(mvi); spin_unlock(&mvi->lock); -#else - tasklet_schedule(&mvi->tasklet); -#endif + return IRQ_HANDLED; } @@ -1581,15 +1376,12 @@ static irqreturn_t mvs_msi_interrupt(int irq, void *opaque) { struct mvs_info *mvi = opaque; -#ifndef MVS_USE_TASKLET spin_lock(&mvi->lock); mvs_int_rx(mvi, true); spin_unlock(&mvi->lock); -#else - tasklet_schedule(&mvi->tasklet); -#endif + return IRQ_HANDLED; } #endif @@ -1784,19 +1576,15 @@ static u8 mvs_assign_reg_set(struct mvs_info *mvi, struct mvs_port *port) return MVS_ID_NOT_MAPPED; } -static u32 mvs_get_ncq_tag(struct sas_task *task, u32 *tag) +static u32 mvs_get_ncq_tag(struct sas_task *task) { + u32 tag = 0; struct ata_queued_cmd *qc = task->uldd_task; - if (qc) { - if (qc->tf.command == ATA_CMD_FPDMA_WRITE || - qc->tf.command == ATA_CMD_FPDMA_READ) { - *tag = qc->tag; - return 1; - } - } + if (qc) + tag = qc->tag; - return 0; + return tag; } static int mvs_task_prep_ata(struct mvs_info *mvi, @@ -1840,9 +1628,11 @@ static int mvs_task_prep_ata(struct mvs_info *mvi, hdr->flags = cpu_to_le32(flags); /* FIXME: the low order order 5 bits for the TAG if enable NCQ */ - if (task->ata_task.use_ncq && mvs_get_ncq_tag(task, &hdr->tags)) - task->ata_task.fis.sector_count |= hdr->tags << 3; - else + if (task->ata_task.use_ncq) { + hdr->tags = cpu_to_le32(mvs_get_ncq_tag(task)); + /*Fill in task file */ + task->ata_task.fis.sector_count = hdr->tags << 3; + } else hdr->tags = cpu_to_le32(tag); hdr->data_len = cpu_to_le32(task->total_xfer_len); @@ -1935,16 +1725,13 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, u32 flags; u32 resp_len, req_len, i, tag = tei->tag; const u32 max_resp_len = SB_RFB_MAX; - u8 phy_mask; slot = &mvi->slot_info[tag]; - phy_mask = (port->wide_port_phymap) ? port->wide_port_phymap : - task->dev->port->phy_mask; slot->tx = mvi->tx_prod; mvi->tx[mvi->tx_prod] = cpu_to_le32(TXQ_MODE_I | tag | (TXQ_CMD_SSP << TXQ_CMD_SHIFT) | - (phy_mask << TXQ_PHY_SHIFT)); + (port->wide_port_phymap << TXQ_PHY_SHIFT)); flags = MCH_RETRY; if (task->ssp_task.enable_first_burst) { @@ -2045,32 +1832,22 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) void __iomem *regs = mvi->regs; struct mvs_task_exec_info tei; struct sas_task *t = task; - struct mvs_slot_info *slot; u32 tag = 0xdeadbeef, rc, n_elem = 0; unsigned long flags; u32 n = num, pass = 0; spin_lock_irqsave(&mvi->lock, flags); + do { - dev = t->dev; tei.port = &mvi->port[dev->port->id]; if (!tei.port->port_attached) { - if (sas_protocol_ata(t->task_proto)) { - rc = SAS_PHY_DOWN; - goto out_done; - } else { - struct task_status_struct *ts = &t->task_status; - ts->resp = SAS_TASK_UNDELIVERED; - ts->stat = SAS_PHY_DOWN; - t->task_done(t); - if (n > 1) - t = list_entry(t->list.next, - struct sas_task, list); - continue; - } + struct task_status_struct *ts = &t->task_status; + ts->stat = SAS_PHY_DOWN; + t->task_done(t); + rc = 0; + goto exec_exit; } - if (!sas_protocol_ata(t->task_proto)) { if (t->num_scatter) { n_elem = pci_map_sg(mvi->pdev, t->scatter, @@ -2089,10 +1866,9 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) if (rc) goto err_out; - slot = &mvi->slot_info[tag]; - t->lldd_task = NULL; - slot->n_elem = n_elem; - memset(slot->buf, 0, MVS_SLOT_BUF_SZ); + mvi->slot_info[tag].task = t; + mvi->slot_info[tag].n_elem = n_elem; + memset(mvi->slot_info[tag].buf, 0, MVS_SLOT_BUF_SZ); tei.task = t; tei.hdr = &mvi->slot[tag]; tei.tag = tag; @@ -2121,26 +1897,28 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) if (rc) goto err_out_tag; - slot->task = t; - slot->port = tei.port; - t->lldd_task = (void *) slot; - list_add_tail(&slot->list, &slot->port->list); /* TODO: select normal or high priority */ spin_lock(&t->task_state_lock); t->task_state_flags |= SAS_TASK_AT_INITIATOR; spin_unlock(&t->task_state_lock); + if (n == 1) { + spin_unlock_irqrestore(&mvi->lock, flags); + mw32(TX_PROD_IDX, mvi->tx_prod); + } mvs_hba_memory_dump(mvi, tag, t->task_proto); ++pass; mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1); - if (n > 1) - t = list_entry(t->list.next, struct sas_task, list); + + if (n == 1) + break; + + t = list_entry(t->list.next, struct sas_task, list); } while (--n); - rc = 0; - goto out_done; + return 0; err_out_tag: mvs_tag_free(mvi, tag); @@ -2150,7 +1928,7 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) if (n_elem) pci_unmap_sg(mvi->pdev, t->scatter, n_elem, t->data_dir); -out_done: +exec_exit: if (pass) mw32(TX_PROD_IDX, (mvi->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1)); spin_unlock_irqrestore(&mvi->lock, flags); @@ -2159,59 +1937,42 @@ static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags) static int mvs_task_abort(struct sas_task *task) { - int rc; + int rc = 1; unsigned long flags; struct mvs_info *mvi = task->dev->port->ha->lldd_ha; struct pci_dev *pdev = mvi->pdev; - int tag; spin_lock_irqsave(&task->task_state_lock, flags); if (task->task_state_flags & SAS_TASK_STATE_DONE) { rc = TMF_RESP_FUNC_COMPLETE; - spin_unlock_irqrestore(&task->task_state_lock, flags); goto out_done; } spin_unlock_irqrestore(&task->task_state_lock, flags); + /*FIXME*/ + rc = TMF_RESP_FUNC_COMPLETE; + switch (task->task_proto) { case SAS_PROTOCOL_SMP: - dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! \n"); + dev_printk(KERN_DEBUG, &pdev->dev, "SMP Abort! "); break; case SAS_PROTOCOL_SSP: - dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! \n"); + dev_printk(KERN_DEBUG, &pdev->dev, "SSP Abort! "); break; case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_STP: case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:{ - dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! \n"); -#if _MV_DUMP - dev_printk(KERN_DEBUG, &pdev->dev, "Dump D2H FIS: \n"); + dev_printk(KERN_DEBUG, &pdev->dev, "STP Abort! " + "Dump D2H FIS: \n"); mvs_hexdump(sizeof(struct host_to_dev_fis), (void *)&task->ata_task.fis, 0); dev_printk(KERN_DEBUG, &pdev->dev, "Dump ATAPI Cmd : \n"); mvs_hexdump(16, task->ata_task.atapi_packet, 0); -#endif - spin_lock_irqsave(&task->task_state_lock, flags); - if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET) { - /* TODO */ - ; - } - spin_unlock_irqrestore(&task->task_state_lock, flags); break; } default: break; } - - if (mvs_find_tag(mvi, task, &tag)) { - spin_lock_irqsave(&mvi->lock, flags); - mvs_slot_task_free(mvi, task, &mvi->slot_info[tag], tag); - spin_unlock_irqrestore(&mvi->lock, flags); - } - if (!mvs_task_exec(task, 1, GFP_ATOMIC)) - rc = TMF_RESP_FUNC_COMPLETE; - else - rc = TMF_RESP_FUNC_FAILED; out_done: return rc; } @@ -2240,7 +2001,7 @@ static void mvs_free(struct mvs_info *mvi) mvi->rx_fis, mvi->rx_fis_dma); if (mvi->rx) dma_free_coherent(&mvi->pdev->dev, - sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1), + sizeof(*mvi->rx) * MVS_RX_RING_SZ, mvi->rx, mvi->rx_dma); if (mvi->slot) dma_free_coherent(&mvi->pdev->dev, @@ -2348,9 +2109,6 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev, return NULL; spin_lock_init(&mvi->lock); -#ifdef MVS_USE_TASKLET - tasklet_init(&mvi->tasklet, mvs_tasklet, (unsigned long)mvi); -#endif mvi->pdev = pdev; mvi->chip = chip; @@ -2374,10 +2132,6 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev, mvs_phy_init(mvi, i); arr_phy[i] = &mvi->phy[i].sas_phy; arr_port[i] = &mvi->port[i].sas_port; - mvi->port[i].taskfileset = MVS_ID_NOT_MAPPED; - mvi->port[i].wide_port_phymap = 0; - mvi->port[i].port_attached = 0; - INIT_LIST_HEAD(&mvi->port[i].list); } SHOST_TO_SAS_HA(mvi->shost) = &mvi->sas; @@ -2394,10 +2148,9 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev, mvi->sas.sas_phy = arr_phy; mvi->sas.sas_port = arr_port; mvi->sas.num_phys = chip->n_phy; - mvi->sas.lldd_max_execute_num = 1; + mvi->sas.lldd_max_execute_num = MVS_CHIP_SLOT_SZ - 1; mvi->sas.lldd_queue_size = MVS_QUEUE_SIZE; - mvi->shost->can_queue = MVS_CAN_QUEUE; - mvi->shost->cmd_per_lun = MVS_SLOTS / mvi->sas.num_phys; + mvi->can_queue = (MVS_CHIP_SLOT_SZ >> 1) - 1; mvi->sas.lldd_ha = mvi; mvi->sas.core.shost = mvi->shost; @@ -2450,11 +2203,11 @@ static struct mvs_info *__devinit mvs_alloc(struct pci_dev *pdev, memset(mvi->rx_fis, 0, MVS_RX_FISL_SZ); mvi->rx = dma_alloc_coherent(&pdev->dev, - sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1), + sizeof(*mvi->rx) * MVS_RX_RING_SZ, &mvi->rx_dma, GFP_KERNEL); if (!mvi->rx) goto err_out; - memset(mvi->rx, 0, sizeof(*mvi->rx) * (MVS_RX_RING_SZ + 1)); + memset(mvi->rx, 0, sizeof(*mvi->rx) * MVS_RX_RING_SZ); mvi->rx[0] = cpu_to_le32(0xfff); mvi->rx_cons = 0xfff; @@ -2604,7 +2357,7 @@ static void __devinit mvs_phy_hacks(struct mvs_info *mvi) mvs_cw32(regs, CMD_SAS_CTL0, tmp); /* workaround for WDTIMEOUT , set to 550 ms */ - mvs_cw32(regs, CMD_WD_TIMER, 0x86470); + mvs_cw32(regs, CMD_WD_TIMER, 0xffffff); /* not to halt for different port op during wideport link change */ mvs_cw32(regs, CMD_APP_ERR_CONFIG, 0xffefbf7d); @@ -2712,16 +2465,17 @@ static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i) { u32 tmp; struct mvs_phy *phy = &mvi->phy[i]; - struct mvs_port *port = phy->port;; + struct mvs_port *port; tmp = mvs_read_phy_ctl(mvi, i); if ((tmp & PHY_READY_MASK) && !(phy->irq_status & PHYEV_POOF)) { - if (!port) + if (!phy->port) phy->phy_attached = 1; return tmp; } + port = phy->port; if (port) { if (phy->phy_type & PORT_TYPE_SAS) { port->wide_port_phymap &= ~(1U << i); @@ -2743,7 +2497,7 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, { struct mvs_phy *phy = &mvi->phy[i]; struct pci_dev *pdev = mvi->pdev; - u32 tmp; + u32 tmp, j; u64 tmp64; mvs_write_port_cfg_addr(mvi, i, PHYR_IDENTIFY); @@ -2770,20 +2524,46 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, sas_phy->linkrate = (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET; - phy->minimum_linkrate = - (phy->phy_status & - PHY_MIN_SPP_PHYS_LINK_RATE_MASK) >> 8; - phy->maximum_linkrate = - (phy->phy_status & - PHY_MAX_SPP_PHYS_LINK_RATE_MASK) >> 12; - if (phy->phy_type & PORT_TYPE_SAS) { - /* Updated attached_sas_addr */ - mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI); - phy->att_dev_sas_addr = + /* Updated attached_sas_addr */ + mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_HI); + phy->att_dev_sas_addr = (u64) mvs_read_port_cfg_data(mvi, i) << 32; - mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO); - phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); + + mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_ADDR_LO); + phy->att_dev_sas_addr |= mvs_read_port_cfg_data(mvi, i); + + dev_printk(KERN_DEBUG, &pdev->dev, + "phy[%d] Get Attached Address 0x%llX ," + " SAS Address 0x%llX\n", + i, phy->att_dev_sas_addr, phy->dev_sas_addr); + dev_printk(KERN_DEBUG, &pdev->dev, + "Rate = %x , type = %d\n", + sas_phy->linkrate, phy->phy_type); + +#if 1 + /* + * If the device is capable of supporting a wide port + * on its phys, it may configure the phys as a wide port. + */ + if (phy->phy_type & PORT_TYPE_SAS) + for (j = 0; j < mvi->chip->n_phy && j != i; ++j) { + if ((mvi->phy[j].phy_attached) && + (mvi->phy[j].phy_type & PORT_TYPE_SAS)) + if (phy->att_dev_sas_addr == + mvi->phy[j].att_dev_sas_addr - 1) { + phy->att_dev_sas_addr = + mvi->phy[j].att_dev_sas_addr; + break; + } + } + +#endif + + tmp64 = cpu_to_be64(phy->att_dev_sas_addr); + memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE); + + if (phy->phy_type & PORT_TYPE_SAS) { mvs_write_port_cfg_addr(mvi, i, PHYR_ATT_DEV_INFO); phy->att_dev_info = mvs_read_port_cfg_data(mvi, i); phy->identify.device_type = @@ -2802,7 +2582,6 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, } else if (phy->phy_type & PORT_TYPE_SATA) { phy->identify.target_port_protocols = SAS_PROTOCOL_STP; if (mvs_is_sig_fis_received(phy->irq_status)) { - phy->att_dev_sas_addr = i; /* temp */ if (phy_st & PHY_OOB_DTCTD) sas_phy->oob_mode = SATA_OOB_MODE; phy->frame_rcvd_size = @@ -2812,34 +2591,20 @@ static void mvs_update_phyinfo(struct mvs_info *mvi, int i, } else { dev_printk(KERN_DEBUG, &pdev->dev, "No sig fis\n"); - phy->phy_type &= ~(PORT_TYPE_SATA); - goto out_done; } } - tmp64 = cpu_to_be64(phy->att_dev_sas_addr); - memcpy(sas_phy->attached_sas_addr, &tmp64, SAS_ADDR_SIZE); - - dev_printk(KERN_DEBUG, &pdev->dev, - "phy[%d] Get Attached Address 0x%llX ," - " SAS Address 0x%llX\n", - i, phy->att_dev_sas_addr, phy->dev_sas_addr); - dev_printk(KERN_DEBUG, &pdev->dev, - "Rate = %x , type = %d\n", - sas_phy->linkrate, phy->phy_type); - /* workaround for HW phy decoding error on 1.5g disk drive */ mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6); tmp = mvs_read_port_vsr_data(mvi, i); if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >> PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET) == SAS_LINK_RATE_1_5_GBPS) - tmp &= ~PHY_MODE6_LATECLK; + tmp &= ~PHY_MODE6_DTL_SPEED; else - tmp |= PHY_MODE6_LATECLK; + tmp |= PHY_MODE6_DTL_SPEED; mvs_write_port_vsr_data(mvi, i, tmp); } -out_done: if (get_st) mvs_write_port_irq_stat(mvi, i, phy->irq_status); } @@ -2864,11 +2629,6 @@ static void mvs_port_formed(struct asd_sas_phy *sas_phy) spin_unlock_irqrestore(&mvi->lock, flags); } -static int mvs_I_T_nexus_reset(struct domain_device *dev) -{ - return TMF_RESP_FUNC_FAILED; -} - static int __devinit mvs_hw_init(struct mvs_info *mvi) { void __iomem *regs = mvi->regs; @@ -3030,12 +2790,13 @@ static int __devinit mvs_hw_init(struct mvs_info *mvi) /* enable CMD/CMPL_Q/RESP mode */ mw32(PCS, PCS_SATA_RETRY | PCS_FIS_RX_EN | PCS_CMD_EN); + /* re-enable interrupts globally */ + mvs_hba_interrupt_enable(mvi); + /* enable completion queue interrupt */ - tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS); + tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM); mw32(INT_MASK, tmp); - /* Enable SRS interrupt */ - mw32(INT_MASK_SRS, 0xFF); return 0; } @@ -3109,8 +2870,6 @@ static int __devinit mvs_pci_init(struct pci_dev *pdev, mvs_print_info(mvi); - mvs_hba_interrupt_enable(mvi); - scsi_scan_host(mvi->shost); return 0; @@ -3156,22 +2915,12 @@ static struct sas_domain_function_template mvs_transport_ops = { .lldd_execute_task = mvs_task_exec, .lldd_control_phy = mvs_phy_control, .lldd_abort_task = mvs_task_abort, - .lldd_port_formed = mvs_port_formed, - .lldd_I_T_nexus_reset = mvs_I_T_nexus_reset, + .lldd_port_formed = mvs_port_formed }; static struct pci_device_id __devinitdata mvs_pci_table[] = { { PCI_VDEVICE(MARVELL, 0x6320), chip_6320 }, { PCI_VDEVICE(MARVELL, 0x6340), chip_6440 }, - { - .vendor = PCI_VENDOR_ID_MARVELL, - .device = 0x6440, - .subvendor = PCI_ANY_ID, - .subdevice = 0x6480, - .class = 0, - .class_mask = 0, - .driver_data = chip_6480, - }, { PCI_VDEVICE(MARVELL, 0x6440), chip_6440 }, { PCI_VDEVICE(MARVELL, 0x6480), chip_6480 }, diff --git a/trunk/drivers/scsi/scsi_sysfs.c b/trunk/drivers/scsi/scsi_sysfs.c index ed83cdb6e67d..b9b09a704584 100644 --- a/trunk/drivers/scsi/scsi_sysfs.c +++ b/trunk/drivers/scsi/scsi_sysfs.c @@ -294,6 +294,7 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) } if (sdev->request_queue) { + bsg_unregister_queue(sdev->request_queue); sdev->request_queue->queuedata = NULL; /* user context needed to free queue */ scsi_free_queue(sdev->request_queue); @@ -857,7 +858,6 @@ void __scsi_remove_device(struct scsi_device *sdev) if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) return; - bsg_unregister_queue(sdev->request_queue); class_device_unregister(&sdev->sdev_classdev); transport_remove_device(dev); device_del(dev); diff --git a/trunk/fs/afs/cell.c b/trunk/fs/afs/cell.c index 584bb0f9c36a..788865df1bc9 100644 --- a/trunk/fs/afs/cell.c +++ b/trunk/fs/afs/cell.c @@ -138,7 +138,6 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist) cell = afs_cell_alloc(name, vllist); if (IS_ERR(cell)) { _leave(" = %ld", PTR_ERR(cell)); - up_write(&afs_cells_sem); return cell; } diff --git a/trunk/include/linux/iocontext.h b/trunk/include/linux/iocontext.h index cac4b364cd40..1b4ccf25b4d2 100644 --- a/trunk/include/linux/iocontext.h +++ b/trunk/include/linux/iocontext.h @@ -2,7 +2,6 @@ #define IOCONTEXT_H #include -#include /* * This is the per-process anticipatory I/O scheduler state. @@ -55,8 +54,6 @@ struct cfq_io_context { void (*dtor)(struct io_context *); /* destructor */ void (*exit)(struct io_context *); /* called on task exit */ - - struct rcu_head rcu_head; }; /* diff --git a/trunk/include/linux/netdevice.h b/trunk/include/linux/netdevice.h index ee81906b5164..a2f003239c85 100644 --- a/trunk/include/linux/netdevice.h +++ b/trunk/include/linux/netdevice.h @@ -383,11 +383,9 @@ static inline void __napi_complete(struct napi_struct *n) static inline void napi_complete(struct napi_struct *n) { - unsigned long flags; - - local_irq_save(flags); + local_irq_disable(); __napi_complete(n); - local_irq_restore(flags); + local_irq_enable(); } /** @@ -1074,14 +1072,12 @@ static inline int netif_is_multiqueue(const struct net_device *dev) } /* Use this variant when it is known for sure that it - * is executing from hardware interrupt context or with hardware interrupts - * disabled. + * is executing from interrupt context. */ extern void dev_kfree_skb_irq(struct sk_buff *skb); /* Use this variant in places where it could be invoked - * from either hardware interrupt or other context, with hardware interrupts - * either disabled or enabled. + * either from interrupt or non-interrupt context. */ extern void dev_kfree_skb_any(struct sk_buff *skb); diff --git a/trunk/include/net/llc.h b/trunk/include/net/llc.h index 7940da1606e7..f5024583fc8b 100644 --- a/trunk/include/net/llc.h +++ b/trunk/include/net/llc.h @@ -65,6 +65,7 @@ struct llc_sap { extern struct list_head llc_sap_list; extern rwlock_t llc_sap_list_lock; +extern unsigned char llc_station_mac_sa[ETH_ALEN]; extern int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); diff --git a/trunk/include/net/llc_pdu.h b/trunk/include/net/llc_pdu.h index 75b8e2968c9b..4a8f58b17e43 100644 --- a/trunk/include/net/llc_pdu.h +++ b/trunk/include/net/llc_pdu.h @@ -381,7 +381,7 @@ static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb, xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */ xid_info->type = svcs_supported; xid_info->rw = rx_window << 1; /* size of receive window */ - skb_put(skb, sizeof(struct llc_xid_info)); + skb_put(skb, 3); } /** @@ -406,7 +406,7 @@ static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb, xid_info->fmt_id = LLC_XID_FMT_ID; xid_info->type = svcs_supported; xid_info->rw = rx_window << 1; - skb_put(skb, sizeof(struct llc_xid_info)); + skb_put(skb, 3); } /* LLC Type 2 FRMR response information field format */ diff --git a/trunk/include/net/llc_sap.h b/trunk/include/net/llc_sap.h index ed25bec2f648..2c56dbece729 100644 --- a/trunk/include/net/llc_sap.h +++ b/trunk/include/net/llc_sap.h @@ -1,8 +1,5 @@ #ifndef LLC_SAP_H #define LLC_SAP_H - -#include - /* * Copyright (c) 1997 by Procom Technology,Inc. * 2001-2003 by Arnaldo Carvalho de Melo @@ -22,8 +19,8 @@ struct sock; extern void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb); extern void llc_save_primitive(struct sock *sk, struct sk_buff* skb, unsigned char prim); -extern struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, - u8 type, u32 data_size); +extern struct sk_buff *llc_alloc_frame(struct sock *sk, + struct net_device *dev); extern void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb, diff --git a/trunk/net/8021q/vlan.c b/trunk/net/8021q/vlan.c index b33410abfd6b..dbc81b965096 100644 --- a/trunk/net/8021q/vlan.c +++ b/trunk/net/8021q/vlan.c @@ -374,35 +374,17 @@ static void vlan_sync_address(struct net_device *dev, memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); } -static void __vlan_device_event(struct net_device *dev, unsigned long event) -{ - switch (event) { - case NETDEV_CHANGENAME: - vlan_proc_rem_dev(dev); - if (vlan_proc_add_dev(dev) < 0) - pr_warning("8021q: failed to change proc name for %s\n", - dev->name); - break; - } -} - static int vlan_device_event(struct notifier_block *unused, unsigned long event, void *ptr) { struct net_device *dev = ptr; - struct vlan_group *grp; + struct vlan_group *grp = __vlan_find_group(dev->ifindex); int i, flgs; struct net_device *vlandev; if (dev->nd_net != &init_net) return NOTIFY_DONE; - if (is_vlan_dev(dev)) { - __vlan_device_event(dev, event); - goto out; - } - - grp = __vlan_find_group(dev->ifindex); if (!grp) goto out; diff --git a/trunk/net/8021q/vlan.h b/trunk/net/8021q/vlan.h index 51271aea402b..73efcc715ccb 100644 --- a/trunk/net/8021q/vlan.h +++ b/trunk/net/8021q/vlan.h @@ -45,9 +45,4 @@ void vlan_netlink_fini(void); extern struct rtnl_link_ops vlan_link_ops; -static inline int is_vlan_dev(struct net_device *dev) -{ - return dev->priv_flags & IFF_802_1Q_VLAN; -} - #endif /* !(__BEN_VLAN_802_1Q_INC__) */ diff --git a/trunk/net/8021q/vlanproc.c b/trunk/net/8021q/vlanproc.c index 9671aa51af2c..146cfb0e9882 100644 --- a/trunk/net/8021q/vlanproc.c +++ b/trunk/net/8021q/vlanproc.c @@ -210,6 +210,11 @@ int vlan_proc_rem_dev(struct net_device *vlandev) * The following few functions build the content of /proc/net/vlan/config */ +static inline int is_vlan_dev(struct net_device *dev) +{ + return dev->priv_flags & IFF_802_1Q_VLAN; +} + /* start read of /proc/net/vlan/config */ static void *vlan_seq_start(struct seq_file *seq, loff_t *pos) __acquires(dev_base_lock) diff --git a/trunk/net/bluetooth/af_bluetooth.c b/trunk/net/bluetooth/af_bluetooth.c index d366423c8392..1220d8a41eb5 100644 --- a/trunk/net/bluetooth/af_bluetooth.c +++ b/trunk/net/bluetooth/af_bluetooth.c @@ -53,30 +53,6 @@ /* Bluetooth sockets */ #define BT_MAX_PROTO 8 static struct net_proto_family *bt_proto[BT_MAX_PROTO]; - -static struct lock_class_key bt_slock_key[BT_MAX_PROTO]; -static struct lock_class_key bt_lock_key[BT_MAX_PROTO]; -static const char *bt_key_strings[BT_MAX_PROTO] = { - "sk_lock-AF_BLUETOOTH-BTPROTO_L2CAP", - "sk_lock-AF_BLUETOOTH-BTPROTO_HCI", - "sk_lock-AF_BLUETOOTH-BTPROTO_SCO", - "sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM", - "sk_lock-AF_BLUETOOTH-BTPROTO_BNEP", - "sk_lock-AF_BLUETOOTH-BTPROTO_CMTP", - "sk_lock-AF_BLUETOOTH-BTPROTO_HIDP", - "sk_lock-AF_BLUETOOTH-BTPROTO_AVDTP", -}; - -static const char *bt_slock_key_strings[BT_MAX_PROTO] = { - "slock-AF_BLUETOOTH-BTPROTO_L2CAP", - "slock-AF_BLUETOOTH-BTPROTO_HCI", - "slock-AF_BLUETOOTH-BTPROTO_SCO", - "slock-AF_BLUETOOTH-BTPROTO_RFCOMM", - "slock-AF_BLUETOOTH-BTPROTO_BNEP", - "slock-AF_BLUETOOTH-BTPROTO_CMTP", - "slock-AF_BLUETOOTH-BTPROTO_HIDP", - "slock-AF_BLUETOOTH-BTPROTO_AVDTP", -}; static DEFINE_RWLOCK(bt_proto_lock); int bt_sock_register(int proto, struct net_proto_family *ops) @@ -119,21 +95,6 @@ int bt_sock_unregister(int proto) } EXPORT_SYMBOL(bt_sock_unregister); -static void bt_reclassify_sock_lock(struct socket *sock, int proto) -{ - struct sock *sk = sock->sk; - - if (!sk) - return; - BUG_ON(sock_owned_by_user(sk)); - - sock_lock_init_class_and_name(sk, - bt_slock_key_strings[proto], - &bt_slock_key[proto], - bt_key_strings[proto], - &bt_lock_key[proto]); -} - static int bt_sock_create(struct net *net, struct socket *sock, int proto) { int err; @@ -156,7 +117,6 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto) if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) { err = bt_proto[proto]->create(net, sock, proto); - bt_reclassify_sock_lock(sock, proto); module_put(bt_proto[proto]->owner); } diff --git a/trunk/net/bluetooth/hci_sock.c b/trunk/net/bluetooth/hci_sock.c index 1d36c093523b..b5d4019d3572 100644 --- a/trunk/net/bluetooth/hci_sock.c +++ b/trunk/net/bluetooth/hci_sock.c @@ -84,7 +84,7 @@ static struct hci_sec_filter hci_sec_filter = { }; static struct bt_sock_list hci_sk_list = { - .lock = __RW_LOCK_UNLOCKED(hci_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; /* Send frame to RAW socket */ diff --git a/trunk/net/bluetooth/l2cap.c b/trunk/net/bluetooth/l2cap.c index 2957df4b6c0b..34f8bf98bc05 100644 --- a/trunk/net/bluetooth/l2cap.c +++ b/trunk/net/bluetooth/l2cap.c @@ -62,7 +62,7 @@ static u32 l2cap_feat_mask = 0x0000; static const struct proto_ops l2cap_sock_ops; static struct bt_sock_list l2cap_sk_list = { - .lock = __RW_LOCK_UNLOCKED(l2cap_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void __l2cap_sock_close(struct sock *sk, int reason); diff --git a/trunk/net/bluetooth/rfcomm/core.c b/trunk/net/bluetooth/rfcomm/core.c index eb62558e9b09..0c2c93735e93 100644 --- a/trunk/net/bluetooth/rfcomm/core.c +++ b/trunk/net/bluetooth/rfcomm/core.c @@ -423,8 +423,8 @@ static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err) rfcomm_dlc_lock(d); d->state = BT_CLOSED; - rfcomm_dlc_unlock(d); d->state_change(d, err); + rfcomm_dlc_unlock(d); skb_queue_purge(&d->tx_queue); rfcomm_dlc_unlink(d); diff --git a/trunk/net/bluetooth/rfcomm/sock.c b/trunk/net/bluetooth/rfcomm/sock.c index af4e3934ee84..c46d51035e77 100644 --- a/trunk/net/bluetooth/rfcomm/sock.c +++ b/trunk/net/bluetooth/rfcomm/sock.c @@ -60,7 +60,7 @@ static const struct proto_ops rfcomm_sock_ops; static struct bt_sock_list rfcomm_sk_list = { - .lock = __RW_LOCK_UNLOCKED(rfcomm_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void rfcomm_sock_close(struct sock *sk); diff --git a/trunk/net/bluetooth/rfcomm/tty.c b/trunk/net/bluetooth/rfcomm/tty.c index c3f749abb2d0..e4c779bb8d76 100644 --- a/trunk/net/bluetooth/rfcomm/tty.c +++ b/trunk/net/bluetooth/rfcomm/tty.c @@ -570,7 +570,12 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) return; rfcomm_dev_del(dev); + /* We have to drop DLC lock here, otherwise + rfcomm_dev_put() will dead lock if it's + the last reference. */ + rfcomm_dlc_unlock(dlc); rfcomm_dev_put(dev); + rfcomm_dlc_lock(dlc); } } else tty_hangup(dev->tty); diff --git a/trunk/net/bluetooth/sco.c b/trunk/net/bluetooth/sco.c index cd887cdca426..b91d3c81a73c 100644 --- a/trunk/net/bluetooth/sco.c +++ b/trunk/net/bluetooth/sco.c @@ -58,7 +58,7 @@ static const struct proto_ops sco_sock_ops; static struct bt_sock_list sco_sk_list = { - .lock = __RW_LOCK_UNLOCKED(sco_sk_list.lock) + .lock = RW_LOCK_UNLOCKED }; static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent); diff --git a/trunk/net/ipv4/esp4.c b/trunk/net/ipv4/esp4.c index 4e73e5708e70..f3ceca31aa45 100644 --- a/trunk/net/ipv4/esp4.c +++ b/trunk/net/ipv4/esp4.c @@ -336,7 +336,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) struct scatterlist *asg; int err = -EINVAL; - if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) + if (!pskb_may_pull(skb, sizeof(*esph))) goto out; if (elen <= 0) diff --git a/trunk/net/ipv4/inet_fragment.c b/trunk/net/ipv4/inet_fragment.c index a0a3c78cb5e0..724d69aed031 100644 --- a/trunk/net/ipv4/inet_fragment.c +++ b/trunk/net/ipv4/inet_fragment.c @@ -86,10 +86,7 @@ EXPORT_SYMBOL(inet_frags_fini); void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f) { nf->low_thresh = 0; - - local_bh_disable(); inet_frag_evictor(nf, f); - local_bh_enable(); } EXPORT_SYMBOL(inet_frags_exit_net); diff --git a/trunk/net/ipv4/ip_forward.c b/trunk/net/ipv4/ip_forward.c index a4506c8cfef0..0b3b328d82db 100644 --- a/trunk/net/ipv4/ip_forward.c +++ b/trunk/net/ipv4/ip_forward.c @@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb) if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway) goto sr_failed; - if (unlikely(skb->len > dst_mtu(&rt->u.dst) && !skb_is_gso(skb) && + if (unlikely(skb->len > dst_mtu(&rt->u.dst) && (ip_hdr(skb)->frag_off & htons(IP_DF))) && !skb->local_df) { IP_INC_STATS(IPSTATS_MIB_FRAGFAILS); icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, diff --git a/trunk/net/ipv4/netfilter/ip_queue.c b/trunk/net/ipv4/netfilter/ip_queue.c index 4dc162894cb2..fe05da41d6ba 100644 --- a/trunk/net/ipv4/netfilter/ip_queue.c +++ b/trunk/net/ipv4/netfilter/ip_queue.c @@ -588,9 +588,11 @@ static int __init ip_queue_init(void) } #ifdef CONFIG_PROC_FS - proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net, - &ip_queue_proc_fops); - if (!proc) { + proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net); + if (proc) { + proc->owner = THIS_MODULE; + proc->proc_fops = &ip_queue_proc_fops; + } else { printk(KERN_ERR "ip_queue: failed to create proc entry\n"); goto cleanup_ipqnl; } diff --git a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c index 52926c8e3cc1..c6cf84c77611 100644 --- a/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/trunk/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -167,13 +167,14 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip, /* create proc dir entry */ sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip)); - c->pde = proc_create(buffer, S_IWUSR|S_IRUSR, - clusterip_procdir, &clusterip_proc_fops); + c->pde = create_proc_entry(buffer, S_IWUSR|S_IRUSR, + clusterip_procdir); if (!c->pde) { kfree(c); return NULL; } } + c->pde->proc_fops = &clusterip_proc_fops; c->pde->data = c; #endif diff --git a/trunk/net/ipv4/netfilter/ipt_recent.c b/trunk/net/ipv4/netfilter/ipt_recent.c index 50e06690eb5b..8e8f0425a8ed 100644 --- a/trunk/net/ipv4/netfilter/ipt_recent.c +++ b/trunk/net/ipv4/netfilter/ipt_recent.c @@ -276,11 +276,12 @@ recent_mt_check(const char *tablename, const void *ip, for (i = 0; i < ip_list_hash_size; i++) INIT_LIST_HEAD(&t->iphash[i]); #ifdef CONFIG_PROC_FS - t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops); + t->proc = create_proc_entry(t->name, ip_list_perms, proc_dir); if (t->proc == NULL) { kfree(t); goto out; } + t->proc->proc_fops = &recent_fops; t->proc->uid = ip_list_uid; t->proc->gid = ip_list_gid; t->proc->data = t; diff --git a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c index f500b0fdaef4..089252e82c01 100644 --- a/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/trunk/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c @@ -395,10 +395,13 @@ int __init nf_conntrack_ipv4_compat_init(void) if (!proc_exp) goto err2; - proc_stat = proc_create("ip_conntrack", S_IRUGO, - init_net.proc_net_stat, &ct_cpu_seq_fops); + proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, init_net.proc_net_stat); if (!proc_stat) goto err3; + + proc_stat->proc_fops = &ct_cpu_seq_fops; + proc_stat->owner = THIS_MODULE; + return 0; err3: diff --git a/trunk/net/ipv4/udp.c b/trunk/net/ipv4/udp.c index 1704c1474ea1..7ea1b67b6de1 100644 --- a/trunk/net/ipv4/udp.c +++ b/trunk/net/ipv4/udp.c @@ -1556,14 +1556,14 @@ static void *udp_seq_start(struct seq_file *seq, loff_t *pos) __acquires(udp_hash_lock) { read_lock(&udp_hash_lock); - return *pos ? udp_get_idx(seq, *pos-1) : SEQ_START_TOKEN; + return *pos ? udp_get_idx(seq, *pos-1) : (void *)1; } static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) { struct sock *sk; - if (v == SEQ_START_TOKEN) + if (v == (void *)1) sk = udp_get_idx(seq, 0); else sk = udp_get_next(seq, v); diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index e7a1882db048..101e0e70ba27 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -776,7 +776,6 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i struct inet6_dev *idev = ifp->idev; struct in6_addr addr, *tmpaddr; unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; - unsigned long regen_advance; int tmp_plen; int ret = 0; int max_addresses; @@ -837,23 +836,8 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i tmp_tstamp = ifp->tstamp; spin_unlock_bh(&ifp->lock); - regen_advance = idev->cnf.regen_max_retry * - idev->cnf.dad_transmits * - idev->nd_parms->retrans_time / HZ; write_unlock(&idev->lock); - /* A temporary address is created only if this calculated Preferred - * Lifetime is greater than REGEN_ADVANCE time units. In particular, - * an implementation must not create a temporary address with a zero - * Preferred Lifetime. - */ - if (tmp_prefered_lft <= regen_advance) { - in6_ifa_put(ifp); - in6_dev_put(idev); - ret = -1; - goto out; - } - addr_flags = IFA_F_TEMPORARY; /* set in addrconf_prefix_rcv() */ if (ifp->flags & IFA_F_OPTIMISTIC) @@ -1847,9 +1831,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) * lifetimes of an existing temporary address * when processing a Prefix Information Option. */ - if (ifp != ift->ifpub) - continue; - spin_lock(&ift->lock); flags = ift->flags; if (ift->valid_lft > valid_lft && diff --git a/trunk/net/ipv6/esp6.c b/trunk/net/ipv6/esp6.c index c6bb4c6d24b3..0ec1402320ea 100644 --- a/trunk/net/ipv6/esp6.c +++ b/trunk/net/ipv6/esp6.c @@ -282,7 +282,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) struct scatterlist *sg; struct scatterlist *asg; - if (!pskb_may_pull(skb, sizeof(*esph) + crypto_aead_ivsize(aead))) { + if (!pskb_may_pull(skb, sizeof(*esph))) { ret = -EINVAL; goto out; } diff --git a/trunk/net/ipv6/icmp.c b/trunk/net/ipv6/icmp.c index f204a7275a0d..121d517bf91c 100644 --- a/trunk/net/ipv6/icmp.c +++ b/trunk/net/ipv6/icmp.c @@ -436,10 +436,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info, } if (xfrm_decode_session_reverse(skb, &fl2, AF_INET6)) - goto out_dst_release; + goto out; if (ip6_dst_lookup(sk, &dst2, &fl)) - goto out_dst_release; + goto out; err = xfrm_lookup(&dst2, &fl, sk, XFRM_LOOKUP_ICMP); if (err == -ENOENT) { diff --git a/trunk/net/ipv6/ip6_input.c b/trunk/net/ipv6/ip6_input.c index 98ab4f459905..178aebc0427a 100644 --- a/trunk/net/ipv6/ip6_input.c +++ b/trunk/net/ipv6/ip6_input.c @@ -239,7 +239,8 @@ int ip6_mc_input(struct sk_buff *skb) IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); hdr = ipv6_hdr(skb); - deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); + deliver = unlikely(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI)) || + ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); /* * IPv6 multicast router mode isnt currently supported. diff --git a/trunk/net/ipv6/netfilter/ip6_queue.c b/trunk/net/ipv6/netfilter/ip6_queue.c index 8d366f7f2a9a..cc2f9afcf808 100644 --- a/trunk/net/ipv6/netfilter/ip6_queue.c +++ b/trunk/net/ipv6/netfilter/ip6_queue.c @@ -591,9 +591,11 @@ static int __init ip6_queue_init(void) } #ifdef CONFIG_PROC_FS - proc = proc_create(IPQ_PROC_FS_NAME, 0, init_net.proc_net, - &ip6_queue_proc_fops); - if (!proc) { + proc = create_proc_entry(IPQ_PROC_FS_NAME, 0, init_net.proc_net); + if (proc) { + proc->owner = THIS_MODULE; + proc->proc_fops = &ip6_queue_proc_fops; + } else { printk(KERN_ERR "ip6_queue: failed to create proc entry\n"); goto cleanup_ipqnl; } diff --git a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c index 24c0d03095bf..2a0d698b24d5 100644 --- a/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/trunk/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -171,9 +171,7 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq) static void nf_ct_frag6_evictor(void) { - local_bh_disable(); inet_frag_evictor(&nf_init_frags, &nf_frags); - local_bh_enable(); } static void nf_ct_frag6_expire(unsigned long data) diff --git a/trunk/net/llc/af_llc.c b/trunk/net/llc/af_llc.c index 8c50eb430c19..46cf962f7f88 100644 --- a/trunk/net/llc/af_llc.c +++ b/trunk/net/llc/af_llc.c @@ -155,9 +155,6 @@ static int llc_ui_create(struct net *net, struct socket *sock, int protocol) struct sock *sk; int rc = -ESOCKTNOSUPPORT; - if (!capable(CAP_NET_RAW)) - return -EPERM; - if (net != &init_net) return -EAFNOSUPPORT; diff --git a/trunk/net/llc/llc_c_ac.c b/trunk/net/llc/llc_c_ac.c index 71a00225bdb3..860140caa6e0 100644 --- a/trunk/net/llc/llc_c_ac.c +++ b/trunk/net/llc/llc_c_ac.c @@ -198,7 +198,7 @@ int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -223,7 +223,7 @@ int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -249,7 +249,7 @@ int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -282,8 +282,7 @@ int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb) llc_pdu_decode_pf_bit(skb, &f_bit); else f_bit = 0; - nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_frmr_info)); + nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -307,8 +306,7 @@ int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_frmr_info)); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -338,8 +336,7 @@ int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) struct llc_sock *llc = llc_sk(sk); llc_pdu_decode_pf_bit(skb, &f_bit); - nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_frmr_info)); + nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); @@ -427,7 +424,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk, struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb); int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -462,7 +459,7 @@ int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -486,7 +483,7 @@ int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -510,7 +507,7 @@ int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -534,7 +531,7 @@ int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -558,7 +555,7 @@ int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -582,7 +579,7 @@ int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -618,7 +615,7 @@ int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -642,7 +639,7 @@ int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -666,7 +663,7 @@ int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -691,7 +688,7 @@ int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -715,7 +712,7 @@ int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -739,7 +736,7 @@ int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -773,7 +770,7 @@ int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb) { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; @@ -802,7 +799,7 @@ int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb) u8 f_bit; int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_U, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); llc_pdu_decode_pf_bit(skb, &f_bit); if (nskb) { @@ -959,7 +956,7 @@ static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk, { int rc = -ENOBUFS; struct llc_sock *llc = llc_sk(sk); - struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev, LLC_PDU_TYPE_S, 0); + struct sk_buff *nskb = llc_alloc_frame(sk, llc->dev); if (nskb) { struct llc_sap *sap = llc->sap; diff --git a/trunk/net/llc/llc_core.c b/trunk/net/llc/llc_core.c index 50d5b10e23a2..248b5903bb13 100644 --- a/trunk/net/llc/llc_core.c +++ b/trunk/net/llc/llc_core.c @@ -25,6 +25,8 @@ LIST_HEAD(llc_sap_list); DEFINE_RWLOCK(llc_sap_list_lock); +unsigned char llc_station_mac_sa[ETH_ALEN]; + /** * llc_sap_alloc - allocates and initializes sap. * @@ -35,8 +37,8 @@ static struct llc_sap *llc_sap_alloc(void) struct llc_sap *sap = kzalloc(sizeof(*sap), GFP_ATOMIC); if (sap) { - /* sap->laddr.mac - leave as a null, it's filled by bind */ sap->state = LLC_SAP_STATE_ACTIVE; + memcpy(sap->laddr.mac, llc_station_mac_sa, ETH_ALEN); rwlock_init(&sap->sk_list.lock); atomic_set(&sap->refcnt, 1); } @@ -165,6 +167,10 @@ static int __init llc_init(void) if (dev != NULL) dev = next_net_device(dev); + if (dev != NULL) + memcpy(llc_station_mac_sa, dev->dev_addr, ETH_ALEN); + else + memset(llc_station_mac_sa, 0, ETH_ALEN); dev_add_pack(&llc_packet_type); dev_add_pack(&llc_tr_packet_type); return 0; @@ -179,6 +185,7 @@ static void __exit llc_exit(void) module_init(llc_init); module_exit(llc_exit); +EXPORT_SYMBOL(llc_station_mac_sa); EXPORT_SYMBOL(llc_sap_list); EXPORT_SYMBOL(llc_sap_list_lock); EXPORT_SYMBOL(llc_sap_find); diff --git a/trunk/net/llc/llc_input.c b/trunk/net/llc/llc_input.c index bfd2567dd365..c40c9b2a345a 100644 --- a/trunk/net/llc/llc_input.c +++ b/trunk/net/llc/llc_input.c @@ -117,12 +117,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb) skb_pull(skb, llc_len); if (skb->protocol == htons(ETH_P_802_2)) { __be16 pdulen = eth_hdr(skb)->h_proto; - s32 data_size = ntohs(pdulen) - llc_len; + u16 data_size = ntohs(pdulen) - llc_len; - if (data_size < 0 || - ((skb_tail_pointer(skb) - - (u8 *)pdu) - llc_len) < data_size) - return 0; if (unlikely(pskb_trim_rcsum(skb, data_size))) return 0; } diff --git a/trunk/net/llc/llc_pdu.c b/trunk/net/llc/llc_pdu.c index 2e6cb79196bb..fa8324396db3 100644 --- a/trunk/net/llc/llc_pdu.c +++ b/trunk/net/llc/llc_pdu.c @@ -241,7 +241,7 @@ void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu, FRMR_INFO_SET_PDU_INFO_2LONG_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INVALID_Nr_IND(frmr_info, vzyxw); FRMR_INFO_SET_PDU_INVALID_Ns_IND(frmr_info, vzyxw); - skb_put(skb, sizeof(struct llc_frmr_info)); + skb_put(skb, 5); } /** diff --git a/trunk/net/llc/llc_s_ac.c b/trunk/net/llc/llc_s_ac.c index a94bd56bcac6..ac3d93b210d2 100644 --- a/trunk/net/llc/llc_s_ac.c +++ b/trunk/net/llc/llc_s_ac.c @@ -103,8 +103,7 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb) llc_pdu_decode_sa(skb, mac_da); llc_pdu_decode_da(skb, mac_sa); llc_pdu_decode_ssap(skb, &dsap); - nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_xid_info)); + nskb = llc_alloc_frame(NULL, skb->dev); if (!nskb) goto out; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, @@ -145,15 +144,11 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb) u8 mac_da[ETH_ALEN], mac_sa[ETH_ALEN], dsap; struct sk_buff *nskb; int rc = 1; - u32 data_size; llc_pdu_decode_sa(skb, mac_da); llc_pdu_decode_da(skb, mac_sa); llc_pdu_decode_ssap(skb, &dsap); - - /* The test request command is type U (llc_len = 3) */ - data_size = ntohs(eth_hdr(skb)->h_proto) - 3; - nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); + nskb = llc_alloc_frame(NULL, skb->dev); if (!nskb) goto out; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap, dsap, diff --git a/trunk/net/llc/llc_sap.c b/trunk/net/llc/llc_sap.c index e2ddde755019..2525165e2e8f 100644 --- a/trunk/net/llc/llc_sap.c +++ b/trunk/net/llc/llc_sap.c @@ -24,41 +24,20 @@ #include #include -static int llc_mac_header_len(unsigned short devtype) -{ - switch (devtype) { - case ARPHRD_ETHER: - case ARPHRD_LOOPBACK: - return sizeof(struct ethhdr); -#ifdef CONFIG_TR - case ARPHRD_IEEE802_TR: - return sizeof(struct trh_hdr); -#endif - } - return 0; -} - /** * llc_alloc_frame - allocates sk_buff for frame * @dev: network device this skb will be sent over - * @type: pdu type to allocate - * @data_size: data size to allocate * * Allocates an sk_buff for frame and initializes sk_buff fields. * Returns allocated skb or %NULL when out of memory. */ -struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev, - u8 type, u32 data_size) +struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev) { - int hlen = type == LLC_PDU_TYPE_U ? 3 : 4; - struct sk_buff *skb; - - hlen += llc_mac_header_len(dev->type); - skb = alloc_skb(hlen + data_size, GFP_ATOMIC); + struct sk_buff *skb = alloc_skb(128, GFP_ATOMIC); if (skb) { skb_reset_mac_header(skb); - skb_reserve(skb, hlen); + skb_reserve(skb, 50); skb_reset_network_header(skb); skb_reset_transport_header(skb); skb->protocol = htons(ETH_P_802_2); diff --git a/trunk/net/llc/llc_station.c b/trunk/net/llc/llc_station.c index 83da13339490..6f2ea2090322 100644 --- a/trunk/net/llc/llc_station.c +++ b/trunk/net/llc/llc_station.c @@ -253,14 +253,13 @@ static int llc_station_ac_inc_xid_r_cnt_by_1(struct sk_buff *skb) static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) { int rc = 1; - struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_xid_info)); + struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); if (!nskb) goto out; llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, 0, LLC_PDU_CMD); llc_pdu_init_as_xid_cmd(nskb, LLC_XID_NULL_CLASS_2, 127); - rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, skb->dev->dev_addr); + rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, llc_station_mac_sa); if (unlikely(rc)) goto free; llc_station_send_pdu(nskb); @@ -275,8 +274,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) { u8 mac_da[ETH_ALEN], dsap; int rc = 1; - struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, - sizeof(struct llc_xid_info)); + struct sk_buff* nskb = llc_alloc_frame(NULL, skb->dev); if (!nskb) goto out; @@ -285,7 +283,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) llc_pdu_decode_ssap(skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127); - rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da); + rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); if (unlikely(rc)) goto free; llc_station_send_pdu(nskb); @@ -300,12 +298,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) { u8 mac_da[ETH_ALEN], dsap; int rc = 1; - u32 data_size; - struct sk_buff *nskb; - - /* The test request command is type U (llc_len = 3) */ - data_size = ntohs(eth_hdr(skb)->h_proto) - 3; - nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size); + struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev); if (!nskb) goto out; @@ -314,7 +307,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) llc_pdu_decode_ssap(skb, &dsap); llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP); llc_pdu_init_as_test_rsp(nskb, skb); - rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da); + rc = llc_mac_hdr_init(nskb, llc_station_mac_sa, mac_da); if (unlikely(rc)) goto free; llc_station_send_pdu(nskb); diff --git a/trunk/net/mac80211/ieee80211.c b/trunk/net/mac80211/ieee80211.c index 8e586390a2ef..28bcdf9fc3df 100644 --- a/trunk/net/mac80211/ieee80211.c +++ b/trunk/net/mac80211/ieee80211.c @@ -286,18 +286,6 @@ static int ieee80211_open(struct net_device *dev) if (need_hw_reconfig) ieee80211_hw_config(local); - /* - * ieee80211_sta_work is disabled while network interface - * is down. Therefore, some configuration changes may not - * yet be effective. Trigger execution of ieee80211_sta_work - * to fix this. - */ - if(sdata->vif.type == IEEE80211_IF_TYPE_STA || - sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - queue_work(local->hw.workqueue, &ifsta->work); - } - netif_start_queue(dev); return 0; diff --git a/trunk/net/mac80211/ieee80211_sta.c b/trunk/net/mac80211/ieee80211_sta.c index e0c72d04584b..9aeed5320228 100644 --- a/trunk/net/mac80211/ieee80211_sta.c +++ b/trunk/net/mac80211/ieee80211_sta.c @@ -319,7 +319,7 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; struct ieee80211_if_sta *ifsta = &sdata->u.sta; bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; - bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; + bool preamble_mode = (erp_value & WLAN_ERP_BARKER_PREAMBLE) != 0; DECLARE_MAC_BUF(mac); u32 changed = 0; @@ -335,15 +335,16 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, changed |= BSS_CHANGED_ERP_CTS_PROT; } - if (use_short_preamble != bss_conf->use_short_preamble) { + if (preamble_mode != bss_conf->use_short_preamble) { if (net_ratelimit()) { printk(KERN_DEBUG "%s: switched to %s barker preamble" " (BSSID=%s)\n", sdata->dev->name, - use_short_preamble ? "short" : "long", + (preamble_mode == WLAN_ERP_PREAMBLE_SHORT) ? + "short" : "long", print_mac(mac, ifsta->bssid)); } - bss_conf->use_short_preamble = use_short_preamble; + bss_conf->use_short_preamble = preamble_mode; changed |= BSS_CHANGED_ERP_PREAMBLE; } diff --git a/trunk/net/netfilter/nf_conntrack_standalone.c b/trunk/net/netfilter/nf_conntrack_standalone.c index 8599068050ec..e88e96af613d 100644 --- a/trunk/net/netfilter/nf_conntrack_standalone.c +++ b/trunk/net/netfilter/nf_conntrack_standalone.c @@ -395,7 +395,7 @@ EXPORT_SYMBOL_GPL(nf_ct_log_invalid); static int __init nf_conntrack_standalone_init(void) { #ifdef CONFIG_PROC_FS - struct proc_dir_entry *proc; + struct proc_dir_entry *proc, *proc_stat; #endif int ret = 0; @@ -407,9 +407,12 @@ static int __init nf_conntrack_standalone_init(void) proc = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); if (!proc) goto cleanup_init; - if (!proc_create("nf_conntrack", S_IRUGO, - init_net.proc_net_stat, &ct_cpu_seq_fops)) + proc_stat = create_proc_entry("nf_conntrack", S_IRUGO, init_net.proc_net_stat); + if (!proc_stat) goto cleanup_proc; + + proc_stat->proc_fops = &ct_cpu_seq_fops; + proc_stat->owner = THIS_MODULE; #endif #ifdef CONFIG_SYSCTL nf_ct_sysctl_header = register_sysctl_paths(nf_ct_path, diff --git a/trunk/net/netfilter/nf_log.c b/trunk/net/netfilter/nf_log.c index bc11d7092032..cec9976aecbf 100644 --- a/trunk/net/netfilter/nf_log.c +++ b/trunk/net/netfilter/nf_log.c @@ -168,9 +168,13 @@ static const struct file_operations nflog_file_ops = { int __init netfilter_log_init(void) { #ifdef CONFIG_PROC_FS - if (!proc_create("nf_log", S_IRUGO, - proc_net_netfilter, &nflog_file_ops)) + struct proc_dir_entry *pde; + + pde = create_proc_entry("nf_log", S_IRUGO, proc_net_netfilter); + if (!pde) return -1; + + pde->proc_fops = &nflog_file_ops; #endif return 0; } diff --git a/trunk/net/netfilter/nf_queue.c b/trunk/net/netfilter/nf_queue.c index bbd26893c0c4..ddc80ea114cd 100644 --- a/trunk/net/netfilter/nf_queue.c +++ b/trunk/net/netfilter/nf_queue.c @@ -348,9 +348,12 @@ static const struct file_operations nfqueue_file_ops = { int __init netfilter_queue_init(void) { #ifdef CONFIG_PROC_FS - if (!proc_create("nf_queue", S_IRUGO, - proc_net_netfilter, &nfqueue_file_ops)) + struct proc_dir_entry *pde; + + pde = create_proc_entry("nf_queue", S_IRUGO, proc_net_netfilter); + if (!pde) return -1; + pde->proc_fops = &nfqueue_file_ops; #endif return 0; } diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index b8173af8c24a..bf3f19b21fe4 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -923,6 +923,9 @@ static const struct file_operations nful_file_ops = { static int __init nfnetlink_log_init(void) { int i, status = -ENOMEM; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_nful; +#endif for (i = 0; i < INSTANCE_BUCKETS; i++) INIT_HLIST_HEAD(&instance_table[i]); @@ -940,9 +943,11 @@ static int __init nfnetlink_log_init(void) } #ifdef CONFIG_PROC_FS - if (!proc_create("nfnetlink_log", 0440, - proc_net_netfilter, &nful_file_ops)) + proc_nful = create_proc_entry("nfnetlink_log", 0440, + proc_net_netfilter); + if (!proc_nful) goto cleanup_subsys; + proc_nful->proc_fops = &nful_file_ops; #endif return status; diff --git a/trunk/net/netfilter/nfnetlink_queue.c b/trunk/net/netfilter/nfnetlink_queue.c index 10522c04ed24..012cb6910820 100644 --- a/trunk/net/netfilter/nfnetlink_queue.c +++ b/trunk/net/netfilter/nfnetlink_queue.c @@ -896,6 +896,9 @@ static const struct file_operations nfqnl_file_ops = { static int __init nfnetlink_queue_init(void) { int i, status = -ENOMEM; +#ifdef CONFIG_PROC_FS + struct proc_dir_entry *proc_nfqueue; +#endif for (i = 0; i < INSTANCE_BUCKETS; i++) INIT_HLIST_HEAD(&instance_table[i]); @@ -908,9 +911,11 @@ static int __init nfnetlink_queue_init(void) } #ifdef CONFIG_PROC_FS - if (!proc_create("nfnetlink_queue", 0440, - proc_net_netfilter, &nfqnl_file_ops)) + proc_nfqueue = create_proc_entry("nfnetlink_queue", 0440, + proc_net_netfilter); + if (!proc_nfqueue) goto cleanup_subsys; + proc_nfqueue->proc_fops = &nfqnl_file_ops; #endif register_netdevice_notifier(&nfqnl_dev_notifier); diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index dc29007c52cd..5418ce59ac3a 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -237,14 +237,14 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family) hinfo->family = family; hinfo->rnd_initialized = 0; spin_lock_init(&hinfo->lock); - hinfo->pde = proc_create(minfo->name, 0, - family == AF_INET ? hashlimit_procdir4 : - hashlimit_procdir6, - &dl_file_ops); + hinfo->pde = create_proc_entry(minfo->name, 0, + family == AF_INET ? hashlimit_procdir4 : + hashlimit_procdir6); if (!hinfo->pde) { vfree(hinfo); return -1; } + hinfo->pde->proc_fops = &dl_file_ops; hinfo->pde->data = hinfo; setup_timer(&hinfo->timer, htable_gc, (unsigned long )hinfo); @@ -301,14 +301,14 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, hinfo->rnd_initialized = 0; spin_lock_init(&hinfo->lock); - hinfo->pde = proc_create(minfo->name, 0, - family == AF_INET ? hashlimit_procdir4 : - hashlimit_procdir6, - &dl_file_ops); + hinfo->pde = create_proc_entry(minfo->name, 0, + family == AF_INET ? hashlimit_procdir4 : + hashlimit_procdir6); if (hinfo->pde == NULL) { vfree(hinfo); return -1; } + hinfo->pde->proc_fops = &dl_file_ops; hinfo->pde->data = hinfo; setup_timer(&hinfo->timer, htable_gc, (unsigned long)hinfo); diff --git a/trunk/net/rose/af_rose.c b/trunk/net/rose/af_rose.c index 063cbc5c26b1..4a31a81059ab 100644 --- a/trunk/net/rose/af_rose.c +++ b/trunk/net/rose/af_rose.c @@ -598,24 +598,17 @@ static int rose_release(struct socket *sock) if (sk == NULL) return 0; - sock_hold(sk); - sock_orphan(sk); - lock_sock(sk); rose = rose_sk(sk); switch (rose->state) { case ROSE_STATE_0: - release_sock(sk); rose_disconnect(sk, 0, -1, -1); - lock_sock(sk); rose_destroy_socket(sk); break; case ROSE_STATE_2: rose->neighbour->use--; - release_sock(sk); rose_disconnect(sk, 0, -1, -1); - lock_sock(sk); rose_destroy_socket(sk); break; @@ -640,8 +633,6 @@ static int rose_release(struct socket *sock) } sock->sk = NULL; - release_sock(sk); - sock_put(sk); return 0; } diff --git a/trunk/net/sched/sch_generic.c b/trunk/net/sched/sch_generic.c index b741618e4d54..10b5c0887fff 100644 --- a/trunk/net/sched/sch_generic.c +++ b/trunk/net/sched/sch_generic.c @@ -184,22 +184,10 @@ static inline int qdisc_restart(struct net_device *dev) void __qdisc_run(struct net_device *dev) { - unsigned long start_time = jiffies; - - while (qdisc_restart(dev)) { - if (netif_queue_stopped(dev)) - break; - - /* - * Postpone processing if - * 1. another process needs the CPU; - * 2. we've been doing it for too long. - */ - if (need_resched() || jiffies != start_time) { - netif_schedule(dev); + do { + if (!qdisc_restart(dev)) break; - } - } + } while (!netif_queue_stopped(dev)); clear_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); } diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index c2fef7b12dc7..41a049f50f58 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -1630,12 +1630,6 @@ static inline u32 file_to_av(struct file *file) else av |= FILE__WRITE; } - if (!av) { - /* - * Special file opened with flags 3 for ioctl-only use. - */ - av = FILE__IOCTL; - } return av; }